diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index 92d7daf..b41cedc 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -28,8 +28,8 @@ "react/prop-types": "off", "@typescript-eslint/explicit-function-return-type": "warn", "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": ["error", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }], - "prettier/prettier": "error" + "prettier/prettier": "error", + "@typescript-eslint/no-unused-vars": ["error", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }] }, "settings": { "react": { diff --git a/frontend/src/components/BackstoryQuery.tsx b/frontend/src/components/BackstoryQuery.tsx index b58b65a..f2ad2bf 100644 --- a/frontend/src/components/BackstoryQuery.tsx +++ b/frontend/src/components/BackstoryQuery.tsx @@ -1,3 +1,4 @@ +import React, { JSX } from 'react'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; @@ -10,7 +11,7 @@ interface BackstoryQueryInterface { submitQuery?: ChatSubmitQueryInterface; } -const BackstoryQuery = (props: BackstoryQueryInterface) => { +const BackstoryQuery = (props: BackstoryQueryInterface): JSX.Element => { const { question, submitQuery } = props; if (submitQuery === undefined) { @@ -25,7 +26,7 @@ const BackstoryQuery = (props: BackstoryQueryInterface) => { m: 1, }} size="small" - onClick={(e: any) => { + onClick={(): void => { submitQuery(question); }} > diff --git a/frontend/src/components/BackstoryTab.tsx b/frontend/src/components/BackstoryTab.tsx index 9d39460..04a990b 100644 --- a/frontend/src/components/BackstoryTab.tsx +++ b/frontend/src/components/BackstoryTab.tsx @@ -1,8 +1,6 @@ -import React, { ReactElement, JSXElementConstructor } from 'react'; +import React, { ReactElement, JSX } from 'react'; import Box from '@mui/material/Box'; import { SxProps, Theme } from '@mui/material'; -import { ChatSubmitQueryInterface } from './BackstoryQuery'; -import { SetSnackType } from './Snack'; interface BackstoryElementProps { // setSnack: SetSnackType, @@ -24,12 +22,12 @@ interface BackstoryTabProps { tabProps?: { label?: string; sx?: SxProps; - icon?: string | ReactElement> | undefined; + icon?: string | ReactElement | undefined; iconPosition?: 'bottom' | 'top' | 'start' | 'end' | undefined; }; } -function BackstoryPage(props: BackstoryTabProps) { +function BackstoryPage(props: BackstoryTabProps): JSX.Element { const { className, active, children } = props; return ( diff --git a/frontend/src/components/BackstoryTextField.tsx b/frontend/src/components/BackstoryTextField.tsx index 2fefb57..2841ff7 100644 --- a/frontend/src/components/BackstoryTextField.tsx +++ b/frontend/src/components/BackstoryTextField.tsx @@ -72,21 +72,21 @@ const BackstoryTextField = React.forwardRef cancelAnimationFrame(raf); + return (): void => cancelAnimationFrame(raf); }, [editValue, placeholder]); // Expose getValue method via ref useImperativeHandle(ref, () => ({ - getValue: () => editValue, - setValue: (value: string) => setEditValue(value), - getAndResetValue: () => { + getValue: (): string => editValue, + setValue: (value: string): void => setEditValue(value), + getAndResetValue: (): string => { const _ev = editValue; setEditValue(''); return _ev; }, })); - const handleKeyDown = (event: KeyboardEvent) => { + const handleKeyDown = (event: KeyboardEvent): void => { if (!onEnter) { return; } @@ -122,7 +122,7 @@ const BackstoryTextField = React.forwardRef { + onChange={(e): void => { setEditValue(e.target.value); onChange && onChange(e.target.value); }} @@ -152,7 +152,7 @@ const BackstoryTextField = React.forwardRef( onResponse, placeholder, preamble, - resetAction, resetLabel, sx, - type, } = props; const { apiClient } = useAuth(); const [processing, setProcessing] = useState(false); - const [countdown, setCountdown] = useState(0); const [conversation, setConversation] = useState([]); const conversationRef = useRef([]); const [filteredConversation, setFilteredConversation] = useState([]); @@ -144,7 +142,7 @@ const Conversation = forwardRef( if (chatSession) { return; } - const createChatSession = async () => { + const createChatSession = async (): Promise => { try { const chatContext: ChatContext = { type: 'general' }; const response: ChatSession = await apiClient.createChatSession(chatContext); @@ -156,7 +154,7 @@ const Conversation = forwardRef( }; createChatSession(); - }, [chatSession, setChatSession]); + }, [chatSession, setChatSession, apiClient, setSnack]); const getChatMessages = useCallback(async () => { if (!chatSession || !chatSession.id) { @@ -193,7 +191,7 @@ const Conversation = forwardRef( }, 3000); setSnack('Unable to obtain chat history.', 'error'); } - }, [chatSession]); + }, [chatSession, apiClient, setSnack]); // Set the initial chat history to "loading" or the welcome message if loaded. useEffect(() => { @@ -208,9 +206,9 @@ const Conversation = forwardRef( setNoInteractions(true); getChatMessages(); - }, [chatSession]); + }, [chatSession, getChatMessages]); - const handleEnter = (value: string) => { + const handleEnter = (value: string): void => { const query: ChatQuery = { prompt: value, }; @@ -218,10 +216,10 @@ const Conversation = forwardRef( }; useImperativeHandle(ref, () => ({ - submitQuery: (query: ChatQuery) => { + submitQuery: (query: ChatQuery): void => { processQuery(query); }, - fetchHistory: () => { + fetchHistory: (): void => { getChatMessages(); }, })); @@ -256,7 +254,7 @@ const Conversation = forwardRef( // } // }; - const cancelQuery = () => { + const cancelQuery = (): void => { console.log('Stop query'); if (controllerRef.current) { controllerRef.current.cancel(); @@ -264,12 +262,10 @@ const Conversation = forwardRef( controllerRef.current = null; }; - const processQuery = (query: ChatQuery) => { + const processQuery = (query: ChatQuery): void => { if (controllerRef.current || !chatSession || !chatSession.id) { return; } - const sessionId: string = chatSession.id; - setNoInteractions(false); setConversation([ ...conversationRef.current, @@ -396,17 +392,6 @@ const Conversation = forwardRef( aria-label="Loading Spinner" data-testid="loader" /> - {processing === true && countdown > 0 && ( - - Response will be stopped in: {countdown}s - - )} ( { + onDelete={(): void => { /*reset(); resetAction && resetAction(); */ }} /> @@ -453,7 +438,7 @@ const Conversation = forwardRef( sx={{ m: 1, gap: 1, flexGrow: 1 }} variant="contained" disabled={!chatSession || processingMessage !== undefined} - onClick={() => { + onClick={(): void => { processQuery({ prompt: (backstoryTextRef.current && @@ -473,7 +458,7 @@ const Conversation = forwardRef( {/* This span is used to wrap the IconButton to ensure Tooltip works even when disabled */} { + onClick={(): void => { cancelQuery(); }} sx={{ display: 'flex', margin: 'auto 0px' }} @@ -502,7 +487,7 @@ const Conversation = forwardRef( ); } ); - +Conversation.displayName = 'Conversation'; export type { ConversationProps, ConversationHandle }; export { Conversation }; diff --git a/frontend/src/components/CopyBubble.tsx b/frontend/src/components/CopyBubble.tsx index 887faaf..c494fd8 100644 --- a/frontend/src/components/CopyBubble.tsx +++ b/frontend/src/components/CopyBubble.tsx @@ -1,3 +1,4 @@ +import React, { JSX } from 'react'; import { useState } from 'react'; import ContentCopyIcon from '@mui/icons-material/ContentCopy'; import CheckIcon from '@mui/icons-material/Check'; @@ -17,10 +18,10 @@ const CopyBubble = ({ tooltip = 'Copy to clipboard', onClick, ...rest -}: CopyBubbleProps) => { +}: CopyBubbleProps): JSX.Element => { const [copied, setCopied] = useState(false); - const handleCopy = (e: any) => { + const handleCopy = (e: React.MouseEvent): void => { if (content === undefined) { return; } @@ -38,7 +39,7 @@ const CopyBubble = ({ return ( { + onClick={(e): void => { handleCopy(e); }} sx={{ diff --git a/frontend/src/components/DeleteConfirmation.tsx b/frontend/src/components/DeleteConfirmation.tsx index 9984d19..a39c53d 100644 --- a/frontend/src/components/DeleteConfirmation.tsx +++ b/frontend/src/components/DeleteConfirmation.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { JSX, useState } from 'react'; import { IconButton, Dialog, @@ -45,11 +45,11 @@ interface DeleteConfirmationProps { cancelButtonText?: string; } -function capitalizeFirstLetter(str: string) { +function capitalizeFirstLetter(str: string): string { return str.charAt(0).toUpperCase() + str.slice(1); } -const DeleteConfirmation = (props: DeleteConfirmationProps) => { +const DeleteConfirmation = (props: DeleteConfirmationProps): JSX.Element => { const { // Legacy props onDelete, @@ -79,13 +79,13 @@ const DeleteConfirmation = (props: DeleteConfirmationProps) => { const isControlled = controlledOpen !== undefined; const isOpen = isControlled ? controlledOpen : internalOpen; - const handleClickOpen = () => { + const handleClickOpen = (): void => { if (!isControlled) { setInternalOpen(true); } }; - const handleClose = () => { + const handleClose = (): void => { if (isControlled) { controlledOnClose?.(); } else { @@ -93,7 +93,7 @@ const DeleteConfirmation = (props: DeleteConfirmationProps) => { } }; - const handleConfirm = () => { + const handleConfirm = (): void => { if (isControlled) { onConfirm?.(); } else { @@ -122,7 +122,7 @@ const DeleteConfirmation = (props: DeleteConfirmationProps) => { {/* This span is used to wrap the IconButton to ensure Tooltip works even when disabled */} { + onClick={(e): void => { e.stopPropagation(); e.preventDefault(); handleClickOpen(); diff --git a/frontend/src/components/Document.tsx b/frontend/src/components/Document.tsx index 1904fd8..1fdee17 100644 --- a/frontend/src/components/Document.tsx +++ b/frontend/src/components/Document.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, JSX } from 'react'; import { BackstoryElementProps } from './BackstoryTab'; import { StyledMarkdown } from './StyledMarkdown'; @@ -6,7 +6,7 @@ interface DocumentProps extends BackstoryElementProps { filepath?: string; } -const Document = (props: DocumentProps) => { +const Document = (props: DocumentProps): JSX.Element => { const { filepath } = props; const [document, setDocument] = useState(''); @@ -16,7 +16,7 @@ const Document = (props: DocumentProps) => { if (!filepath) { return; } - const fetchDocument = async () => { + const fetchDocument = async (): Promise => { try { const response = await fetch(filepath, { method: 'GET', @@ -29,7 +29,7 @@ const Document = (props: DocumentProps) => { } const data = await response.text(); setDocument(data); - } catch (error: any) { + } catch (error) { console.error('Error obtaining Docs content information:', error); setDocument(`${filepath} not found.`); } diff --git a/frontend/src/components/DocumentManager.tsx b/frontend/src/components/DocumentManager.tsx index 7fed159..cf83d24 100644 --- a/frontend/src/components/DocumentManager.tsx +++ b/frontend/src/components/DocumentManager.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, JSX } from 'react'; import { Box, Button, @@ -44,7 +44,7 @@ const VisuallyHiddenInput = styled('input')({ width: 1, }); -const DocumentManager = (props: BackstoryElementProps) => { +const DocumentManager = (_props: BackstoryElementProps): JSX.Element => { const theme = useTheme(); const { setSnack } = useAppState(); const isMobile = useMediaQuery(theme.breakpoints.down('sm')); @@ -63,23 +63,23 @@ const DocumentManager = (props: BackstoryElementProps) => { // Load documents on component mount useEffect(() => { + const loadDocuments = async (): Promise => { + try { + const results = await apiClient.getCandidateDocuments(); + setDocuments(results.documents); + } catch (error) { + console.error(error); + setSnack('Failed to load documents', 'error'); + } + }; + if (candidate) { loadDocuments(); } - }, [candidate]); - - const loadDocuments = async () => { - try { - const results = await apiClient.getCandidateDocuments(); - setDocuments(results.documents); - } catch (error) { - console.error(error); - setSnack('Failed to load documents', 'error'); - } - }; + }, [candidate, apiClient, setSnack]); // Handle document upload - const handleDocumentUpload = async (e: React.ChangeEvent) => { + const handleDocumentUpload = async (e: React.ChangeEvent): Promise => { if (e.target.files && e.target.files[0]) { const file = e.target.files[0]; const fileExtension = '.' + file.name.split('.').pop()?.toLowerCase(); @@ -132,7 +132,7 @@ const DocumentManager = (props: BackstoryElementProps) => { }; // Handle document deletion - const handleDeleteDocument = async (document: Types.Document) => { + const handleDeleteDocument = async (document: Types.Document): Promise => { try { // Call API to delete document await apiClient.deleteCandidateDocument(document); @@ -152,7 +152,10 @@ const DocumentManager = (props: BackstoryElementProps) => { }; // Handle RAG flag toggle - const handleRAGToggle = async (document: Types.Document, includeInRag: boolean) => { + const handleRAGToggle = async ( + document: Types.Document, + includeInRag: boolean + ): Promise => { try { document.options = { includeInRag }; // Call API to update RAG flag @@ -168,7 +171,7 @@ const DocumentManager = (props: BackstoryElementProps) => { }; // Handle document rename - const handleRenameDocument = async (document: Types.Document, newName: string) => { + const handleRenameDocument = async (document: Types.Document, newName: string): Promise => { if (!newName.trim()) { setSnack('Document name cannot be empty', 'error'); return; @@ -192,7 +195,7 @@ const DocumentManager = (props: BackstoryElementProps) => { }; // Handle document content viewing - const handleViewDocument = async (document: Types.Document) => { + const handleViewDocument = async (document: Types.Document): Promise => { try { setSelectedDocument(document); setIsViewingContent(true); @@ -207,7 +210,7 @@ const DocumentManager = (props: BackstoryElementProps) => { }; // Start rename process - const startRename = (document: Types.Document, currentName: string) => { + const startRename = (document: Types.Document, currentName: string): void => { setEditingDocument(document); setEditingName(currentName); setIsRenameDialogOpen(true); @@ -331,7 +334,9 @@ const DocumentManager = (props: BackstoryElementProps) => { control={ handleRAGToggle(doc, e.target.checked)} + onChange={(e): void => { + handleRAGToggle(doc, e.target.checked); + }} size="small" /> } @@ -346,7 +351,9 @@ const DocumentManager = (props: BackstoryElementProps) => { handleViewDocument(doc)} + onClick={(): void => { + handleViewDocument(doc); + }} title="View content" > @@ -354,7 +361,9 @@ const DocumentManager = (props: BackstoryElementProps) => { startRename(doc, doc.filename)} + onClick={(): void => { + startRename(doc, doc.filename); + }} title="Rename" > @@ -362,7 +371,9 @@ const DocumentManager = (props: BackstoryElementProps) => { handleDeleteDocument(doc)} + onClick={(): void => { + handleDeleteDocument(doc); + }} title="Delete" color="error" > @@ -395,7 +406,7 @@ const DocumentManager = (props: BackstoryElementProps) => { Document Content { + onClick={(): void => { setIsViewingContent(false); setSelectedDocument(null); setDocumentContent(''); @@ -433,7 +444,9 @@ const DocumentManager = (props: BackstoryElementProps) => { {/* Rename Dialog */} setIsRenameDialogOpen(false)} + onClose={(): void => { + setIsRenameDialogOpen(false); + }} maxWidth="sm" fullWidth > @@ -446,8 +459,10 @@ const DocumentManager = (props: BackstoryElementProps) => { fullWidth variant="outlined" value={editingName} - onChange={e => setEditingName(e.target.value)} - onKeyPress={e => { + onChange={(e): void => { + setEditingName(e.target.value); + }} + onKeyUp={(e): void => { if (e.key === 'Enter' && editingDocument) { handleRenameDocument(editingDocument, editingName); } @@ -455,9 +470,17 @@ const DocumentManager = (props: BackstoryElementProps) => { /> - + @@ -190,7 +193,13 @@ const EmailVerificationPage = (props: BackstoryPageProps) => { > Resend Verification Email - @@ -205,9 +214,9 @@ const EmailVerificationPage = (props: BackstoryPageProps) => { interface MFAVerificationDialogProps { open: boolean; onClose: () => void; - onVerificationSuccess: (authData: any) => void; + onVerificationSuccess: () => void; } -const MFAVerificationDialog = (props: MFAVerificationDialogProps) => { +const MFAVerificationDialog = (props: MFAVerificationDialogProps): JSX.Element => { const { open, onClose, onVerificationSuccess } = props; const { verifyMFA, resendMFACode, clearMFA, mfaResponse, isLoading, error } = useAuth(); const [code, setCode] = useState(''); @@ -243,13 +252,13 @@ const MFAVerificationDialog = (props: MFAVerificationDialogProps) => { return () => clearInterval(timer); }, [open]); - const formatTime = (seconds: number) => { + const formatTime = (seconds: number): string => { const mins = Math.floor(seconds / 60); const secs = seconds % 60; return `${mins}:${secs.toString().padStart(2, '0')}`; }; - const handleVerifyMFA = async () => { + const handleVerifyMFA = async (): Promise => { if (!code || code.length !== 6) { setLocalError('Please enter a valid 6-digit code'); return; @@ -271,7 +280,7 @@ const MFAVerificationDialog = (props: MFAVerificationDialogProps) => { }); if (success) { - onVerificationSuccess({ success: true }); + onVerificationSuccess(); onClose(); } } catch (error) { @@ -279,7 +288,7 @@ const MFAVerificationDialog = (props: MFAVerificationDialogProps) => { } }; - const handleResendCode = async () => { + const handleResendCode = async (): Promise => { if (!mfaResponse || !mfaResponse.mfaData) { setLocalError('MFA data not available'); return; @@ -301,12 +310,12 @@ const MFAVerificationDialog = (props: MFAVerificationDialogProps) => { } }; - const handleClose = () => { + const handleClose = (): void => { clearMFA(); onClose(); }; - if (!mfaResponse || !mfaResponse.mfaData) return null; + if (!mfaResponse || !mfaResponse.mfaData) return <>; return ( @@ -319,12 +328,12 @@ const MFAVerificationDialog = (props: MFAVerificationDialogProps) => { - We've detected a login from a new device:{' '} + We've detected a login from a new device:{' '} {mfaResponse.mfaData.deviceName} - We've sent a 6-digit verification code to: + We've sent a 6-digit verification code to: {mfaResponse.mfaData.email} @@ -334,7 +343,7 @@ const MFAVerificationDialog = (props: MFAVerificationDialogProps) => { fullWidth label="Enter 6-digit code" value={code} - onChange={e => { + onChange={(e): void => { const value = e.target.value.replace(/\D/g, '').slice(0, 6); setCode(value); setLocalError(''); @@ -370,7 +379,9 @@ const MFAVerificationDialog = (props: MFAVerificationDialogProps) => { control={ setRememberDevice(e.target.checked)} + onChange={(e): void => { + setRememberDevice(e.target.checked); + }} /> } label="Remember this device for 90 days" @@ -378,7 +389,7 @@ const MFAVerificationDialog = (props: MFAVerificationDialogProps) => { - If you didn't attempt to log in, please change your password immediately. + If you didn't attempt to log in, please change your password immediately. @@ -410,18 +421,19 @@ const RegistrationSuccessDialog = ({ onClose: () => void; email: string; userType: string; -}) => { +}): JSX.Element => { const { resendEmailVerification, isLoading } = useAuth(); const [resendMessage, setResendMessage] = useState(''); - const handleResendVerification = async () => { + const handleResendVerification = async (): Promise => { try { const success = await resendEmailVerification(email); if (success) { setResendMessage('Verification email sent!'); } - } catch (error: any) { - setResendMessage(error?.message || 'Network error. Please try again.'); + } catch (error: unknown) { + const tmp = error as { message?: string }; + setResendMessage(tmp?.message || 'Network error. Please try again.'); } }; @@ -435,7 +447,7 @@ const RegistrationSuccessDialog = ({ - We've sent a verification link to: + We'e sent a verification link to: @@ -478,7 +490,7 @@ const RegistrationSuccessDialog = ({ }; // Enhanced Login Component with MFA Support -const LoginForm = () => { +const LoginForm = (): JSX.Element => { const { login, mfaResponse, isLoading, error, user } = useAuth(); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); @@ -496,7 +508,7 @@ const LoginForm = () => { setErrorMessage(data.error.message); }, [error]); - const handleLogin = async (e: React.FormEvent) => { + const handleLogin = async (e: React.FormEvent): Promise => { e.preventDefault(); const success = await login({ @@ -512,11 +524,11 @@ const LoginForm = () => { } }; - const handleMFASuccess = (authData: any) => { + const handleMFASuccess = (): void => { handleLoginSuccess(); }; - const handleLoginSuccess = () => { + const handleLoginSuccess = (): void => { if (!user) { navigate('/'); } else { @@ -533,7 +545,9 @@ const LoginForm = () => { fullWidth label="Email or Username" value={email} - onChange={e => setEmail(e.target.value)} + onChange={(e): void => { + setEmail(e.target.value); + }} autoComplete="email" autoFocus /> @@ -542,7 +556,9 @@ const LoginForm = () => { label="Password" type={showPassword ? 'text' : 'password'} value={password} - onChange={e => setPassword(e.target.value)} + onChange={(e): void => { + setPassword(e.target.value); + }} autoComplete="current-password" placeholder="Create a strong password" required @@ -551,8 +567,12 @@ const LoginForm = () => { setShowPassword(!showPassword)} - onMouseDown={e => e.preventDefault()} + onClick={(): void => { + setShowPassword(!showPassword); + }} + onMouseDown={(e): void => { + e.preventDefault(); + }} edge="end" > {showPassword ? : } @@ -581,7 +601,9 @@ const LoginForm = () => { {/* MFA Dialog */} {}} // This will be handled by clearMFA in the dialog + onClose={(): void => { + console.log(); + }} // This will be handled by clearMFA in the dialog onVerificationSuccess={handleMFASuccess} /> @@ -589,9 +611,9 @@ const LoginForm = () => { }; // Device Management Component -const TrustedDevicesManager = () => { - const [devices, setDevices] = useState([]); - const [loading, setLoading] = useState(true); +const TrustedDevicesManager = (): JSX.Element => { + const [devices, _setDevices] = useState([]); + const [_loading, setLoading] = useState(true); // This would need API endpoints to manage trusted devices useEffect(() => { @@ -608,8 +630,8 @@ const TrustedDevicesManager = () => { - Manage devices that you've marked as trusted. You won't need to verify your identity when - signing in from these devices. + Manage devices that you've marked as trusted. You won't need to verify your + identity when signing in from these devices. {devices.length === 0 ? ( @@ -624,18 +646,18 @@ const TrustedDevicesManager = () => { {device.deviceName} - + {/* Added: {new Date(device.addedAt).toLocaleDateString()} - - + */} + {/* Last used: {new Date(device.lastUsed).toLocaleDateString()} - + */} first. + {' '} + first. ); - const fetchRAGMeta = async (node: Node) => { + const fetchRAGMeta = async (node: Node): Promise => { try { const result = await apiClient.getCandidateRAGContent(node.id); const update: Node = { @@ -478,8 +494,8 @@ const VectorVisualizer: React.FC = (props: VectorVisualiz } }; - const onNodeSelected = (metadata: any) => { - let node: Node; + const onNodeSelected = (metadata: Metadata): void => { + let node: Partial; console.log(metadata); if (metadata.docType === 'query') { node = { @@ -503,7 +519,7 @@ The scatter graph shows the query in N-dimensional space, mapped to ${ backgroundColor: colorMap[metadata.docType] || '#ff8080', }, }; - setNode(node); + setNode(node as Node); return; } @@ -513,9 +529,9 @@ The scatter graph shows the query in N-dimensional space, mapped to ${ emoji: emojiMap[metadata.docType] || '❓', }; - setNode(node); + setNode(node as Node); - fetchRAGMeta(node); + fetchRAGMeta(node as Node); }; return ( @@ -552,7 +568,7 @@ The scatter graph shows the query in N-dimensional space, mapped to ${ flexGrow: 0, }} control={} - onChange={() => { + onChange={(): void => { setView2D(!view2D); setResult(null); }} @@ -560,7 +576,7 @@ The scatter graph shows the query in N-dimensional space, mapped to ${ /> { + onClick={(event: { points: { customdata: Metadata }[] }): void => { onNodeSelected(event.points[0].customdata); }} data={plotData} @@ -775,7 +791,9 @@ The scatter graph shows the query in N-dimensional space, mapped to ${ fullWidth type="text" value={newQuery} - onChange={e => setNewQuery(e.target.value)} + onChange={(e): void => { + setNewQuery(e.target.value); + }} onKeyDown={handleKeyPress} placeholder="Enter query to find related documents..." id="QueryInput" @@ -784,7 +802,7 @@ The scatter graph shows the query in N-dimensional space, mapped to ${