Skip to content

Conversation

@nicotsx
Copy link
Owner

@nicotsx nicotsx commented Jan 2, 2026

Summary by CodeRabbit

  • Tests
    • Added comprehensive client-side tests for file tree selection behavior and test setup for the browser-like environment.
  • Bug Fixes
    • Fixed selection consolidation so parent/child selections behave consistently across nested folders and edge cases.
  • Style
    • Adjusted minimum height of loading, error, and empty state placeholders in the file browser.
  • Chores
    • Added separate scripts and tooling for running server and client tests.

✏️ Tip: You can customize this high-level summary in your review settings.

When all childs of a folder are selected in the tree, the selected path
was only simplifiyng one level. But if the reduction was also making its
own parent "fully selected" it was not correctly reporting only the
parent as selected
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 2, 2026

Walkthrough

Adds a FileTree test suite and related test setup, updates FileTree selection consolidation and parent/child handling, changes NodeButton rendering from button to div, adjusts placeholder height utilities in the volume file browser, and adds separate client/server test scripts and test dependencies.

Changes

Cohort / File(s) Summary
FileTree tests & logic
app/client/components/__test__/file-tree.test.tsx, app/client/components/file-tree.tsx
Adds tests validating selection simplification, recursive consolidation, deselection behavior, and deep-path handling. Reworks selection consolidation loop (iterative map-based consolidation), fixes descendant removal iteration, and adjusts parent/child deselection flows.
Node UI rendering
app/client/components/file-tree.tsx
Replaces button rendering with a div for NodeButton and adds biome-ignore comments for static interaction/key-with-click patterns.
Volume file browser UI
app/client/components/volume-file-browser.tsx
Replaces min-h-[200px] with min-h-50 in loading, error, and empty placeholder containers (styling change only).
Test setup & scripts
app/test/setup-client.ts, package.json
Adds Happy DOM global registration via app/test/setup-client.ts. Introduces test:server and test:client scripts and updates test to run both. Adds devDependencies: @happy-dom/global-registrator, @testing-library/dom, @testing-library/react.

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix/file tree selection parents' directly relates to the main changes in the PR, which focus on fixing file tree selection logic and parent/child deselection handling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fbc4a3a and 8a88d2c.

📒 Files selected for processing (2)
  • app/client/components/__test__/file-tree.test.tsx
  • app/client/components/file-tree.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/client/components/file-tree.tsx
  • app/client/components/test/file-tree.test.tsx

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nicotsx nicotsx force-pushed the fix/file-tree-selection-parents branch from fbc4a3a to 8a88d2c Compare January 2, 2026 15:53
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
app/client/components/file-tree.tsx (1)

196-237: Consider adding a maximum iteration limit as a safeguard for deeply nested hierarchies.

The consolidation algorithm has O(depth × fileList.length × selectedItems) complexity. While the break statement limits iterations to tree depth (typically manageable), adding a max iterations check would prevent any edge cases with unusual hierarchies from causing performance issues.

let changed = true;
let iterations = 0;
const MAX_ITERATIONS = 100; // Safeguard for pathological cases

while (changed && iterations < MAX_ITERATIONS) {
	iterations++;
	changed = false;
	// ... rest of algorithm
}
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f836e2f and fbc4a3a.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • app/client/components/__test__/file-tree.test.tsx
  • app/client/components/file-tree.tsx
  • app/client/components/volume-file-browser.tsx
  • app/test/setup-client.ts
  • package.json
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use Biome for code formatting and linting with bunx biome check --write ., format only with bunx biome format --write ., or lint with bunx biome lint .

Files:

  • app/client/components/__test__/file-tree.test.tsx
  • app/client/components/file-tree.tsx
  • package.json
  • app/test/setup-client.ts
  • app/client/components/volume-file-browser.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Use tabs (not spaces) for indentation with a line width of 120 characters
Use double quotes for strings
Do not auto-organize imports - imports organization is disabled in Biome
All imports must include file extensions when targeting Node/Bun, as the project uses "type": "module"

Files:

  • app/client/components/__test__/file-tree.test.tsx
  • app/client/components/file-tree.tsx
  • app/test/setup-client.ts
  • app/client/components/volume-file-browser.tsx
app/client/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

app/client/**/*.{ts,tsx}: Client uses TanStack Query for server state management
Client uses Radix UI primitives with custom Tailwind styling
Use Server-Sent Events hook (use-server-events.ts) for real-time updates in the client

Files:

  • app/client/components/__test__/file-tree.test.tsx
  • app/client/components/file-tree.tsx
  • app/client/components/volume-file-browser.tsx
🧠 Learnings (7)
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Use `bun run test` to run all tests, or `bunx dotenv-cli -e .env.test -- bun test --preload ./app/test/setup.ts` for specific test files

Applied to files:

  • package.json
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Use `bun run gen:api-client` to generate TypeScript API client from OpenAPI spec

Applied to files:

  • package.json
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Use `bun run build` for production builds

Applied to files:

  • package.json
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json} : Use Biome for code formatting and linting with `bunx biome check --write .`, format only with `bunx biome format --write .`, or lint with `bunx biome lint .`

Applied to files:

  • package.json
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Use `bun run tsc` for type checking and generating React Router types

Applied to files:

  • package.json
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/drizzle/**/*.ts : Never create migration files manually. Always use the provided command to generate migrations

Applied to files:

  • package.json
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/client/**/*.{ts,tsx} : Client uses Radix UI primitives with custom Tailwind styling

Applied to files:

  • app/client/components/volume-file-browser.tsx
🧬 Code graph analysis (1)
app/client/components/__test__/file-tree.test.tsx (1)
app/client/components/file-tree.tsx (2)
  • FileEntry (19-25)
  • FileTree (45-338)
🪛 GitHub Actions: Checks
app/client/components/__test__/file-tree.test.tsx

[warning] 36-36: Forbidden non-null assertion. (noNonNullAssertion)


[warning] 59-59: Forbidden non-null assertion. (noNonNullAssertion)


[warning] 90-90: Forbidden non-null assertion. (noNonNullAssertion)


[warning] 130-130: Forbidden non-null assertion. (noNonNullAssertion)


[warning] 161-161: Forbidden non-null assertion. (noNonNullAssertion)

🔇 Additional comments (8)
app/client/components/volume-file-browser.tsx (1)

60-60: LGTM! Consistent styling update.

The change from min-h-[200px] to min-h-50 is semantically equivalent in Tailwind (50 × 4px = 200px) and consistently applied across all three placeholder states.

Also applies to: 68-68, 76-76

app/test/setup-client.ts (1)

1-4: LGTM! Clean test setup for client tests.

The setup correctly imports shared test configuration and registers Happy DOM globals for client-side testing. The module-level GlobalRegistrator.register() call ensures the DOM environment is available before tests execute.

package.json (1)

20-22: LGTM! Well-structured test script organization.

The split between test:server and test:client with appropriate preload files is clean and maintainable. Sequential execution ensures server tests pass before running client tests.

app/client/components/__test__/file-tree.test.tsx (1)

1-167: Excellent test coverage for selection logic!

The test suite comprehensively validates the FileTree selection consolidation behaviors including parent simplification, child deselection, recursive consolidation, and deep path handling. The test scenarios align well with the updated selection logic in file-tree.tsx.

app/client/components/file-tree.tsx (4)

119-127: LGTM! Performance optimization for collapsed state sync.

The addition of hasChanges tracking prevents unnecessary state updates when the collapsed folder set hasn't changed. This is a clean optimization that avoids triggering re-renders.


154-157: LGTM! Correct iterator for descendant removal.

The change from iterating over fileList to iterating over newSelection is correct—you only need to check paths that are already in the selection set to find descendants to remove.


187-188: LGTM! Enhanced sibling restoration logic.

The additional conditions correctly prevent re-adding the unchecked path itself and any ancestors of the unchecked path when expanding a selected parent to its siblings.


493-503: Add keyboard accessibility to interactive tree node elements.

The NodeButton component lacks keyboard support for folder expansion and file/folder selection. The biome-ignore comments acknowledge accessibility violations, but they're not actually resolved. While the nested Checkbox (a Radix UI primitive) is keyboard accessible and doesn't cause nesting issues, the parent NodeButton div itself isn't keyboard navigable—there are no keyboard event handlers, no role attribute, and no tabIndex.

Consider either:

  • Adding keyboard handlers (onKeyDown for Enter/Space to toggle folders, arrow keys for navigation) and appropriate ARIA attributes
  • Using an actual <button> element instead of a div
  • Using a Radix primitive like @radix-ui/react-primitive or rendering with the Button component's asChild pattern (as demonstrated in ui/button.tsx)

Disabling linting rules doesn't replace the missing keyboard interaction logic.

@nicotsx nicotsx merged commit 013fe5a into main Jan 2, 2026
6 checks passed
@nicotsx nicotsx deleted the fix/file-tree-selection-parents branch January 2, 2026 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants