summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 15:40:28 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 15:40:28 +0000
commitb595cb0c1dec83de5bdee18284abe86614bed33b (patch)
tree8c3d4540f193c5ff98019352f554e921b3a41a72 /app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens
parent2f9104a328fc8a4bddeaa4627b595166d24671d0 (diff)
downloadgitlab-ce-b595cb0c1dec83de5bdee18284abe86614bed33b.tar.gz
Add latest changes from gitlab-org/gitlab@15-2-stable-eev15.2.0-rc42
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens')
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/crm_contact_token.vue131
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/crm_organization_token.vue125
2 files changed, 256 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/crm_contact_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/crm_contact_token.vue
new file mode 100644
index 00000000000..adfe0559b62
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/crm_contact_token.vue
@@ -0,0 +1,131 @@
+<script>
+import { GlFilteredSearchSuggestion } from '@gitlab/ui';
+
+import { ITEM_TYPE } from '~/groups/constants';
+import { getIdFromGraphQLId, convertToGraphQLId } from '~/graphql_shared/utils';
+import createFlash from '~/flash';
+import { isPositiveInteger } from '~/lib/utils/number_utils';
+import { __ } from '~/locale';
+import searchCrmContactsQuery from '../queries/search_crm_contacts.query.graphql';
+
+import { DEFAULT_NONE_ANY } from '../constants';
+
+import BaseToken from './base_token.vue';
+
+export default {
+ components: {
+ BaseToken,
+ GlFilteredSearchSuggestion,
+ },
+ props: {
+ config: {
+ type: Object,
+ required: true,
+ },
+ value: {
+ type: Object,
+ required: true,
+ },
+ active: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ contacts: this.config.initialContacts || [],
+ loading: false,
+ };
+ },
+ computed: {
+ defaultContacts() {
+ return this.config.defaultContacts || DEFAULT_NONE_ANY;
+ },
+ namespace() {
+ return this.config.isProject ? ITEM_TYPE.PROJECT : ITEM_TYPE.GROUP;
+ },
+ },
+ methods: {
+ getActiveContact(contacts, data) {
+ return contacts.find((contact) => {
+ return `${this.formatContactId(contact)}` === data;
+ });
+ },
+ getContactName(contact) {
+ return `${contact.firstName} ${contact.lastName}`;
+ },
+ fetchContacts(searchTerm) {
+ let searchString = null;
+ let searchId = null;
+ if (isPositiveInteger(searchTerm)) {
+ searchId = this.formatContactGraphQLId(searchTerm);
+ } else {
+ searchString = searchTerm;
+ }
+
+ this.loading = true;
+
+ this.$apollo
+ .query({
+ query: searchCrmContactsQuery,
+ variables: {
+ fullPath: this.config.fullPath,
+ searchString,
+ searchIds: searchId ? [searchId] : null,
+ isProject: this.config.isProject,
+ },
+ })
+ .then(({ data }) => {
+ this.contacts = this.config.isProject
+ ? data[this.namespace]?.group.contacts.nodes
+ : data[this.namespace]?.contacts.nodes;
+ })
+ .catch(() =>
+ createFlash({
+ message: __('There was a problem fetching CRM contacts.'),
+ }),
+ )
+ .finally(() => {
+ this.loading = false;
+ });
+ },
+ formatContactId(contact) {
+ return `${getIdFromGraphQLId(contact.id)}`;
+ },
+ formatContactGraphQLId(id) {
+ return convertToGraphQLId('CustomerRelations::Contact', id);
+ },
+ },
+};
+</script>
+
+<template>
+ <base-token
+ :config="config"
+ :value="value"
+ :active="active"
+ :suggestions-loading="loading"
+ :suggestions="contacts"
+ :get-active-token-value="getActiveContact"
+ :default-suggestions="defaultContacts"
+ v-bind="$attrs"
+ @fetch-suggestions="fetchContacts"
+ v-on="$listeners"
+ >
+ <template #view="{ viewTokenProps: { inputValue, activeTokenValue } }">
+ {{ activeTokenValue ? getContactName(activeTokenValue) : inputValue }}
+ </template>
+ <template #suggestions-list="{ suggestions }">
+ <gl-filtered-search-suggestion
+ v-for="contact in suggestions"
+ :key="formatContactId(contact)"
+ :value="formatContactId(contact)"
+ >
+ <div>
+ <div>{{ getContactName(contact) }}</div>
+ <div class="gl-font-sm">{{ contact.email }}</div>
+ </div>
+ </gl-filtered-search-suggestion>
+ </template>
+ </base-token>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/crm_organization_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/crm_organization_token.vue
new file mode 100644
index 00000000000..e6ab944449e
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/crm_organization_token.vue
@@ -0,0 +1,125 @@
+<script>
+import { GlFilteredSearchSuggestion } from '@gitlab/ui';
+
+import { ITEM_TYPE } from '~/groups/constants';
+import { getIdFromGraphQLId, convertToGraphQLId } from '~/graphql_shared/utils';
+import createFlash from '~/flash';
+import { isPositiveInteger } from '~/lib/utils/number_utils';
+import { __ } from '~/locale';
+import searchCrmOrganizationsQuery from '../queries/search_crm_organizations.query.graphql';
+
+import { DEFAULT_NONE_ANY } from '../constants';
+
+import BaseToken from './base_token.vue';
+
+export default {
+ components: {
+ BaseToken,
+ GlFilteredSearchSuggestion,
+ },
+ props: {
+ config: {
+ type: Object,
+ required: true,
+ },
+ value: {
+ type: Object,
+ required: true,
+ },
+ active: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ organizations: this.config.initialOrganizations || [],
+ loading: false,
+ };
+ },
+ computed: {
+ defaultOrganizations() {
+ return this.config.defaultOrganizations || DEFAULT_NONE_ANY;
+ },
+ namespace() {
+ return this.config.isProject ? ITEM_TYPE.PROJECT : ITEM_TYPE.GROUP;
+ },
+ },
+ methods: {
+ getActiveOrganization(organizations, data) {
+ return organizations.find((organization) => {
+ return `${this.formatOrganizationId(organization)}` === data;
+ });
+ },
+ fetchOrganizations(searchTerm) {
+ let searchString = null;
+ let searchId = null;
+ if (isPositiveInteger(searchTerm)) {
+ searchId = this.formatOrganizationGraphQLId(searchTerm);
+ } else {
+ searchString = searchTerm;
+ }
+
+ this.loading = true;
+
+ this.$apollo
+ .query({
+ query: searchCrmOrganizationsQuery,
+ variables: {
+ fullPath: this.config.fullPath,
+ searchString,
+ searchIds: searchId ? [searchId] : null,
+ isProject: this.config.isProject,
+ },
+ })
+ .then(({ data }) => {
+ this.organizations = this.config.isProject
+ ? data[this.namespace]?.group.organizations.nodes
+ : data[this.namespace]?.organizations.nodes;
+ })
+ .catch(() =>
+ createFlash({
+ message: __('There was a problem fetching CRM organizations.'),
+ }),
+ )
+ .finally(() => {
+ this.loading = false;
+ });
+ },
+ formatOrganizationId(organization) {
+ return `${getIdFromGraphQLId(organization.id)}`;
+ },
+ formatOrganizationGraphQLId(id) {
+ return convertToGraphQLId('CustomerRelations::Organization', id);
+ },
+ },
+};
+</script>
+
+<template>
+ <base-token
+ :config="config"
+ :value="value"
+ :active="active"
+ :suggestions-loading="loading"
+ :suggestions="organizations"
+ :get-active-token-value="getActiveOrganization"
+ :default-suggestions="defaultOrganizations"
+ v-bind="$attrs"
+ @fetch-suggestions="fetchOrganizations"
+ v-on="$listeners"
+ >
+ <template #view="{ viewTokenProps: { inputValue, activeTokenValue } }">
+ {{ activeTokenValue ? activeTokenValue.name : inputValue }}
+ </template>
+ <template #suggestions-list="{ suggestions }">
+ <gl-filtered-search-suggestion
+ v-for="organization in suggestions"
+ :key="formatOrganizationId(organization)"
+ :value="formatOrganizationId(organization)"
+ >
+ {{ organization.name }}
+ </gl-filtered-search-suggestion>
+ </template>
+ </base-token>
+</template>