diff --git a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsFilters.tsx b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsFilters.tsx index 7cb1da9d5..0b92fc3c9 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsFilters.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsFilters.tsx @@ -86,7 +86,7 @@ export function DocumentsFilters({ placeholder="Search types" value={typeSearchQuery} onChange={(e) => setTypeSearchQuery(e.target.value)} - className="h-6 pl-6 text-sm bg-transparent border-0 shadow-none focus-visible:ring-0" + className="h-6 pl-6 text-sm bg-transparent border-0 shadow-none" /> @@ -172,7 +172,7 @@ export function DocumentsFilters({ onSearch(e.target.value)} placeholder="Search docs" diff --git a/surfsense_web/components/assistant-ui/connector-popup.tsx b/surfsense_web/components/assistant-ui/connector-popup.tsx index cadf976d8..6aef4b52a 100644 --- a/surfsense_web/components/assistant-ui/connector-popup.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup.tsx @@ -50,7 +50,7 @@ export const ConnectorIndicator = forwardRef { const searchSpaceId = useAtomValue(activeSearchSpaceIdAtom); const setSearchSpaceSettingsDialog = useSetAtom(searchSpaceSettingsDialogAtom); - const { data: currentUser } = useAtomValue(currentUserAtom); + useAtomValue(currentUserAtom); const { data: preferences = {}, isFetching: preferencesLoading } = useAtomValue(llmPreferencesAtom); const { data: globalConfigs = [], isFetching: globalConfigsLoading } = @@ -274,7 +274,7 @@ export const ConnectorIndicator = forwardRef { if (pickerOpen) e.preventDefault(); }} - className="max-w-3xl w-[95vw] sm:w-full h-[75vh] sm:h-[85vh] flex flex-col p-0 gap-0 overflow-hidden border border-border ring-0 dark:ring-0 bg-muted dark:bg-muted text-foreground focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 [&>button]:right-4 sm:[&>button]:right-12 [&>button]:top-6 sm:[&>button]:top-10 [&>button]:opacity-80 hover:[&>button]:opacity-100 [&>button_svg]:size-5 select-none" + className="max-w-3xl w-[95vw] sm:w-full h-[75vh] sm:h-[85vh] flex flex-col p-0 gap-0 overflow-hidden border border-border ring-0 dark:ring-0 bg-muted dark:bg-muted text-foreground [&>button]:right-4 sm:[&>button]:right-12 [&>button]:top-6 sm:[&>button]:top-10 [&>button]:opacity-80 hover:[&>button]:opacity-100 [&>button_svg]:size-5 select-none" > Manage Connectors {/* YouTube Crawler View - shown when adding YouTube videos */} diff --git a/surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/elasticsearch-connect-form.tsx b/surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/elasticsearch-connect-form.tsx index b3298cbe0..7a9e866ac 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/elasticsearch-connect-form.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/elasticsearch-connect-form.tsx @@ -1,7 +1,7 @@ "use client"; import { zodResolver } from "@hookform/resolvers/zod"; -import * as RadioGroup from "@radix-ui/react-radio-group"; +import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { Info } from "lucide-react"; import type { FC } from "react"; import { useId, useRef, useState } from "react"; @@ -282,10 +282,9 @@ export const ElasticsearchConnectForm: FC = ({ onSubmit, isSub render={({ field }) => ( - { field.onChange(value); - // Clear auth fields when method changes if (value !== "basic") { form.setValue("username", ""); form.setValue("password", ""); @@ -295,38 +294,22 @@ export const ElasticsearchConnectForm: FC = ({ onSubmit, isSub } }} value={field.value} - className="flex flex-col space-y-2" + className="flex flex-col gap-2" > -
- - -
- - +
+
-
- - -
- - +
+
- + diff --git a/surfsense_web/components/assistant-ui/connector-popup/connector-configs/components/elasticsearch-config.tsx b/surfsense_web/components/assistant-ui/connector-popup/connector-configs/components/elasticsearch-config.tsx index 3cae3fdde..3e514fafc 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/connector-configs/components/elasticsearch-config.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/connector-configs/components/elasticsearch-config.tsx @@ -1,9 +1,9 @@ "use client"; -import * as RadioGroup from "@radix-ui/react-radio-group"; +import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { KeyRound, Server } from "lucide-react"; import type { FC } from "react"; -import { useEffect, useId, useState } from "react"; +import { useEffect, useId, useRef, useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; @@ -56,8 +56,12 @@ export const ElasticsearchConfig: FC = ({ : "" ); - // Update values when connector changes + // Update values when the connector identity changes (e.g. switching to a different connector) + const connectorIdRef = useRef(connector.id); useEffect(() => { + if (connectorIdRef.current === connector.id) return; + connectorIdRef.current = connector.id; + setName(connector.name || ""); setEndpointUrl((connector.config?.ELASTICSEARCH_URL as string) || ""); setAuthMethod( @@ -82,7 +86,7 @@ export const ElasticsearchConfig: FC = ({ ? String(connector.config.ELASTICSEARCH_MAX_DOCUMENTS) : "" ); - }, [connector.config, connector.name]); + }, [connector]); const stringToArray = (str: string): string[] => { const items = str @@ -192,9 +196,9 @@ export const ElasticsearchConfig: FC = ({ const handleMaxDocumentsChange = (value: string) => { setMaxDocuments(value); - if (value && value.trim()) { + if (value?.trim()) { const num = parseInt(value, 10); - if (!isNaN(num) && num > 0) { + if (!Number.isNaN(num) && num > 0) { updateConfig({ ELASTICSEARCH_MAX_DOCUMENTS: num }); } } else { @@ -255,41 +259,25 @@ export const ElasticsearchConfig: FC = ({
- handleAuthMethodChange(value as "basic" | "api_key")} - className="flex flex-col space-y-2" + className="flex flex-col gap-2" > -
- - -
- - +
+
-
- - -
- - +
+
- + {authMethod === "basic" && (
diff --git a/surfsense_web/components/ui/input.tsx b/surfsense_web/components/ui/input.tsx index ffdad1aa3..d2b9edec3 100644 --- a/surfsense_web/components/ui/input.tsx +++ b/surfsense_web/components/ui/input.tsx @@ -9,7 +9,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) { data-slot="input" className={cn( "border-input file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", - "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", + "focus-visible:border-ring", "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", className )} diff --git a/surfsense_web/components/ui/radio-group.tsx b/surfsense_web/components/ui/radio-group.tsx new file mode 100644 index 000000000..6e18f4b99 --- /dev/null +++ b/surfsense_web/components/ui/radio-group.tsx @@ -0,0 +1,45 @@ +"use client" + +import type * as React from "react" +import { CircleIcon } from "lucide-react" +import * as RadioGroupPrimitive from "@radix-ui/react-radio-group" + +import { cn } from "@/lib/utils" + +function RadioGroup({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function RadioGroupItem({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + + + ) +} + +export { RadioGroup, RadioGroupItem }