Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements “Primary Client POC” by adding a primary flag to ClientContact and wiring it through Django forms/formset validation, UI templates/JS behavior, and an AJAX flow that can carry a client contact’s primary status into a project contact when appropriate.
Changes:
- Add
primaryboolean field toClientContact(with migration) and update factories/tests accordingly. - Add inline formset validation and UI toggle behavior to ensure only one primary client contact can be selected in formsets.
- Update AJAX “assign project contact” flow to optionally inherit
primaryontoProjectContactwhen the project has no primary yet.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| ghostwriter/rolodex/models.py | Adds ClientContact.primary; adjusts model metadata (currently also changes plural labels). |
| ghostwriter/rolodex/migrations/0060_alter_clientcontact_options_and_more.py | Adds DB field and alters model options (currently includes plural-label changes). |
| ghostwriter/rolodex/forms_client.py | Adds “single primary” validation to client contact inline formset and adds a toggle control to the form layout. |
| ghostwriter/rolodex/views.py | Updates AJAX project-contact assignment to conditionally inherit primary and avoid copying primary directly. |
| ghostwriter/factories.py | Updates ClientContactFactory to include primary. |
| ghostwriter/rolodex/tests/test_models.py | Adds model tests for default/set behavior of primary. |
| ghostwriter/rolodex/tests/test_forms.py | Updates form helper to include primary and adds validation test for multiple primary contacts. |
| ghostwriter/rolodex/tests/test_views.py | Adds tests for primary inheritance behavior during AJAX assignment. |
| ghostwriter/rolodex/templates/rolodex/client_form.html | Adds JS handler to enforce a single selected primary toggle in the formset UI. |
| ghostwriter/rolodex/templates/rolodex/client_detail.html | Adds a “Primary” column indicator for client contacts (and removes phone from the table). |
| ghostwriter/rolodex/templates/snippets/project_contacts_table.html | Adds screen-reader-only text for primary/non-primary indicators. |
| ghostwriter/shepherd/templates/snippets/client_contact_detail_modal.html | Adds phone display to the contact details modal (helps offset phone removal from the table). |
ghostwriter/rolodex/migrations/0060_alter_clientcontact_options_and_more.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
ghostwriter/shepherd/templates/snippets/client_contact_detail_modal.html:26
- The modal checks
poc.note, butClientContactuses thedescriptionfield (nonoteattribute). As-is, the “No additional information available.” branch will always render for client contacts. Update the template to read and sanitizepoc.description(consistent with how the form stores rich text).
{% if poc.note %}
<p>{{ poc.note|bleach|safe }}</p>
{% else %}
<p>No additional information available.</p>
{% endif %}
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #841 +/- ##
==========================================
+ Coverage 91.56% 91.60% +0.03%
==========================================
Files 372 373 +1
Lines 21364 21488 +124
==========================================
+ Hits 19563 19685 +122
- Misses 1801 1803 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This closes #789 by adding a
primaryfield to theClientContactmodel and supporting JavaScript and validation code for handling the field in forms. This field works like the field on theProjectContactmodel with some adjustments.This PR includes the following changes and behavior:
primaryfield to theClientContact(just likeProjectContact)primaryfield to theClientContactForm(just likeProjectContactForm)BaseClientContactInlineFormSetand JavaScript for handling what happens if a user selects multiple primary contacts in the formset (just likeProjectContactFormandBaseProjectContactInlineFormSet)ClientContactto a project and theProjectContactentries for a project do not already have a primary contact set for the project, carries-over theClientContactentry'sprimarystatus