fix(web): allow selecting loaded GitHub folder pages

This commit is contained in:
FFXN committed 2026-11-10 11:18:22 +08:00
1 parent c26dd9b43b
commit fab0e6c9fa
2 files changed
+37 -16

No files matched your search

@@ -902,7 +902,7 @@ describe('ConnectedSourceWorkflow', () => {
expect(clientMock.deleteSource).not.toHaveBeenCalled()
})
it('loads GitHub tree branches on expansion and imports only explicitly selected pages', async () => {
it('selects only loaded GitHub pages through repository and folder checkboxes', async () => {
const user = userEvent.setup()
const connection = connectionResponse({
configuration: {
@@ -1007,14 +1007,19 @@ describe('ConnectedSourceWorkflow', () => {
params: { control_space_id: 'space-1', source_id: 'preview-source' },
query: { limit: 30, parentId: 'repo:FFXN/dify', view: 'tree' },
})
expect(screen.queryByRole('checkbox', { name: 'Contents' })).not.toBeInTheDocument()
expect(screen.queryByRole('checkbox', { name: 'Pull requests' })).not.toBeInTheDocument()
const contentsCheckbox = screen.getByRole('checkbox', { name: 'Contents' })
const pullRequestsCheckbox = screen.getByRole('checkbox', { name: 'Pull requests' })
expect(contentsCheckbox).toHaveAttribute('aria-disabled', 'true')
expect(pullRequestsCheckbox).toHaveAttribute('aria-disabled', 'true')
expect(repository).toBeChecked()
await user.click(screen.getByRole('button', { name: 'Pull requests' }))
const firstPr = await screen.findByRole('checkbox', { name: 'PR #1' })
expect(firstPr).not.toBeChecked()
expect(repository).toBePartiallyChecked()
expect(pullRequestsCheckbox).not.toHaveAttribute('aria-disabled', 'true')
await user.click(pullRequestsCheckbox)
expect(firstPr).toBeChecked()
const branchLoadMore = screen.getByRole('button', { name: 'knowledgeSpace.loadMore' })
expect(firstPr.closest('li')?.nextElementSibling).toBe(branchLoadMore.closest('li'))
await user.click(branchLoadMore)
@@ -1024,9 +1029,16 @@ describe('ConnectedSourceWorkflow', () => {
query: { cursor: 'pr-next', limit: 30, parentId: 'prs:FFXN/dify', view: 'tree' },
})
expect(secondPr).not.toBeChecked()
expect(pullRequestsCheckbox).toBePartiallyChecked()
await user.click(pullRequestsCheckbox)
expect(firstPr).toBeChecked()
expect(secondPr).toBeChecked()
await user.click(contents)
expect(await screen.findByRole('button', { name: 'src' })).toBeInTheDocument()
const srcCheckbox = screen.getByRole('checkbox', { name: 'src' })
expect(contentsCheckbox).not.toHaveAttribute('aria-disabled', 'true')
expect(srcCheckbox).toHaveAttribute('aria-disabled', 'true')
await user.click(screen.getByRole('button', { name: 'src' }))
const codeFile = await screen.findByRole('checkbox', { name: 'main.py' })
expect(clientMock.getPages).toHaveBeenCalledWith({
@@ -1034,11 +1046,15 @@ describe('ConnectedSourceWorkflow', () => {
query: { limit: 30, parentId: 'dir:FFXN/dify:src', view: 'tree' },
})
expect(codeFile).not.toBeChecked()
await user.click(repository)
expect(firstPr).toBeChecked()
expect(secondPr).toBeChecked()
expect(srcCheckbox).not.toHaveAttribute('aria-disabled', 'true')
await user.click(srcCheckbox)
expect(codeFile).toBeChecked()
await user.click(repository)
expect(screen.getByRole('checkbox', { name: 'README.md' })).toBeChecked()
await user.click(repository)
expect(firstPr).not.toBeChecked()
expect(secondPr).not.toBeChecked()
expect(codeFile).not.toBeChecked()
await user.click(secondPr)
await user.click(codeFile)
await user.click(screen.getByRole('button', { name: 'knowledgeSpace.addSource' }))
@@ -488,24 +488,28 @@ function ResourceList({
const pageBranch = resource.kind === 'page' ? pageBranches.get(resource.key) : undefined
const emptyDriveFolder =
hasDriveFolderCheckbox(resource) && driveBranch?.loaded && !selectionKeys.length
const githubPreviewContainer = isGitHubPreviewContainer(resource)
const selectionBlocked = selectionAtLimit && !checked
const checkboxDisabled =
selectionBlocked || emptyDriveFolder || Boolean(driveBranch?.loading)
selectionBlocked ||
emptyDriveFolder ||
Boolean(driveBranch?.loading) ||
(githubPreviewContainer && !hasSelectionKeys)
const expanded =
resource.kind === 'page'
? treePreview
? expandedPageKeys.has(resource.key)
: !collapsed.has(resource.key)
: expandedDriveContainers.has(resource.key)
const githubPreviewContainer = isGitHubPreviewContainer(resource)
const rendersCheckbox = hasDriveFolderCheckbox(resource) || isSelectableResource(resource)
const rendersCheckbox =
hasDriveFolderCheckbox(resource) ||
githubPreviewContainer ||
isSelectableResource(resource)
return (
<Fragment key={resource.key}>
<li
className={cn('flex items-center gap-2 pe-3', expandable ? 'h-8.5' : 'h-7.5')}
style={{
paddingInlineStart: `${12 + resource.depth * 26 + (githubPreviewContainer ? 24 : 0)}px`,
}}
style={{ paddingInlineStart: `${12 + resource.depth * 26}px` }}
>
{expandable ? (
<button
@@ -537,9 +541,9 @@ function ResourceList({
indeterminate={indeterminate}
onCheckedChange={() => onToggle(resource)}
/>
) : !githubPreviewContainer ? (
) : (
<span className="size-4 shrink-0" />
) : null}
)}
<span aria-hidden className={`${resourceIcon(resource)} size-4 shrink-0`} />
<span className="min-w-0 flex-1 truncate system-xs-regular text-text-primary">
{resourceName(resource)}
@@ -1254,7 +1258,7 @@ function ResourceConfiguration({
void toggleDriveFolder(resource)
return
}
if (!isSelectableResource(resource)) return
if (!isSelectableResource(resource) && !isGitHubPreviewContainer(resource)) return
const removingResource = selectedRef.current.has(resource.key)
if (resource.kind === 'file' && removingResource)
setFolderSelectionIntents((intents) => {
@@ -1265,13 +1269,14 @@ function ResourceConfiguration({
const resourcesToToggle =
resource.kind === 'page'
? [
resource,
...(isSelectableResource(resource) ? [resource] : []),
...pageResources.filter(
(candidate) =>
resource.descendantKeys.includes(candidate.key) && isSelectableResource(candidate),
),
]
: [resource]
if (!resourcesToToggle.length) return
updateSelected((current) => {
const next = new Map(current)
const removing = resourcesToToggle.every((candidate) => next.has(candidate.key))