Skip to content

Collapse/expand for the queue sections#178

Open
theMackabu wants to merge 12 commits intostylessh:mainfrom
theMackabu:themackabu/persist-collapse
Open

Collapse/expand for the queue sections#178
theMackabu wants to merge 12 commits intostylessh:mainfrom
theMackabu:themackabu/persist-collapse

Conversation

@theMackabu
Copy link
Copy Markdown

@theMackabu theMackabu commented Apr 23, 2026

changes

  • implemented collapse/expand for the queue sections on both issues and pull requests
  • codebase side panel collapse state now persists
Screen.Recording.2026-04-23.at.3.39.59.PM.mov

Summary by CodeRabbit

  • New Features

    • Per-group collapse on Issues and Pulls with persistent state.
    • Shared sticky group headers with collapse toggles.
    • Dashboard counts deduplicated for more accurate totals.
  • Style

    • Improved command palette spacing and item layout.
    • Side panel collapse now persists across sessions.
    • Loading skeletons simplified (staggered animations removed).

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 23, 2026

📝 Walkthrough

Walkthrough

Persist side-panel and per-group collapse state to localStorage via new hooks; add shared StickyGroupHeader/StickyGroupContent (sticky detection, toggle, animations); deduplicate issue/pull counts with a new utility; remove staggered skeleton animations; minor styling and pnpm/miniflare patch.

Changes

Cohort / File(s) Summary
Side-panel & collapsed-groups storage
apps/dashboard/src/components/layouts/dashboard-side-panel.tsx, apps/dashboard/src/lib/collapsible-groups-storage.ts
Persist side-panel collapsed state to diffkit:side-panel-collapsed. Add useCollapsedGroups(storageKey) hook storing Record<string, boolean> in localStorage with validation and memoized updater.
Shared sticky header/content
apps/dashboard/src/components/shared/sticky-group-header.tsx
Add StickyGroupHeader (stuck detection, toggle, aria-expanded, chevron rotation) and StickyGroupContent (conditional rendering with AnimatePresence; chooses animation strategy by item count).
Issues & Pulls pages
apps/dashboard/src/routes/_protected/issues.tsx, apps/dashboard/src/routes/_protected/pulls.tsx
Replace route-local sticky header logic with shared components; wire per-group persistent collapse via useCollapsedGroups(...); metric clicks un-collapse groups; render items inside StickyGroupContent; change total counts to deduplicated totals.
Counts / utilities / layout
apps/dashboard/src/components/layouts/dashboard-layout.tsx, apps/dashboard/src/lib/count-unique.ts
Add countUniqueById and update dashboard layout to compute deduplicated pull/issue totals using it (replace summing of lengths).
Skeleton / animation removals
apps/dashboard/src/components/details/detail-page.tsx, apps/dashboard/src/components/compare/compare-page.tsx, apps/dashboard/src/components/issues/detail/issue-detail-page.tsx, apps/dashboard/src/components/pulls/detail/pull-detail-page.tsx
Remove staggered motion wrappers (StaggerItem/StaggerLoop) and mainItemCount usage; render static skeleton blocks directly.
Command palette styling
apps/dashboard/src/components/navigation/command-palette.tsx
Adjust Tailwind classes to remove horizontal padding and normalize group/item paddings and item rounding.
Miniflare patch & package config
package.json, patches/[email protected]
Add pnpm patched dependency entry for [email protected] and patch that adds v8Flags with --max-old-space-size=4096.

Sequence Diagram(s)

sequenceDiagram
  participant User as "User"
  participant Header as "StickyGroupHeader"
  participant Hook as "useCollapsedGroups"
  participant Storage as "localStorage\n(useLocalStorageState)"
  participant Content as "StickyGroupContent / Page"

  rect rgba(235,245,255,0.5)
  User->>Header: Click collapse toggle
  end

  rect rgba(220,255,235,0.5)
  Header->>Hook: setGroupCollapsed(groupId, newState)
  Hook->>Storage: write JSON for storageKey
  Storage-->>Hook: confirm write
  Hook-->>Header: update collapsedGroups
  end

  rect rgba(255,245,235,0.5)
  Hook->>Content: collapsedGroups change -> re-render
  Content-->>User: show/hide items with animation
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • stylessh
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description covers the main changes and includes a video demonstration, but lacks key template sections: missing Summary section context, no structured Changes list with details, and no Test Plan with checkboxes or testing confirmation. Expand the description to follow the template: add a Summary section explaining why this feature matters, detail the Changes with bullet points covering each file/feature, and include a Test Plan section with specific testing steps and checkboxes.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Collapse/expand for the queue sections' directly and specifically describes the main feature added in this PR—collapsible/expandable queue sections for issues and pull requests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot added the tembo Pull request created by Tembo label Apr 23, 2026
Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
apps/dashboard/src/routes/_protected/pulls.tsx (1)

316-405: Consider extracting StickyGroupHeader to a shared component.

The StickyGroupHeader implementation in pulls.tsx and issues.tsx is nearly identical. Extracting it to a shared component would reduce duplication and ensure consistent behavior across both pages.

This can be deferred to a follow-up PR if preferred.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/dashboard/src/routes/_protected/pulls.tsx` around lines 316 - 405,
Duplicate StickyGroupHeader exists in pulls.tsx and issues.tsx; extract it into
a shared component to remove duplication. Create a new component (e.g.,
StickyGroupHeader) in a shared UI/components location, preserve the same
props/signature (sectionRef, scrollContainerRef, stickyTop, icon, title, count,
isEmpty, isCollapsed, onCollapsedChange) and the internal logic (headerRef,
useEffect with updateStickyState, className handling and button JSX), export it,
then replace the local implementations in both pulls.tsx and issues.tsx with
imports that use the shared StickyGroupHeader so behavior and styling remain
identical. Ensure prop types and Icon component type match the original to avoid
type errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/dashboard/src/routes/_protected/pulls.tsx`:
- Around line 316-405: Duplicate StickyGroupHeader exists in pulls.tsx and
issues.tsx; extract it into a shared component to remove duplication. Create a
new component (e.g., StickyGroupHeader) in a shared UI/components location,
preserve the same props/signature (sectionRef, scrollContainerRef, stickyTop,
icon, title, count, isEmpty, isCollapsed, onCollapsedChange) and the internal
logic (headerRef, useEffect with updateStickyState, className handling and
button JSX), export it, then replace the local implementations in both pulls.tsx
and issues.tsx with imports that use the shared StickyGroupHeader so behavior
and styling remain identical. Ensure prop types and Icon component type match
the original to avoid type errors.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7009cc60-a824-4512-a11f-39b46287d533

📥 Commits

Reviewing files that changed from the base of the PR and between ab16402 and 1333b9a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • apps/dashboard/src/components/layouts/dashboard-side-panel.tsx
  • apps/dashboard/src/components/navigation/command-palette.tsx
  • apps/dashboard/src/lib/collapsible-groups-storage.ts
  • apps/dashboard/src/routes/_protected/issues.tsx
  • apps/dashboard/src/routes/_protected/pulls.tsx
  • package.json
  • patches/[email protected]

Copy link
Copy Markdown
Owner

@theMackabu this is nice!

i'm just not a big fan on animating lists display, bc anim gets weirder as the list gets longer.

@theMackabu
Copy link
Copy Markdown
Author

@theMackabu this is nice!

i'm just not a big fan on animating lists display, bc anim gets weirder as the list gets longer.

oh let me either remove or fix that, didn't consider long lists

@theMackabu
Copy link
Copy Markdown
Author

@stylessh reworked the animation for long groups, let me know if I should remove the animation fully or if this is good

Screen.Recording.2026-04-23.at.4.04.56.PM.mov

Copy link
Copy Markdown
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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/dashboard/src/components/shared/sticky-group-header.tsx`:
- Around line 73-83: The button currently hardcodes the top offset via the class
"-top-8" which ignores the computed stickyTop, causing desync when callers
supply a different offset; remove the hardcoded "-top-8" from the className on
the button (the element using headerRef and isStickyActive) and apply the
computed stickyTop as an inline style (e.g., top: stickyTop) so the sticky
positioning follows the stickyTop value used by the sticky state logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 37372dff-8f19-4fec-ab55-ceefae56c13b

📥 Commits

Reviewing files that changed from the base of the PR and between 1333b9a and 7f5548f.

📒 Files selected for processing (5)
  • apps/dashboard/src/components/layouts/dashboard-layout.tsx
  • apps/dashboard/src/components/shared/sticky-group-header.tsx
  • apps/dashboard/src/lib/count-unique.ts
  • apps/dashboard/src/routes/_protected/issues.tsx
  • apps/dashboard/src/routes/_protected/pulls.tsx
✅ Files skipped from review due to trivial changes (1)
  • apps/dashboard/src/lib/count-unique.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/dashboard/src/routes/_protected/issues.tsx

Comment thread apps/dashboard/src/components/shared/sticky-group-header.tsx
Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
apps/dashboard/src/routes/_protected/pulls.tsx (1)

109-141: Keep the group props stable so the memo(...) wrappers can actually help.

Line 109 rebuilds groups on every render, and Lines 167 and 184 create fresh callbacks for every item. Since PullMetricCard and PullGroup are memoized, toggling one section still ends up rerendering every section and row. That will be most noticeable in the long-list case this PR is trying to smooth out.

Also applies to: 161-189, 209-254, 256-308

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/dashboard/src/routes/_protected/pulls.tsx` around lines 109 - 141, The
groups array and item callbacks are being recreated every render which defeats
memoization for PullMetricCard and PullGroup; wrap the groups construction (the
const groups = [...] that uses applyFilters and countUniqueById) in useMemo
keyed on the inputs (data.reviewRequested, data.assigned, data.authored,
data.mentioned, data.involved and filterState) so the same groups object
identity is preserved across renders, and wrap any callbacks passed into
PullGroup/PullMetricCard (the per-item handlers created around applyFilters
usage and item actions referenced in the diff) in useCallback with appropriate
dependency arrays so they remain stable; ensure countUniqueById is called
against the memoized groups result so totalPulls is stable too.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/dashboard/src/routes/_protected/pulls.tsx`:
- Around line 109-141: The groups array and item callbacks are being recreated
every render which defeats memoization for PullMetricCard and PullGroup; wrap
the groups construction (the const groups = [...] that uses applyFilters and
countUniqueById) in useMemo keyed on the inputs (data.reviewRequested,
data.assigned, data.authored, data.mentioned, data.involved and filterState) so
the same groups object identity is preserved across renders, and wrap any
callbacks passed into PullGroup/PullMetricCard (the per-item handlers created
around applyFilters usage and item actions referenced in the diff) in
useCallback with appropriate dependency arrays so they remain stable; ensure
countUniqueById is called against the memoized groups result so totalPulls is
stable too.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7b97063c-b8ef-41d0-8284-e91820b40971

📥 Commits

Reviewing files that changed from the base of the PR and between 7f5548f and 3d15031.

📒 Files selected for processing (3)
  • apps/dashboard/src/components/shared/sticky-group-header.tsx
  • apps/dashboard/src/routes/_protected/issues.tsx
  • apps/dashboard/src/routes/_protected/pulls.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/dashboard/src/components/shared/sticky-group-header.tsx
  • apps/dashboard/src/routes/_protected/issues.tsx

Copy link
Copy Markdown
Owner

let's remove the animation for now, sorry!

@theMackabu
Copy link
Copy Markdown
Author

animation removed

Copy link
Copy Markdown
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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/dashboard/src/components/details/detail-page.tsx`:
- Around line 86-92: DetailPageSkeletonLayout's API changed: it no longer
accepts mainItemCount nor exports StaggerItem; update consuming modules that
import StaggerItem and pass mainItemCount to instead pass the value as
sidebarSectionCount to DetailPageSkeletonLayout and remove any StaggerItem
usage/wrapping. Specifically, drop the StaggerItem import/JSX and directly
render the children previously wrapped by <StaggerItem>, and replace occurrences
like mainItemCount={N} on DetailPageSkeletonLayout with sidebarSectionCount={N};
update any references to the removed StaggerItem symbol accordingly so
type-checking/build succeed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 41d6b8c2-bff2-4cb7-a53a-23da9a63a6dd

📥 Commits

Reviewing files that changed from the base of the PR and between 3d15031 and fb028be.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • apps/dashboard/src/components/compare/compare-page.tsx
  • apps/dashboard/src/components/details/detail-page.tsx
  • apps/dashboard/src/components/issues/detail/issue-detail-page.tsx
  • apps/dashboard/src/components/pulls/detail/pull-detail-page.tsx

Comment on lines 86 to 92
export function DetailPageSkeletonLayout({
children,
mainItemCount,
sidebarSectionCount = 3,
}: {
children: React.ReactNode;
mainItemCount: number;
children: ReactNode;
sidebarSectionCount?: number;
}) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find stale imports/usages of removed detail-page skeleton API.
rg -n --type=tsx -C2 'from "#/components/details/detail-page"'
rg -n --type=tsx -C2 '\bStaggerItem\b'
rg -n --type=tsx -C2 '<DetailPageSkeletonLayout[^>]*mainItemCount='

Repository: stylessh/diffkit

Length of output: 144


🏁 Script executed:

#!/bin/bash
# Search for imports from detail-page (use extension pattern instead of file type)
echo "=== Searching for imports from detail-page ==="
rg 'from.*detail-page' --include='*.tsx' --include='*.ts' -n

echo ""
echo "=== Searching for StaggerItem usage ==="
rg '\bStaggerItem\b' --include='*.tsx' --include='*.ts' -n

echo ""
echo "=== Searching for mainItemCount usage ==="
rg '\bmainItemCount\b' --include='*.tsx' --include='*.ts' -n

echo ""
echo "=== Checking detail-page.tsx exports ==="
cat apps/dashboard/src/components/details/detail-page.tsx | head -100

Repository: stylessh/diffkit

Length of output: 4094


🏁 Script executed:

#!/bin/bash
# Get full detail-page.tsx file
echo "=== Full detail-page.tsx ==="
wc -l apps/dashboard/src/components/details/detail-page.tsx

# Read the full file
cat apps/dashboard/src/components/details/detail-page.tsx

echo ""
echo "=== workflow-job-page.tsx imports (first 50 lines) ==="
head -50 apps/dashboard/src/components/workflows/workflow-job-page.tsx

echo ""
echo "=== workflow-run-page.tsx imports (first 50 lines) ==="
head -50 apps/dashboard/src/components/workflows/workflow-run-page.tsx

# Search using simpler grep patterns
echo ""
echo "=== StaggerItem mentions in tsx/ts files ==="
find apps/dashboard/src -type f \( -name "*.tsx" -o -name "*.ts" \) -exec grep -l "StaggerItem" {} \;

echo ""
echo "=== mainItemCount mentions in tsx/ts files ==="
find apps/dashboard/src -type f \( -name "*.tsx" -o -name "*.ts" \) -exec grep -l "mainItemCount" {} \;

Repository: stylessh/diffkit

Length of output: 6903


🏁 Script executed:

#!/bin/bash
# Check StaggerItem and mainItemCount usage in workflow-job-page.tsx
echo "=== workflow-job-page.tsx: lines 234-260 ==="
sed -n '234,260p' apps/dashboard/src/components/workflows/workflow-job-page.tsx

echo ""
echo "=== workflow-job-page.tsx: StaggerItem usage ==="
grep -n "StaggerItem\|mainItemCount" apps/dashboard/src/components/workflows/workflow-job-page.tsx | head -20

echo ""
echo "=== workflow-run-page.tsx: lines 166-200 ==="
sed -n '166,200p' apps/dashboard/src/components/workflows/workflow-run-page.tsx

echo ""
echo "=== workflow-run-page.tsx: StaggerItem usage ==="
grep -n "StaggerItem\|mainItemCount" apps/dashboard/src/components/workflows/workflow-run-page.tsx | head -20

Repository: stylessh/diffkit

Length of output: 2251


Breaking API change requires fixes in consuming modules.

DetailPageSkeletonLayout no longer accepts mainItemCount parameter and no longer exports StaggerItem. However, both are still imported and used in:

  • workflow-job-page.tsx (line 20 imports StaggerItem; line 236 passes mainItemCount={2}; lines 237–253 render <StaggerItem> components)
  • workflow-run-page.tsx (line 12 imports StaggerItem; line 168 passes mainItemCount={3}; lines 169–190 render <StaggerItem> components)

These imports and usages will fail type-check and build until both files are updated to use the new sidebarSectionCount prop instead and remove StaggerItem wrapping.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/dashboard/src/components/details/detail-page.tsx` around lines 86 - 92,
DetailPageSkeletonLayout's API changed: it no longer accepts mainItemCount nor
exports StaggerItem; update consuming modules that import StaggerItem and pass
mainItemCount to instead pass the value as sidebarSectionCount to
DetailPageSkeletonLayout and remove any StaggerItem usage/wrapping.
Specifically, drop the StaggerItem import/JSX and directly render the children
previously wrapped by <StaggerItem>, and replace occurrences like
mainItemCount={N} on DetailPageSkeletonLayout with sidebarSectionCount={N};
update any references to the removed StaggerItem symbol accordingly so
type-checking/build succeed.

Copy link
Copy Markdown
Owner

sorry! i made some changes conflicting with this, can you fix that? i will approved pr for now

@stylessh
Copy link
Copy Markdown
Owner

type checks are failing

@theMackabu
Copy link
Copy Markdown
Author

github prs seem to finally be working for me again LOL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tembo Pull request created by Tembo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants