From 45217c0f02dd41a1a2400837697fb3124a95e139 Mon Sep 17 00:00:00 2001 From: waleed Date: Wed, 1 Jul 2026 11:30:30 -0700 Subject: [PATCH 1/2] improvement(settings): react-doctor perf & correctness pass - combine multi-pass array iterations into single passes (api-keys, credential-sets, secrets-manager, team-management) - cache/hoist Intl formatters to module scope (billing); hoist pure functions and inline-default constants - stabilize react-query array fallbacks so memos stop recomputing while loading (api-keys, byok, workflow-mcp) - fix create-workflow-mcp modal reset via render-phase prevOpen compare instead of a state-adjusting effect - accessibility: aria-labels on real inputs, aria-hidden on autofill decoys, native setName(e.target.value)} onKeyDown={handleKeyDown} diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/inbox/components/inbox-enable-toggle/inbox-enable-toggle.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/inbox/components/inbox-enable-toggle/inbox-enable-toggle.tsx index f3976f33415..b8eb1683031 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/inbox/components/inbox-enable-toggle/inbox-enable-toggle.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/inbox/components/inbox-enable-toggle/inbox-enable-toggle.tsx @@ -27,16 +27,13 @@ export function InboxEnableToggle() { const [isDisableOpen, setIsDisableOpen] = useState(false) const [enableUsername, setEnableUsername] = useState('') - const handleToggle = useCallback( - async (checked: boolean) => { - if (checked) { - setIsEnableOpen(true) - return - } - setIsDisableOpen(true) - }, - [workspaceId] - ) + const handleToggle = useCallback(async (checked: boolean) => { + if (checked) { + setIsEnableOpen(true) + return + } + setIsDisableOpen(true) + }, []) const handleDisable = useCallback(async () => { try { @@ -45,7 +42,7 @@ export function InboxEnableToggle() { } catch (error) { logger.error('Failed to disable inbox', { error }) } - }, [workspaceId]) + }, [workspaceId, toggleInbox.mutateAsync]) const handleEnable = useCallback(async () => { try { @@ -59,7 +56,7 @@ export function InboxEnableToggle() { } catch (error) { logger.error('Failed to enable inbox', { error }) } - }, [workspaceId, enableUsername]) + }, [workspaceId, enableUsername, toggleInbox.mutateAsync]) return ( <> diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/inbox/components/inbox-settings-tab/inbox-settings-tab.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/inbox/components/inbox-settings-tab/inbox-settings-tab.tsx index 942fd5d8acd..4bb93b6a2ba 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/inbox/components/inbox-settings-tab/inbox-settings-tab.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/inbox/components/inbox-settings-tab/inbox-settings-tab.tsx @@ -65,7 +65,7 @@ export function InboxSettingsTab() { } catch (error) { setEditAddressError(getErrorMessage(error, 'Failed to update address')) } - }, [workspaceId, newUsername]) + }, [workspaceId, newUsername, updateAddress.mutateAsync]) const handleAddSender = useCallback(async () => { if (!newSenderEmail.trim()) return @@ -82,7 +82,7 @@ export function InboxSettingsTab() { } catch (error) { setAddSenderError(getErrorMessage(error, 'Failed to add sender')) } - }, [workspaceId, newSenderEmail, newSenderLabel]) + }, [workspaceId, newSenderEmail, newSenderLabel, addSender.mutateAsync]) const handleRemoveSender = useCallback( async (senderId: string) => { @@ -93,7 +93,7 @@ export function InboxSettingsTab() { setRemoveSenderError(getErrorMessage(error, 'Failed to remove sender')) } }, - [workspaceId] + [workspaceId, removeSender.mutateAsync] ) return ( diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/inbox/components/inbox-task-list/inbox-task-list.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/inbox/components/inbox-task-list/inbox-task-list.tsx index 3b52de1ea3f..de8232f90c8 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/inbox/components/inbox-task-list/inbox-task-list.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/inbox/components/inbox-task-list/inbox-task-list.tsx @@ -134,23 +134,16 @@ export function InboxTaskList() { const isClickable = task.chatId && (task.status === 'completed' || task.status === 'failed') return ( -
handleTaskClick(task)} - onKeyDown={(e) => { - if (isClickable && (e.key === 'Enter' || e.key === ' ')) { - e.preventDefault() - handleTaskClick(task) - } - }} >
@@ -202,7 +195,7 @@ export function InboxTaskList() { )}
-
+ ) })}
diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/mcp/components/mcp-server-form-modal/mcp-server-form-modal.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/mcp/components/mcp-server-form-modal/mcp-server-form-modal.tsx index a7bbfc7d4a0..9c93dd8fa01 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/mcp/components/mcp-server-form-modal/mcp-server-form-modal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/mcp/components/mcp-server-form-modal/mcp-server-form-modal.tsx @@ -672,6 +672,7 @@ export function McpServerFormModal({ type='text' name='fakeusernameremembered' autoComplete='username' + aria-hidden='true' style={{ position: 'absolute', left: '-9999px', opacity: 0, pointerEvents: 'none' }} tabIndex={-1} readOnly @@ -680,6 +681,7 @@ export function McpServerFormModal({ type='password' name='fakepasswordremembered' autoComplete='current-password' + aria-hidden='true' style={{ position: 'absolute', left: '-9999px', opacity: 0, pointerEvents: 'none' }} tabIndex={-1} readOnly diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/recently-deleted/recently-deleted.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/recently-deleted/recently-deleted.tsx index 78f91e8510e..e1f79ef2cd5 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/recently-deleted/recently-deleted.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/recently-deleted/recently-deleted.tsx @@ -303,7 +303,7 @@ export function RecentlyDeleted() { } const col = (activeSort ?? DEFAULT_SORT).column const dir = (activeSort ?? DEFAULT_SORT).direction - items = [...items].sort((a, b) => { + items.sort((a, b) => { let cmp = 0 switch (col) { case 'name': diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/secrets/components/secrets-manager/secrets-manager.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/secrets/components/secrets-manager/secrets-manager.tsx index 84b226c14ea..b49c4e801e5 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/secrets/components/secrets-manager/secrets-manager.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/secrets/components/secrets-manager/secrets-manager.tsx @@ -173,10 +173,14 @@ function parseEnvVarLine(line: string): UIEnvironmentVariable | null { /** Parses an array of raw text lines, returning only valid non-empty KEY=VALUE entries. */ function parseValidEnvVars(lines: string[]): UIEnvironmentVariable[] { - return lines - .map(parseEnvVarLine) - .filter((parsed): parsed is UIEnvironmentVariable => parsed !== null) - .filter(({ key, value }) => key && value) + const result: UIEnvironmentVariable[] = [] + for (const line of lines) { + const parsed = parseEnvVarLine(line) + if (parsed?.key && parsed.value) { + result.push(parsed) + } + } + return result } interface WorkspaceVariableRowProps { @@ -771,9 +775,10 @@ export function SecretsManager() { } const personalChanged = (() => { - const initialMap = new Map( - initialVarsRef.current.filter((v) => v.key && v.value).map((v) => [v.key, v.value]) - ) + const initialMap = new Map() + for (const v of initialVarsRef.current) { + if (v.key && v.value) initialMap.set(v.key, v.value) + } const currentKeys = Object.keys(validVariables) if (initialMap.size !== currentKeys.length) return true for (const [key, value] of Object.entries(validVariables)) { @@ -912,13 +917,14 @@ export function SecretsManager() { return ( <> -
+ diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/team-management/components/no-organization-view/no-organization-view.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/team-management/components/no-organization-view/no-organization-view.tsx index f3f30c7bca0..5b91277a2aa 100644 --- a/apps/sim/app/workspace/[workspaceId]/settings/components/team-management/components/no-organization-view/no-organization-view.tsx +++ b/apps/sim/app/workspace/[workspaceId]/settings/components/team-management/components/no-organization-view/no-organization-view.tsx @@ -65,6 +65,8 @@ export function NoOrganizationView({ style={{ position: 'absolute', left: '-9999px', opacity: 0, pointerEvents: 'none' }} tabIndex={-1} readOnly + aria-hidden='true' + aria-label='Ignore this field' />