Skip to content

PR 5: refactor(effort): component extraction + report context centralization#178

Open
rlorenzo wants to merge 12 commits intorefactor/dead-code-and-shared-chromefrom
refactor/effort-component-extraction
Open

PR 5: refactor(effort): component extraction + report context centralization#178
rlorenzo wants to merge 12 commits intorefactor/dead-code-and-shared-chromefrom
refactor/effort-component-extraction

Conversation

@rlorenzo
Copy link
Copy Markdown
Contributor

@rlorenzo rlorenzo commented May 5, 2026

Summary

Part 5 of 6. Stacks on top of PR #177.

Effort-area refactors driven by jscpd (duplication detection): extract repeated UI shells, dialog scaffolding, and form-field clusters into reusable components. Plus a small report-service consolidation in C#. Also folds in the EmergencyContact shared page shell because it pairs naturally with the Effort UI patterns.

What's in this PR

Vue/UI extractions

  • EmergencyContactPageShell — shared page shell for emergency contact forms
  • DialogSubmitActions — submit/cancel button cluster used across multiple dialogs
  • PercentAssignmentFormFields — shared form-field cluster
  • EffortReportPage — page-layout shell for report screens
  • EffortRecordSharedFields — duplicate field cluster across record dialogs
  • InstructorPageShell — breadcrumbs + loading/error states for instructor pages
  • AsyncOperationDialog — preview-dialog shell
  • TermTable — term-selection rows component

C# / report services

  • BaseReportService centralizes report context loading; per-report services now consume it instead of each loading the term/context independently
  • CalculateWeightedAverage extracted in EvaluationReportService to replace four near-identical N5..N1 weighted-average + divide-by-zero guards

Bundled fixes

  • fix(effort): restore StatusBanner import in InstructorEdit — the InstructorPageShell extraction dropped a StatusBanner import the template still referenced. Pairs with the extraction commit it patches.
  • chore(quality): materialize CalculateWeightedAverage rows once — carry-over from PR 3's materialize IEnumerable batch. The helper that needed materialization is introduced in this PR, so the analyzer fix is bundled here rather than in PR 3.

Commits

  • refactor(emergency-contact): extract shared page shell
  • refactor(effort): extract DialogSubmitActions component
  • refactor(effort): extract PercentAssignmentFormFields
  • refactor(effort): extract EffortReportPage layout shell
  • refactor(effort): extract EffortRecordSharedFields from dialogs
  • refactor(effort): extract InstructorPageShell for breadcrumbs and states
  • refactor(effort): extract AsyncOperationDialog shell for preview dialogs
  • refactor(effort): extract TermTable for term selection rows
  • refactor(effort): centralize report context loading in BaseReportService
  • refactor(effort): extract CalculateWeightedAverage in EvaluationReportService
  • fix(effort): restore StatusBanner import in InstructorEdit
  • chore(quality): materialize CalculateWeightedAverage rows once

PR stack

Test plan

  • CI green
  • Effort instructor edit page: save flow + error banners render
  • Effort report pages: department/instructor/eval reports render the same as before
  • Percent assignment dialogs: add/edit submit flow
  • Term selection table: rendering + selection
  • Emergency contact form: page shell renders
  • EvaluationReportService: report numbers unchanged (spot-check a known eval period)

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • main
  • VPR-.*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ca38e1bf-6f56-4410-b788-2819cb547091

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/effort-component-extraction

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.

@rlorenzo rlorenzo force-pushed the refactor/effort-component-extraction branch from eee8d10 to 8f5ffd2 Compare May 5, 2026 07:39
@rlorenzo rlorenzo force-pushed the refactor/dead-code-and-shared-chrome branch from ebe32ec to 75abeb2 Compare May 5, 2026 07:39
rlorenzo added 12 commits May 5, 2026 07:46
Hoist breadcrumb, loading spinner, and not-found banner from
EmergencyContactForm.vue and EmergencyContactView.vue into a new
EmergencyContactPageShell.vue. Each page now owns only its h1 and
body content. Pure template refactor; no runtime change.
AddCourseEffortDialog and EffortRecordEditDialog shared a Cancel +
primary-action q-card-actions block with an identical #loading slot.
Hoist into DialogSubmitActions.vue parameterized by submitLabel and
isSaving. Other Effort dialogs still inline the pattern; migrate as
they are touched.
PercentAssignmentAddDialog and PercentAssignmentEditDialog shared a
165-line q-select/q-input/q-checkbox form body. Hoist into
PercentAssignmentFormFields.vue, v-modeled on the form state the
usePercentageForm composable already centralized. Each dialog now
owns only its title, save logic, banner variants, and footer. Also
migrate both footers to DialogSubmitActions. PercentageFormState
and TypeOption are re-exported from the composable so the new
component can type its props.
Consolidates the h1 + ReportFilterForm + loading spinner + ReportLayout
header/ExportToolbar + empty-state boilerplate that was duplicated
across all 9 standard Effort report pages into a single wrapper, so
individual pages only define their table content.
Share the Role / Effort Value / Notes / warning + error banner block
between EffortRecordAddDialog and EffortRecordEditDialog, and route the
Add dialog's footer through the existing DialogSubmitActions component.
Share the Instructors breadcrumb, loading spinner, and error banner
between InstructorDetail and InstructorEdit via a slot-based shell.
Share the dialog scaffold (close affordance, title/subtitle, loading
spinner, progress bar, and error state) between HarvestDialog,
PercentRolloverDialog, and ClinicalImportDialog. Per-dialog preview
bodies and action buttons stay in the consumers.
Share the desktop table + mobile list rendering across unopened / open /
closed term sections instead of inlining three near-identical q-table
blocks.
Move ITermService injection into BaseReportService and add shared
helpers (LoadSingleTermContextAsync, LoadYearlyReportContextAsync,
ExtractDistinctEffortTypes) so DeptSummary, SchoolSummary, and
TeachingActivity services no longer hand-roll the same row +
clinical-faculty + term-name plumbing.
…tService

Replace four near-identical N5..N1 weighted-average + divide-by-zero
guards in the summary and detail builders with a single helper.
The InstructorPageShell extraction (refactor 4601108) replaced the
StatusBanner import in InstructorEdit.vue, but the template still
references StatusBanner three times for save/error feedback. Vue logged
"Failed to resolve component: StatusBanner" warnings and rendered those
banners blank.
Carry-over from the analyzer-driven cleanup batch (PR 3). The materialization fix targets the helper extracted in d12711e — that helper doesn't exist in PR 3's base, so the fix moves here.
@rlorenzo rlorenzo force-pushed the refactor/effort-component-extraction branch from 8f5ffd2 to 9cad656 Compare May 5, 2026 14:47
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.

1 participant