From 1900a390d81f0ffef9b86e7900fada54209c17c6 Mon Sep 17 00:00:00 2001 From: pablodanswer Date: Mon, 7 Oct 2024 13:21:07 -0700 Subject: [PATCH] Linting (#2704) * effect cleanup * remove unused imports * remove unne * remove unnecessary packages * k * temp * minor --- backend/danswer/llm/chat_llm.py | 1 + web/.eslintrc.json | 5 +- web/package.json | 2 +- web/src/app/admin/add-connector/page.tsx | 23 ++--- .../app/admin/assistants/AssistantEditor.tsx | 6 +- .../admin/assistants/CollapsibleSection.tsx | 1 - web/src/app/admin/assistants/PersonaTable.tsx | 10 +-- web/src/app/admin/assistants/lib.ts | 2 +- web/src/app/admin/assistants/page.tsx | 2 +- .../admin/bot/SlackBotConfigCreationForm.tsx | 3 +- web/src/app/admin/bot/new/page.tsx | 3 +- web/src/app/admin/bot/page.tsx | 15 +--- .../llm/CustomLLMProviderUpdateForm.tsx | 2 + web/src/app/admin/configuration/llm/page.tsx | 1 - .../configuration/search/UpgradingPage.tsx | 17 ++-- .../[ccPairId]/IndexingAttemptsTable.tsx | 88 +++++++++++-------- .../app/admin/connector/[ccPairId]/page.tsx | 47 +++++----- .../[connector]/AddConnectorPage.tsx | 5 +- .../[connector]/ConnectorWrapper.tsx | 2 +- .../admin/connectors/[connector]/Sidebar.tsx | 2 +- .../pages/ConnectorInput/NumberInput.tsx | 2 +- .../pages/ConnectorInput/SelectInput.tsx | 6 +- .../[connector]/pages/gdrive/Credential.tsx | 5 +- .../pages/gdrive/GoogleDrivePage.tsx | 7 +- .../[connector]/pages/gmail/Credential.tsx | 1 + .../[connector]/pages/gmail/GmailPage.tsx | 9 +- .../app/admin/documents/explorer/Explorer.tsx | 32 ++++--- .../feedback/DocumentFeedbackTable.tsx | 1 - .../sets/DocumentSetCreationForm.tsx | 4 +- web/src/app/admin/documents/sets/new/page.tsx | 1 - web/src/app/admin/documents/sets/page.tsx | 7 +- .../EmbeddingModelSelectionForm.tsx | 1 - .../modals/ChangeCredentialsModal.tsx | 2 +- .../embeddings/modals/ModelSelectionModal.tsx | 5 +- .../modals/ProviderCreationModal.tsx | 3 + .../pages/AdvancedEmbeddingFormPage.tsx | 3 +- .../embeddings/pages/CloudEmbeddingPage.tsx | 4 +- .../embeddings/pages/EmbeddingFormPage.tsx | 2 +- .../embeddings/pages/OpenEmbeddingPage.tsx | 11 ++- web/src/app/admin/indexing/[id]/page.tsx | 1 - web/src/app/admin/indexing/status/page.tsx | 4 - .../prompt-library/modals/AddPromptModal.tsx | 4 +- .../admin/prompt-library/promptLibrary.tsx | 1 - web/src/app/admin/settings/SettingsForm.tsx | 6 +- web/src/app/admin/token-rate-limits/page.tsx | 2 +- web/src/app/admin/tools/ToolEditor.tsx | 43 ++++----- web/src/app/admin/tools/ToolsTable.tsx | 1 - .../app/admin/tools/edit/[toolId]/page.tsx | 1 - web/src/app/admin/tools/new/page.tsx | 1 - web/src/app/admin/tools/page.tsx | 2 +- web/src/app/admin/users/page.tsx | 1 - web/src/app/assistants/SidebarWrapper.tsx | 13 ++- .../assistants/gallery/AssistantsGallery.tsx | 1 - .../assistants/mine/AssistantSharingModal.tsx | 2 +- .../app/assistants/mine/AssistantsList.tsx | 12 +-- .../assistants/mine/WrappedInputPrompts.tsx | 1 - web/src/app/auth/login/LoginText.tsx | 3 +- web/src/app/auth/verify-email/Verify.tsx | 8 +- web/src/app/chat/ChatPage.tsx | 26 ++++-- web/src/app/chat/ChatPopup.tsx | 2 +- web/src/app/chat/RegenerateOption.tsx | 1 - .../documentSidebar/ChatDocumentDisplay.tsx | 1 + .../chat/documentSidebar/DocumentSidebar.tsx | 2 +- web/src/app/chat/files/InputBarPreview.tsx | 2 +- .../files/images/InputBarPreviewImage.tsx | 1 + web/src/app/chat/folders/FolderManagement.tsx | 2 - web/src/app/chat/input/ChatInputBar.tsx | 2 +- web/src/app/chat/input/ChatInputOption.tsx | 6 +- web/src/app/chat/lib.tsx | 15 +--- web/src/app/chat/message/ContinueMessage.tsx | 2 +- web/src/app/chat/message/Messages.tsx | 9 +- web/src/app/chat/message/SearchSummary.tsx | 2 +- web/src/app/chat/message/SkippedSearch.tsx | 2 +- web/src/app/chat/modal/FeedbackModal.tsx | 7 +- .../app/chat/modal/SetDefaultModelModal.tsx | 4 +- .../app/chat/modal/ShareChatSessionModal.tsx | 3 +- .../modal/configuration/AssistantsTab.tsx | 1 - .../app/chat/modal/configuration/LlmTab.tsx | 20 ++--- .../app/chat/modifiers/SearchTypeSelector.tsx | 2 +- .../app/chat/modifiers/SelectedDocuments.tsx | 3 +- web/src/app/chat/page.tsx | 2 - .../sessionSidebar/ChatSessionDisplay.tsx | 6 +- .../chat/sessionSidebar/HistorySidebar.tsx | 3 +- web/src/app/chat/sessionSidebar/PagesTab.tsx | 2 +- .../ee/admin/api-key/DanswerApiKeyForm.tsx | 1 - web/src/app/ee/admin/api-key/page.tsx | 2 +- .../app/ee/admin/groups/ConnectorEditor.tsx | 2 +- web/src/app/ee/admin/groups/UserEditor.tsx | 1 - .../ee/admin/groups/UserGroupCreationForm.tsx | 2 - .../groups/[groupId]/AddConnectorForm.tsx | 1 - .../app/ee/admin/groups/[groupId]/page.tsx | 1 - web/src/app/ee/admin/groups/page.tsx | 4 +- .../query-history/QueryHistoryTable.tsx | 5 +- .../performance/query-history/[id]/page.tsx | 7 +- .../admin/performance/usage/UsageReports.tsx | 4 +- .../app/ee/admin/performance/usage/page.tsx | 1 - .../ee/admin/standard-answer/[id]/page.tsx | 1 - .../app/ee/admin/standard-answer/new/page.tsx | 1 - web/src/app/ee/admin/standard-answer/page.tsx | 13 +-- .../ee/admin/whitelabeling/ImageUpload.tsx | 6 +- web/src/app/layout.tsx | 3 +- web/src/app/search/page.tsx | 2 +- web/src/components/Dropdown.tsx | 22 +++-- web/src/components/IsPublicGroupSelector.tsx | 7 +- web/src/components/SSRAutoRefresh.tsx | 2 +- web/src/components/UserDropdown.tsx | 8 +- .../connectors/AccessTypeGroupSelector.tsx | 9 +- .../components/assistants/AssistantIcon.tsx | 1 + web/src/components/chat_search/Header.tsx | 2 +- .../chat_search/ProviderContext.tsx | 14 ++- web/src/components/chat_search/hooks.ts | 1 + .../components/context/EmbeddingContext.tsx | 2 +- web/src/components/context/FormContext.tsx | 2 +- web/src/components/health/healthcheck.tsx | 10 +-- .../search/NoCompleteSourceModal.tsx | 2 +- .../initialSetup/welcome/WelcomeModal.tsx | 2 +- web/src/components/search/SearchSection.tsx | 10 +-- web/src/lib/sources.ts | 8 -- web/src/lib/types.ts | 2 +- 119 files changed, 368 insertions(+), 371 deletions(-) diff --git a/backend/danswer/llm/chat_llm.py b/backend/danswer/llm/chat_llm.py index 274e0006c..1021f82ab 100644 --- a/backend/danswer/llm/chat_llm.py +++ b/backend/danswer/llm/chat_llm.py @@ -283,6 +283,7 @@ class DefaultMultiLLM(LLM): _convert_message_to_dict(msg) if isinstance(msg, BaseMessage) else msg for msg in prompt ] + elif isinstance(prompt, str): prompt = [_convert_message_to_dict(HumanMessage(content=prompt))] diff --git a/web/.eslintrc.json b/web/.eslintrc.json index bffb357a7..f0f3abee4 100644 --- a/web/.eslintrc.json +++ b/web/.eslintrc.json @@ -1,3 +1,6 @@ { - "extends": "next/core-web-vitals" + "extends": "next/core-web-vitals", + "rules": { + "@next/next/no-img-element": "off" + } } diff --git a/web/package.json b/web/package.json index 190ec9b1a..1e55fec59 100644 --- a/web/package.json +++ b/web/package.json @@ -56,4 +56,4 @@ "eslint-config-next": "^14.1.0", "prettier": "2.8.8" } -} +} \ No newline at end of file diff --git a/web/src/app/admin/add-connector/page.tsx b/web/src/app/admin/add-connector/page.tsx index 8d73131e6..ecf459d61 100644 --- a/web/src/app/admin/add-connector/page.tsx +++ b/web/src/app/admin/add-connector/page.tsx @@ -6,7 +6,7 @@ import { SourceCategory, SourceMetadata } from "@/lib/search/interfaces"; import { listSourceMetadata } from "@/lib/sources"; import { Title, Text, Button } from "@tremor/react"; import Link from "next/link"; -import { useEffect, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; function SourceTile({ sourceMetadata, @@ -49,15 +49,18 @@ export default function Page() { searchInputRef.current.focus(); } }, []); - const filterSources = (sources: SourceMetadata[]) => { - if (!searchTerm) return sources; - const lowerSearchTerm = searchTerm.toLowerCase(); - return sources.filter( - (source) => - source.displayName.toLowerCase().includes(lowerSearchTerm) || - source.category.toLowerCase().includes(lowerSearchTerm) - ); - }; + const filterSources = useCallback( + (sources: SourceMetadata[]) => { + if (!searchTerm) return sources; + const lowerSearchTerm = searchTerm.toLowerCase(); + return sources.filter( + (source) => + source.displayName.toLowerCase().includes(lowerSearchTerm) || + source.category.toLowerCase().includes(lowerSearchTerm) + ); + }, + [searchTerm] + ); const categorizedSources = useMemo(() => { const filtered = filterSources(sources); diff --git a/web/src/app/admin/assistants/AssistantEditor.tsx b/web/src/app/admin/assistants/AssistantEditor.tsx index 731070783..b9bd51521 100644 --- a/web/src/app/admin/assistants/AssistantEditor.tsx +++ b/web/src/app/admin/assistants/AssistantEditor.tsx @@ -132,7 +132,7 @@ export function AssistantEditor({ if (defaultIconShape === null) { setDefaultIconShape(generateRandomIconShape().encodedGrid); } - }, []); + }, [defaultIconShape]); const [isIconDropdownOpen, setIsIconDropdownOpen] = useState(false); @@ -166,7 +166,7 @@ export function AssistantEditor({ existingPersona.num_chunks === 0 ); } - }, [isUpdate, existingPrompt]); + }, [isUpdate, existingPrompt, existingPersona?.num_chunks]); const defaultProvider = llmProviders.find( (llmProvider) => llmProvider.is_default_provider @@ -888,7 +888,7 @@ export function AssistantEditor({ values.document_set_ids.indexOf( documentSet.id ); - let isSelected = ind !== -1; + const isSelected = ind !== -1; return ( p.id.toString()) - ); + const editablePersonaIds = useMemo(() => { + return new Set(editablePersonas.map((p) => p.id.toString())); + }, [editablePersonas]); const sortedPersonas = useMemo(() => { const editable = editablePersonas.sort(personaComparator); diff --git a/web/src/app/admin/assistants/lib.ts b/web/src/app/admin/assistants/lib.ts index fd5851ac7..9b79ea7ef 100644 --- a/web/src/app/admin/assistants/lib.ts +++ b/web/src/app/admin/assistants/lib.ts @@ -276,7 +276,7 @@ export function buildFinalPrompt( taskPrompt: string, retrievalDisabled: boolean ) { - let queryString = Object.entries({ + const queryString = Object.entries({ system_prompt: systemPrompt, task_prompt: taskPrompt, retrieval_disabled: retrievalDisabled, diff --git a/web/src/app/admin/assistants/page.tsx b/web/src/app/admin/assistants/page.tsx index 159094705..7f3922ac4 100644 --- a/web/src/app/admin/assistants/page.tsx +++ b/web/src/app/admin/assistants/page.tsx @@ -5,7 +5,7 @@ import { Divider, Text, Title } from "@tremor/react"; import { fetchSS } from "@/lib/utilsSS"; import { ErrorCallout } from "@/components/ErrorCallout"; import { Persona } from "./interfaces"; -import { AssistantsIcon, RobotIcon } from "@/components/icons/icons"; +import { AssistantsIcon } from "@/components/icons/icons"; import { AdminPageTitle } from "@/components/admin/Title"; export default async function Page() { diff --git a/web/src/app/admin/bot/SlackBotConfigCreationForm.tsx b/web/src/app/admin/bot/SlackBotConfigCreationForm.tsx index 4f79c7993..9fb5aa063 100644 --- a/web/src/app/admin/bot/SlackBotConfigCreationForm.tsx +++ b/web/src/app/admin/bot/SlackBotConfigCreationForm.tsx @@ -20,7 +20,6 @@ import { Button, Card, Divider } from "@tremor/react"; import { useRouter } from "next/navigation"; import { Persona } from "../assistants/interfaces"; import { useState } from "react"; -import MultiSelectDropdown from "@/components/MultiSelectDropdown"; import { AdvancedOptionsToggle } from "@/components/AdvancedOptionsToggle"; import { DocumentSetSelectable } from "@/components/documentSet/DocumentSetSelectable"; import CollapsibleSection from "../assistants/CollapsibleSection"; @@ -229,7 +228,7 @@ export const SlackBotCreationForm = ({ const ind = values.document_sets.indexOf( documentSet.id ); - let isSelected = ind !== -1; + const isSelected = ind !== -1; return ( { className="text-blue-500" href="https://docs.danswer.dev/slack_bot_setup" target="_blank" + rel="noreferrer" > guide{" "} diff --git a/web/src/app/admin/configuration/llm/CustomLLMProviderUpdateForm.tsx b/web/src/app/admin/configuration/llm/CustomLLMProviderUpdateForm.tsx index 66b306d77..18ef2202c 100644 --- a/web/src/app/admin/configuration/llm/CustomLLMProviderUpdateForm.tsx +++ b/web/src/app/admin/configuration/llm/CustomLLMProviderUpdateForm.tsx @@ -220,6 +220,7 @@ export function CustomLLMProviderUpdateForm({ target="_blank" href="https://docs.litellm.ai/docs/providers" className="text-link" + rel="noreferrer" > https://docs.litellm.ai/docs/providers @@ -373,6 +374,7 @@ export function CustomLLMProviderUpdateForm({ target="_blank" href="https://models.litellm.ai/" className="text-link" + rel="noreferrer" > here diff --git a/web/src/app/admin/configuration/llm/page.tsx b/web/src/app/admin/configuration/llm/page.tsx index 9771a53c3..e68b225df 100644 --- a/web/src/app/admin/configuration/llm/page.tsx +++ b/web/src/app/admin/configuration/llm/page.tsx @@ -1,7 +1,6 @@ "use client"; import { AdminPageTitle } from "@/components/admin/Title"; -import { FiCpu } from "react-icons/fi"; import { LLMConfiguration } from "./LLMConfiguration"; import { CpuIcon } from "@/components/icons/icons"; diff --git a/web/src/app/admin/configuration/search/UpgradingPage.tsx b/web/src/app/admin/configuration/search/UpgradingPage.tsx index bbbb75797..2d9415e10 100644 --- a/web/src/app/admin/configuration/search/UpgradingPage.tsx +++ b/web/src/app/admin/configuration/search/UpgradingPage.tsx @@ -63,13 +63,16 @@ export default function UpgradingPage({ } setIsCancelling(false); }; - const statusOrder: Record = { - failed: 0, - completed_with_errors: 1, - not_started: 2, - in_progress: 3, - success: 4, - }; + const statusOrder: Record = useMemo( + () => ({ + failed: 0, + completed_with_errors: 1, + not_started: 2, + in_progress: 3, + success: 4, + }), + [] + ); const sortedReindexingProgress = useMemo(() => { return [...(ongoingReIndexingStatus || [])].sort((a, b) => { diff --git a/web/src/app/admin/connector/[ccPairId]/IndexingAttemptsTable.tsx b/web/src/app/admin/connector/[ccPairId]/IndexingAttemptsTable.tsx index 37cfac874..517fb1585 100644 --- a/web/src/app/admin/connector/[ccPairId]/IndexingAttemptsTable.tsx +++ b/web/src/app/admin/connector/[ccPairId]/IndexingAttemptsTable.tsx @@ -1,6 +1,6 @@ "use client"; -import { useEffect, useRef } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { Table, TableHead, @@ -10,9 +10,8 @@ import { TableCell, Text, } from "@tremor/react"; -import { CCPairFullInfo } from "./types"; +import { CCPairFullInfo, PaginatedIndexAttempts } from "./types"; import { IndexAttemptStatus } from "@/components/Status"; -import { useState } from "react"; import { PageSelector } from "@/components/PageSelector"; import { ThreeDotsLoader } from "@/components/Loading"; import { buildCCPairInfoUrl } from "./lib"; @@ -22,7 +21,6 @@ import { ErrorCallout } from "@/components/ErrorCallout"; import { InfoIcon, SearchIcon } from "@/components/icons/icons"; import Link from "next/link"; import ExceptionTraceModal from "@/components/modals/ExceptionTraceModal"; -import { PaginatedIndexAttempts } from "./types"; import { useRouter } from "next/navigation"; import { Tooltip } from "@/components/tooltip/Tooltip"; @@ -61,47 +59,59 @@ export function IndexingAttemptsTable({ ccPair }: { ccPair: CCPairFullInfo }) { // we use it to avoid duplicate requests const ongoingRequestsRef = useRef>(new Set()); - const batchRetrievalUrlBuilder = (batchNum: number) => - `${buildCCPairInfoUrl(ccPair.id)}/index-attempts?page=${batchNum}&page_size=${BATCH_SIZE * NUM_IN_PAGE}`; + const batchRetrievalUrlBuilder = useCallback( + (batchNum: number) => { + return `${buildCCPairInfoUrl(ccPair.id)}/index-attempts?page=${batchNum}&page_size=${BATCH_SIZE * NUM_IN_PAGE}`; + }, + [ccPair.id] + ); // This fetches and caches the data for a given batch number - const fetchBatchData = async (batchNum: number) => { - if (ongoingRequestsRef.current.has(batchNum)) return; - ongoingRequestsRef.current.add(batchNum); + const fetchBatchData = useCallback( + async (batchNum: number) => { + if (ongoingRequestsRef.current.has(batchNum)) return; + ongoingRequestsRef.current.add(batchNum); - try { - const response = await fetch(batchRetrievalUrlBuilder(batchNum + 1)); - if (!response.ok) { - throw new Error("Failed to fetch data"); - } - const data = await response.json(); + try { + const response = await fetch(batchRetrievalUrlBuilder(batchNum + 1)); + if (!response.ok) { + throw new Error("Failed to fetch data"); + } + const data = await response.json(); - const newBatchData: PaginatedIndexAttempts[] = []; - for (let i = 0; i < BATCH_SIZE; i++) { - const startIndex = i * NUM_IN_PAGE; - const endIndex = startIndex + NUM_IN_PAGE; - const pageIndexAttempts = data.index_attempts.slice( - startIndex, - endIndex + const newBatchData: PaginatedIndexAttempts[] = []; + for (let i = 0; i < BATCH_SIZE; i++) { + const startIndex = i * NUM_IN_PAGE; + const endIndex = startIndex + NUM_IN_PAGE; + const pageIndexAttempts = data.index_attempts.slice( + startIndex, + endIndex + ); + newBatchData.push({ + ...data, + index_attempts: pageIndexAttempts, + }); + } + + setCachedBatches((prev) => ({ + ...prev, + [batchNum]: newBatchData, + })); + } catch (error) { + setCurrentPageError( + error instanceof Error ? error : new Error("An error occurred") ); - newBatchData.push({ - ...data, - index_attempts: pageIndexAttempts, - }); + } finally { + ongoingRequestsRef.current.delete(batchNum); } - - setCachedBatches((prev) => ({ - ...prev, - [batchNum]: newBatchData, - })); - } catch (error) { - setCurrentPageError( - error instanceof Error ? error : new Error("An error occurred") - ); - } finally { - ongoingRequestsRef.current.delete(batchNum); - } - }; + }, + [ + ongoingRequestsRef, + setCachedBatches, + setCurrentPageError, + batchRetrievalUrlBuilder, + ] + ); // This fetches and caches the data for the current batch and the next and previous batches useEffect(() => { diff --git a/web/src/app/admin/connector/[ccPairId]/page.tsx b/web/src/app/admin/connector/[ccPairId]/page.tsx index dc5ca7aea..91c2e197b 100644 --- a/web/src/app/admin/connector/[ccPairId]/page.tsx +++ b/web/src/app/admin/connector/[ccPairId]/page.tsx @@ -1,29 +1,29 @@ "use client"; -import { CCPairFullInfo, ConnectorCredentialPairStatus } from "./types"; -import { CCPairStatus } from "@/components/Status"; import { BackButton } from "@/components/BackButton"; -import { Button, Divider, Title } from "@tremor/react"; -import { IndexingAttemptsTable } from "./IndexingAttemptsTable"; -import { AdvancedConfigDisplay, ConfigDisplay } from "./ConfigDisplay"; -import { ModifyStatusButtonCluster } from "./ModifyStatusButtonCluster"; -import { DeletionButton } from "./DeletionButton"; import { ErrorCallout } from "@/components/ErrorCallout"; -import { ReIndexButton } from "./ReIndexButton"; -import { ValidSources } from "@/lib/types"; -import useSWR, { mutate } from "swr"; -import { errorHandlingFetcher } from "@/lib/fetcher"; import { ThreeDotsLoader } from "@/components/Loading"; -import CredentialSection from "@/components/credentials/CredentialSection"; -import { buildCCPairInfoUrl } from "./lib"; import { SourceIcon } from "@/components/SourceIcon"; -import { credentialTemplates } from "@/lib/connectors/credentials"; -import { useEffect, useRef, useState } from "react"; -import { CheckmarkIcon, EditIcon, XIcon } from "@/components/icons/icons"; +import { CCPairStatus } from "@/components/Status"; import { usePopup } from "@/components/admin/connectors/Popup"; +import CredentialSection from "@/components/credentials/CredentialSection"; +import { CheckmarkIcon, EditIcon, XIcon } from "@/components/icons/icons"; import { updateConnectorCredentialPairName } from "@/lib/connector"; -import DeletionErrorStatus from "./DeletionErrorStatus"; +import { credentialTemplates } from "@/lib/connectors/credentials"; +import { errorHandlingFetcher } from "@/lib/fetcher"; +import { ValidSources } from "@/lib/types"; +import { Button, Divider, Title } from "@tremor/react"; import { useRouter } from "next/navigation"; +import { useCallback, useEffect, useRef, useState } from "react"; +import useSWR, { mutate } from "swr"; +import { AdvancedConfigDisplay, ConfigDisplay } from "./ConfigDisplay"; +import { DeletionButton } from "./DeletionButton"; +import DeletionErrorStatus from "./DeletionErrorStatus"; +import { IndexingAttemptsTable } from "./IndexingAttemptsTable"; +import { ModifyStatusButtonCluster } from "./ModifyStatusButtonCluster"; +import { ReIndexButton } from "./ReIndexButton"; +import { buildCCPairInfoUrl } from "./lib"; +import { CCPairFullInfo, ConnectorCredentialPairStatus } from "./types"; // since the uploaded files are cleaned up after some period of time // re-indexing will not work for the file connector. Also, it would not @@ -49,7 +49,7 @@ function Main({ ccPairId }: { ccPairId: number }) { const { popup, setPopup } = usePopup(); - const finishConnectorDeletion = () => { + const finishConnectorDeletion = useCallback(() => { setPopup({ message: "Connector deleted successfully", type: "success", @@ -57,7 +57,7 @@ function Main({ ccPairId }: { ccPairId: number }) { setTimeout(() => { router.push("/admin/indexing/status"); }, 2000); - }; + }, [router, setPopup]); useEffect(() => { if (isEditing && inputRef.current) { @@ -80,7 +80,14 @@ function Main({ ccPairId }: { ccPairId: number }) { ) { finishConnectorDeletion(); } - }, [isLoading, ccPair, error, hasLoadedOnce, router]); + }, [ + isLoading, + ccPair, + error, + hasLoadedOnce, + router, + finishConnectorDeletion, + ]); const handleNameChange = (e: React.ChangeEvent) => { setEditableName(e.target.value); diff --git a/web/src/app/admin/connectors/[connector]/AddConnectorPage.tsx b/web/src/app/admin/connectors/[connector]/AddConnectorPage.tsx index 07b719d83..b01347eda 100644 --- a/web/src/app/admin/connectors/[connector]/AddConnectorPage.tsx +++ b/web/src/app/admin/connectors/[connector]/AddConnectorPage.tsx @@ -1,6 +1,6 @@ "use client"; -import { FetchError, errorHandlingFetcher } from "@/lib/fetcher"; +import { errorHandlingFetcher } from "@/lib/fetcher"; import useSWR, { mutate } from "swr"; import { HealthCheckBanner } from "@/components/health/healthcheck"; @@ -29,6 +29,8 @@ import { defaultPruneFreqDays, defaultRefreshFreqMinutes, isLoadState, + Connector, + ConnectorBase, } from "@/lib/connectors/connectors"; import { Modal } from "@/components/Modal"; import GDriveMain from "./pages/gdrive/GoogleDrivePage"; @@ -47,7 +49,6 @@ export interface AdvancedConfig { pruneFreq: number; indexingStart: string; } -import { Connector, ConnectorBase } from "@/lib/connectors/connectors"; const BASE_CONNECTOR_URL = "/api/manage/admin/connector"; diff --git a/web/src/app/admin/connectors/[connector]/ConnectorWrapper.tsx b/web/src/app/admin/connectors/[connector]/ConnectorWrapper.tsx index c038cdbb4..282aafbfb 100644 --- a/web/src/app/admin/connectors/[connector]/ConnectorWrapper.tsx +++ b/web/src/app/admin/connectors/[connector]/ConnectorWrapper.tsx @@ -1,6 +1,6 @@ "use client"; -import { ConfigurableSources, ValidSources } from "@/lib/types"; +import { ConfigurableSources } from "@/lib/types"; import AddConnector from "./AddConnectorPage"; import { FormProvider } from "@/components/context/FormContext"; import Sidebar from "./Sidebar"; diff --git a/web/src/app/admin/connectors/[connector]/Sidebar.tsx b/web/src/app/admin/connectors/[connector]/Sidebar.tsx index 4b7f2970d..c31e3930c 100644 --- a/web/src/app/admin/connectors/[connector]/Sidebar.tsx +++ b/web/src/app/admin/connectors/[connector]/Sidebar.tsx @@ -1,7 +1,7 @@ import { useFormContext } from "@/components/context/FormContext"; import { HeaderTitle } from "@/components/header/HeaderTitle"; -import { BackIcon, SettingsIcon } from "@/components/icons/icons"; +import { SettingsIcon } from "@/components/icons/icons"; import { Logo } from "@/components/Logo"; import { SettingsContext } from "@/components/settings/SettingsProvider"; import { credentialTemplates } from "@/lib/connectors/credentials"; diff --git a/web/src/app/admin/connectors/[connector]/pages/ConnectorInput/NumberInput.tsx b/web/src/app/admin/connectors/[connector]/pages/ConnectorInput/NumberInput.tsx index b7fcb49cf..0f19c22ad 100644 --- a/web/src/app/admin/connectors/[connector]/pages/ConnectorInput/NumberInput.tsx +++ b/web/src/app/admin/connectors/[connector]/pages/ConnectorInput/NumberInput.tsx @@ -1,5 +1,5 @@ import { SubLabel } from "@/components/admin/connectors/Field"; -import { Field, useFormikContext } from "formik"; +import { Field } from "formik"; export default function NumberInput({ label, diff --git a/web/src/app/admin/connectors/[connector]/pages/ConnectorInput/SelectInput.tsx b/web/src/app/admin/connectors/[connector]/pages/ConnectorInput/SelectInput.tsx index a7c14deec..2f926e641 100644 --- a/web/src/app/admin/connectors/[connector]/pages/ConnectorInput/SelectInput.tsx +++ b/web/src/app/admin/connectors/[connector]/pages/ConnectorInput/SelectInput.tsx @@ -1,9 +1,5 @@ import CredentialSubText from "@/components/credentials/CredentialFields"; -import { - ListOption, - SelectOption, - StringWithDescription, -} from "@/lib/connectors/connectors"; +import { StringWithDescription } from "@/lib/connectors/connectors"; import { Field } from "formik"; export default function SelectInput({ diff --git a/web/src/app/admin/connectors/[connector]/pages/gdrive/Credential.tsx b/web/src/app/admin/connectors/[connector]/pages/gdrive/Credential.tsx index 8fc1fa767..371bbef6d 100644 --- a/web/src/app/admin/connectors/[connector]/pages/gdrive/Credential.tsx +++ b/web/src/app/admin/connectors/[connector]/pages/gdrive/Credential.tsx @@ -10,15 +10,13 @@ import { GOOGLE_DRIVE_AUTH_IS_ADMIN_COOKIE_NAME } from "@/lib/constants"; import Cookies from "js-cookie"; import { TextFormField } from "@/components/admin/connectors/Field"; import { Form, Formik } from "formik"; -import { Card } from "@tremor/react"; +import { Button as TremorButton } from "@tremor/react"; import { Credential, GoogleDriveCredentialJson, GoogleDriveServiceAccountCredentialJson, } from "@/lib/connectors/credentials"; -import { Button as TremorButton } from "@tremor/react"; - type GoogleDriveCredentialJsonTypes = "authorized_user" | "service_account"; export const DriveJsonUpload = ({ @@ -285,6 +283,7 @@ export const DriveJsonUploadSection = ({ className="text-link" target="_blank" href="https://docs.danswer.dev/connectors/google_drive#authorization" + rel="noreferrer" > here {" "} diff --git a/web/src/app/admin/connectors/[connector]/pages/gdrive/GoogleDrivePage.tsx b/web/src/app/admin/connectors/[connector]/pages/gdrive/GoogleDrivePage.tsx index 247b64e61..d8a14db03 100644 --- a/web/src/app/admin/connectors/[connector]/pages/gdrive/GoogleDrivePage.tsx +++ b/web/src/app/admin/connectors/[connector]/pages/gdrive/GoogleDrivePage.tsx @@ -1,14 +1,16 @@ "use client"; import React from "react"; -import { useState, useEffect } from "react"; import useSWR from "swr"; import { FetchError, errorHandlingFetcher } from "@/lib/fetcher"; import { ErrorCallout } from "@/components/ErrorCallout"; import { LoadingAnimation } from "@/components/Loading"; import { usePopup } from "@/components/admin/connectors/Popup"; import { ConnectorIndexingStatus } from "@/lib/types"; -import { usePublicCredentials } from "@/lib/hooks"; +import { + usePublicCredentials, + useConnectorCredentialIndexingStatus, +} from "@/lib/hooks"; import { Title } from "@tremor/react"; import { DriveJsonUploadSection, DriveOAuthSection } from "./Credential"; import { @@ -18,7 +20,6 @@ import { } from "@/lib/connectors/credentials"; import { GoogleDriveConfig } from "@/lib/connectors/connectors"; import { useUser } from "@/components/user/UserProvider"; -import { useConnectorCredentialIndexingStatus } from "@/lib/hooks"; const GDriveMain = ({}: {}) => { const { isLoadingUser, isAdmin } = useUser(); diff --git a/web/src/app/admin/connectors/[connector]/pages/gmail/Credential.tsx b/web/src/app/admin/connectors/[connector]/pages/gmail/Credential.tsx index 8b456884f..51502bd44 100644 --- a/web/src/app/admin/connectors/[connector]/pages/gmail/Credential.tsx +++ b/web/src/app/admin/connectors/[connector]/pages/gmail/Credential.tsx @@ -271,6 +271,7 @@ export const GmailJsonUploadSection = ({ className="text-link" target="_blank" href="https://docs.danswer.dev/connectors/gmail#authorization" + rel="noreferrer" > here {" "} diff --git a/web/src/app/admin/connectors/[connector]/pages/gmail/GmailPage.tsx b/web/src/app/admin/connectors/[connector]/pages/gmail/GmailPage.tsx index 5f52eb310..1a7fbe5de 100644 --- a/web/src/app/admin/connectors/[connector]/pages/gmail/GmailPage.tsx +++ b/web/src/app/admin/connectors/[connector]/pages/gmail/GmailPage.tsx @@ -5,20 +5,19 @@ import { errorHandlingFetcher } from "@/lib/fetcher"; import { LoadingAnimation } from "@/components/Loading"; import { usePopup } from "@/components/admin/connectors/Popup"; import { ConnectorIndexingStatus } from "@/lib/types"; -import { getCurrentUser } from "@/lib/user"; -import { User, UserRole } from "@/lib/types"; import { Credential, GmailCredentialJson, GmailServiceAccountCredentialJson, } from "@/lib/connectors/credentials"; import { GmailOAuthSection, GmailJsonUploadSection } from "./Credential"; -import { usePublicCredentials } from "@/lib/hooks"; +import { + usePublicCredentials, + useConnectorCredentialIndexingStatus, +} from "@/lib/hooks"; import { Title } from "@tremor/react"; import { GmailConfig } from "@/lib/connectors/connectors"; -import { useState, useEffect } from "react"; import { useUser } from "@/components/user/UserProvider"; -import { useConnectorCredentialIndexingStatus } from "@/lib/hooks"; export const GmailMain = () => { const { isLoadingUser, isAdmin } = useUser(); diff --git a/web/src/app/admin/documents/explorer/Explorer.tsx b/web/src/app/admin/documents/explorer/Explorer.tsx index c1722b01e..4d47d6c7a 100644 --- a/web/src/app/admin/documents/explorer/Explorer.tsx +++ b/web/src/app/admin/documents/explorer/Explorer.tsx @@ -2,7 +2,7 @@ import { adminSearch } from "./lib"; import { MagnifyingGlass } from "@phosphor-icons/react"; -import { useState, useEffect } from "react"; +import { useState, useEffect, useCallback } from "react"; import { DanswerDocument } from "@/lib/search/interfaces"; import { buildDocumentSummaryDisplay } from "@/components/search/DocumentDisplay"; import { CustomCheckbox } from "@/components/CustomCheckbox"; @@ -121,19 +121,27 @@ export function Explorer({ const filterManager = useFilters(); - const onSearch = async (query: string) => { - const filters = buildFilters( - filterManager.selectedSources, + const onSearch = useCallback( + async (query: string) => { + const filters = buildFilters( + filterManager.selectedSources, + filterManager.selectedDocumentSets, + filterManager.timeRange, + filterManager.selectedTags + ); + const results = await adminSearch(query, filters); + if (results.ok) { + setResults((await results.json()).documents); + } + setTimeoutId(null); + }, + [ filterManager.selectedDocumentSets, + filterManager.selectedSources, filterManager.timeRange, - filterManager.selectedTags - ); - const results = await adminSearch(query, filters); - if (results.ok) { - setResults((await results.json()).documents); - } - setTimeoutId(null); - }; + filterManager.selectedTags, + ] + ); useEffect(() => { if (timeoutId !== null) { diff --git a/web/src/app/admin/documents/feedback/DocumentFeedbackTable.tsx b/web/src/app/admin/documents/feedback/DocumentFeedbackTable.tsx index 936afad12..09713b104 100644 --- a/web/src/app/admin/documents/feedback/DocumentFeedbackTable.tsx +++ b/web/src/app/admin/documents/feedback/DocumentFeedbackTable.tsx @@ -1,4 +1,3 @@ -import { BasicTable } from "@/components/admin/connectors/BasicTable"; import { usePopup } from "@/components/admin/connectors/Popup"; import { useState } from "react"; import { diff --git a/web/src/app/admin/documents/sets/DocumentSetCreationForm.tsx b/web/src/app/admin/documents/sets/DocumentSetCreationForm.tsx index fb7e56cc6..8da5ee0a8 100644 --- a/web/src/app/admin/documents/sets/DocumentSetCreationForm.tsx +++ b/web/src/app/admin/documents/sets/DocumentSetCreationForm.tsx @@ -177,7 +177,7 @@ export const DocumentSetCreationForm = ({ const ind = props.values.cc_pair_ids.indexOf( ccPair.cc_pair_id ); - let isSelected = ind !== -1; + const isSelected = ind !== -1; return (
here {" "} @@ -175,6 +176,7 @@ export function ProviderCreationModal({ className="cursor-pointer underline" target="_blank" href={selectedProvider.apiLink} + rel="noreferrer" > {isProxy ? "API URL" : "API KEY"} @@ -223,6 +225,7 @@ export function ProviderCreationModal({ href={selectedProvider.apiLink} target="_blank" className="underline cursor-pointer" + rel="noreferrer" > Learn more here diff --git a/web/src/app/admin/embeddings/pages/AdvancedEmbeddingFormPage.tsx b/web/src/app/admin/embeddings/pages/AdvancedEmbeddingFormPage.tsx index c965bdfab..b70867511 100644 --- a/web/src/app/admin/embeddings/pages/AdvancedEmbeddingFormPage.tsx +++ b/web/src/app/admin/embeddings/pages/AdvancedEmbeddingFormPage.tsx @@ -1,7 +1,6 @@ -import React, { Dispatch, forwardRef, SetStateAction } from "react"; +import React, { forwardRef } from "react"; import { Formik, Form, FormikProps, FieldArray, Field } from "formik"; import * as Yup from "yup"; -import CredentialSubText from "@/components/credentials/CredentialFields"; import { TrashIcon } from "@/components/icons/icons"; import { FaPlus } from "react-icons/fa"; import { AdvancedSearchConfiguration } from "../interfaces"; diff --git a/web/src/app/admin/embeddings/pages/CloudEmbeddingPage.tsx b/web/src/app/admin/embeddings/pages/CloudEmbeddingPage.tsx index a6c71530f..dd202dc4f 100644 --- a/web/src/app/admin/embeddings/pages/CloudEmbeddingPage.tsx +++ b/web/src/app/admin/embeddings/pages/CloudEmbeddingPage.tsx @@ -1,6 +1,6 @@ "use client"; -import { Button, Card, Text, Title } from "@tremor/react"; +import { Card, Text, Title } from "@tremor/react"; import { CloudEmbeddingProvider, @@ -56,7 +56,7 @@ export default function CloudEmbeddingPage({ ); } - let providers: CloudEmbeddingProviderFull[] = AVAILABLE_CLOUD_PROVIDERS.map( + const providers: CloudEmbeddingProviderFull[] = AVAILABLE_CLOUD_PROVIDERS.map( (model) => ({ ...model, configured: diff --git a/web/src/app/admin/embeddings/pages/EmbeddingFormPage.tsx b/web/src/app/admin/embeddings/pages/EmbeddingFormPage.tsx index 196c99da0..6060868e8 100644 --- a/web/src/app/admin/embeddings/pages/EmbeddingFormPage.tsx +++ b/web/src/app/admin/embeddings/pages/EmbeddingFormPage.tsx @@ -165,7 +165,7 @@ export default function EmbeddingForm() { } const updateSearch = async () => { - let values: SavedSearchSettings = { + const values: SavedSearchSettings = { ...rerankingDetails, ...advancedEmbeddingDetails, provider_type: diff --git a/web/src/app/admin/embeddings/pages/OpenEmbeddingPage.tsx b/web/src/app/admin/embeddings/pages/OpenEmbeddingPage.tsx index 2e28ce8e4..1b573cdd3 100644 --- a/web/src/app/admin/embeddings/pages/OpenEmbeddingPage.tsx +++ b/web/src/app/admin/embeddings/pages/OpenEmbeddingPage.tsx @@ -1,5 +1,5 @@ "use client"; -import { Button, Card, Text } from "@tremor/react"; +import { Button, Card, Text, Title } from "@tremor/react"; import { ModelSelector } from "../../../../components/embedding/ModelSelector"; import { AVAILABLE_MODELS, @@ -8,7 +8,6 @@ import { } from "../../../../components/embedding/interfaces"; import { CustomModelForm } from "../../../../components/embedding/CustomModelForm"; import { useState } from "react"; -import { Title } from "@tremor/react"; export default function OpenEmbeddingPage({ onSelectOpenSource, selectedProvider, @@ -34,7 +33,12 @@ export default function OpenEmbeddingPage({ Alternatively, (if you know what you're doing) you can specify a{" "} - + SentenceTransformers -compatible model of your choice below. The rough list of supported @@ -43,6 +47,7 @@ export default function OpenEmbeddingPage({ target="_blank" href="https://huggingface.co/models?library=sentence-transformers&sort=trending" className="text-link" + rel="noreferrer" > here diff --git a/web/src/app/admin/indexing/[id]/page.tsx b/web/src/app/admin/indexing/[id]/page.tsx index 51fe69454..041f7bda9 100644 --- a/web/src/app/admin/indexing/[id]/page.tsx +++ b/web/src/app/admin/indexing/[id]/page.tsx @@ -4,7 +4,6 @@ import { BackButton } from "@/components/BackButton"; import { ErrorCallout } from "@/components/ErrorCallout"; import { ThreeDotsLoader } from "@/components/Loading"; import { errorHandlingFetcher } from "@/lib/fetcher"; -import { ValidSources } from "@/lib/types"; import { Title } from "@tremor/react"; import useSWR from "swr"; import { IndexAttemptErrorsTable } from "./IndexAttemptErrorsTable"; diff --git a/web/src/app/admin/indexing/status/page.tsx b/web/src/app/admin/indexing/status/page.tsx index bb56ceaa7..e5f1ea6ce 100644 --- a/web/src/app/admin/indexing/status/page.tsx +++ b/web/src/app/admin/indexing/status/page.tsx @@ -1,11 +1,7 @@ "use client"; -import useSWR from "swr"; - import { LoadingAnimation } from "@/components/Loading"; import { NotebookIcon } from "@/components/icons/icons"; -import { errorHandlingFetcher } from "@/lib/fetcher"; -import { ConnectorIndexingStatus } from "@/lib/types"; import { CCPairIndexingStatusTable } from "./CCPairIndexingStatusTable"; import { AdminPageTitle } from "@/components/admin/Title"; import Link from "next/link"; diff --git a/web/src/app/admin/prompt-library/modals/AddPromptModal.tsx b/web/src/app/admin/prompt-library/modals/AddPromptModal.tsx index 0d385f484..be83a19e9 100644 --- a/web/src/app/admin/prompt-library/modals/AddPromptModal.tsx +++ b/web/src/app/admin/prompt-library/modals/AddPromptModal.tsx @@ -1,8 +1,8 @@ import React from "react"; -import { Formik, Form, Field, ErrorMessage } from "formik"; +import { Formik, Form } from "formik"; import * as Yup from "yup"; import { ModalWrapper } from "@/components/modals/ModalWrapper"; -import { Button, Textarea, TextInput } from "@tremor/react"; +import { Button } from "@tremor/react"; import { BookstackIcon } from "@/components/icons/icons"; import { AddPromptModalProps } from "../interfaces"; diff --git a/web/src/app/admin/prompt-library/promptLibrary.tsx b/web/src/app/admin/prompt-library/promptLibrary.tsx index 18cb5927b..a5427bdf0 100644 --- a/web/src/app/admin/prompt-library/promptLibrary.tsx +++ b/web/src/app/admin/prompt-library/promptLibrary.tsx @@ -16,7 +16,6 @@ import { FilterDropdown } from "@/components/search/filtering/FilterDropdown"; import { FiTag } from "react-icons/fi"; import { PageSelector } from "@/components/PageSelector"; import { InputPrompt } from "./interfaces"; -import { Modal } from "@/components/Modal"; import { DeleteEntityModal } from "@/components/modals/DeleteEntityModal"; const CategoryBubble = ({ diff --git a/web/src/app/admin/settings/SettingsForm.tsx b/web/src/app/admin/settings/SettingsForm.tsx index 03a017136..9017c920a 100644 --- a/web/src/app/admin/settings/SettingsForm.tsx +++ b/web/src/app/admin/settings/SettingsForm.tsx @@ -2,15 +2,13 @@ import { Label, SubLabel } from "@/components/admin/connectors/Field"; import { usePopup } from "@/components/admin/connectors/Popup"; -import { Title } from "@tremor/react"; +import { Title, Button } from "@tremor/react"; import { Settings } from "./interfaces"; import { useRouter } from "next/navigation"; import { DefaultDropdown, Option } from "@/components/Dropdown"; -import { useContext } from "react"; +import React, { useContext, useState, useEffect } from "react"; import { SettingsContext } from "@/components/settings/SettingsProvider"; -import React, { useState, useEffect } from "react"; import { usePaidEnterpriseFeaturesEnabled } from "@/components/settings/usePaidEnterpriseFeaturesEnabled"; -import { Button } from "@tremor/react"; function Checkbox({ label, diff --git a/web/src/app/admin/token-rate-limits/page.tsx b/web/src/app/admin/token-rate-limits/page.tsx index fb4b711a2..c64a8cc5f 100644 --- a/web/src/app/admin/token-rate-limits/page.tsx +++ b/web/src/app/admin/token-rate-limits/page.tsx @@ -11,7 +11,7 @@ import { Text, } from "@tremor/react"; import { useState } from "react"; -import { FiGlobe, FiShield, FiUser, FiUsers } from "react-icons/fi"; +import { FiGlobe, FiUser, FiUsers } from "react-icons/fi"; import { insertGlobalTokenRateLimit, insertGroupTokenRateLimit, diff --git a/web/src/app/admin/tools/ToolEditor.tsx b/web/src/app/admin/tools/ToolEditor.tsx index 0ffb8750e..b6d080ebd 100644 --- a/web/src/app/admin/tools/ToolEditor.tsx +++ b/web/src/app/admin/tools/ToolEditor.tsx @@ -13,7 +13,7 @@ import { import * as Yup from "yup"; import { MethodSpec, ToolSnapshot } from "@/lib/tools/interfaces"; import { TextFormField } from "@/components/admin/connectors/Field"; -import { Button, Divider, Text } from "@tremor/react"; +import { Button, Divider } from "@tremor/react"; import { createCustomTool, updateCustomTool, @@ -64,28 +64,31 @@ function ToolForm({ const [definitionError, setDefinitionError] = definitionErrorState; const [methodSpecs, setMethodSpecs] = methodSpecsState; const [showAdvancedOptions, setShowAdvancedOptions] = useState(false); - const debouncedValidateDefinition = useCallback( - debounce(async (definition: string) => { - try { - const parsedDefinition = parseJsonWithTrailingCommas(definition); - const response = await validateToolDefinition({ - definition: parsedDefinition, - }); - if (response.error) { + (definition: string) => { + const validateDefinition = async () => { + try { + const parsedDefinition = parseJsonWithTrailingCommas(definition); + const response = await validateToolDefinition({ + definition: parsedDefinition, + }); + if (response.error) { + setMethodSpecs(null); + setDefinitionError(response.error); + } else { + setMethodSpecs(response.data); + setDefinitionError(null); + } + } catch (error) { + console.log(error); setMethodSpecs(null); - setDefinitionError(response.error); - } else { - setMethodSpecs(response.data); - setDefinitionError(null); + setDefinitionError("Invalid JSON format"); } - } catch (error) { - console.log(error); - setMethodSpecs(null); - setDefinitionError("Invalid JSON format"); - } - }, 300), - [] + }; + + debounce(validateDefinition, 300)(); + }, + [setMethodSpecs, setDefinitionError] ); useEffect(() => { diff --git a/web/src/app/admin/tools/ToolsTable.tsx b/web/src/app/admin/tools/ToolsTable.tsx index 88b91edda..a283718af 100644 --- a/web/src/app/admin/tools/ToolsTable.tsx +++ b/web/src/app/admin/tools/ToolsTable.tsx @@ -1,7 +1,6 @@ "use client"; import { - Text, Table, TableHead, TableRow, diff --git a/web/src/app/admin/tools/edit/[toolId]/page.tsx b/web/src/app/admin/tools/edit/[toolId]/page.tsx index 8ae1e908a..7a9e86b2f 100644 --- a/web/src/app/admin/tools/edit/[toolId]/page.tsx +++ b/web/src/app/admin/tools/edit/[toolId]/page.tsx @@ -3,7 +3,6 @@ import { Card, Text, Title } from "@tremor/react"; import { ToolEditor } from "@/app/admin/tools/ToolEditor"; import { fetchToolByIdSS } from "@/lib/tools/fetchTools"; import { DeleteToolButton } from "./DeleteToolButton"; -import { FiTool } from "react-icons/fi"; import { AdminPageTitle } from "@/components/admin/Title"; import { BackButton } from "@/components/BackButton"; import { ToolIcon } from "@/components/icons/icons"; diff --git a/web/src/app/admin/tools/new/page.tsx b/web/src/app/admin/tools/new/page.tsx index efff155be..79042eb67 100644 --- a/web/src/app/admin/tools/new/page.tsx +++ b/web/src/app/admin/tools/new/page.tsx @@ -5,7 +5,6 @@ import { BackButton } from "@/components/BackButton"; import { AdminPageTitle } from "@/components/admin/Title"; import { ToolIcon } from "@/components/icons/icons"; import { Card } from "@tremor/react"; -import { FiTool } from "react-icons/fi"; export default function NewToolPage() { return ( diff --git a/web/src/app/admin/tools/page.tsx b/web/src/app/admin/tools/page.tsx index 543f89ac3..a1b20c79d 100644 --- a/web/src/app/admin/tools/page.tsx +++ b/web/src/app/admin/tools/page.tsx @@ -1,6 +1,6 @@ import { ToolsTable } from "./ToolsTable"; import { ToolSnapshot } from "@/lib/tools/interfaces"; -import { FiPlusSquare, FiTool } from "react-icons/fi"; +import { FiPlusSquare } from "react-icons/fi"; import Link from "next/link"; import { Divider, Text, Title } from "@tremor/react"; import { fetchSS } from "@/lib/utilsSS"; diff --git a/web/src/app/admin/users/page.tsx b/web/src/app/admin/users/page.tsx index 0c258cd85..8d34594c8 100644 --- a/web/src/app/admin/users/page.tsx +++ b/web/src/app/admin/users/page.tsx @@ -12,7 +12,6 @@ import { AdminPageTitle } from "@/components/admin/Title"; import { usePopup, PopupSpec } from "@/components/admin/connectors/Popup"; import { UsersIcon } from "@/components/icons/icons"; import { errorHandlingFetcher } from "@/lib/fetcher"; -import { type User, UserStatus } from "@/lib/types"; import useSWR, { mutate } from "swr"; import { ErrorCallout } from "@/components/ErrorCallout"; import { HidableSection } from "@/app/admin/assistants/HidableSection"; diff --git a/web/src/app/assistants/SidebarWrapper.tsx b/web/src/app/assistants/SidebarWrapper.tsx index 2feae5892..9a1d320d7 100644 --- a/web/src/app/assistants/SidebarWrapper.tsx +++ b/web/src/app/assistants/SidebarWrapper.tsx @@ -6,7 +6,14 @@ import { Folder } from "@/app/chat/folders/interfaces"; import { User } from "@/lib/types"; import Cookies from "js-cookie"; import { SIDEBAR_TOGGLED_COOKIE_NAME } from "@/components/resizable/constants"; -import { ReactNode, useContext, useEffect, useRef, useState } from "react"; +import { + ReactNode, + useCallback, + useContext, + useEffect, + useRef, + useState, +} from "react"; import { useSidebarVisibility } from "@/components/chat_search/hooks"; import FunctionalHeader from "@/components/chat_search/Header"; import { useRouter } from "next/navigation"; @@ -54,7 +61,7 @@ export default function SidebarWrapper({ }, 200); }; - const toggleSidebar = () => { + const toggleSidebar = useCallback(() => { Cookies.set( SIDEBAR_TOGGLED_COOKIE_NAME, String(!toggledSidebar).toLocaleLowerCase() @@ -63,7 +70,7 @@ export default function SidebarWrapper({ path: "/", }; setToggledSidebar((toggledSidebar) => !toggledSidebar); - }; + }, [toggledSidebar]); const sidebarElementRef = useRef(null); diff --git a/web/src/app/assistants/gallery/AssistantsGallery.tsx b/web/src/app/assistants/gallery/AssistantsGallery.tsx index 8926238b4..635bb80cf 100644 --- a/web/src/app/assistants/gallery/AssistantsGallery.tsx +++ b/web/src/app/assistants/gallery/AssistantsGallery.tsx @@ -4,7 +4,6 @@ import { Persona } from "@/app/admin/assistants/interfaces"; import { AssistantIcon } from "@/components/assistants/AssistantIcon"; import { User } from "@/lib/types"; import { Button } from "@tremor/react"; -import Link from "next/link"; import { useState } from "react"; import { FiList, FiMinus, FiPlus } from "react-icons/fi"; import { AssistantsPageTitle } from "../AssistantsPageTitle"; diff --git a/web/src/app/assistants/mine/AssistantSharingModal.tsx b/web/src/app/assistants/mine/AssistantSharingModal.tsx index b0e96b000..a30f3ce08 100644 --- a/web/src/app/assistants/mine/AssistantSharingModal.tsx +++ b/web/src/app/assistants/mine/AssistantSharingModal.tsx @@ -1,7 +1,7 @@ import { useState } from "react"; import { Modal } from "@/components/Modal"; import { MinimalUserSnapshot, User } from "@/lib/types"; -import { Button, Divider, Text } from "@tremor/react"; +import { Button } from "@tremor/react"; import { FiPlus, FiX } from "react-icons/fi"; import { Persona } from "@/app/admin/assistants/interfaces"; import { SearchMultiSelectDropdown } from "@/components/Dropdown"; diff --git a/web/src/app/assistants/mine/AssistantsList.tsx b/web/src/app/assistants/mine/AssistantsList.tsx index a16c22d3a..84eca4d13 100644 --- a/web/src/app/assistants/mine/AssistantsList.tsx +++ b/web/src/app/assistants/mine/AssistantsList.tsx @@ -1,15 +1,9 @@ "use client"; -import React, { - Dispatch, - ReactNode, - SetStateAction, - useEffect, - useState, -} from "react"; +import React, { Dispatch, SetStateAction, useEffect, useState } from "react"; import { MinimalUserSnapshot, User } from "@/lib/types"; import { Persona } from "@/app/admin/assistants/interfaces"; -import { Button, Divider, Text } from "@tremor/react"; +import { Button, Divider } from "@tremor/react"; import { FiEdit2, FiList, @@ -51,8 +45,8 @@ import { SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy, + useSortable, } from "@dnd-kit/sortable"; -import { useSortable } from "@dnd-kit/sortable"; import { DragHandle } from "@/components/table/DragHandle"; import { diff --git a/web/src/app/assistants/mine/WrappedInputPrompts.tsx b/web/src/app/assistants/mine/WrappedInputPrompts.tsx index 4428b5244..31bcd28d9 100644 --- a/web/src/app/assistants/mine/WrappedInputPrompts.tsx +++ b/web/src/app/assistants/mine/WrappedInputPrompts.tsx @@ -5,7 +5,6 @@ import { Folder } from "@/app/chat/folders/interfaces"; import { Persona } from "@/app/admin/assistants/interfaces"; import { User } from "@/lib/types"; -import { InstantSSRAutoRefresh } from "@/components/SSRAutoRefresh"; import { AssistantsPageTitle } from "../AssistantsPageTitle"; import { useInputPrompts } from "@/app/admin/prompt-library/hooks"; import { PromptSection } from "@/app/admin/prompt-library/promptSection"; diff --git a/web/src/app/auth/login/LoginText.tsx b/web/src/app/auth/login/LoginText.tsx index b465ad335..a875b407a 100644 --- a/web/src/app/auth/login/LoginText.tsx +++ b/web/src/app/auth/login/LoginText.tsx @@ -1,7 +1,6 @@ "use client"; -import React from "react"; -import { useContext } from "react"; +import React, { useContext } from "react"; import { SettingsContext } from "@/components/settings/SettingsProvider"; export const LoginText = () => { diff --git a/web/src/app/auth/verify-email/Verify.tsx b/web/src/app/auth/verify-email/Verify.tsx index aea4d1bfe..2b5fd1dcc 100644 --- a/web/src/app/auth/verify-email/Verify.tsx +++ b/web/src/app/auth/verify-email/Verify.tsx @@ -2,7 +2,7 @@ import { HealthCheckBanner } from "@/components/health/healthcheck"; import { useRouter, useSearchParams } from "next/navigation"; -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { Text } from "@tremor/react"; import { RequestNewVerificationEmail } from "../waiting-on-verification/RequestNewVerificationEmail"; import { User } from "@/lib/types"; @@ -14,7 +14,7 @@ export function Verify({ user }: { user: User | null }) { const [error, setError] = useState(""); - async function verify() { + const verify = useCallback(async () => { const token = searchParams.get("token"); if (!token) { setError( @@ -39,11 +39,11 @@ export function Verify({ user }: { user: User | null }) { `Failed to verify your email - ${errorDetail}. Please try requesting a new verification email.` ); } - } + }, [searchParams, router]); useEffect(() => { verify(); - }, []); + }, [verify]); return (
diff --git a/web/src/app/chat/ChatPage.tsx b/web/src/app/chat/ChatPage.tsx index 4f052e738..707491193 100644 --- a/web/src/app/chat/ChatPage.tsx +++ b/web/src/app/chat/ChatPage.tsx @@ -123,7 +123,7 @@ export function ChatPage({ const router = useRouter(); const searchParams = useSearchParams(); - let { + const { chatSessions, availableSources, availableDocumentSets, @@ -243,7 +243,8 @@ export function ChatPage({ destructureValue(user?.preferences.default_model) ); } - }, [liveAssistant]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [liveAssistant, llmProviders, user?.preferences.default_model]); const stopGenerating = () => { const currentSession = currentSessionId(); @@ -436,6 +437,7 @@ export function ChatPage({ } initialSessionFetch(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [existingChatSessionId]); const [message, setMessage] = useState( @@ -696,7 +698,7 @@ export function ChatPage({ finalAssistants.find((persona) => persona.id === defaultAssistantId) ); } - }, [defaultAssistantId]); + }, [defaultAssistantId, finalAssistants, messageHistory.length]); const [ selectedDocuments, @@ -772,7 +774,7 @@ export function ChatPage({ const handleInputResize = () => { setTimeout(() => { if (inputRef.current && lastMessageRef.current) { - let newHeight: number = + const newHeight: number = inputRef.current?.getBoundingClientRect().height!; const heightDifference = newHeight - previousHeight.current; if ( @@ -984,7 +986,7 @@ export function ChatPage({ setAlternativeGeneratingAssistant(alternativeAssistantOverride); clientScrollToBottom(); let currChatSessionId: number; - let isNewSession = chatSessionIdRef.current === null; + const isNewSession = chatSessionIdRef.current === null; const searchParamBasedChatSessionName = searchParams.get(SEARCH_PARAM_NAMES.TITLE) || null; @@ -1067,7 +1069,7 @@ export function ChatPage({ let answer = ""; - let stopReason: StreamStopReason | null = null; + const stopReason: StreamStopReason | null = null; let query: string | null = null; let retrievalType: RetrievalType = selectedDocuments.length > 0 @@ -1668,17 +1670,22 @@ export function ChatPage({ useEffect(() => { initializeVisibleRange(); - }, [router, messageHistory, chatSessionIdRef.current]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [router, messageHistory]); useLayoutEffect(() => { + const scrollableDiv = scrollableDivRef.current; + const handleScroll = () => { updateVisibleRangeBasedOnScroll(); }; - scrollableDivRef.current?.addEventListener("scroll", handleScroll); + + scrollableDiv?.addEventListener("scroll", handleScroll); return () => { - scrollableDivRef.current?.removeEventListener("scroll", handleScroll); + scrollableDiv?.removeEventListener("scroll", handleScroll); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [messageHistory]); const currentVisibleRange = visibleRange.get(currentSessionId()) || { @@ -1728,6 +1735,7 @@ export function ChatPage({ return () => { window.removeEventListener("keydown", handleKeyDown); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [router]); const [sharedChatSession, setSharedChatSession] = useState(); diff --git a/web/src/app/chat/ChatPopup.tsx b/web/src/app/chat/ChatPopup.tsx index b26bd19b9..664cfffac 100644 --- a/web/src/app/chat/ChatPopup.tsx +++ b/web/src/app/chat/ChatPopup.tsx @@ -17,7 +17,7 @@ export function ChatPopup() { setCompletedFlow( localStorage.getItem(ALL_USERS_INITIAL_POPUP_FLOW_COMPLETED) === "true" ); - }); + }, []); const settings = useContext(SettingsContext); const enterpriseSettings = settings?.enterpriseSettings; diff --git a/web/src/app/chat/RegenerateOption.tsx b/web/src/app/chat/RegenerateOption.tsx index 7c0f97676..f28a83b03 100644 --- a/web/src/app/chat/RegenerateOption.tsx +++ b/web/src/app/chat/RegenerateOption.tsx @@ -14,7 +14,6 @@ import { destructureValue, getFinalLLM, structureValue } from "@/lib/llm/utils"; import { useState } from "react"; import { Hoverable } from "@/components/Hoverable"; import { Popover } from "@/components/popover/Popover"; -import { FiStar } from "react-icons/fi"; import { StarFeedback } from "@/components/icons/icons"; import { IconType } from "react-icons"; diff --git a/web/src/app/chat/documentSidebar/ChatDocumentDisplay.tsx b/web/src/app/chat/documentSidebar/ChatDocumentDisplay.tsx index 2c6acf371..85ac429c4 100644 --- a/web/src/app/chat/documentSidebar/ChatDocumentDisplay.tsx +++ b/web/src/app/chat/documentSidebar/ChatDocumentDisplay.tsx @@ -51,6 +51,7 @@ export function ChatDocumentDisplay({ "rounded-lg flex font-bold flex-shrink truncate" + (document.link ? "" : "pointer-events-none") } + rel="noreferrer" > {isInternet ? ( diff --git a/web/src/app/chat/documentSidebar/DocumentSidebar.tsx b/web/src/app/chat/documentSidebar/DocumentSidebar.tsx index 57bfee363..e20fd8e67 100644 --- a/web/src/app/chat/documentSidebar/DocumentSidebar.tsx +++ b/web/src/app/chat/documentSidebar/DocumentSidebar.tsx @@ -3,7 +3,7 @@ import { Divider, Text } from "@tremor/react"; import { ChatDocumentDisplay } from "./ChatDocumentDisplay"; import { usePopup } from "@/components/admin/connectors/Popup"; import { removeDuplicateDocs } from "@/lib/documentUtils"; -import { Message, RetrievalType } from "../interfaces"; +import { Message } from "../interfaces"; import { ForwardedRef, forwardRef } from "react"; interface DocumentSidebarProps { diff --git a/web/src/app/chat/files/InputBarPreview.tsx b/web/src/app/chat/files/InputBarPreview.tsx index 5d473b9f2..d218db04f 100644 --- a/web/src/app/chat/files/InputBarPreview.tsx +++ b/web/src/app/chat/files/InputBarPreview.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef, useState } from "react"; -import { ChatFileType, FileDescriptor } from "../interfaces"; +import { FileDescriptor } from "../interfaces"; import { FiX, FiLoader, FiFileText } from "react-icons/fi"; import { InputBarPreviewImage } from "./images/InputBarPreviewImage"; diff --git a/web/src/app/chat/files/images/InputBarPreviewImage.tsx b/web/src/app/chat/files/images/InputBarPreviewImage.tsx index 51260af1d..a46d3c098 100644 --- a/web/src/app/chat/files/images/InputBarPreviewImage.tsx +++ b/web/src/app/chat/files/images/InputBarPreviewImage.tsx @@ -30,6 +30,7 @@ export function InputBarPreviewImage({ fileId }: { fileId: string }) { `} > preview setFullImageShowing(true)} className="h-8 w-8 object-cover rounded-lg bg-background cursor-pointer" src={buildImgUrl(fileId)} diff --git a/web/src/app/chat/folders/FolderManagement.tsx b/web/src/app/chat/folders/FolderManagement.tsx index b1d245147..7e5abca0a 100644 --- a/web/src/app/chat/folders/FolderManagement.tsx +++ b/web/src/app/chat/folders/FolderManagement.tsx @@ -1,5 +1,3 @@ -import { useState, useEffect, FC } from "react"; - // Function to create a new folder export async function createFolder(folderName: string): Promise { const response = await fetch("/api/folder", { diff --git a/web/src/app/chat/input/ChatInputBar.tsx b/web/src/app/chat/input/ChatInputBar.tsx index cef0bc49f..cce1bba53 100644 --- a/web/src/app/chat/input/ChatInputBar.tsx +++ b/web/src/app/chat/input/ChatInputBar.tsx @@ -98,7 +98,7 @@ export function ChatInputBar({ MAX_INPUT_HEIGHT )}px`; } - }, [message]); + }, [message, textAreaRef]); const handlePaste = (event: React.ClipboardEvent) => { const items = event.clipboardData?.items; diff --git a/web/src/app/chat/input/ChatInputOption.tsx b/web/src/app/chat/input/ChatInputOption.tsx index d2d7bc5fd..5d5e9d45f 100644 --- a/web/src/app/chat/input/ChatInputOption.tsx +++ b/web/src/app/chat/input/ChatInputOption.tsx @@ -1,9 +1,5 @@ import React, { useState, useRef, useEffect } from "react"; -import { - ChevronDownIcon, - ChevronRightIcon, - IconProps, -} from "@/components/icons/icons"; +import { ChevronDownIcon, IconProps } from "@/components/icons/icons"; interface ChatInputOptionProps { name?: string; diff --git a/web/src/app/chat/lib.tsx b/web/src/app/chat/lib.tsx index 01090aa56..73ddd63c6 100644 --- a/web/src/app/chat/lib.tsx +++ b/web/src/app/chat/lib.tsx @@ -4,16 +4,9 @@ import { Filters, StreamStopInfo, } from "@/lib/search/interfaces"; -import { handleSSEStream, handleStream } from "@/lib/search/streamingUtils"; +import { handleSSEStream } from "@/lib/search/streamingUtils"; import { ChatState, FeedbackType } from "./types"; -import { - Dispatch, - MutableRefObject, - RefObject, - SetStateAction, - useEffect, - useRef, -} from "react"; +import { MutableRefObject, RefObject, useEffect, useRef } from "react"; import { BackendMessage, ChatSession, @@ -664,7 +657,7 @@ export async function useScrollonStream({ useEffect(() => { if (chatState != "input" && scrollableDivRef && scrollableDivRef.current) { - let newHeight: number = scrollableDivRef.current?.scrollTop!; + const newHeight: number = scrollableDivRef.current?.scrollTop!; const heightDifference = newHeight - previousScroll.current; previousScroll.current = newHeight; @@ -729,5 +722,5 @@ export async function useScrollonStream({ }); } } - }, [chatState]); + }, [chatState, distance, scrollDist, scrollableDivRef]); } diff --git a/web/src/app/chat/message/ContinueMessage.tsx b/web/src/app/chat/message/ContinueMessage.tsx index 097b3e57e..e60a13a53 100644 --- a/web/src/app/chat/message/ContinueMessage.tsx +++ b/web/src/app/chat/message/ContinueMessage.tsx @@ -1,6 +1,6 @@ import { EmphasizedClickable } from "@/components/BasicClickable"; import { useEffect, useState } from "react"; -import { FiBook, FiPlayCircle } from "react-icons/fi"; +import { FiPlayCircle } from "react-icons/fi"; export function ContinueGenerating({ handleContinueGenerating, diff --git a/web/src/app/chat/message/Messages.tsx b/web/src/app/chat/message/Messages.tsx index e10f5cea0..7a8a47ced 100644 --- a/web/src/app/chat/message/Messages.tsx +++ b/web/src/app/chat/message/Messages.tsx @@ -202,7 +202,7 @@ export const AIMessage = ({ const selectedDocumentIds = selectedDocuments?.map((document) => document.document_id) || []; - let citedDocumentIds: string[] = []; + const citedDocumentIds: string[] = []; citedDocuments?.forEach((doc) => { citedDocumentIds.push(doc[1].document_id); @@ -272,7 +272,7 @@ export const AIMessage = ({ ); }, }), - [messageId, content] + [finalContent] ); const renderedMarkdown = useMemo(() => { @@ -286,7 +286,7 @@ export const AIMessage = ({ {finalContent as string} ); - }, [finalContent]); + }, [finalContent, markdownComponents]); const includeMessageSwitcher = currentMessageInd !== undefined && @@ -412,6 +412,7 @@ export const AIMessage = ({ href={doc.link || undefined} target="_blank" className="text-sm flex w-full pt-1 gap-x-1.5 overflow-hidden justify-between font-semibold text-text-700" + rel="noreferrer" >

@@ -670,7 +671,7 @@ export const HumanMessage = ({ if (!isEditing) { setEditedContent(content); } - }, [content]); + }, [content, isEditing]); useEffect(() => { if (textareaRef.current) { diff --git a/web/src/app/chat/message/SearchSummary.tsx b/web/src/app/chat/message/SearchSummary.tsx index 66f12aa2d..6b7ea248e 100644 --- a/web/src/app/chat/message/SearchSummary.tsx +++ b/web/src/app/chat/message/SearchSummary.tsx @@ -83,7 +83,7 @@ export function SearchSummary({ if (!isEditing) { setFinalQuery(query); } - }, [query]); + }, [query, isEditing]); const searchingForDisplay = (

diff --git a/web/src/app/chat/message/SkippedSearch.tsx b/web/src/app/chat/message/SkippedSearch.tsx index b339ac784..05dc8f2d8 100644 --- a/web/src/app/chat/message/SkippedSearch.tsx +++ b/web/src/app/chat/message/SkippedSearch.tsx @@ -1,5 +1,5 @@ import { EmphasizedClickable } from "@/components/BasicClickable"; -import { FiArchive, FiBook, FiSearch } from "react-icons/fi"; +import { FiBook } from "react-icons/fi"; function ForceSearchButton({ messageId, diff --git a/web/src/app/chat/modal/FeedbackModal.tsx b/web/src/app/chat/modal/FeedbackModal.tsx index 6b3df8793..64feffefc 100644 --- a/web/src/app/chat/modal/FeedbackModal.tsx +++ b/web/src/app/chat/modal/FeedbackModal.tsx @@ -2,13 +2,8 @@ import { useState } from "react"; import { FeedbackType } from "../types"; -import { FiThumbsDown, FiThumbsUp } from "react-icons/fi"; import { ModalWrapper } from "@/components/modals/ModalWrapper"; -import { - DislikeFeedbackIcon, - FilledLikeIcon, - LikeFeedbackIcon, -} from "@/components/icons/icons"; +import { FilledLikeIcon } from "@/components/icons/icons"; const predefinedPositiveFeedbackOptions = process.env.NEXT_PUBLIC_POSITIVE_PREDEFINED_FEEDBACK_OPTIONS?.split(",") || diff --git a/web/src/app/chat/modal/SetDefaultModelModal.tsx b/web/src/app/chat/modal/SetDefaultModelModal.tsx index 97e05cf59..46482a9ee 100644 --- a/web/src/app/chat/modal/SetDefaultModelModal.tsx +++ b/web/src/app/chat/modal/SetDefaultModelModal.tsx @@ -1,6 +1,6 @@ -import { Dispatch, SetStateAction, useState, useEffect, useRef } from "react"; +import { Dispatch, SetStateAction, useEffect, useRef } from "react"; import { ModalWrapper } from "@/components/modals/ModalWrapper"; -import { Badge, Text } from "@tremor/react"; +import { Text } from "@tremor/react"; import { getDisplayNameForModel, LlmOverride } from "@/lib/hooks"; import { LLMProviderDescriptor } from "@/app/admin/configuration/llm/interfaces"; diff --git a/web/src/app/chat/modal/ShareChatSessionModal.tsx b/web/src/app/chat/modal/ShareChatSessionModal.tsx index 6c287a6ce..e220fdb6d 100644 --- a/web/src/app/chat/modal/ShareChatSessionModal.tsx +++ b/web/src/app/chat/modal/ShareChatSessionModal.tsx @@ -3,7 +3,7 @@ import { ModalWrapper } from "@/components/modals/ModalWrapper"; import { Button, Callout, Divider, Text } from "@tremor/react"; import { Spinner } from "@/components/Spinner"; import { ChatSessionSharedStatus } from "../interfaces"; -import { FiCopy, FiX } from "react-icons/fi"; +import { FiCopy } from "react-icons/fi"; import { CopyButton } from "@/components/CopyButton"; function buildShareLink(chatSessionId: number) { @@ -82,6 +82,7 @@ export function ShareChatSessionModal({ href={shareLink} target="_blank" className="underline text-link mt-1 ml-1 text-sm my-auto" + rel="noreferrer" > {shareLink} diff --git a/web/src/app/chat/modal/configuration/AssistantsTab.tsx b/web/src/app/chat/modal/configuration/AssistantsTab.tsx index 1db03cd60..fca691d8f 100644 --- a/web/src/app/chat/modal/configuration/AssistantsTab.tsx +++ b/web/src/app/chat/modal/configuration/AssistantsTab.tsx @@ -19,7 +19,6 @@ import { getFinalLLM } from "@/lib/llm/utils"; import React, { useState } from "react"; import { updateUserAssistantList } from "@/lib/assistants/updateAssistantPreferences"; import { DraggableAssistantCard } from "@/components/assistants/AssistantCards"; -import { useRouter } from "next/navigation"; export function AssistantsTab({ selectedAssistant, diff --git a/web/src/app/chat/modal/configuration/LlmTab.tsx b/web/src/app/chat/modal/configuration/LlmTab.tsx index 86ead4309..2cd40290d 100644 --- a/web/src/app/chat/modal/configuration/LlmTab.tsx +++ b/web/src/app/chat/modal/configuration/LlmTab.tsx @@ -1,14 +1,10 @@ import { useChatContext } from "@/components/context/ChatContext"; -import { getDisplayNameForModel, LlmOverrideManager } from "@/lib/hooks"; +import { LlmOverrideManager } from "@/lib/hooks"; import React, { forwardRef, useCallback, useState } from "react"; import { debounce } from "lodash"; import { Text } from "@tremor/react"; import { Persona } from "@/app/admin/assistants/interfaces"; -import { - checkLLMSupportsImageInput, - destructureValue, - structureValue, -} from "@/lib/llm/utils"; +import { destructureValue } from "@/lib/llm/utils"; import { updateModelOverrideForChatSession } from "../../lib"; import { GearIcon } from "@/components/icons/icons"; import { LlmList } from "@/components/llm/LLMList"; @@ -44,12 +40,14 @@ export const LlmTab = forwardRef( const [localTemperature, setLocalTemperature] = useState( temperature || 0 ); - const debouncedSetTemperature = useCallback( - debounce((value) => { - setTemperature(value); - }, 300), - [] + (value: number) => { + const debouncedFunction = debounce((value: number) => { + setTemperature(value); + }, 300); + return debouncedFunction(value); + }, + [setTemperature] ); const handleTemperatureChange = (value: number) => { diff --git a/web/src/app/chat/modifiers/SearchTypeSelector.tsx b/web/src/app/chat/modifiers/SearchTypeSelector.tsx index c9f1f8a5c..94c1ec704 100644 --- a/web/src/app/chat/modifiers/SearchTypeSelector.tsx +++ b/web/src/app/chat/modifiers/SearchTypeSelector.tsx @@ -1,7 +1,7 @@ import { BasicClickable } from "@/components/BasicClickable"; import { ControlledPopup, DefaultDropdownElement } from "@/components/Dropdown"; import { useState } from "react"; -import { FiCpu, FiFilter, FiSearch } from "react-icons/fi"; +import { FiCpu, FiSearch } from "react-icons/fi"; export const QA = "Question Answering"; export const SEARCH = "Search Only"; diff --git a/web/src/app/chat/modifiers/SelectedDocuments.tsx b/web/src/app/chat/modifiers/SelectedDocuments.tsx index be3b81f37..fbae7029c 100644 --- a/web/src/app/chat/modifiers/SelectedDocuments.tsx +++ b/web/src/app/chat/modifiers/SelectedDocuments.tsx @@ -1,7 +1,6 @@ import { BasicClickable } from "@/components/BasicClickable"; import { DanswerDocument } from "@/lib/search/interfaces"; -import { useState } from "react"; -import { FiBook, FiFilter } from "react-icons/fi"; +import { FiBook } from "react-icons/fi"; export function SelectedDocuments({ selectedDocuments, diff --git a/web/src/app/chat/page.tsx b/web/src/app/chat/page.tsx index 72a1cf1aa..c192c55aa 100644 --- a/web/src/app/chat/page.tsx +++ b/web/src/app/chat/page.tsx @@ -5,8 +5,6 @@ import { WelcomeModal } from "@/components/initialSetup/welcome/WelcomeModalWrap import { ChatProvider } from "@/components/context/ChatContext"; import { fetchChatData } from "@/lib/chat/fetchChatData"; import WrappedChat from "./WrappedChat"; -import { ProviderContextProvider } from "@/components/chat_search/ProviderContext"; -import { orderAssistantsForUser } from "@/lib/assistants/utils"; export default async function Page({ searchParams, diff --git a/web/src/app/chat/sessionSidebar/ChatSessionDisplay.tsx b/web/src/app/chat/sessionSidebar/ChatSessionDisplay.tsx index aeea9b977..8b690968c 100644 --- a/web/src/app/chat/sessionSidebar/ChatSessionDisplay.tsx +++ b/web/src/app/chat/sessionSidebar/ChatSessionDisplay.tsx @@ -3,11 +3,7 @@ import { useRouter } from "next/navigation"; import { ChatSession } from "../interfaces"; import { useState, useEffect, useContext } from "react"; -import { - deleteChatSession, - getChatRetentionInfo, - renameChatSession, -} from "../lib"; +import { getChatRetentionInfo, renameChatSession } from "../lib"; import { BasicSelectable } from "@/components/BasicClickable"; import Link from "next/link"; import { diff --git a/web/src/app/chat/sessionSidebar/HistorySidebar.tsx b/web/src/app/chat/sessionSidebar/HistorySidebar.tsx index beb45e177..9e072050b 100644 --- a/web/src/app/chat/sessionSidebar/HistorySidebar.tsx +++ b/web/src/app/chat/sessionSidebar/HistorySidebar.tsx @@ -1,7 +1,7 @@ "use client"; import { FiEdit, FiFolderPlus } from "react-icons/fi"; -import { ForwardedRef, forwardRef, useContext, useState } from "react"; +import React, { ForwardedRef, forwardRef, useContext, useState } from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { ChatSession } from "../interfaces"; @@ -11,7 +11,6 @@ import { createFolder } from "../folders/FolderManagement"; import { usePopup } from "@/components/admin/connectors/Popup"; import { SettingsContext } from "@/components/settings/SettingsProvider"; -import React from "react"; import { AssistantsIconSkeleton, ClosedBookIcon, diff --git a/web/src/app/chat/sessionSidebar/PagesTab.tsx b/web/src/app/chat/sessionSidebar/PagesTab.tsx index e6612a96c..8477e197d 100644 --- a/web/src/app/chat/sessionSidebar/PagesTab.tsx +++ b/web/src/app/chat/sessionSidebar/PagesTab.tsx @@ -7,7 +7,7 @@ import { Folder } from "../folders/interfaces"; import { CHAT_SESSION_ID_KEY, FOLDER_ID_KEY } from "@/lib/drag/constants"; import { usePopup } from "@/components/admin/connectors/Popup"; import { useRouter } from "next/navigation"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import { pageType } from "./types"; export function PagesTab({ diff --git a/web/src/app/ee/admin/api-key/DanswerApiKeyForm.tsx b/web/src/app/ee/admin/api-key/DanswerApiKeyForm.tsx index 4232929c8..8703beb1d 100644 --- a/web/src/app/ee/admin/api-key/DanswerApiKeyForm.tsx +++ b/web/src/app/ee/admin/api-key/DanswerApiKeyForm.tsx @@ -6,7 +6,6 @@ import { } from "@/components/admin/connectors/Field"; import { createApiKey, updateApiKey } from "./lib"; import { Modal } from "@/components/Modal"; -import { XIcon } from "@/components/icons/icons"; import { Button, Divider, Text } from "@tremor/react"; import { UserRole } from "@/lib/types"; import { APIKey } from "./types"; diff --git a/web/src/app/ee/admin/api-key/page.tsx b/web/src/app/ee/admin/api-key/page.tsx index 4c5447932..2b7db0bce 100644 --- a/web/src/app/ee/admin/api-key/page.tsx +++ b/web/src/app/ee/admin/api-key/page.tsx @@ -16,10 +16,10 @@ import { TableRow, Text, Title, + Table, } from "@tremor/react"; import { usePopup } from "@/components/admin/connectors/Popup"; import { useState } from "react"; -import { Table } from "@tremor/react"; import { DeleteButton } from "@/components/DeleteButton"; import { FiCopy, FiEdit2, FiRefreshCw, FiX } from "react-icons/fi"; import { Modal } from "@/components/Modal"; diff --git a/web/src/app/ee/admin/groups/ConnectorEditor.tsx b/web/src/app/ee/admin/groups/ConnectorEditor.tsx index ab6bbb0be..2283b71fb 100644 --- a/web/src/app/ee/admin/groups/ConnectorEditor.tsx +++ b/web/src/app/ee/admin/groups/ConnectorEditor.tsx @@ -19,7 +19,7 @@ export const ConnectorEditor = ({ .filter((ccPair) => !(ccPair.access_type === "public")) .map((ccPair) => { const ind = selectedCCPairIds.indexOf(ccPair.cc_pair_id); - let isSelected = ind !== -1; + const isSelected = ind !== -1; return (
{document.link ? ( - + {document.semantic_identifier} ) : ( diff --git a/web/src/app/ee/admin/performance/usage/UsageReports.tsx b/web/src/app/ee/admin/performance/usage/UsageReports.tsx index 9dbeb6ca2..f05162543 100644 --- a/web/src/app/ee/admin/performance/usage/UsageReports.tsx +++ b/web/src/app/ee/admin/performance/usage/UsageReports.tsx @@ -16,9 +16,9 @@ import { TableRow, Text, Title, + Button, } from "@tremor/react"; import useSWR from "swr"; -import { Button } from "@tremor/react"; import { useState } from "react"; import { UsageReport } from "./types"; import { ThreeDotsLoader } from "@/components/Loading"; @@ -36,7 +36,7 @@ function GenerateReportInput() { const [errorOccurred, setErrorOccurred] = useState(null); const download = (bytes: Blob) => { - let elm = document.createElement("a"); + const elm = document.createElement("a"); elm.href = URL.createObjectURL(bytes); elm.setAttribute("download", "usage_reports.zip"); elm.click(); diff --git a/web/src/app/ee/admin/performance/usage/page.tsx b/web/src/app/ee/admin/performance/usage/page.tsx index 4fd287ecc..ccb2822e2 100644 --- a/web/src/app/ee/admin/performance/usage/page.tsx +++ b/web/src/app/ee/admin/performance/usage/page.tsx @@ -4,7 +4,6 @@ import { DateRangeSelector } from "../DateRangeSelector"; import { DanswerBotChart } from "./DanswerBotChart"; import { FeedbackChart } from "./FeedbackChart"; import { QueryPerformanceChart } from "./QueryPerformanceChart"; -import { BarChartIcon } from "@/components/icons/icons"; import { useTimeRange } from "../lib"; import { AdminPageTitle } from "@/components/admin/Title"; import { FiActivity } from "react-icons/fi"; diff --git a/web/src/app/ee/admin/standard-answer/[id]/page.tsx b/web/src/app/ee/admin/standard-answer/[id]/page.tsx index 6d949331b..772b1507d 100644 --- a/web/src/app/ee/admin/standard-answer/[id]/page.tsx +++ b/web/src/app/ee/admin/standard-answer/[id]/page.tsx @@ -3,7 +3,6 @@ import { StandardAnswerCreationForm } from "@/app/ee/admin/standard-answer/Stand import { fetchSS } from "@/lib/utilsSS"; import { ErrorCallout } from "@/components/ErrorCallout"; import { BackButton } from "@/components/BackButton"; -import { Text } from "@tremor/react"; import { ClipboardIcon } from "@/components/icons/icons"; import { StandardAnswer, StandardAnswerCategory } from "@/lib/types"; diff --git a/web/src/app/ee/admin/standard-answer/new/page.tsx b/web/src/app/ee/admin/standard-answer/new/page.tsx index e671f5e1a..5a5cccb9c 100644 --- a/web/src/app/ee/admin/standard-answer/new/page.tsx +++ b/web/src/app/ee/admin/standard-answer/new/page.tsx @@ -3,7 +3,6 @@ import { StandardAnswerCreationForm } from "@/app/ee/admin/standard-answer/Stand import { fetchSS } from "@/lib/utilsSS"; import { ErrorCallout } from "@/components/ErrorCallout"; import { BackButton } from "@/components/BackButton"; -import { Text } from "@tremor/react"; import { ClipboardIcon } from "@/components/icons/icons"; import { StandardAnswerCategory } from "@/lib/types"; diff --git a/web/src/app/ee/admin/standard-answer/page.tsx b/web/src/app/ee/admin/standard-answer/page.tsx index 867770ede..0cff20af8 100644 --- a/web/src/app/ee/admin/standard-answer/page.tsx +++ b/web/src/app/ee/admin/standard-answer/page.tsx @@ -6,12 +6,10 @@ import { PopupSpec, usePopup } from "@/components/admin/connectors/Popup"; import { useStandardAnswers, useStandardAnswerCategories } from "./hooks"; import { ThreeDotsLoader } from "@/components/Loading"; import { ErrorCallout } from "@/components/ErrorCallout"; -import { Button, Divider, Text } from "@tremor/react"; -import Link from "next/link"; -import { StandardAnswer, StandardAnswerCategory } from "@/lib/types"; -import { MagnifyingGlass } from "@phosphor-icons/react"; -import { useState } from "react"; import { + Button, + Divider, + Text, Table, TableHead, TableRow, @@ -19,12 +17,15 @@ import { TableBody, TableCell, } from "@tremor/react"; +import Link from "next/link"; +import { StandardAnswer, StandardAnswerCategory } from "@/lib/types"; +import { MagnifyingGlass } from "@phosphor-icons/react"; +import { useState } from "react"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; import { deleteStandardAnswer } from "./lib"; import { FilterDropdown } from "@/components/search/filtering/FilterDropdown"; import { FiTag } from "react-icons/fi"; -import { SelectedBubble } from "@/components/search/filtering/Filters"; import { PageSelector } from "@/components/PageSelector"; import { CustomCheckbox } from "@/components/CustomCheckbox"; diff --git a/web/src/app/ee/admin/whitelabeling/ImageUpload.tsx b/web/src/app/ee/admin/whitelabeling/ImageUpload.tsx index 3158fca8c..f9be5343c 100644 --- a/web/src/app/ee/admin/whitelabeling/ImageUpload.tsx +++ b/web/src/app/ee/admin/whitelabeling/ImageUpload.tsx @@ -61,7 +61,11 @@ export function ImageUpload({ {tmpImageUrl && (
Uploaded Image: - + Uploaded Image
)} diff --git a/web/src/app/layout.tsx b/web/src/app/layout.tsx index 415990373..f64edd179 100644 --- a/web/src/app/layout.tsx +++ b/web/src/app/layout.tsx @@ -6,12 +6,11 @@ import { } from "@/components/settings/lib"; import { CUSTOM_ANALYTICS_ENABLED, - EE_ENABLED, SERVER_SIDE_ONLY__PAID_ENTERPRISE_FEATURES_ENABLED, } from "@/lib/constants"; import { SettingsProvider } from "@/components/settings/SettingsProvider"; import { Metadata } from "next"; -import { buildClientUrl, fetchSS } from "@/lib/utilsSS"; +import { buildClientUrl } from "@/lib/utilsSS"; import { Inter } from "next/font/google"; import Head from "next/head"; import { EnterpriseSettings } from "./admin/settings/interfaces"; diff --git a/web/src/app/search/page.tsx b/web/src/app/search/page.tsx index c490e1971..818dfe6b9 100644 --- a/web/src/app/search/page.tsx +++ b/web/src/app/search/page.tsx @@ -136,7 +136,7 @@ export default async function Home() { const storedSearchType = cookies().get("searchType")?.value as | string | undefined; - let searchTypeDefault: SearchType = + const searchTypeDefault: SearchType = storedSearchType !== undefined && SearchType.hasOwnProperty(storedSearchType) ? (storedSearchType as SearchType) diff --git a/web/src/components/Dropdown.tsx b/web/src/components/Dropdown.tsx index 5e36dca98..78867b0dc 100644 --- a/web/src/components/Dropdown.tsx +++ b/web/src/components/Dropdown.tsx @@ -2,6 +2,7 @@ import { ChangeEvent, FC, forwardRef, + useCallback, useEffect, useRef, useState, @@ -411,14 +412,17 @@ export function ControlledPopup({ }) { const filtersRef = useRef(null); // hides logout popup on any click outside - const handleClickOutside = (event: MouseEvent) => { - if ( - filtersRef.current && - !filtersRef.current.contains(event.target as Node) - ) { - setIsOpen(false); - } - }; + const handleClickOutside = useCallback( + (event: MouseEvent) => { + if ( + filtersRef.current && + !filtersRef.current.contains(event.target as Node) + ) { + setIsOpen(false); + } + }, + [filtersRef, setIsOpen] + ); useEffect(() => { document.addEventListener("mousedown", handleClickOutside); @@ -426,7 +430,7 @@ export function ControlledPopup({ return () => { document.removeEventListener("mousedown", handleClickOutside); }; - }, []); + }, [handleClickOutside]); return (
diff --git a/web/src/components/IsPublicGroupSelector.tsx b/web/src/components/IsPublicGroupSelector.tsx index 37a9d47b3..7cb8ff8f8 100644 --- a/web/src/components/IsPublicGroupSelector.tsx +++ b/web/src/components/IsPublicGroupSelector.tsx @@ -49,12 +49,7 @@ export const IsPublicGroupSelector = ({ setShouldHideContent(false); } } - }, [ - user, - userGroups, - formikProps.setFieldValue, - formikProps.values.is_public, - ]); + }, [user, userGroups, formikProps, isPaidEnterpriseFeaturesEnabled]); if (isLoadingUser || userGroupsIsLoading) { return
Loading...
; diff --git a/web/src/components/SSRAutoRefresh.tsx b/web/src/components/SSRAutoRefresh.tsx index 24f0edf53..31e9fede4 100644 --- a/web/src/components/SSRAutoRefresh.tsx +++ b/web/src/components/SSRAutoRefresh.tsx @@ -25,7 +25,7 @@ export function InstantSSRAutoRefresh() { useEffect(() => { router.refresh(); - }, []); + }, [router]); return <>; } diff --git a/web/src/components/UserDropdown.tsx b/web/src/components/UserDropdown.tsx index 8a8db1822..e59e7291c 100644 --- a/web/src/components/UserDropdown.tsx +++ b/web/src/components/UserDropdown.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, useRef, useContext, useEffect } from "react"; +import { useState, useRef, useContext, useEffect, useMemo } from "react"; import { FiLogOut } from "react-icons/fi"; import Link from "next/link"; import { useRouter } from "next/navigation"; @@ -67,8 +67,10 @@ export function UserDropdown({ const router = useRouter(); const combinedSettings = useContext(SettingsContext); - const customNavItems: NavigationItem[] = - combinedSettings?.enterpriseSettings?.custom_nav_items || []; + const customNavItems: NavigationItem[] = useMemo( + () => combinedSettings?.enterpriseSettings?.custom_nav_items || [], + [combinedSettings] + ); useEffect(() => { const iconNames = customNavItems diff --git a/web/src/components/admin/connectors/AccessTypeGroupSelector.tsx b/web/src/components/admin/connectors/AccessTypeGroupSelector.tsx index 830ca5b50..d90fbedbf 100644 --- a/web/src/components/admin/connectors/AccessTypeGroupSelector.tsx +++ b/web/src/components/admin/connectors/AccessTypeGroupSelector.tsx @@ -46,7 +46,14 @@ export function AccessTypeGroupSelector({}: {}) { setShouldHideContent(false); } } - }, [user, userGroups, access_type.value]); + }, [ + user, + userGroups, + access_type.value, + access_type_helpers, + groups_helpers, + isPaidEnterpriseFeaturesEnabled, + ]); if (isLoadingUser || userGroupsIsLoading) { return
Loading...
; diff --git a/web/src/components/assistants/AssistantIcon.tsx b/web/src/components/assistants/AssistantIcon.tsx index 07ab05aa1..58a5b11b2 100644 --- a/web/src/components/assistants/AssistantIcon.tsx +++ b/web/src/components/assistants/AssistantIcon.tsx @@ -36,6 +36,7 @@ export function AssistantIcon({ // Prioritization order: image, graph, defaults assistant.uploaded_image_id ? ( {assistant.name} { window.removeEventListener("keydown", handleKeyDown); }; - }, []); + }, [page, currentChatSession]); const router = useRouter(); const handleNewChat = () => { diff --git a/web/src/components/chat_search/ProviderContext.tsx b/web/src/components/chat_search/ProviderContext.tsx index 3907b98a6..609713f87 100644 --- a/web/src/components/chat_search/ProviderContext.tsx +++ b/web/src/components/chat_search/ProviderContext.tsx @@ -1,6 +1,12 @@ "use client"; import { WellKnownLLMProviderDescriptor } from "@/app/admin/configuration/llm/interfaces"; -import React, { createContext, useContext, useState, useEffect } from "react"; +import React, { + createContext, + useContext, + useState, + useEffect, + useCallback, +} from "react"; import { useUser } from "../user/UserProvider"; import { useRouter } from "next/navigation"; import { checkLlmProvider } from "../initialSetup/welcome/lib"; @@ -28,16 +34,16 @@ export function ProviderContextProvider({ WellKnownLLMProviderDescriptor[] >([]); - const fetchProviderInfo = async () => { + const fetchProviderInfo = useCallback(async () => { const { providers, options, defaultCheckSuccessful } = await checkLlmProvider(user); setValidProviderExists(providers.length > 0 && defaultCheckSuccessful); setProviderOptions(options); - }; + }, [user, setValidProviderExists, setProviderOptions]); useEffect(() => { fetchProviderInfo(); - }, [router, user]); + }, [router, user, fetchProviderInfo]); const shouldShowConfigurationNeeded = !validProviderExists && providerOptions.length > 0; diff --git a/web/src/components/chat_search/hooks.ts b/web/src/components/chat_search/hooks.ts index 314810b55..d83059636 100644 --- a/web/src/components/chat_search/hooks.ts +++ b/web/src/components/chat_search/hooks.ts @@ -77,6 +77,7 @@ export const useSidebarVisibility = ({ document.removeEventListener("mousemove", handleEvent); document.removeEventListener("mouseleave", handleMouseLeave); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [showDocSidebar, toggledSidebar, sidebarElementRef, mobile]); return { showDocSidebar }; diff --git a/web/src/components/context/EmbeddingContext.tsx b/web/src/components/context/EmbeddingContext.tsx index 3d03b99b1..33bb850a8 100644 --- a/web/src/components/context/EmbeddingContext.tsx +++ b/web/src/components/context/EmbeddingContext.tsx @@ -74,7 +74,7 @@ export const EmbeddingFormProvider: React.FC<{ if (stepFromUrl !== formStep) { setFormStep(stepFromUrl); } - }, [searchParams]); + }, [searchParams, formStep]); const contextValue: EmbeddingFormContextType = { formStep, diff --git a/web/src/components/context/FormContext.tsx b/web/src/components/context/FormContext.tsx index d445782f7..ee6e9dab7 100644 --- a/web/src/components/context/FormContext.tsx +++ b/web/src/components/context/FormContext.tsx @@ -73,7 +73,7 @@ export const FormProvider: React.FC<{ if (stepFromUrl !== formStep) { setFormStep(stepFromUrl); } - }, [searchParams]); + }, [searchParams, formStep]); const contextValue: FormContextType = { formStep, diff --git a/web/src/components/health/healthcheck.tsx b/web/src/components/health/healthcheck.tsx index 037082ca0..d537f0577 100644 --- a/web/src/components/health/healthcheck.tsx +++ b/web/src/components/health/healthcheck.tsx @@ -3,7 +3,7 @@ import { errorHandlingFetcher, RedirectError } from "@/lib/fetcher"; import useSWR from "swr"; import { Modal } from "../Modal"; -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { getSecondsUntilExpiration } from "@/lib/time"; import { User } from "@/lib/types"; import { mockedRefreshToken, refreshToken } from "./refreshUtils"; @@ -20,7 +20,7 @@ export const HealthCheckBanner = () => { errorHandlingFetcher ); - const updateExpirationTime = async () => { + const updateExpirationTime = useCallback(async () => { const updatedUser = await mutateUser(); if (updatedUser) { @@ -28,11 +28,11 @@ export const HealthCheckBanner = () => { setSecondsUntilExpiration(seconds); console.debug(`Updated seconds until expiration:! ${seconds}`); } - }; + }, [mutateUser]); useEffect(() => { updateExpirationTime(); - }, [user]); + }, [user, updateExpirationTime]); useEffect(() => { if (CUSTOM_REFRESH_URL) { @@ -89,7 +89,7 @@ export const HealthCheckBanner = () => { clearTimeout(expireTimeoutId); }; } - }, [secondsUntilExpiration, user]); + }, [secondsUntilExpiration, user, mutateUser, updateExpirationTime]); if (!error && !expired) { return null; diff --git a/web/src/components/initialSetup/search/NoCompleteSourceModal.tsx b/web/src/components/initialSetup/search/NoCompleteSourceModal.tsx index 42aba7ab1..decf302e2 100644 --- a/web/src/components/initialSetup/search/NoCompleteSourceModal.tsx +++ b/web/src/components/initialSetup/search/NoCompleteSourceModal.tsx @@ -20,7 +20,7 @@ export function NoCompleteSourcesModal({ }, 5000); return () => clearInterval(interval); - }, []); + }, [router]); if (isHidden) { return null; diff --git a/web/src/components/initialSetup/welcome/WelcomeModal.tsx b/web/src/components/initialSetup/welcome/WelcomeModal.tsx index d2229ab90..1fac38030 100644 --- a/web/src/components/initialSetup/welcome/WelcomeModal.tsx +++ b/web/src/components/initialSetup/welcome/WelcomeModal.tsx @@ -48,7 +48,7 @@ export function _WelcomeModal({ user }: { user: User | null }) { } fetchProviderInfo(); - }, []); + }, [user]); return ( <> diff --git a/web/src/components/search/SearchSection.tsx b/web/src/components/search/SearchSection.tsx index a9641511a..8ff4fdd31 100644 --- a/web/src/components/search/SearchSection.tsx +++ b/web/src/components/search/SearchSection.tsx @@ -1,6 +1,6 @@ "use client"; -import { useContext, useEffect, useRef, useState } from "react"; +import { useCallback, useContext, useEffect, useRef, useState } from "react"; import { FullSearchBar } from "./SearchBar"; import { SearchResultsDisplay } from "./SearchResultsDisplay"; import { SourceSelector } from "./filtering/Filters"; @@ -106,15 +106,15 @@ export const SearchSection = ({ const [agentic, setAgentic] = useState(agenticSearchEnabled); - const toggleAgentic = () => { + const toggleAgentic = useCallback(() => { Cookies.set( AGENTIC_SEARCH_TYPE_COOKIE_NAME, String(!agentic).toLocaleLowerCase() ); setAgentic((agentic) => !agentic); - }; + }, [agentic]); - const toggleSidebar = () => { + const toggleSidebar = useCallback(() => { Cookies.set( SIDEBAR_TOGGLED_COOKIE_NAME, String(!toggledSidebar).toLocaleLowerCase() @@ -123,7 +123,7 @@ export const SearchSection = ({ path: "/", }; toggle(); - }; + }, [toggledSidebar, toggle]); useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { diff --git a/web/src/lib/sources.ts b/web/src/lib/sources.ts index 7347964a7..18bc3336a 100644 --- a/web/src/lib/sources.ts +++ b/web/src/lib/sources.ts @@ -27,7 +27,6 @@ import { SharepointIcon, TeamsIcon, SlabIcon, - SlackIcon, ZendeskIcon, ZulipIcon, MediaWikiIcon, @@ -358,10 +357,3 @@ export function getSourcesForPersona(persona: Persona): ValidSources[] { }); return personaSources; } - -function stripTrailingSlash(str: string) { - if (str.substr(-1) === "/") { - return str.substr(0, str.length - 1); - } - return str; -} diff --git a/web/src/lib/types.ts b/web/src/lib/types.ts index f47517808..c760074f4 100644 --- a/web/src/lib/types.ts +++ b/web/src/lib/types.ts @@ -3,7 +3,7 @@ import { Credential } from "./connectors/credentials"; import { Connector } from "./connectors/connectors"; import { ConnectorCredentialPairStatus } from "@/app/admin/connector/[ccPairId]/types"; -export interface UserPreferences { +interface UserPreferences { chosen_assistants: number[] | null; visible_assistants: number[]; hidden_assistants: number[];