Skip to content

Add confirm review button with auto-advance to rubric sidebar#695

Merged
jon-bell merged 12 commits into
pawtograder:stagingfrom
LavishSphere:staging
May 23, 2026
Merged

Add confirm review button with auto-advance to rubric sidebar#695
jon-bell merged 12 commits into
pawtograder:stagingfrom
LavishSphere:staging

Conversation

@LavishSphere

@LavishSphere LavishSphere commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

Resolves #308

Three major changes:

  • Added useNextIncompleteReviewUrl hook to share the "next incomplete review" URL logic that was previously only in the grading toolbar
  • Added a Confirm Review button at the bottom of the rubric sidebar so reviewers no longer need to scroll back to the top after finishing all their checks
  • Added an auto-advance toggle inside the confirmation popover. When enabled, confirming a review automatically navigates to the next incomplete submission (defaults to off, saved in browser storage)

Summary by CodeRabbit

  • New Features

    • Added an auto-advance toggle to automatically navigate to the next incomplete review after marking a submission complete.
    • Added a dedicated “Complete Review” button in the rubric sidebar for quicker access.
  • Improvements

    • Smarter next-incomplete navigation so the toolbar and completion flow reliably pick the appropriate next submission.

Copilot AI review requested due to automatic review settings April 10, 2026 07:24
@vercel

vercel Bot commented Apr 10, 2026

Copy link
Copy Markdown

@LavishSphere is attempting to deploy a commit to the Pawtograder Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@jon-bell has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 26 minutes and 2 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 26 minutes and 2 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 137f4be2-13d2-4501-9c89-19713de7a284

📥 Commits

Reviewing files that changed from the base of the PR and between b00bc59 and e8d0742.

📒 Files selected for processing (4)
  • components/ui/rubric-sidebar.tsx
  • components/ui/submission-review-toolbar.tsx
  • tests/e2e/grading.test.tsx
  • tests/e2e/pseudonymous-grading.test.tsx

Walkthrough

Introduces an auto-advance workflow for completing reviews: adds useNextIncompleteReviewUrl hook to compute the next incomplete review URL, moves a Complete Review button into the rubric sidebar, and adds a toggleable auto-advance option that navigates to the next review after marking complete.

Changes

Cohort / File(s) Summary
Next Incomplete Review Navigation
hooks/useNextIncompleteReview.ts
New exported hook that reads route params and user review assignments, groups by submission, identifies incomplete reviews, selects the next target submission/review, and returns a files URL or null.
Review Completion & Auto-Advance
components/ui/submission-review-toolbar.tsx
Added useAutoAdvance (localStorage-backed), integrated useNextIncompleteReviewUrl, conditionally shows an auto-advance Switch, and navigates to nextIncompleteUrl after marking complete when enabled.
Review Sidebar Layout
components/ui/rubric-sidebar.tsx
Imported and conditionally renders CompleteReviewButton at the bottom of the rubric list inside a Chakra Box when activeReviewAssignment exists.
Toolbar Navigation
components/ui/assignment-grading-toolbar.tsx
Removed in-component next-incomplete computation and ReviewToolbarStats.nextIncomplete; now uses useNextIncompleteReviewUrl and links to nextIncompleteUrl, updating the all-complete conditional logic.

Sequence Diagram

sequenceDiagram
    actor User
    participant Browser as Browser/Client
    participant Hook as useNextIncompleteReviewUrl
    participant Router as Next.js Router
    participant Page as Submission Files Page

    User->>Browser: Complete review checks / clicks "Mark as Complete"
    Browser->>Hook: Request next incomplete review URL (reads params, assignments)
    Hook-->>Browser: Return nextIncompleteUrl or null

    alt Auto-Advance Enabled & URL Available
        Browser->>Browser: Persist completion state
        Browser->>Router: router.push(nextIncompleteUrl)
        Router->>Page: Load target submission files with review_assignment_id
        Page-->>User: Display next review
    else Auto-Advance Disabled or No URL
        Browser->>Browser: Persist completion state
        Browser-->>User: Remain on current page
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

enhancement, frontend

Poem

A toggle saved, a hook that finds the way,
Click complete, and glide to the next display.
Sidebar button waits where rubrics end,
Steps flow forward—one review to the next, my friend. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: adding a confirm review button with auto-advance functionality to the rubric sidebar.
Linked Issues check ✅ Passed All coding requirements from issue #308 are met: a Confirm Review button added to rubric sidebar, auto-advance to next incomplete review implemented, and the behavior is toggleable with state persisted.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing issue #308 requirements: the new hook, sidebar button integration, and auto-advance toggle functionality are all in scope.

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


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.

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (2)
components/ui/submission-review-toolbar.tsx (2)

350-360: Solid localStorage-backed toggle hook.

The SSR safety check via typeof localStorage === "undefined" is appropriate. One minor consideration: in some privacy-focused browsers or incognito modes, localStorage.getItem or setItem can throw exceptions. This is rare but could be wrapped in a try-catch for extra resilience.

🛡️ Optional: Defensive localStorage access
 function useAutoAdvance(): [boolean, (v: boolean) => void] {
   const [on, setOn] = useState(() => {
-    if (typeof localStorage === "undefined") return false;
-    return localStorage.getItem("pawtograder-auto-advance-review") === "true";
+    try {
+      if (typeof localStorage === "undefined") return false;
+      return localStorage.getItem("pawtograder-auto-advance-review") === "true";
+    } catch {
+      return false;
+    }
   });
   const toggle = (v: boolean) => {
-    localStorage.setItem("pawtograder-auto-advance-review", String(v));
+    try {
+      localStorage.setItem("pawtograder-auto-advance-review", String(v));
+    } catch {
+      // Ignore storage errors in restricted environments
+    }
     setOn(v);
   };
   return [on, toggle];
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/ui/submission-review-toolbar.tsx` around lines 350 - 360, The hook
useAutoAdvance currently accesses localStorage directly which can throw in some
environments; wrap the read in the initializer in a try-catch and return false
on error, and wrap the localStorage.setItem call inside toggle in a try-catch to
silently fail (or optionally console.warn) so the state still updates via
setOn(v); this keeps the existing API ([on, toggle]) and uses the same symbols
(useAutoAdvance, on, toggle, setOn) but makes both getItem and setItem
defensively safe.

490-492: Consider whether navigation should close the popover first.

When auto-advance triggers router.push(nextIncompleteUrl), the popover may briefly remain visible during the navigation transition. This is likely fine given Next.js client-side routing speed, but if you notice a visual flicker, you could close the popover before navigating.

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

In `@components/ui/submission-review-toolbar.tsx` around lines 490 - 492, When
autoAdvance triggers navigation, close the popover first to avoid a visual
flicker: in the block where you check autoAdvance && nextIncompleteUrl (around
the router.push call), invoke the popover closing handler (e.g., call the
component's onClose, closePopover, or setOpen(false) that controls the Popover
state) before calling router.push(nextIncompleteUrl); if the popover close is
asynchronous, ensure you await or sequence it (close then push) so the popover
is hidden prior to navigation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@components/ui/submission-review-toolbar.tsx`:
- Around line 350-360: The hook useAutoAdvance currently accesses localStorage
directly which can throw in some environments; wrap the read in the initializer
in a try-catch and return false on error, and wrap the localStorage.setItem call
inside toggle in a try-catch to silently fail (or optionally console.warn) so
the state still updates via setOn(v); this keeps the existing API ([on, toggle])
and uses the same symbols (useAutoAdvance, on, toggle, setOn) but makes both
getItem and setItem defensively safe.
- Around line 490-492: When autoAdvance triggers navigation, close the popover
first to avoid a visual flicker: in the block where you check autoAdvance &&
nextIncompleteUrl (around the router.push call), invoke the popover closing
handler (e.g., call the component's onClose, closePopover, or setOpen(false)
that controls the Popover state) before calling router.push(nextIncompleteUrl);
if the popover close is asynchronous, ensure you await or sequence it (close
then push) so the popover is hidden prior to navigation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d845c700-91a9-4e2e-af40-539a3a3d8991

📥 Commits

Reviewing files that changed from the base of the PR and between f7c3db4 and b7ccb64.

📒 Files selected for processing (4)
  • components/ui/assignment-grading-toolbar.tsx
  • components/ui/rubric-sidebar.tsx
  • components/ui/submission-review-toolbar.tsx
  • hooks/useNextIncompleteReview.ts

coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 10, 2026

Copilot AI left a comment

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.

Pull request overview

Adds a shared “next incomplete review” URL helper and extends the review completion UX so reviewers can confirm from the rubric sidebar and optionally auto-advance to the next pending review.

Changes:

  • Introduced useNextIncompleteReviewUrl hook to centralize next-incomplete navigation logic.
  • Added an auto-advance toggle to the “Complete Review” popover and navigates on completion when enabled.
  • Rendered the “Complete Review” button at the bottom of the rubric sidebar when a review assignment is active.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
hooks/useNextIncompleteReview.ts New hook computing the next incomplete review URL with wrap-around behavior.
components/ui/submission-review-toolbar.tsx Adds auto-advance preference storage and navigation on completing a review.
components/ui/rubric-sidebar.tsx Adds a bottom-of-sidebar “Complete Review” entry point for active review assignments.
components/ui/assignment-grading-toolbar.tsx Refactors Next Incomplete link to use the new shared hook.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread hooks/useNextIncompleteReview.ts
Comment thread components/ui/submission-review-toolbar.tsx Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 10, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 10, 2026

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

components/ui/assignment-grading-toolbar.tsx:396

  • With the current useNextIncompleteReviewUrl() behavior, nextIncompleteUrl can be null while stats.allComplete is still false (e.g., when the only incomplete review is on the current submission). In that case this block renders nothing (neither “Next Incomplete” nor “All reviews completed”), which is confusing. Consider rendering a fallback message/state, or adjusting the hook so nextIncompleteUrl is non-null whenever !stats.allComplete.
            {stats && !stats.allComplete && nextIncompleteUrl ? (
              <Link href={nextIncompleteUrl}>
                <FaArrowRight style={{ marginRight: "4px" }} />
                Next Incomplete
              </Link>
            ) : stats?.allComplete ? (
              <Text color="fg.muted" fontSize="sm">
                All reviews completed!
              </Text>
            ) : null}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread components/ui/rubric-sidebar.tsx Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 10, 2026
@argos-ci

argos-ci Bot commented Apr 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) 👍 Changes approved 36 changed, 7 removed, 1 failure May 23, 2026, 2:40 AM

@jon-bell jon-bell left a comment

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.

LGTM

@jon-bell jon-bell merged commit 8bc747c into pawtograder:staging May 23, 2026
4 of 6 checks passed
@jon-bell

Copy link
Copy Markdown
Contributor

Thanks for the contribution and sorry for the delay in review + merge!

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.

Add an additional "Confirm Review" at the bottom, and automatically move to next

3 participants