diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-07-20 15:40:28 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-07-20 15:40:28 +0000 |
commit | b595cb0c1dec83de5bdee18284abe86614bed33b (patch) | |
tree | 8c3d4540f193c5ff98019352f554e921b3a41a72 /app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens | |
parent | 2f9104a328fc8a4bddeaa4627b595166d24671d0 (diff) | |
download | gitlab-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')
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> |