Skip to content

114 improve project overview page - #115

Merged
InfinityBowman merged 8 commits into
mainfrom
114-improve-project-overview-page
Dec 20, 2025
Merged

114 improve project overview page#115
InfinityBowman merged 8 commits into
mainfrom
114-improve-project-overview-page

Conversation

@InfinityBowman

@InfinityBowman InfinityBowman commented Dec 20, 2025

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Automatic PDF metadata extraction and storage, including title, authors, publication year, journal, and DOI
    • New "Completed Studies" counter displayed on the overview dashboard
  • Improvements

    • Enhanced Google Drive import workflow with improved study targeting
    • Refined visibility filters for completed and reconciled checklists across views
    • Updated chart heading and refined visual styling for improved clarity

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

@InfinityBowman InfinityBowman linked an issue Dec 20, 2025 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Dec 20, 2025

Copy link
Copy Markdown

Walkthrough

This PR introduces PDF metadata extraction during upload and Google Drive import, propagates studyId through the import flow, refactors error handling in Google Drive integration, updates completion-status filtering for dual-reviewer studies, integrates a PDF metadata editing modal, and performs minor code simplifications and styling adjustments across multiple components.

Changes

Cohort / File(s) Change Summary
API Error Handling
packages/web/src/api/google-drive.js
Replaced ad-hoc error handling with centralized parseApiError() function in getGoogleDriveStatus, disconnectGoogleDrive, importFromGoogleDrive, getGoogleDrivePickerToken, and connectGoogleAccount; added diagnostic logging in importFromGoogleDrive.
Chart Color Adjustments
packages/web/src/components/charts/AMSTARDistribution.jsx, packages/web/src/components/charts/AMSTARRobvis.jsx
Updated greyscale color map values for yes, partial yes, no, and no-ma states to uniformly darker shades; added palette source comment.
Code Simplifications
packages/web/src/components/checklist-ui/compare/NotesCompareSection.jsx, packages/web/src/components/project-ui/ProjectDashboard.jsx
Consolidated hasAnyNote function to single-line declaration; simplified inline note-type array rendering; removed standalone comment line.
PDF Metadata Extraction & Storage
packages/web/src/stores/projectActionsStore/pdfs.js, packages/web/src/stores/projectActionsStore/studies.js, packages/web/src/components/project-ui/ProjectView.jsx
Introduced extractPdfMetadata() to derive title, DOI, firstAuthor, publicationYear, and journal; integrated metadata extraction into upload and Google Drive import flows; added metadata fields to stored PDF entries with graceful error handling.
Study Completion Logic
packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx, packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx, packages/web/src/components/project-ui/overview-tab/ChartSection.jsx, packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
Added status filter requiring both isReconciled and status === 'completed' for dual-reviewer checklists; introduced completedStudies computation; updated chart data filtering; changed "Quality Assessment Charts" heading to "Figures"; updated In Progress tile from blue-50 to amber-50; added Completed tile with blue-50 background.
Google Drive Import Flow
packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx, packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx, packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
Added studyId parameter propagation through picker flow; enhanced handleGoogleDriveImportSuccess to accept optional studyId with fallback logic; updated handlePicked to receive and pass studyId as second parameter; added runtime logging.
Component Refactoring
packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx, packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
Replaced internal getter functions with direct prop usage (study, expanded); integrated EditPdfMetadataModal with handleEditMetadata and handleSaveMetadata callbacks in StudyPdfSection.
Minor Styling & Updates
packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
Added shadow-sm class to outer container div.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Component as ProjectView/<br/>StudyPdfSection
    participant Store as projectActionsStore
    participant PDF as PDF Utils
    participant DOI as DOI API
    participant Firebase as Firebase

    User->>Component: Upload/Import PDF
    Component->>Store: handleUpload() or<br/>handleGoogleDriveImport()
    Store->>PDF: extractPdfMetadata(arrayBuffer)
    PDF->>PDF: extractPdfTitle()
    PDF->>PDF: extractPdfDoi()
    PDF->>DOI: fetchFromDOI(doi)
    DOI-->>PDF: {firstAuthor,<br/>publicationYear, journal}
    PDF-->>Store: {title, doi, firstAuthor,<br/>publicationYear, journal}
    Store->>Firebase: addPdfToStudy(file,<br/>pdfMetadata)
    Firebase-->>Store: PDF record created
    Store-->>Component: Success callback
    Component->>Component: Update UI
    Component-->>User: Display PDF with<br/>extracted metadata
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Metadata extraction logic in pdfs.js and studies.js: Async operations, DOI lookup integration, error handling and caching require careful validation.
  • Completion status filtering: Changes to dual-reviewer logic must be verified consistently across CompletedStudyCard, CompletedTab, ChartSection, and OverviewTab to prevent data inconsistency.
  • Google Drive import flow: StudyId propagation through multiple layers of components and callbacks needs tracing to confirm correct parameter passing.
  • Props refactoring in StudyCard: Replacement of getter functions with direct props requires verification that all child components and callbacks receive correct references.

Possibly related PRs

Poem

🐰 Metadata hops through PDF lands,
From upload streams to Firebase strands,
DOI lookups fetch the journal's name,
Completion filters sort the game,
Metadata Modal shines so bright,
Study cards now cast their light!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title references improving the project overview page, but the changeset includes substantial modifications across 18 files spanning API error handling, PDF metadata extraction, checklist filtering, chart changes, and UI styling—far beyond just the overview tab. Consider a more comprehensive title that captures the main scope, such as 'Enhance project management with PDF metadata extraction and improved checklist filtering' or 'Add PDF metadata extraction and refactor checklist completion logic'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 114-improve-project-overview-page

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

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
corates 81072e3 Commit Preview URL Dec 20 2025, 07:29 AM

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (6)
packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx (1)

337-497: Consider consolidating ReviewerPoolSection props.

The ReviewerPoolSection component receives 9 distinct properties (title, pool, available, total, isValid, onAdd, onRemove, onUpdatePercent, onDistributeEvenly), which exceeds the recommended maximum of 1–5 props per component. While this is an internal component, consolidating this state or extracting pool management logic into a shared primitive could improve maintainability.

For example, you could create a custom hook/primitive for pool operations and pass a single pool state object, or use Solid context to provide pool callbacks globally within this component's scope.

packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx (1)

140-140: Remove diagnostic console.log.

This debug statement should be removed before merging to production.

Proposed fix
-      console.log('picked', picked, studyId);
       await props.onPick?.(picked, studyId);
packages/web/src/api/google-drive.js (1)

52-52: Remove diagnostic console.log.

This debug statement should be removed before merging to production.

Proposed fix
-  console.log('importing from google drive', fileId, projectId, studyId);
   const response = await fetch(`${API_BASE}/api/google-drive/import`, {
packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx (1)

77-85: Consider user-facing error for missing studyId.

The guard correctly prevents passing an undefined studyId downstream, but only logs to console. Users won't know why their import failed. Consider showing a toast notification.

Proposed improvement
   const handleGoogleDriveImportSuccess = (file, studyId) => {
     // Use studyId from callback if provided, otherwise fall back to state
     const targetStudyId = studyId || googleDriveTargetStudyId();
     if (!targetStudyId) {
       console.error('No study ID available for Google Drive import');
+      showToast.error('Import Failed', 'Unable to determine target study');
       return;
     }
     projectActionsStore.pdf.handleGoogleDriveImport(targetStudyId, file);
   };
packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx (1)

30-30: Remove diagnostic console.log.

This debug statement should be removed before merging to production.

Proposed fix
       try {
-        console.log('importing from google drive', file.id, projectId(), studyId);
         setImporting(true);
packages/web/src/stores/projectActionsStore/pdfs.js (1)

47-48: Dead code: condition will never be true.

At line 37, metadata.doi is set when extractedDoi is truthy. Since we're inside the if (extractedDoi) block (line 40), metadata.doi is already assigned. The condition if (!metadata.doi) will always be false.

If the intent is to prefer refData.doi over the extracted DOI when available, the logic should be inverted. Otherwise, these lines can be removed.

Option A: Prefer refData.doi when available
-            if (!metadata.doi) metadata.doi = refData.doi || extractedDoi;
+            if (refData.doi) metadata.doi = refData.doi;
Option B: Remove dead code if extracted DOI is preferred
-            // Use extracted DOI if refData doesn't have one
-            if (!metadata.doi) metadata.doi = refData.doi || extractedDoi;
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4845668 and 81072e3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (18)
  • packages/web/src/api/google-drive.js (7 hunks)
  • packages/web/src/components/charts/AMSTARDistribution.jsx (1 hunks)
  • packages/web/src/components/charts/AMSTARRobvis.jsx (1 hunks)
  • packages/web/src/components/checklist-ui/compare/NotesCompareSection.jsx (2 hunks)
  • packages/web/src/components/project-ui/ProjectDashboard.jsx (0 hunks)
  • packages/web/src/components/project-ui/ProjectView.jsx (1 hunks)
  • packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx (1 hunks)
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx (1 hunks)
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx (4 hunks)
  • packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx (1 hunks)
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx (1 hunks)
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx (2 hunks)
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx (2 hunks)
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx (2 hunks)
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx (3 hunks)
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx (1 hunks)
  • packages/web/src/stores/projectActionsStore/pdfs.js (7 hunks)
  • packages/web/src/stores/projectActionsStore/studies.js (2 hunks)
💤 Files with no reviewable changes (1)
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
🧰 Additional context used
📓 Path-based instructions (11)
**/*

📄 CodeRabbit inference engine (.cursorrules)

Do not use emojis in code, comments, documentation, or commit messages

Files:

  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/api/google-drive.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/stores/projectActionsStore/pdfs.js
  • packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/checklist-ui/compare/NotesCompareSection.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
packages/web/src/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx,js,ts}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Import stores directly where needed instead of passing values through multiple components
When you need to compute a value based on props or state in SolidJS, use createMemo to ensure it updates reactively
For complex state or state objects in SolidJS, use Solid's createStore for better performance and reactivity
You may create reusable logic in 'primitives' (hooks) that can be shared across components to keep components clean and focused on rendering

Files:

  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/api/google-drive.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/stores/projectActionsStore/pdfs.js
  • packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/checklist-ui/compare/NotesCompareSection.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
packages/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability
Prefer using config files rather than hardcoding values
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Each file should handle one coherent responsibility
Use Zod for schema and input validation

Files:

  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/api/google-drive.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/stores/projectActionsStore/pdfs.js
  • packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/checklist-ui/compare/NotesCompareSection.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
packages/web/src/components/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/components/**/*.{jsx,tsx}: Use responsive design principles for UI components
Use Zag.js for UI components and design system
Zag components exist in packages/web/src/components/zag/* and should be reused; check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state
If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Components should be lean and focused and should not implement business logic; move business logic into stores, utilities, or primitives
Never have a component act as a 'God component' coordinating multiple large concerns

Files:

  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/checklist-ui/compare/NotesCompareSection.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
packages/web/src/**/*.{jsx,tsx,js,ts,css}

📄 CodeRabbit inference engine (.cursorrules)

Ensure browser compatibility for all frontend code (Safari is usually problematic)

Files:

  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/api/google-drive.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/stores/projectActionsStore/pdfs.js
  • packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/checklist-ui/compare/NotesCompareSection.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
packages/web/src/components/**/*.{jsx,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Group related components in subdirectories with an index.js barrel export

Files:

  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/checklist-ui/compare/NotesCompareSection.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
packages/web/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

packages/web/src/**/*.{jsx,tsx}: Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Files:

  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/checklist-ui/compare/NotesCompareSection.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/**/*.{js,jsx,ts,tsx}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Ensure browser compatibility for all frontend code (Safari is usually problematic)
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Use createMemo for derived values to ensure they update reactively

Files:

  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/api/google-drive.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/stores/projectActionsStore/pdfs.js
  • packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/checklist-ui/compare/NotesCompareSection.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability

Files:

  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/api/google-drive.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/stores/projectActionsStore/pdfs.js
  • packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/stores/projectActionsStore/studies.js
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/checklist-ui/compare/NotesCompareSection.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
packages/web/src/components/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/components/**/*.{js,jsx,ts,tsx}: Use responsive design principles for UI components
Group related components in subdirectories with an index.js barrel export
Use Zag.js for UI components and design system
Zag component exist in packages/web/src/components/zag/* and should be reused. Check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state. If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date
Components should be lean and focused. They should not implement business logic; move that into stores, utilities, or primitives
Never have a component act as a God component coordinating multiple large concerns

Files:

  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/project-ui/ProjectView.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx
  • packages/web/src/components/charts/AMSTARRobvis.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
  • packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx
  • packages/web/src/components/checklist-ui/compare/NotesCompareSection.jsx
  • packages/web/src/components/charts/AMSTARDistribution.jsx
  • packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx
packages/web/src/stores/**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Solid's createStore for complex state or state objects for better performance and reactivity

Files:

  • packages/web/src/stores/projectActionsStore/pdfs.js
  • packages/web/src/stores/projectActionsStore/studies.js
🧠 Learnings (3)
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx} : Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Applied to files:

  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx
📚 Learning: 2025-12-19T14:49:49.717Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.717Z
Learning: Applies to packages/web/src/components/**/*.{js,jsx,ts,tsx} : Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Applied to files:

  • packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx
📚 Learning: 2025-12-19T12:38:18.491Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-19T12:38:18.491Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx} : Use responsive design principles for UI components

Applied to files:

  • packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx
🧬 Code graph analysis (8)
packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx (2)
packages/web/src/stores/projectActionsStore/index.js (3)
  • pdf (114-114)
  • projectActionsStore (145-145)
  • study (112-112)
packages/web/src/components/project-ui/all-studies-tab/EditPdfMetadataModal.jsx (1)
  • EditPdfMetadataModal (16-192)
packages/web/src/api/google-drive.js (1)
packages/web/src/lib/error-utils.js (1)
  • parseApiError (23-37)
packages/web/src/components/project-ui/ProjectView.jsx (3)
packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCardHeader.jsx (1)
  • studyName (47-47)
packages/web/src/api/pdf-api.js (1)
  • uploadPdf (40-70)
packages/web/src/primitives/pdfCache.js (1)
  • cachePdf (111-138)
packages/web/src/stores/projectActionsStore/pdfs.js (4)
packages/web/src/lib/pdfUtils.js (2)
  • extractPdfTitle (69-71)
  • extractPdfDoi (216-218)
packages/web/src/lib/referenceLookup.js (1)
  • fetchFromDOI (139-170)
packages/web/src/api/pdf-api.js (1)
  • downloadPdf (79-93)
packages/web/src/primitives/pdfCache.js (1)
  • cachePdf (111-138)
packages/web/src/components/charts/AMSTARRobvis.jsx (1)
packages/web/src/components/charts/AMSTARDistribution.jsx (1)
  • colorMapGreyscale (82-87)
packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx (3)
packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx (2)
  • completedStudies (19-32)
  • studies (17-17)
packages/web/src/primitives/useProject/index.js (1)
  • studies (166-166)
packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx (1)
  • isSingleReviewer (16-16)
packages/web/src/components/project-ui/all-studies-tab/AllStudiesTab.jsx (2)
packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx (1)
  • studyId (36-36)
packages/web/src/stores/projectActionsStore/index.js (1)
  • projectActionsStore (145-145)
packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx (2)
packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx (1)
  • studyId (36-36)
packages/web/src/api/google-drive.js (1)
  • importFromGoogleDrive (51-68)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Workers Builds: corates
🔇 Additional comments (18)
packages/web/src/components/project-ui/overview-tab/ReviewerAssignment.jsx (1)

428-428: Visual polish looks good.

The addition of shadow-sm enhances the visual hierarchy and complements the broader UI refinements in the Overview tab.

packages/web/src/components/checklist-ui/compare/NotesCompareSection.jsx (2)

55-55: LGTM - Clean consolidation.

The single-line arrow function maintains the same logic and reactivity while improving code conciseness.


107-109: LGTM - Cleaner formatting.

The single-line array expression maintains identical logic (conditional entries with filter and join) while being more compact and readable.

packages/web/src/components/project-ui/completed-tab/CompletedStudyCard.jsx (1)

19-27: LGTM! Consistent dual-reviewer completion criteria.

The filter logic correctly distinguishes between single and dual-reviewer studies. For dual-reviewer studies, requiring both isReconciled and status === 'completed' ensures only fully reconciled and completed checklists are displayed. This aligns with the updated completion logic applied consistently across CompletedTab.jsx, OverviewTab.jsx, and ChartSection.jsx.

packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx (3)

45-53: LGTM! Consistent completed studies calculation.

The completedStudies calculation correctly implements the dual-status requirement for dual-reviewer studies, matching the logic in CompletedTab.jsx (lines 19-31) and other related components. Using .some() to check for at least one qualifying checklist is appropriate.


103-114: LGTM! Improved visual distinction with color scheme.

The tile styling changes improve the visual hierarchy:

  • Amber theme for "In Progress" studies
  • Blue theme for "Completed" studies

This provides better visual distinction between different study states and makes the dashboard more intuitive.


205-205: LGTM! Minor text refinement.

The heading change from "Charts" to "Figures" is a minor text refinement that uses more academically appropriate terminology.

packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx (1)

19-31: LGTM! Consistent dual-reviewer completion logic.

The updated completedStudies memo correctly requires both isReconciled and status === 'completed' for dual-reviewer studies. This aligns with the filtering logic applied across CompletedStudyCard.jsx (line 26), ChartSection.jsx (line 172), and OverviewTab.jsx (line 52), ensuring consistent completion criteria throughout the application.

packages/web/src/components/project-ui/overview-tab/ChartSection.jsx (1)

149-173: LGTM! Clear filtering logic with helpful comments.

The filtering logic correctly implements the dual-status requirement for dual-reviewer studies and is consistent with changes in CompletedTab.jsx, CompletedStudyCard.jsx, and OverviewTab.jsx. The comments clearly document the intended behavior.

For the edge case of studies with no reviewers assigned: the logic treats them as dual-reviewer studies (since isSingleReviewer = study.reviewer1 && !study.reviewer2 evaluates to false), requiring reconciled checklists to be included. This is safe because the reconciliation system requires both reviewers to be present for isReconciled to ever be true, so studies without reviewers will naturally be filtered out.

packages/web/src/api/google-drive.js (1)

6-6: LGTM: Centralized error handling.

The refactor to use parseApiError provides consistent error handling across all API calls. This improves maintainability and ensures uniform error response parsing.

Also applies to: 19-20, 37-38, 63-64, 81-82, 107-108

packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx (1)

12-12: LGTM: EditPdfMetadataModal integration.

The modal integration is clean, with appropriate local state management. The flow correctly opens the modal with the selected PDF and delegates saves to the store.

Also applies to: 21-22, 84-90, 178-185

packages/web/src/components/project-ui/all-studies-tab/study-card/StudyCard.jsx (1)

28-28: LGTM: Correct SolidJS reactivity pattern.

The changes correctly use direct prop access instead of destructuring, maintaining reactivity. This aligns with the coding guidelines and learnings for SolidJS components.

Based on learnings, direct prop access ensures props remain reactive in SolidJS.

Also applies to: 31-31, 37-38, 40-40, 47-47

packages/web/src/stores/projectActionsStore/studies.js (1)

178-191: LGTM: PDF metadata extraction during upload.

The metadata extraction is well-integrated with appropriate error handling. Failures are logged but don't block the upload flow, ensuring robustness. The extracted metadata (title, firstAuthor, publicationYear, journal, doi) is correctly passed to the PDF record with safe null fallbacks.

Also applies to: 203-207

packages/web/src/components/project-ui/ProjectView.jsx (1)

94-101: LGTM: Metadata extraction and study creation flow.

The changes correctly:

  • Derive study name from filename with appropriate fallback
  • Extract and map PDF metadata fields to the PDF record
  • Handle metadata errors gracefully with cleanup of orphaned files

The error handling pattern ensures that if metadata processing fails after upload, the uploaded file is properly cleaned up to avoid orphaned resources.

Also applies to: 108-127

packages/web/src/components/project-ui/google-drive/GoogleDrivePickerModal.jsx (1)

21-22: LGTM: studyId propagation through import flow.

The changes correctly propagate studyId through the Google Drive import flow:

  • Accessor functions maintain reactivity for props
  • studyId is passed from modal to launcher and back through the callback
  • Both file and studyId are correctly passed to onImportSuccess

Also applies to: 24-24, 32-32, 38-38, 64-64

packages/web/src/stores/projectActionsStore/pdfs.js (3)

7-8: LGTM!

Imports are appropriate for the new metadata extraction functionality and use the expected aliases.


156-175: LGTM!

Clean integration of metadata extraction into the upload flow. The || null fallbacks ensure consistent shape, and the guard at line 28 handles the case where arrayBuffer might be null.


237-290: LGTM!

The async conversion and metadata extraction integration look good. The graceful degradation when download fails (continuing without metadata) is appropriate, and the cleanup on error maintains consistency.

Comment on lines +99 to 105
// https://dev.to/finnhvman/grayscale-color-palette-with-equal-contrast-ratios-2pgl
const colorMapGreyscale = {
yes: '#1f2937',
'partial yes': '#6b7280',
no: '#d1d5db',
'no ma': '#f3f4f6',
yes: '#1b1b1b',
'partial yes': '#484848',
no: '#727272',
'no ma': '#a2a2a2',
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Extract color maps to a shared constants file.

Both AMSTARRobvis.jsx and AMSTARDistribution.jsx define identical greyscale color maps. This duplication violates the DRY principle and makes maintenance harder—future color adjustments would need to be applied in multiple places.

Proposed refactor

Create a new shared constants file:

// packages/web/src/components/charts/amstarColorMaps.js

// https://dev.to/finnhvman/grayscale-color-palette-with-equal-contrast-ratios-2pgl
export const AMSTAR_COLOR_MAP_DEFAULT = {
  yes: '#10b981',
  'partial yes': '#facc15',
  no: '#ef4444',
  'no ma': '#9ca3af',
};

export const AMSTAR_COLOR_MAP_GREYSCALE = {
  yes: '#1b1b1b',
  'partial yes': '#484848',
  no: '#727272',
  'no ma': '#a2a2a2',
};

Then import in both chart components:

 import { onCleanup, createEffect, createSignal } from 'solid-js';
 import * as d3 from 'd3';
+import { AMSTAR_COLOR_MAP_DEFAULT, AMSTAR_COLOR_MAP_GREYSCALE } from './amstarColorMaps';

And replace the local definitions:

-  const colorMapDefault = {
-    yes: '#10b981',
-    'partial yes': '#facc15',
-    no: '#ef4444',
-    'no ma': '#9ca3af',
-  };
-
-  // https://dev.to/finnhvman/grayscale-color-palette-with-equal-contrast-ratios-2pgl
-  const colorMapGreyscale = {
-    yes: '#1b1b1b',
-    'partial yes': '#484848',
-    no: '#727272',
-    'no ma': '#a2a2a2',
-  };
-
-  const colorMap = () => (greyscale() ? colorMapGreyscale : colorMapDefault);
+  const colorMap = () => (greyscale() ? AMSTAR_COLOR_MAP_GREYSCALE : AMSTAR_COLOR_MAP_DEFAULT);

Apply the same changes to AMSTARDistribution.jsx.

As per coding guidelines, keep files modular and avoid duplication.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In packages/web/src/components/charts/AMSTARRobvis.jsx around lines 99-105 there
is a duplicated greyscale color map; extract both greyscale and default AMSTAR
color maps into a new shared constants module (suggested path:
packages/web/src/components/charts/amstarColorMaps.js), export named maps
(AMSTAR_COLOR_MAP_DEFAULT and AMSTAR_COLOR_MAP_GREYSCALE), then replace the
local colorMapGreyscale definition with an import from that module and do the
same change in AMSTARDistribution.jsx so both components consume the shared
constants and the local duplicated definitions are removed.

Comment on lines +88 to 90
const handleSaveMetadata = async (studyId, pdfId, metadata) => {
projectActionsStore.pdf.updateMetadata(studyId, pdfId, metadata);
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find projectActionsStore definition
fd -t f "projectActionsStore" --search-path packages/web/src 2>/dev/null | head -20

Repository: InfinityBowman/corates

Length of output: 48


🏁 Script executed:

#!/bin/bash
# Search for updateMetadata in the codebase
rg "updateMetadata" packages/web/src -A 5 -B 2 --type ts --type tsx --type js --type jsx 2>/dev/null | head -100

Repository: InfinityBowman/corates

Length of output: 48


🏁 Script executed:

#!/bin/bash
# Look at StudyPdfSection.jsx directly, especially around lines 88-90
if [ -f "packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx" ]; then
  cat -n packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx | sed -n '80,100p'
fi

Repository: InfinityBowman/corates

Length of output: 750


🏁 Script executed:

#!/bin/bash
# Search for projectActionsStore definition and updateMetadata method
rg "updateMetadata" packages/web/src -A 10 -B 3 --type ts --type tsx --type js --type jsx 2>/dev/null

Repository: InfinityBowman/corates

Length of output: 48


🏁 Script executed:

#!/bin/bash
# Find where handleSaveMetadata is called (likely the modal)
rg "handleSaveMetadata" packages/web/src -B 5 -A 5 --type ts --type tsx --type js --type jsx 2>/dev/null

Repository: InfinityBowman/corates

Length of output: 48


🏁 Script executed:

#!/bin/bash
# Find projectActionsStore or similar store definitions
fd "store" packages/web/src --search-path packages/web/src/stores 2>/dev/null | head -20

Repository: InfinityBowman/corates

Length of output: 48


🏁 Script executed:

#!/bin/bash
# List files in stores directory
ls -la packages/web/src/stores/ 2>/dev/null | head -30

Repository: InfinityBowman/corates

Length of output: 454


🏁 Script executed:

#!/bin/bash
# Search for updateMetadata more broadly across all file types
find packages/web/src -type f \( -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" \) -exec grep -l "updateMetadata" {} \; 2>/dev/null

Repository: InfinityBowman/corates

Length of output: 203


🏁 Script executed:

#!/bin/bash
# Search for projectActionsStore
find packages/web/src -type f \( -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" \) -exec grep -l "projectActionsStore" {} \; 2>/dev/null | head -10

Repository: InfinityBowman/corates

Length of output: 776


🏁 Script executed:

#!/bin/bash
# Read the pdfs.js file which contains updateMetadata
cat packages/web/src/stores/projectActionsStore/pdfs.js

Repository: InfinityBowman/corates

Length of output: 9980


🏁 Script executed:

#!/bin/bash
# Find the modal component that uses handleSaveMetadata
grep -r "handleSaveMetadata" packages/web/src --include="*.jsx" --include="*.tsx" -B 10 -A 10

Repository: InfinityBowman/corates

Length of output: 3998


🏁 Script executed:

#!/bin/bash
# List all files in projectActionsStore directory
ls -la packages/web/src/stores/projectActionsStore/

Repository: InfinityBowman/corates

Length of output: 611


🏁 Script executed:

#!/bin/bash
# Find the EditPdfMetadataModal
find packages/web/src -type f \( -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" \) -exec grep -l "EditPdfMetadataModal" {} \;

Repository: InfinityBowman/corates

Length of output: 231


🏁 Script executed:

#!/bin/bash
# Search for the modal component definition
find packages/web/src -type f \( -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" \) | xargs grep -l "export.*EditPdfMetadataModal\|function EditPdfMetadataModal\|const EditPdfMetadataModal"

Repository: InfinityBowman/corates

Length of output: 145


🏁 Script executed:

#!/bin/bash
# Read the EditPdfMetadataModal component
cat packages/web/src/components/project-ui/all-studies-tab/EditPdfMetadataModal.jsx

Repository: InfinityBowman/corates

Length of output: 6919


Remove unnecessary async declaration from handleSaveMetadata.

The handleSaveMetadata handler is declared as async but doesn't await anything. The underlying updateMetadata method is synchronous and directly calls Y.js operations. Either remove the async keyword or wrap the call if actual async error handling becomes necessary in the future.

🤖 Prompt for AI Agents
In
packages/web/src/components/project-ui/all-studies-tab/study-card/StudyPdfSection.jsx
around lines 88 to 90, the handler handleSaveMetadata is declared async but
performs only a synchronous call to projectActionsStore.pdf.updateMetadata;
remove the async keyword from the function declaration to avoid misleading async
semantics (or if you intend to handle async behavior, convert the updateMetadata
call to return a Promise and await it). Ensure the function signature is updated
accordingly and any callers are unaffected.

Comment on lines +35 to +36
// eslint-disable-next-line solid/reactivity
let studyId = props.studyId;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Reactivity issue: studyId won't update if props change.

The let studyId = props.studyId assignment captures the initial value but won't update if props.studyId changes. In SolidJS, this creates a stale closure. When handleOpenPicker executes later, it may pass an outdated studyId to the callback.

Recommended fix: access props.studyId directly
-  // eslint-disable-next-line solid/reactivity
-  let studyId = props.studyId;

Then update line 141:

-      await props.onPick?.(picked, studyId);
+      await props.onPick?.(picked, props.studyId);

As per coding guidelines, props should be accessed directly to ensure reactivity in SolidJS components.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
packages/web/src/components/project-ui/google-drive/GoogleDrivePickerLauncher.jsx
around lines 35-36, the component assigns let studyId = props.studyId which
captures the initial value and becomes stale if props change; update the code to
stop copying props into a local variable and instead reference props.studyId
directly wherever studyId is used (e.g., in handleOpenPicker and callbacks) so
the component uses the reactive prop value; remove the local let studyId
declaration to avoid the stale closure.

@InfinityBowman
InfinityBowman merged commit 3cfea9a into main Dec 20, 2025
2 checks passed
@InfinityBowman
InfinityBowman deleted the 114-improve-project-overview-page branch December 20, 2025 08:15
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.

Improve project overview page

2 participants