Skip to content

Add ability to search issues by crm organization

Lee Tickett requested to merge 2256-search-issues-by-crm-organization into master

What does this MR do and why?

Related to #2256

If you're new to customer relations/crm- take a quick glance at the docs for some background https://docs.gitlab.com/ee/user/crm/#customer-relations-management-crm

This MR adds crm organization filtering to the issue finder, in turn allowing querying by manipulating the querystring (e.g. we don't have a pretty UI/search filter bar widget thingy).

We also add a button to the crm organizations list to navigate directly to all group issues for that organiztion.

We have just merged the same functionality for crm contacts !75451 (merged) - so hopefully this will be plain sailing 🤞

Screenshots or screen recordings

issue_search_by_crm_organization

How to set up and validate locally

From rails console:
1. Enable feature flag:
Feature.enable(:customer_relations)
From GraphiQL (http://gdk.test:3000/-/graphql-explorer):
2. Pick a an issue (I used http://gdk.test:3000/flightjs/Flight/-/issues/30)
4. Create a few organizations for the group the issue belongs to:
mutation {
  customerRelationsOrganizationCreate(input:
    { 
      groupId: "gid://gitlab/Group/26" 
      name: "Some company inc"
    }) {
    organization {
      id
    }
    errors
  }
}
5. Create a few contacts for the group the issue belongs to (attaching them to the organizations you just created):
mutation {
  customerRelationsContactCreate(input:
    {
      groupId: "gid://gitlab/Group/26"
      firstName: "Lee"
      lastName: "Tickett"
      email: "example@gitlab.com"
      organizationId: "gid://gitlab/CustomerRelations::Organization/4"
    }) {
    contact {
      id
      firstName
      lastName
    }
    errors
  }
}
6. Attempt to add/remove those contacts from your issue (via graphql... or via `/add_contacts` quick action):
mutation {
  issueSetCrmContacts(input:
    {
      projectPath: "flightjs/Flight"
      iid: "30"
      operationMode: REPLACE
	contactIds: [
        "gid://gitlab/CustomerRelations::Contact/14",
        "gid://gitlab/CustomerRelations::Contact/12"
      ]
    }) {
    issue {
     id
      customerRelationsContacts {
        nodes {
          id
          firstName
          lastName
        }
      }
    }
    errors
  }
}
7. Visit the group organizations list http://gdk.test:3000/groups/flightjs/-/crm/organizations
8. Click the issues button for an organization and ensure the correct issues are returned

Database

Generated SQL

SELECT issues.* FROM issues WHERE EXISTS (SELECT "issue_customer_relations_contacts".* FROM "issue_customer_relations_contacts" INNER JOIN "customer_relations_contacts" "contact" ON "contact"."id" = "issue_customer_relations_contacts"."contact_id" WHERE "contact"."organization_id" = 4 AND (issue_id = issues.id))
Query plan
 Nested Loop  (cost=19.40..43.98 rows=7 width=1410) (actual time=0.058..0.059 rows=0 loops=1)
   Buffers: shared hit=5
   I/O Timings: read=0.000 write=0.000
   ->  HashAggregate  (cost=18.83..18.90 rows=7 width=8) (actual time=0.057..0.058 rows=0 loops=1)
         Group Key: issue_customer_relations_contacts.issue_id
         Buffers: shared hit=5
         I/O Timings: read=0.000 write=0.000
         ->  Nested Loop  (cost=0.30..18.82 rows=7 width=8) (actual time=0.021..0.021 rows=0 loops=1)
               Buffers: shared hit=5
               I/O Timings: read=0.000 write=0.000
               ->  Index Scan using index_customer_relations_contacts_on_organization_id on public.customer_relations_contacts contact  (cost=0.15..4.68 rows=2 width=8) (actual time=0.020..0.020 rows=0 loops=1)
                     Index Cond: (contact.organization_id = 4)
                     Buffers: shared hit=5
                     I/O Timings: read=0.000 write=0.000
               ->  Index Scan using index_issue_customer_relations_contacts_on_contact_id on public.issue_customer_relations_contacts  (cost=0.15..7.01 rows=6 width=16) (actual time=0.000..0.000 rows=0 loops=0)
                     Index Cond: (issue_customer_relations_contacts.contact_id = contact.id)
                     I/O Timings: read=0.000 write=0.000
   ->  Index Scan using issues_pkey on public.issues  (cost=0.56..3.58 rows=1 width=1410) (actual time=0.000..0.000 rows=0 loops=0)
         Index Cond: (issues.id = issue_customer_relations_contacts.issue_id)
         I/O Timings: read=0.000 write=0.000
Timing
         Time: 6.696 ms
         - planning: 6.523 ms
         - execution: 0.173 ms
           - I/O read: 0.000 ms
           - I/O write: 0.000 ms
       
       Shared buffers:
         - hits: 5 (~40.00 KiB) from the buffer pool
         - reads: 0 from the OS file cache, including disk I/O
         - dirtied: 0
         - writes: 0

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Lee Tickett

Merge request reports

Loading