Skip to content

Handle missing data better#1668

Merged
nygrenh merged 1 commit intomasterfrom
fix-stuff-2
Mar 6, 2026
Merged

Handle missing data better#1668
nygrenh merged 1 commit intomasterfrom
fix-stuff-2

Conversation

@nygrenh
Copy link
Member

@nygrenh nygrenh commented Mar 6, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a dedicated error UI component that displays when data fails to load, with a "Try again" button to retry the operation.
    • Enhanced error handling across the application to distinguish between loading states and missing data scenarios, providing users with clearer feedback and recovery options.
  • Localization

    • Added new translation strings for error messaging and retry button text.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 6, 2026

📝 Walkthrough

Walkthrough

This PR introduces a new DataLoadError component and refactors 16+ components across the frontend to split combined "loading or missing data" conditions into separate branches, displaying a Spinner during loading and a dedicated error UI with retry functionality when data is unavailable.

Changes

Cohort / File(s) Summary
DataLoadError Component
shared-module/packages/common/src/components/DataLoadError.tsx
New React component that renders a generic data-load error banner with a retry button. Accepts onRetry callback and optional buttonVariant/buttonSize props. Defaults to "primary" button variant and "medium" size.
Localization Entries
shared-module/packages/common/src/locales/en/shared-module.json
Added two new i18n keys: button-text-try-again ("Try again") and label-error-loading ("Error loading data.").
Manage Pages Refactored
services/main-frontend/src/app/manage/.../course-status-summary-for-user/[user_id]/page.tsx, services/main-frontend/src/app/manage/courses/[id]/change-requests/EditProposalList.tsx, services/main-frontend/src/app/manage/courses/[id]/change-requests/EditProposalPage.tsx, services/main-frontend/src/app/manage/courses/[id]/exercises/ExerciseRepositories.tsx, services/main-frontend/src/app/manage/courses/[id]/feedback/FeedbackList.tsx, services/main-frontend/src/app/manage/courses/[id]/feedback/FeedbackPage.tsx, services/main-frontend/src/app/manage/courses/[id]/pages/CourseModules.tsx, services/main-frontend/src/app/manage/courses/[id]/stats/visualizations/overview/CourseUsersCountsByExercise.tsx, services/main-frontend/src/app/manage/courses/[id]/stats/visualizations/user-activity/CourseSubmissionsByWeekdayAndHour.tsx, services/main-frontend/src/app/manage/courses/[id]/user-status-summary/[user_id]/page.tsx, services/main-frontend/src/app/manage/pages/[id]/history/HistoryPage.tsx, services/main-frontend/src/app/manage/regradings/[id]/page.tsx, services/main-frontend/src/app/manage/regradings/page.tsx, services/main-frontend/src/app/manage/users/[id]/CourseEnrollmentsList.tsx, services/main-frontend/src/app/manage/users/[id]/page.tsx
All refactored to split loading and missing-data checks: Spinner displays only during isLoading, while DataLoadError renders when data is absent with an onRetry callback triggering refetch(). Existing error banners for query errors remain unchanged.
Course Material Components
services/main-frontend/src/components/course-material/ContentRenderer/moocfi/ExerciseBlock/PeerOrSelfReviewView/PeerOrSelfReviewsReceivedComponent/index.tsx, services/main-frontend/src/components/course-material/ContentRenderer/moocfi/Glossary/Glossary.tsx, services/main-frontend/src/components/course-material/ContentRenderer/moocfi/NavigationContainer/NextPage.tsx
Refactored to introduce DataLoadError UI for missing data with retry functionality; loading state unchanged. Added necessary imports (DataLoadError, Button where applicable).
Exercise Block Translation Simplification
services/main-frontend/src/components/course-material/ContentRenderer/moocfi/ExerciseBlock/index.tsx
Simplified translation key usage by removing defaultValue fallback in error and retry button text calls, using plain t() instead.
Notification Component
services/main-frontend/src/components/course-material/notifications/UserOnWrongCourseNotification.tsx
Decoupled loading and missing-data states: Spinner shown only when actively loading; DataLoadError renders when data is unavailable with retry via refetch().

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Possibly related PRs

Suggested labels

refactor, feature

Poem

A fluffy rabbit hops with glee, 🐰
New errors now are plain to see!
No more conflating loading states,
With retry buttons—all feels great!
Data loads or shows the way,
Cleaner flows to save the day! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

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.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Handle missing data better' directly reflects the main objective of the changeset, which consistently splits loading and missing-data handling across 18+ files to introduce a dedicated DataLoadError UI component.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-stuff-2

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.

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: 1

🧹 Nitpick comments (2)
shared-module/packages/common/src/components/DataLoadError.tsx (1)

9-37: Make this shared component either configurable or explicitly non-customizable.

DataLoadError is typed with PropsWithChildren, but it never renders children, and the message is fixed. That leaves a misleading public API and is already pushing some callers in this PR back to inline banner+retry markup. Either drop PropsWithChildren, or add a message/children slot so those sites can reuse this component cleanly.

♻️ Possible cleanup
 export interface DataLoadErrorProps {
   onRetry: () => void | Promise<void>
   buttonVariant?: React.ComponentProps<typeof Button>["variant"]
   buttonSize?: React.ComponentProps<typeof Button>["size"]
+  message?: React.ReactNode
 }

 /**
  * Renders a generic data load error with a retry button.
  */
-const DataLoadError: React.FC<React.PropsWithChildren<DataLoadErrorProps>> = ({
+const DataLoadError: React.FC<DataLoadErrorProps> = ({
   onRetry,
   buttonVariant = "primary",
   buttonSize = "medium",
+  message,
 }) => {
   const { t } = useTranslation()

   return (
     <div>
-      <ErrorBanner variant={"readOnly"} error={t("label-error-loading")} />
+      <ErrorBanner variant={"readOnly"} error={message ?? t("label-error-loading")} />
       <Button
         variant={buttonVariant}
         size={buttonSize}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shared-module/packages/common/src/components/DataLoadError.tsx` around lines
9 - 37, The component DataLoadError currently declares React.PropsWithChildren
in its signature but never renders children and has a fixed message; update the
public API to be honest: either remove PropsWithChildren and the ability to pass
children by changing the component type to React.FC<DataLoadErrorProps> (keep
DataLoadErrorProps as-is) or add a configurable message/slot by extending
DataLoadErrorProps with a message?: React.ReactNode (or exposing children) and
render that value in place of the hard-coded t("label-error-loading") so callers
can provide custom text while retaining onRetry, buttonVariant, and buttonSize
behavior.
services/main-frontend/src/app/manage/courses/[id]/exercises/ExerciseRepositories.tsx (1)

59-61: Use Spinner component for loading state instead of text.

This loading state uses a plain <div> with translated text, which is inconsistent with the other files in this PR and violates the coding guideline that states loading states should use the Spinner component from the shared module.

Suggested fix
   if (exerciseRepositories.isLoading) {
-    return <div>{t("loading-text")}</div>
+    return <Spinner variant="medium" />
   }

Note: You'll need to add the import if not already present:

import Spinner from "@/shared-module/common/components/Spinner"

As per coding guidelines: "For loading and error states, use the Spinner and ErrorBanner components from the shared module."

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

In
`@services/main-frontend/src/app/manage/courses/`[id]/exercises/ExerciseRepositories.tsx
around lines 59 - 61, Replace the plain <div> loading text in the
ExerciseRepositories component's loading branch (the block checking
exerciseRepositories.isLoading) with the shared Spinner component; add the
import "import Spinner from '@/shared-module/common/components/Spinner'" if
missing and render <Spinner /> (or Spinner with any existing layout wrappers
used elsewhere) instead of returning the translated loading-text div so the
component follows the project's loading-state convention.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@shared-module/packages/common/src/locales/en/shared-module.json`:
- Line 14: The new i18n key "button-text-try-again" added for DataLoadError.tsx
exists only in en/shared-module.json; add the same key to every other locale's
shared-module.json (or their equivalent locale JSONs) so all locales have this
key (use proper translations or English as a placeholder), ensuring consistency
of keys across locales and running any i18n validation/linting to catch missing
keys.

---

Nitpick comments:
In
`@services/main-frontend/src/app/manage/courses/`[id]/exercises/ExerciseRepositories.tsx:
- Around line 59-61: Replace the plain <div> loading text in the
ExerciseRepositories component's loading branch (the block checking
exerciseRepositories.isLoading) with the shared Spinner component; add the
import "import Spinner from '@/shared-module/common/components/Spinner'" if
missing and render <Spinner /> (or Spinner with any existing layout wrappers
used elsewhere) instead of returning the translated loading-text div so the
component follows the project's loading-state convention.

In `@shared-module/packages/common/src/components/DataLoadError.tsx`:
- Around line 9-37: The component DataLoadError currently declares
React.PropsWithChildren in its signature but never renders children and has a
fixed message; update the public API to be honest: either remove
PropsWithChildren and the ability to pass children by changing the component
type to React.FC<DataLoadErrorProps> (keep DataLoadErrorProps as-is) or add a
configurable message/slot by extending DataLoadErrorProps with a message?:
React.ReactNode (or exposing children) and render that value in place of the
hard-coded t("label-error-loading") so callers can provide custom text while
retaining onRetry, buttonVariant, and buttonSize behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cfc45870-9ffe-4bd6-b08b-ff5ddc78c4c2

📥 Commits

Reviewing files that changed from the base of the PR and between b231cb6 and 23017d0.

📒 Files selected for processing (22)
  • services/main-frontend/src/app/manage/course-instances/[id]/course-status-summary-for-user/[user_id]/page.tsx
  • services/main-frontend/src/app/manage/courses/[id]/change-requests/EditProposalList.tsx
  • services/main-frontend/src/app/manage/courses/[id]/change-requests/EditProposalPage.tsx
  • services/main-frontend/src/app/manage/courses/[id]/exercises/ExerciseRepositories.tsx
  • services/main-frontend/src/app/manage/courses/[id]/feedback/FeedbackList.tsx
  • services/main-frontend/src/app/manage/courses/[id]/feedback/FeedbackPage.tsx
  • services/main-frontend/src/app/manage/courses/[id]/pages/CourseModules.tsx
  • services/main-frontend/src/app/manage/courses/[id]/stats/visualizations/overview/CourseUsersCountsByExercise.tsx
  • services/main-frontend/src/app/manage/courses/[id]/stats/visualizations/user-activity/CourseSubmissionsByWeekdayAndHour.tsx
  • services/main-frontend/src/app/manage/courses/[id]/user-status-summary/[user_id]/page.tsx
  • services/main-frontend/src/app/manage/pages/[id]/history/HistoryPage.tsx
  • services/main-frontend/src/app/manage/regradings/[id]/page.tsx
  • services/main-frontend/src/app/manage/regradings/page.tsx
  • services/main-frontend/src/app/manage/users/[id]/CourseEnrollmentsList.tsx
  • services/main-frontend/src/app/manage/users/[id]/page.tsx
  • services/main-frontend/src/components/course-material/ContentRenderer/moocfi/ExerciseBlock/PeerOrSelfReviewView/PeerOrSelfReviewsReceivedComponent/index.tsx
  • services/main-frontend/src/components/course-material/ContentRenderer/moocfi/ExerciseBlock/index.tsx
  • services/main-frontend/src/components/course-material/ContentRenderer/moocfi/Glossary/Glossary.tsx
  • services/main-frontend/src/components/course-material/ContentRenderer/moocfi/NavigationContainer/NextPage.tsx
  • services/main-frontend/src/components/course-material/notifications/UserOnWrongCourseNotification.tsx
  • shared-module/packages/common/src/components/DataLoadError.tsx
  • shared-module/packages/common/src/locales/en/shared-module.json

@nygrenh nygrenh merged commit 6c74010 into master Mar 6, 2026
16 checks passed
@nygrenh nygrenh deleted the fix-stuff-2 branch March 6, 2026 08:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant