Skip to content

Commit 4ecbfd1

Browse files
committed
fix(knowledge): keep history collapse accessible
1 parent 6d61a62 commit 4ecbfd1

3 files changed

Lines changed: 37 additions & 9 deletions

File tree

apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/connectors-section/connector-actions.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client'
22

3-
import { Fragment, useId } from 'react'
3+
import { Fragment, type Ref, useId } from 'react'
44
import {
55
Checkbox,
66
Chip,
@@ -21,14 +21,15 @@ import { SettingsEmptyState } from '@/app/workspace/[workspaceId]/settings/compo
2121

2222
interface ConnectorActionsProps {
2323
state: ConnectorActionState
24+
triggerRef?: Ref<HTMLButtonElement>
2425
history?: {
2526
expanded: boolean
2627
contentId: string
2728
onToggle: () => void
2829
}
2930
}
3031

31-
export function ConnectorActions({ state, history }: ConnectorActionsProps) {
32+
export function ConnectorActions({ state, triggerRef, history }: ConnectorActionsProps) {
3233
if (!state.canEdit && !history) return null
3334
const actions = orderHeaderActions([
3435
...state.actions,
@@ -45,7 +46,7 @@ export function ConnectorActions({ state, history }: ConnectorActionsProps) {
4546
return (
4647
<DropdownMenu>
4748
<DropdownMenuTrigger asChild>
48-
<Chip aria-label='Connection actions' leftIcon={MoreHorizontal} />
49+
<Chip ref={triggerRef} aria-label='Connection actions' leftIcon={MoreHorizontal} />
4950
</DropdownMenuTrigger>
5051
<DropdownMenuContent align='end'>
5152
{actions.map(({ action }, index) => (

apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/connectors-section/connectors-section.test.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,20 @@ describe('Connector credential reauthorization', () => {
401401

402402
expect(controls[0].getAttribute('aria-expanded')).toBe('true')
403403
expect(controls[1].getAttribute('aria-expanded')).toBe('false')
404-
expect(document.getElementById(historyId!)).not.toBeNull()
404+
const history = document.getElementById(historyId!)!
405+
const collapse = findButton(history, 'Hide history')
406+
expect(collapse.getAttribute('aria-controls')).toBe(historyId)
407+
expect(collapse.getAttribute('aria-expanded')).toBe('true')
408+
act(() => {
409+
collapse.focus()
410+
collapse.click()
411+
})
412+
expect(document.getElementById(historyId!)).toBeNull()
413+
expect(controls[0].getAttribute('aria-expanded')).toBe('false')
414+
expect(controls[1].getAttribute('aria-expanded')).toBe('false')
415+
expect(document.activeElement).toBe(
416+
container.querySelector('button[aria-label="Connection actions"]')
417+
)
405418
expect(lifecycle.sync.mutate).not.toHaveBeenCalled()
406419
})
407420

apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/connectors-section/connectors-section.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client'
22

3-
import { useId, useState } from 'react'
4-
import { Badge, cn } from '@sim/emcn'
3+
import { useId, useRef, useState } from 'react'
4+
import { Badge, Chip, cn } from '@sim/emcn'
55
import { Loader, Users } from '@sim/emcn/icons'
66
import { format, formatDistanceToNow, isPast } from 'date-fns'
77
import type { ConnectorData } from '@/lib/api/contracts/knowledge/connectors'
@@ -106,6 +106,7 @@ function ConnectorCard({
106106
isSearchIndex,
107107
onEdit,
108108
}: ConnectorCardProps) {
109+
const actionsTriggerRef = useRef<HTMLButtonElement>(null)
109110
const actions = useConnectorActions({ connector, knowledgeBaseId, canEdit, onEdit })
110111
const historyId = useId()
111112
const [expanded, setExpanded] = useState(false)
@@ -155,6 +156,7 @@ function ConnectorCard({
155156
trailing={
156157
<ConnectorActions
157158
state={actions}
159+
triggerRef={actionsTriggerRef}
158160
history={{
159161
expanded,
160162
contentId: historyId,
@@ -180,9 +182,21 @@ function ConnectorCard({
180182
<ConnectorActionFeedback state={actions} />
181183
{expanded && (
182184
<div id={historyId} className='border-[var(--border)] border-t pt-3'>
183-
{syncDetails && (
184-
<p className='mb-2 text-[var(--text-muted)] text-caption'>{syncDetails}</p>
185-
)}
185+
<div className='mb-2 flex items-start justify-end gap-2'>
186+
{syncDetails && (
187+
<p className='flex-1 text-[var(--text-muted)] text-caption'>{syncDetails}</p>
188+
)}
189+
<Chip
190+
aria-expanded={expanded}
191+
aria-controls={historyId}
192+
onClick={() => {
193+
setExpanded(false)
194+
actionsTriggerRef.current?.focus()
195+
}}
196+
>
197+
Hide history
198+
</Chip>
199+
</div>
186200
{lastSyncError && <SettingsResourceRow title={lastSyncError} />}
187201
<ConnectorSyncHistory connector={connector} knowledgeBaseId={knowledgeBaseId} />
188202
</div>

0 commit comments

Comments
 (0)