summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/sidebar/components/crm_contacts
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/sidebar/components/crm_contacts')
-rw-r--r--app/assets/javascripts/sidebar/components/crm_contacts/crm_contacts.vue131
-rw-r--r--app/assets/javascripts/sidebar/components/crm_contacts/queries/get_issue_crm_contacts.query.graphql7
-rw-r--r--app/assets/javascripts/sidebar/components/crm_contacts/queries/issue_crm_contacts.fragment.graphql17
-rw-r--r--app/assets/javascripts/sidebar/components/crm_contacts/queries/issue_crm_contacts.subscription.graphql9
4 files changed, 164 insertions, 0 deletions
diff --git a/app/assets/javascripts/sidebar/components/crm_contacts/crm_contacts.vue b/app/assets/javascripts/sidebar/components/crm_contacts/crm_contacts.vue
new file mode 100644
index 00000000000..6d4da104952
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/crm_contacts/crm_contacts.vue
@@ -0,0 +1,131 @@
+<script>
+import { GlIcon, GlPopover, GlTooltipDirective } from '@gitlab/ui';
+import { __, n__, sprintf } from '~/locale';
+import createFlash from '~/flash';
+import { convertToGraphQLId } from '~/graphql_shared/utils';
+import { TYPE_ISSUE } from '~/graphql_shared/constants';
+import getIssueCrmContactsQuery from './queries/get_issue_crm_contacts.query.graphql';
+import issueCrmContactsSubscription from './queries/issue_crm_contacts.subscription.graphql';
+
+export default {
+ components: {
+ GlIcon,
+ GlPopover,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ props: {
+ issueId: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ contacts: [],
+ };
+ },
+ apollo: {
+ contacts: {
+ query: getIssueCrmContactsQuery,
+ variables() {
+ return this.queryVariables;
+ },
+ update(data) {
+ return data?.issue?.customerRelationsContacts?.nodes;
+ },
+ error(error) {
+ createFlash({
+ message: __('Something went wrong trying to load issue contacts.'),
+ error,
+ captureError: true,
+ });
+ },
+ subscribeToMore: {
+ document: issueCrmContactsSubscription,
+ variables() {
+ return this.queryVariables;
+ },
+ updateQuery(prev, { subscriptionData }) {
+ const draftData = subscriptionData?.data?.issueCrmContactsUpdated;
+ if (prev && draftData) return { issue: draftData };
+ return prev;
+ },
+ },
+ },
+ },
+ computed: {
+ shouldShowContacts() {
+ return this.contacts?.length;
+ },
+ queryVariables() {
+ return { id: convertToGraphQLId(TYPE_ISSUE, this.issueId) };
+ },
+ contactsLabel() {
+ return sprintf(n__('%{count} contact', '%{count} contacts', this.contactCount), {
+ count: this.contactCount,
+ });
+ },
+ contactCount() {
+ return this.contacts?.length || 0;
+ },
+ },
+ methods: {
+ shouldShowPopover(contact) {
+ return this.popOverData(contact).length > 0;
+ },
+ divider(index) {
+ if (index < this.contactCount - 1) return ',';
+ return '';
+ },
+ popOverData(contact) {
+ return [contact.organization?.name, contact.email, contact.phone, contact.description].filter(
+ Boolean,
+ );
+ },
+ },
+ i18n: {
+ help: __('Work in progress- click here to find out more'),
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div v-gl-tooltip.left.viewport :title="contactsLabel" class="sidebar-collapsed-icon">
+ <gl-icon name="users" />
+ <span> {{ contactCount }} </span>
+ </div>
+ <div
+ v-gl-tooltip.left.viewport="$options.i18n.help"
+ class="hide-collapsed help-button float-right"
+ >
+ <a href="https://gitlab.com/gitlab-org/gitlab/-/issues/2256"><gl-icon name="question-o" /></a>
+ </div>
+ <div class="title hide-collapsed gl-mb-2 gl-line-height-20">
+ {{ contactsLabel }}
+ </div>
+ <div class="hide-collapsed gl-display-flex gl-flex-wrap">
+ <div
+ v-for="(contact, index) in contacts"
+ :id="`contact_container_${index}`"
+ :key="index"
+ class="gl-pr-2"
+ >
+ <span :id="`contact_${index}`" class="gl-font-weight-bold"
+ >{{ contact.firstName }} {{ contact.lastName }}{{ divider(index) }}</span
+ >
+ <gl-popover
+ v-if="shouldShowPopover(contact)"
+ :target="`contact_${index}`"
+ :container="`contact_container_${index}`"
+ triggers="hover focus"
+ placement="top"
+ >
+ <div v-for="row in popOverData(contact)" :key="row">{{ row }}</div>
+ </gl-popover>
+ </div>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/sidebar/components/crm_contacts/queries/get_issue_crm_contacts.query.graphql b/app/assets/javascripts/sidebar/components/crm_contacts/queries/get_issue_crm_contacts.query.graphql
new file mode 100644
index 00000000000..30a0af10d56
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/crm_contacts/queries/get_issue_crm_contacts.query.graphql
@@ -0,0 +1,7 @@
+#import "./issue_crm_contacts.fragment.graphql"
+
+query issueCrmContacts($id: IssueID!) {
+ issue(id: $id) {
+ ...CrmContacts
+ }
+}
diff --git a/app/assets/javascripts/sidebar/components/crm_contacts/queries/issue_crm_contacts.fragment.graphql b/app/assets/javascripts/sidebar/components/crm_contacts/queries/issue_crm_contacts.fragment.graphql
new file mode 100644
index 00000000000..750e1f1d1af
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/crm_contacts/queries/issue_crm_contacts.fragment.graphql
@@ -0,0 +1,17 @@
+fragment CrmContacts on Issue {
+ id
+ customerRelationsContacts {
+ nodes {
+ id
+ firstName
+ lastName
+ email
+ phone
+ description
+ organization {
+ id
+ name
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/sidebar/components/crm_contacts/queries/issue_crm_contacts.subscription.graphql b/app/assets/javascripts/sidebar/components/crm_contacts/queries/issue_crm_contacts.subscription.graphql
new file mode 100644
index 00000000000..f3b6e4ec06f
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/crm_contacts/queries/issue_crm_contacts.subscription.graphql
@@ -0,0 +1,9 @@
+#import "./issue_crm_contacts.fragment.graphql"
+
+subscription issueCrmContactsUpdated($id: IssuableID!) {
+ issueCrmContactsUpdated(issuableId: $id) {
+ ... on Issue {
+ ...CrmContacts
+ }
+ }
+}