Fetch work item CRM contacts in their own query
What does this MR do and why?
This MR splits the loading of crmContacts widget from main work items query (i.e. namespaceWorkItem) into its own query that loads separate from base query, allowing us to bring down the query complexity of base query.
With this change in place, we're also able to remove 8 query overrides from ee/spec/graphql/all_queries_spec.rb.
Implementation notes
Here's a high level summary of what this MR does:
- We've split the
crmContactswidget from base work item query to its own query. - Unlike the other two splits, base query keeps
crmContacts { contactsAvailable }rather than justtype, because the sidebar gates this widget oncontactsAvailable(i.e. whether CRM is enabled for the group) and not merely on whether the widget is supported, seeworkItemCrmContactscomputed inwork_item_attributes_wrapper.vue. Only the expensivecontacts { nodes { ... } }selection moves out, same for thewidgetspath when flag is off. - The
work_items/components/work_item_crm_contacts.vuecomponent now owns its query, and edits go through a dedicatedworkItemUpdateCrmContactsmutation that returns the same fragment, so selecting contacts from the dropdown keeps updating the exact cache slot the query reads. - A failed query now reports through the page-level alert alongside the Sentry capture, instead of failing silently and leaving the widget looking like the item simply has no contacts.
- There's no subscription here, unlike !252573 (merged) and !252578 (merged).
Issues::SetCrmContactsServicetriggersissue_crm_contacts_updatedrather thanwork_item_updated, so/add_contactsand/remove_contactshave never updated this widget in real time, onmastereither. Splitting the query doesn't change that, and pointing a subscription atworkItemUpdatedwouldn't help since that topic never fires for a contacts change. Worth a follow-up, but out of scope here. - Creating a work item writes contacts into the local draft cache, so
graphql/resolvers.jsnow targets the new document for that draft update. - With this last split in place we can drop 8 per-file overrides from
ee/spec/graphql/all_queries_spec.rb: the detail queries, mutations and the subscription all fit under the default limit now. The list queries keep theirs, because the analyzer scores both thewidgetsandfeaturesbranches even though only one is ever requested. - This is the last of the three splits, so with all of them merged, work items load anonymously with the FF enabled globally.
🎉 Locally thenamespaceWorkItemdocument now scores 191 against the 200 anonymous cap.crmContacts- This MRcurrentUserTodos- !252573 (merged) (merged)linkedResources- !252578 (merged) (merged)
References
- Migrate work_item_crm_contacts.vue to use workI... (#590638 - closed)
- Work item feature - Update each widget to use f... (#587970 - closed)
- Work item features - Rollout `work_item_feature... (#587972)
- Change work item widgets queries to use `workIt... (&20609)
Screenshots or screen recordings
Note: There's no behaviour change when work_item_features_field feature flag is off, as Work Items continue to remain accessible for both logged-in and anonymous users. The recordings below indicate the behaviour for when flag is turned on.
| Before | After | |
|---|---|---|
| Logged In | No change, work items remained accessible before too while logged in | |
| Anonymous |
How to set up and validate locally
- Enable the flag with
Feature.enable(:work_item_features_field). - Open a work item in a project whose group has CRM contacts, and confirm the Contacts widget renders.
- Add and remove a contact, and confirm in the network tab that only
workItemUpdateCrmContactsfires, with nonamespaceWorkItemorworkItemCrmContactsrefetch. - Reload and confirm the change persisted.
- Repeat with the flag disabled to check the
widgetspath. - Start a new work item, add a contact to the draft, and confirm the draft survives a reload.
- With the flag still enabled, sign out and open a public work item, and confirm it renders instead of
Work Item not found.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.