mirror of
https://github.com/stablyai/orca.git
synced 2026-10-08 16:02:37 +00:00
Fix Linear filter chips showing UUIDs after dropdown closes (#12564)
Fetch metadata when filters are selected, not only while the popover is open, so chip labels remain readable after closing the dropdown.
This commit is contained in:
@@ -1,10 +1,48 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import { act } from 'react'
|
||||
import { createRoot, type Root } from 'react-dom/client'
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { LinearTeam } from '../../../shared/types'
|
||||
import {
|
||||
clearLinearIssueAttributeFacet,
|
||||
countLinearIssueAttributeFilters,
|
||||
linearIssueAttributeFilterPillLabels
|
||||
} from './linear-issue-attribute-filter-sections'
|
||||
import type { LinearIssueAttributeFilter } from '../../../shared/linear-issue-attribute-filter'
|
||||
import LinearIssueAttributeFilterDropdowns from './linear-issue-attribute-filter-dropdowns'
|
||||
|
||||
const metadataMocks = vi.hoisted(() => ({
|
||||
useTeamsStates: vi.fn((teamIds: readonly string[]) => ({
|
||||
data: teamIds.length > 0 ? [{ id: 'state-1', name: 'Todo' }] : [],
|
||||
loading: false,
|
||||
error: null
|
||||
})),
|
||||
useTeamsLabels: vi.fn((teamIds: readonly string[]) => ({
|
||||
data: teamIds.length > 0 ? [{ id: 'label-1', name: 'Bug' }] : [],
|
||||
loading: false,
|
||||
error: null
|
||||
})),
|
||||
useTeamsMembers: vi.fn((teamIds: readonly string[]) => ({
|
||||
data: teamIds.length > 0 ? [{ id: 'member-1', displayName: 'Ada Lovelace' }] : [],
|
||||
loading: false,
|
||||
error: null
|
||||
}))
|
||||
}))
|
||||
|
||||
vi.mock('@/hooks/useIssueMetadata', () => metadataMocks)
|
||||
|
||||
const roots: Root[] = []
|
||||
|
||||
afterEach(() => {
|
||||
roots.splice(0).forEach((root) => {
|
||||
act(() => root.unmount())
|
||||
})
|
||||
document.body.replaceChildren()
|
||||
metadataMocks.useTeamsStates.mockClear()
|
||||
metadataMocks.useTeamsLabels.mockClear()
|
||||
metadataMocks.useTeamsMembers.mockClear()
|
||||
})
|
||||
|
||||
const sample: LinearIssueAttributeFilter = {
|
||||
stateIds: ['s1', 's2'],
|
||||
@@ -38,3 +76,72 @@ describe('linear-issue-attribute-filter helpers', () => {
|
||||
expect(pills[3]?.value).toBe('Bug')
|
||||
})
|
||||
})
|
||||
|
||||
describe('LinearIssueAttributeFilterDropdowns', () => {
|
||||
it('keeps metadata lazy while closed with only static filter labels', () => {
|
||||
const team: LinearTeam = { id: 'team-1', name: 'Engineering', key: 'ENG' }
|
||||
const container = document.createElement('div')
|
||||
document.body.appendChild(container)
|
||||
const root = createRoot(container)
|
||||
roots.push(root)
|
||||
|
||||
act(() => {
|
||||
root.render(
|
||||
<LinearIssueAttributeFilterDropdowns
|
||||
value={{
|
||||
stateIds: [],
|
||||
priorities: [1],
|
||||
assignee: { kind: 'unassigned' },
|
||||
labelIds: []
|
||||
}}
|
||||
onChange={() => undefined}
|
||||
workspaceId="workspace-1"
|
||||
isAllWorkspaces={false}
|
||||
primaryTeam={team}
|
||||
selectedTeamIds={[]}
|
||||
availableTeams={[team]}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
expect(metadataMocks.useTeamsStates).toHaveBeenCalledWith([], undefined, null)
|
||||
expect(metadataMocks.useTeamsLabels).toHaveBeenCalledWith([], undefined, null)
|
||||
expect(metadataMocks.useTeamsMembers).toHaveBeenCalledWith([], undefined, null)
|
||||
})
|
||||
|
||||
it('keeps readable metadata names available after the popover closes', () => {
|
||||
const value: LinearIssueAttributeFilter = {
|
||||
stateIds: ['state-1'],
|
||||
priorities: [],
|
||||
assignee: { kind: 'user', id: 'member-1' },
|
||||
labelIds: ['label-1']
|
||||
}
|
||||
const team: LinearTeam = { id: 'team-1', name: 'Engineering', key: 'ENG' }
|
||||
const container = document.createElement('div')
|
||||
document.body.appendChild(container)
|
||||
const root = createRoot(container)
|
||||
roots.push(root)
|
||||
|
||||
act(() => {
|
||||
root.render(
|
||||
<LinearIssueAttributeFilterDropdowns
|
||||
value={value}
|
||||
onChange={() => undefined}
|
||||
workspaceId="workspace-1"
|
||||
isAllWorkspaces={false}
|
||||
primaryTeam={team}
|
||||
selectedTeamIds={[]}
|
||||
availableTeams={[team]}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
expect(container.textContent).toContain('Todo')
|
||||
expect(container.textContent).toContain('Ada Lovelace')
|
||||
expect(container.textContent).toContain('Bug')
|
||||
expect(container.textContent).not.toContain('state-1')
|
||||
expect(metadataMocks.useTeamsStates).toHaveBeenCalledWith(['team-1'], undefined, 'workspace-1')
|
||||
expect(metadataMocks.useTeamsLabels).toHaveBeenCalledWith(['team-1'], undefined, 'workspace-1')
|
||||
expect(metadataMocks.useTeamsMembers).toHaveBeenCalledWith(['team-1'], undefined, 'workspace-1')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -76,9 +76,15 @@ export default function LinearIssueAttributeFilterDropdowns({
|
||||
}: Props): React.JSX.Element {
|
||||
const [popoverOpen, setPopoverOpen] = useState(false)
|
||||
const [openSection, setOpenSection] = useState<LinearIssueFilterSectionKey | null>(null)
|
||||
const activeCount = countLinearIssueAttributeFilters(value)
|
||||
const metadataNeeded =
|
||||
popoverOpen ||
|
||||
value.stateIds.length > 0 ||
|
||||
value.labelIds.length > 0 ||
|
||||
value.assignee?.kind === 'user'
|
||||
|
||||
const activeTeamIds = useMemo(() => {
|
||||
if (!popoverOpen || isAllWorkspaces) {
|
||||
if (!metadataNeeded || isAllWorkspaces) {
|
||||
return [] as string[]
|
||||
}
|
||||
return resolveLinearIssueAttributeFilterTeamIds({
|
||||
@@ -86,10 +92,10 @@ export default function LinearIssueAttributeFilterDropdowns({
|
||||
availableTeams,
|
||||
primaryTeamId: primaryTeam?.id ?? null
|
||||
})
|
||||
}, [popoverOpen, isAllWorkspaces, selectedTeamIds, availableTeams, primaryTeam?.id])
|
||||
}, [metadataNeeded, isAllWorkspaces, selectedTeamIds, availableTeams, primaryTeam?.id])
|
||||
|
||||
const concreteWorkspaceId =
|
||||
popoverOpen && !isAllWorkspaces && workspaceId && workspaceId !== 'all' ? workspaceId : null
|
||||
metadataNeeded && !isAllWorkspaces && workspaceId && workspaceId !== 'all' ? workspaceId : null
|
||||
|
||||
// Why: multi-team / All teams must union filter options across every selected team (#8739).
|
||||
const states = useTeamsStates(activeTeamIds, settings, concreteWorkspaceId)
|
||||
@@ -179,7 +185,6 @@ export default function LinearIssueAttributeFilterDropdowns({
|
||||
[members.data]
|
||||
)
|
||||
|
||||
const activeCount = countLinearIssueAttributeFilters(value)
|
||||
const pills = linearIssueAttributeFilterPillLabels({
|
||||
value,
|
||||
stateNamesById,
|
||||
|
||||
Reference in New Issue
Block a user