Skip to content

VPR-63 Emergency Contact Info#139

Open
rlorenzo wants to merge 12 commits intoVPR-104-accessibility-audit-basefrom
VPR-63-emergency-contact-info
Open

VPR-63 Emergency Contact Info#139
rlorenzo wants to merge 12 commits intoVPR-104-accessibility-audit-basefrom
VPR-63-emergency-contact-info

Conversation

@rlorenzo
Copy link
Copy Markdown
Contributor

@rlorenzo rlorenzo commented Apr 1, 2026

Emergency Contact

  • Full CRUD: list, edit form, read-only view, and report pages
  • Backend: EF Core entities (StudentContact, StudentEmergencyContact), Mapperly DTOs, service layer with IEmergencyContactService
  • Permission-based routing — admins see the student list; students redirect to their own record
  • Admin controls: view editing status (open/closed/individually allowed), grant/revoke individual edit access
  • App access toggled via Access column (0/1) instead of row deletion, preserving audit trail
  • Exports: Excel, CSV, and PDF overview with completeness summary
  • Phone validation with error tracking via provide/inject
  • Completeness logic groups phone fields (any phone = complete)

Shared UI Refactors

  • Extracted ExportToolbar component — replaces duplicated export buttons across 12 Effort reports, Emergency Contact, and Photo Gallery
  • Unified report headers via ReportLayout header slot
  • Extracted compact-form.css from duplicate styles in Effort and Emergency Contact forms

Test Coverage

  • Backend: EmergencyContactControllerTests, EmergencyContactServiceTests
  • Frontend: tests for service, composable, CompletenessIcon, and ContactSection components

Database Change Steps

-- 1. Archive duplicates to backup table
SELECT ec.*
INTO emergencyContact_duplicates_backup
FROM emergencyContact ec
WHERE ec.emContact_id NOT IN (
    SELECT TOP 1 WITH TIES e.emContact_id
    FROM emergencyContact e
    WHERE e.stdContact_id = ec.stdContact_id AND e.type = ec.type
    ORDER BY
        (CASE WHEN e.name IS NOT NULL AND e.name != '' THEN 1 ELSE 0 END
       + CASE WHEN e.relationship IS NOT NULL AND e.relationship != '' THEN 1 ELSE 0 END
       + CASE WHEN e.work IS NOT NULL AND e.work != '' THEN 1 ELSE 0 END
       + CASE WHEN e.home IS NOT NULL AND e.home != '' THEN 1 ELSE 0 END
       + CASE WHEN e.cell IS NOT NULL AND e.cell != '' THEN 1 ELSE 0 END
       + CASE WHEN e.email IS NOT NULL AND e.email != '' THEN 1 ELSE 0 END) DESC,
        e.emContact_id DESC
)
AND ec.stdContact_id IN (
    SELECT stdContact_id FROM emergencyContact
    GROUP BY stdContact_id, type HAVING COUNT(*) > 1
);

-- 2. Verify backup count
SELECT COUNT(*) AS archived_rows FROM emergencyContact_duplicates_backup;

-- 3. Delete the non-canonical rows
DELETE FROM emergencyContact
WHERE emContact_id IN (SELECT emContact_id FROM emergencyContact_duplicates_backup);

-- 4. Verify no more duplicates
SELECT stdContact_id, type, COUNT(*) AS cnt
FROM emergencyContact
GROUP BY stdContact_id, type
HAVING COUNT(*) > 1;

-- 5. Add unique constraint (only after step 4 returns 0 rows)
ALTER TABLE emergencyContact
ADD CONSTRAINT UQ_emergencyContact_stdContact_type
UNIQUE (stdContact_id, type);

-- 6. Verify constraint exists
SELECT i.name AS index_name, i.type_desc, i.is_unique
FROM sys.indexes i
JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
WHERE i.object_id = OBJECT_ID('emergencyContact')
ORDER BY i.name, ic.key_ordinal;

-- 7. Drop backup table (after constraint verified)
DROP TABLE emergencyContact_duplicates_backup;

Copilot AI review requested due to automatic review settings April 1, 2026 18:01
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds the new Students-area “Emergency Contact Info” feature end-to-end (API + EF entities + Vue pages), and refactors shared report/export UI to reduce duplication across multiple Effort reports and Photo Gallery.

Changes:

  • Implemented backend emergency contact domain (EF entities, mapping, service layer, API controller) with permission-based access and exports (Excel/PDF/CSV-like via Excel/QuestPDF).
  • Added full Vue UI for emergency contacts (overview list, edit form, read-only view, report) with phone validation and completeness indicators.
  • Refactored shared UI: introduced ExportToolbar, standardized report headers via ReportLayout, and extracted shared compact form CSS.

Reviewed changes

Copilot reviewed 58 out of 58 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
web/Classes/SQLContext/SISContext.cs Adds EF DbSets + mappings for student contact/emergency contact tables.
web/Areas/Students/Services/PhoneHelper.cs Adds server-side phone normalize/format/validate utilities.
web/Areas/Students/Services/IEmergencyContactService.cs Defines emergency contact service contract.
web/Areas/Students/Services/EmergencyContactService.cs Implements core emergency contact logic, completeness, and access toggles.
web/Areas/Students/Services/EmergencyContactExportService.cs Generates Excel/PDF exports for overview and detailed report.
web/Areas/Students/Models/UpdateStudentContactRequest.cs Request DTO for updates.
web/Areas/Students/Models/StudentInfoDto.cs Student info DTO.
web/Areas/Students/Models/StudentContactReportDto.cs Report DTO for exports/report page.
web/Areas/Students/Models/StudentContactListItemDto.cs Overview/list DTO including completeness status.
web/Areas/Students/Models/StudentContactDetailDto.cs Detail DTO for view/edit pages.
web/Areas/Students/Models/Entities/StudentEmergencyContact.cs EF entity for emergency contact row.
web/Areas/Students/Models/Entities/StudentContact.cs EF entity for student contact row + navigation.
web/Areas/Students/Models/EmergencyContactMapper.cs Mapperly-based mapping + phone formatting/normalization wiring.
web/Areas/Students/Models/ContactInfoDto.cs Contact info DTO with email normalization/validation attribute.
web/Areas/Students/Models/AppAccessStatusDto.cs DTOs for app open/closed + individual grants.
web/Areas/Students/Controllers/EmergencyContactController.cs API endpoints for CRUD-ish operations, access toggles, and exports.
web/Areas/Students/Constants/EmergencyContactPermissions.cs Centralizes permission strings/role name.
web/Areas/RAPS/Services/RAPSAuditService.cs Adds injectable IUserHelper constructor overload for auditing.
VueApp/src/styles/compact-form.css New shared compact form styling for Quasar inputs/errors.
VueApp/src/styles/base.css Extends heading styles to include h1 in dialogs/page containers.
VueApp/src/Students/router/routes.ts Adds Students emergency contact routes + routing guards.
VueApp/src/Students/router/index.ts Enforces per-route meta.permissions in global guard.
VueApp/src/Students/pages/PhotoGallery.vue Replaces duplicated export UI with shared ExportToolbar.
VueApp/src/Students/EmergencyContact/utils/phone.ts Client-side phone digit/format/validate helpers.
VueApp/src/Students/EmergencyContact/utils/phone-errors-key.ts Injection key for shared phone error tracking.
VueApp/src/Students/EmergencyContact/types/index.ts TypeScript types for emergency contact feature.
VueApp/src/Students/EmergencyContact/services/emergency-contact-service.ts Frontend API client for emergency contact endpoints + exports.
VueApp/src/Students/EmergencyContact/pages/EmergencyContactView.vue Read-only detail page.
VueApp/src/Students/EmergencyContact/pages/EmergencyContactReport.vue Admin/SIS report table with exports + search.
VueApp/src/Students/EmergencyContact/pages/EmergencyContactList.vue Overview list with completeness indicators + access icons.
VueApp/src/Students/EmergencyContact/pages/EmergencyContactForm.vue Edit form with validation, warnings, and access controls.
VueApp/src/Students/EmergencyContact/composables/use-emergency-contact.ts Composable for state, dirty tracking, validation, save/load.
VueApp/src/Students/EmergencyContact/components/PhoneInput.vue Quasar-integrated phone input with mask + shared error tracking.
VueApp/src/Students/EmergencyContact/components/ContactSection.vue Reusable contact section (name/relationship/phones/email).
VueApp/src/Students/EmergencyContact/components/CompletenessIcon.vue Completeness indicator icon with tooltip/ARIA label.
VueApp/src/Students/EmergencyContact/components/AppAccessControls.vue Admin widget to toggle app open/closed and show grant counts.
VueApp/src/Students/EmergencyContact/tests/use-emergency-contact.test.ts Vitest coverage for completeness utility logic.
VueApp/src/Students/EmergencyContact/tests/emergency-contact-service.test.ts Vitest coverage for frontend API client behavior.
VueApp/src/Students/EmergencyContact/tests/contact-section.test.ts Logic-only tests for contact-section behavior assumptions.
VueApp/src/Students/EmergencyContact/tests/completeness-icon.test.ts Logic-only tests for completeness icon state selection.
VueApp/src/Effort/pages/TeachingActivityIndividual.vue Uses ReportLayout header slot + ExportToolbar.
VueApp/src/Effort/pages/TeachingActivityGrouped.vue Uses ReportLayout header slot + ExportToolbar.
VueApp/src/Effort/pages/SchoolSummary.vue Uses ExportToolbar; adds horizontal overflow for dept section.
VueApp/src/Effort/pages/ScheduledCliWeeks.vue Uses ExportToolbar; refines banner/header layout.
VueApp/src/Effort/pages/MultiYearReport.vue Uses ReportLayout header slot + ExportToolbar.
VueApp/src/Effort/pages/MeritSummary.vue Uses ReportLayout header slot + ExportToolbar.
VueApp/src/Effort/pages/MeritDetail.vue Uses ReportLayout header slot + ExportToolbar.
VueApp/src/Effort/pages/MeritAverage.vue Uses ReportLayout header slot + ExportToolbar.
VueApp/src/Effort/pages/EvalSummary.vue Uses ReportLayout header slot + ExportToolbar.
VueApp/src/Effort/pages/EvalDetail.vue Uses ReportLayout header slot + ExportToolbar.
VueApp/src/Effort/pages/DeptSummary.vue Uses ReportLayout header slot + ExportToolbar.
VueApp/src/Effort/pages/ClinicalEffort.vue Uses ReportLayout header slot + ExportToolbar.
VueApp/src/Effort/effort-forms.css Imports shared compact form CSS; removes duplicated styles.
VueApp/src/Effort/components/ReportLayout.vue Standardizes header wrapper and improves print page-break behavior.
VueApp/src/components/ExportToolbar.vue New shared export/search/route toolbar component.
VueApp/src/ClinicalScheduler/pages/ClinicalSchedulerHome.vue Adjusts heading markup to align with shared heading styles.
test/Students/EmergencyContactServiceTests.cs Adds extensive backend unit tests for service behavior.
test/Students/EmergencyContactControllerTests.cs Adds controller tests for permissions/results/exports.

Copy link
Copy Markdown

Copilot AI left a comment

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 58 out of 58 changed files in this pull request and generated 2 comments.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 1, 2026

Codecov Report

❌ Patch coverage is 64.27379% with 428 lines in your changes missing coverage. Please review.
✅ Project coverage is 43.34%. Comparing base (e595a95) to head (5da45e3).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...Students/Services/EmergencyContactExportService.cs 0.00% 243 Missing ⚠️
...Areas/Students/Services/EmergencyContactService.cs 82.26% 63 Missing and 17 partials ⚠️
...rgencyContact/composables/use-emergency-contact.ts 24.32% 56 Missing ⚠️
...gencyContact/services/emergency-contact-service.ts 67.53% 23 Missing and 2 partials ⚠️
...Students/Controllers/EmergencyContactController.cs 93.03% 8 Missing and 3 partials ⚠️
...Areas/Students/Models/StudentContactListItemDto.cs 66.66% 10 Missing ⚠️
web/Areas/Students/Models/ContactInfoDto.cs 85.71% 0 Missing and 1 partial ⚠️
...tudents/Models/Entities/StudentEmergencyContact.cs 90.00% 1 Missing ⚠️
...b/Areas/Students/Models/StudentContactDetailDto.cs 91.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #139      +/-   ##
==========================================
+ Coverage   42.66%   43.34%   +0.67%     
==========================================
  Files         802      818      +16     
  Lines       48448    49644    +1196     
  Branches     4446     4568     +122     
==========================================
+ Hits        20672    21517     +845     
- Misses      27285    27606     +321     
- Partials      491      521      +30     
Flag Coverage Δ
backend 43.28% <66.85%> (+0.69%) ⬆️
frontend 44.87% <46.35%> (+0.12%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@codecov-commenter
Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 45.09kB (1.95%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
viper-frontend-esm 2.36MB 45.09kB (1.95%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: viper-frontend-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/quasar.client-*.js 50 bytes 480.18kB 0.01%
assets/GenericError-*.css 34 bytes 203.34kB 0.02%
assets/TermManagement-*.js -4 bytes 55.08kB -0.01%
assets/ManageLinkCollections-*.js -1 bytes 52.21kB -0.0%
assets/RecentSelections-*.js -2 bytes 51.08kB -0.0%
assets/CourseDetail-*.js -1 bytes 40.51kB -0.0%
assets/PhotoGallery-*.js -762 bytes 35.17kB -2.12%
assets/InstructorEdit-*.js 1 bytes 32.11kB 0.0%
assets/InstructorList-*.js -2 bytes 25.93kB -0.01%
assets/CrossListedCoursesSection-*.js 5 bytes 23.64kB 0.02%
assets/MultiYearReport-*.js -266 bytes 18.72kB -1.4%
assets/EmergencyContactForm-*.js (New) 17.75kB 17.75kB 100.0% 🚀
assets/AuditList-*.js 1 bytes 5.2kB 0.02%
assets/AuditList-*.js 1 bytes 17.3kB 0.01%
assets/CourseList-*.js 6 bytes 15.85kB 0.04%
assets/EffortTypeList-*.js 1 bytes 14.95kB 0.01%
assets/EmergencyContactList-*.js (New) 10.86kB 10.86kB 100.0% 🚀
assets/CourseImportDialog-*.js 1 bytes 10.53kB 0.01%
assets/CourseLinkDialog-*.js 1 bytes 9.05kB 0.01%
assets/ManageBundleCompetencies-*.js 1 bytes 8.23kB 0.01%
assets/StudentClassYear-*.js 1 bytes 8.03kB 0.01%
assets/EmergencyContactView-*.js (New) 7.98kB 7.98kB 100.0% 🚀
assets/AssessmentList-*.js 1 bytes 6.81kB 0.01%
assets/TermSelection-*.js 1 bytes 6.48kB 0.02%
assets/UnitList-*.js 1 bytes 6.26kB 0.02%
assets/CompetenciesBundleReport-*.js 1 bytes 5.98kB 0.02%
assets/dist-*.js 648 bytes 5.95kB 12.22% ⚠️
assets/AssessmentEpa-*.js -5 bytes 5.68kB -0.09%
assets/ClinicalEffort-*.js -268 bytes 5.45kB -4.69%
assets/ManageBundles-*.js 1 bytes 4.72kB 0.02%
assets/SchoolSummary-*.js -344 bytes 4.55kB -7.02%
assets/TeachingActivityGrouped-*.js -272 bytes 4.3kB -5.94%
assets/MeritAverage-*.js -284 bytes 4.24kB -6.27%
assets/MeritDetail-*.js -287 bytes 3.96kB -6.76%
assets/TeachingActivityIndividual-*.js -338 bytes 3.92kB -7.94%
assets/DeptSummary-*.js -275 bytes 3.81kB -6.73%
assets/BiorenderStudents-*.js 1 bytes 3.6kB 0.03%
assets/EvalDetail-*.js -293 bytes 3.59kB -7.54%
assets/ClinicalSchedulerHome-*.js -8 bytes 3.59kB -0.22%
assets/MeritSummary-*.js -285 bytes 3.45kB -7.64%
assets/ScheduledCliWeeks-*.js -183 bytes 3.07kB -5.62%
assets/students-*.js 1.56kB 3.06kB 103.66% ⚠️
assets/EmergencyContactReport-*.js (New) 3.0kB 3.0kB 100.0% 🚀
assets/ExportToolbar-*.js (New) 2.75kB 2.75kB 100.0% 🚀
assets/PercentAssignTypeList-*.js 1 bytes 2.75kB 0.04%
assets/EvalSummary-*.js -291 bytes 2.72kB -9.65%
assets/PercentAssignTypeInstructors-*.js 1 bytes 2.45kB 0.04%
assets/emergency-*.js (New) 2.22kB 2.22kB 100.0% 🚀
assets/EmergencyContactForm-*.css (New) 1.9kB 1.9kB 100.0% 🚀
assets/SchoolSummary-*.css 16 bytes 1.8kB 0.9%
assets/validation-*.css 104 bytes 996 bytes 11.66% ⚠️
assets/ReportLayout-*.js 96 bytes 664 bytes 16.9% ⚠️
assets/ReportLayout-*.css 19 bytes 549 bytes 3.58%
assets/EmergencyContactList-*.css (New) 135 bytes 135 bytes 100.0% 🚀
assets/EmergencyContactView-*.css (New) 109 bytes 109 bytes 100.0% 🚀

Files in assets/MultiYearReport-*.js:

  • ./src/Effort/pages/MultiYearReport.vue → Total Size: 222 bytes

Files in assets/EmergencyContactForm-*.js:

  • ./src/Students/EmergencyContact/components/ContactSection.vue → Total Size: 243 bytes

  • ./src/Students/EmergencyContact/components/PhoneInput.vue → Total Size: 231 bytes

  • ./src/Students/EmergencyContact/composables/use-emergency-contact.ts → Total Size: 3.82kB

  • ./src/Students/EmergencyContact/pages/EmergencyContactForm.vue → Total Size: 256 bytes

Files in assets/EmergencyContactList-*.js:

  • ./src/Students/EmergencyContact/components/CompletenessIcon.vue → Total Size: 178 bytes

  • ./src/Students/EmergencyContact/components/AppAccessControls.vue → Total Size: 252 bytes

  • ./src/Students/EmergencyContact/pages/EmergencyContactList.vue → Total Size: 256 bytes

Files in assets/EmergencyContactView-*.js:

  • ./src/Students/EmergencyContact/pages/EmergencyContactView.vue → Total Size: 256 bytes

Files in assets/ClinicalEffort-*.js:

  • ./src/Effort/pages/ClinicalEffort.vue → Total Size: 219 bytes

Files in assets/SchoolSummary-*.js:

  • ./src/Effort/pages/SchoolSummary.vue → Total Size: 216 bytes

Files in assets/TeachingActivityGrouped-*.js:

  • ./src/Effort/pages/TeachingActivityGrouped.vue → Total Size: 246 bytes

Files in assets/MeritAverage-*.js:

  • ./src/Effort/pages/MeritAverage.vue → Total Size: 213 bytes

Files in assets/MeritDetail-*.js:

  • ./src/Effort/pages/MeritDetail.vue → Total Size: 139 bytes

Files in assets/TeachingActivityIndividual-*.js:

  • ./src/Effort/pages/TeachingActivityIndividual.vue → Total Size: 255 bytes

Files in assets/DeptSummary-*.js:

  • ./src/Effort/pages/DeptSummary.vue → Total Size: 139 bytes

Files in assets/EvalDetail-*.js:

  • ./src/Effort/pages/EvalDetail.vue → Total Size: 207 bytes

Files in assets/ClinicalSchedulerHome-*.js:

  • ./src/ClinicalScheduler/pages/ClinicalSchedulerHome.vue → Total Size: 251 bytes

Files in assets/MeritSummary-*.js:

  • ./src/Effort/pages/MeritSummary.vue → Total Size: 142 bytes

Files in assets/ScheduledCliWeeks-*.js:

  • ./src/Effort/pages/ScheduledCliWeeks.vue → Total Size: 157 bytes

Files in assets/EmergencyContactReport-*.js:

  • ./src/Students/EmergencyContact/pages/EmergencyContactReport.vue → Total Size: 191 bytes

Files in assets/EvalSummary-*.js:

  • ./src/Effort/pages/EvalSummary.vue → Total Size: 210 bytes

Files in assets/emergency-*.js:

  • ./src/Students/EmergencyContact/services/emergency-contact-service.ts → Total Size: 3.16kB

Files in assets/ReportLayout-*.js:

  • ./src/Effort/components/ReportLayout.vue → Total Size: 1.03kB

Copy link
Copy Markdown

Copilot AI left a comment

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 58 out of 58 changed files in this pull request and generated 3 comments.

@rlorenzo rlorenzo changed the base branch from main to VPR-104-accessibility-audit-base April 1, 2026 22:20
@rlorenzo rlorenzo force-pushed the VPR-63-emergency-contact-info branch from 5da45e3 to 31fe2ec Compare April 1, 2026 22:21
@rlorenzo rlorenzo requested a review from Copilot April 1, 2026 22:31
Copy link
Copy Markdown

Copilot AI left a comment

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 57 out of 57 changed files in this pull request and generated 3 comments.

@rlorenzo rlorenzo force-pushed the VPR-63-emergency-contact-info branch 2 times, most recently from d61686c to c34b2f8 Compare April 2, 2026 17:08
@rlorenzo rlorenzo requested a review from Copilot April 2, 2026 17:09
Copy link
Copy Markdown

Copilot AI left a comment

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 57 out of 57 changed files in this pull request and generated 6 comments.

Copy link
Copy Markdown

Copilot AI left a comment

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 57 out of 57 changed files in this pull request and generated 3 comments.

Copy link
Copy Markdown

Copilot AI left a comment

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 57 out of 57 changed files in this pull request and generated 1 comment.

@rlorenzo rlorenzo force-pushed the VPR-63-emergency-contact-info branch from 9d2398c to 1d136ac Compare April 3, 2026 19:08
@rlorenzo rlorenzo requested a review from Copilot April 3, 2026 21:02
Copy link
Copy Markdown

Copilot AI left a comment

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 57 out of 57 changed files in this pull request and generated 5 comments.

@rlorenzo rlorenzo requested a review from Copilot April 3, 2026 21:29
Copy link
Copy Markdown

Copilot AI left a comment

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 57 out of 57 changed files in this pull request and generated no new comments.

@rlorenzo rlorenzo force-pushed the VPR-63-emergency-contact-info branch 3 times, most recently from 9dde9d5 to 1672288 Compare April 7, 2026 13:55
rlorenzo added 11 commits April 7, 2026 22:22
- Full CRUD with list, edit form, read-only view, and report pages
- Backend service with EF Core entities, Mapperly DTOs, and Excel/CSV export
- Permission-based routing: admins see student list, students redirect to own record
- Frontend and backend test coverage for controller, service, composable, and components
…X improvements

- Admin badge shows student editing status (open/closed/individually allowed)
- Admin can grant/revoke individual edit access from the form page
- Save button always enabled; shows info notification when no changes
- New overview export (Excel + PDF) with completeness summary
- Completeness logic groups phone fields (any phone = complete)
- DTOs expanded with missing field details, row keys, and contact info
…aders

- Replace duplicated export buttons across 12 Effort reports, Emergency
  Contact, and Photo Gallery with a shared ExportToolbar component
- Move export controls into ReportLayout header slot with report titles
  for consistent layout across all report pages
- ReportLayout header conditionally renders via v-if="$slots.header"
…row deletion

- Flip Access between 0/1 instead of deleting/creating role-permission
  rows, preserving audit trail and avoiding orphaned state
- Extract shared compact-form.css from duplicate styles in effort and
  emergency contact forms
- Add phone validation error tracking via provide/inject to block save
- Expand test coverage: toggle, CanEdit, GetAccessStatus, exports
- set isValid=true on success path to clear stale error state
- update rawDigits so injected phoneErrors Set stays in sync
- PhoneHelper: change \D to [^0-9] so Unicode digits are stripped,
  matching the frontend's ASCII-only behavior
- EmergencyContactList: route non-admin (SIS) users to the read-only
  view page instead of the edit page they can't access
- PDF: Adobe Red (#b30b00)
- Excel: Excel Green (#217346)
- Word: MS Word Blue (#2b579a)
- Print: UC Davis Primary (var(--q-primary))
@rlorenzo rlorenzo force-pushed the VPR-63-emergency-contact-info branch from 43eb031 to 60927b6 Compare April 8, 2026 05:22
- Replace <q-page padding> with <div class="q-pa-md">. QPage hardcodes
  role=main, which created a duplicate landmark alongside the layout's
  own <main id="main-content"> wrapper.
- Change the page title from <div class="text-h5"> to <h1>. The page
  had no level-one heading; the visual typography is preserved via the
  existing text-h5 class.
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.

3 participants