diff --git a/src/modules/routing/modules/chat-gateways/api/chatGateways.js b/src/modules/routing/modules/chat-gateways/api/chatGateways.js index 634a84fcd..55fb9b795 100644 --- a/src/modules/routing/modules/chat-gateways/api/chatGateways.js +++ b/src/modules/routing/modules/chat-gateways/api/chatGateways.js @@ -62,6 +62,7 @@ const webchatRequestConverter = (data) => { data.metadata.chat = JSON.stringify(data.metadata.chat); data.metadata.appointment = JSON.stringify(data.metadata.appointment); data.metadata.alternativeChannels = JSON.stringify(data.metadata.alternativeChannels); + data.metadata.call = JSON.stringify(data.metadata.call); data.metadata._btnCodeDirty = data.metadata._btnCodeDirty.toString(); return data; }; @@ -105,6 +106,9 @@ const webChatResponseConverter = (data) => { if (data.metadata.alternativeChannels) { data.metadata.alternativeChannels = JSON.parse(data.metadata.alternativeChannels); } + if (data.metadata.call) { + data.metadata.call = JSON.parse(data.metadata.call); + } data.metadata._btnCodeDirty = (data.metadata._btnCodeDirty === 'true'); return deepmerge(webChatGateway(), data); diff --git a/src/modules/routing/modules/chat-gateways/components/opened-chat-gateway.vue b/src/modules/routing/modules/chat-gateways/components/opened-chat-gateway.vue index 9ad7ad550..ee19bbdb0 100644 --- a/src/modules/routing/modules/chat-gateways/components/opened-chat-gateway.vue +++ b/src/modules/routing/modules/chat-gateways/components/opened-chat-gateway.vue @@ -16,6 +16,7 @@ @@ -338,7 +339,7 @@ export default { return this.$tc('objects.routing.gateways.gateways', 1); } return this.$t(`objects.routing.chatGateways.${chatTypeLocale}`) - .concat(' ', this.$tc('objects.routing.gateways.gateways', 1)); + .concat(' ', this.$tc('objects.routing.gateways.gateways', 1)); }, path() { diff --git a/src/modules/routing/modules/chat-gateways/modules/webchat/components/copy-code-button.vue b/src/modules/routing/modules/chat-gateways/modules/webchat/components/copy-code-button.vue index 2de563269..012100869 100644 --- a/src/modules/routing/modules/chat-gateways/modules/webchat/components/copy-code-button.vue +++ b/src/modules/routing/modules/chat-gateways/modules/webchat/components/copy-code-button.vue @@ -15,6 +15,7 @@ import isEmpty from '@webitel/ui-sdk/src/scripts/isEmpty'; import clipboardCopy from 'clipboard-copy'; import path from 'path'; import { v4 as uuidv4 } from 'uuid'; +import { mapActions } from 'vuex'; import getChatOriginUrl from '../../../scripts/getChatOriginUrl'; const SCRIPT_URL = getChatOriginUrl(); @@ -23,64 +24,8 @@ const CHAT_URL = import.meta.env.VITE_CHAT_URL; const WS_SERVER_URL = SCRIPT_URL.replace(/^http/, 'ws'); const filterEmptyValues = (obj) => Object - .entries(obj) - .reduce((acc, [key, value]) => (isEmpty(value) ? acc : { ...acc, [key]: value }), {}); - -const processViewConfig = (view) => filterEmptyValues(view); - -const processChatConfig = ({ - enabled, - timeoutIsActive, - openTimeout, - ...rest - }, uri) => { - if (!enabled) return undefined; - const result = { ...filterEmptyValues(rest) }; - if (timeoutIsActive) result.openTimeout = +openTimeout; - result.url = new URL(path.join(CHAT_URL, uri), WS_SERVER_URL); - return result; -}; - -const processAppointmentConfig = ({ - enabled, - queue, - communicationType, - days, - duration, - availableAgents, - showDefaultHeading, - successTitle, - successSubtitle, - ...rest - }, uri) => { - if (!enabled) return undefined; - if (!showDefaultHeading) { - // eslint-disable-next-line no-param-reassign - rest.successTitle = successTitle; - // eslint-disable-next-line no-param-reassign - rest.successSubtitle = successSubtitle; - } - const result = { ...filterEmptyValues(rest) }; - result.url = new URL(path.join(CHAT_URL.replace('chat', 'appointments'), uri), SCRIPT_URL); - return result; -}; - -const processAlternativeChannelsConfig = (channels) => { - const minifyAltChannels = (altChannels) => ( - Object.entries(altChannels) - .reduce((channels, [channelName, { enabled, url }]) => ( - enabled && url ? { ...channels, [channelName]: url } : channels - ), {}) - ); - const result = minifyAltChannels(channels); - return isEmpty(result) ? undefined : result; -}; - -const processCallConfig = ({ enabled, url, ...rest }) => { - if (!enabled) return undefined; - const id = uuidv4(); - return { url, id }; -}; +.entries(obj) +.reduce((acc, [key, value]) => (isEmpty(value) ? acc : { ...acc, [key]: value }), {}); const generateCode = (config) => ` const script = document.createElement('script'); @@ -112,6 +57,10 @@ export default { type: Object, required: true, }, + namespace: { + type: String, + required: true, + }, }, data: () => ({ isCopied: false, @@ -125,17 +74,22 @@ export default { }, }, methods: { + ...mapActions({ + setItemProp(dispatch, payload) { + return dispatch(`${this.namespace}/SET_ITEM_PROPERTY`, payload); + }, + }), copyCode() { - const view = processViewConfig(this.itemInstance.metadata.view); - const chat = processChatConfig(this.itemInstance.metadata.chat, this.itemInstance.uri); - const appointment = processAppointmentConfig( + const view = this.processViewConfig(this.itemInstance.metadata.view); + const chat = this.processChatConfig(this.itemInstance.metadata.chat, this.itemInstance.uri); + const appointment = this.processAppointmentConfig( this.itemInstance.metadata.appointment, this.itemInstance.uri, ); - const alternativeChannels = processAlternativeChannelsConfig( + const alternativeChannels = this.processAlternativeChannelsConfig( this.itemInstance.metadata.alternativeChannels, ); - const call = processCallConfig(this.itemInstance.metadata.call); + const call = this.processCallConfig(this.itemInstance.metadata.call); const code = generateCode({ view, @@ -153,6 +107,63 @@ export default { this.$emit('copied'); }, + + processViewConfig(view) {return filterEmptyValues(view);}, + + processChatConfig({ + enabled, + timeoutIsActive, + openTimeout, + ...rest + }, uri) { + if (!enabled) return undefined; + const result = { ...filterEmptyValues(rest) }; + if (timeoutIsActive) result.openTimeout = +openTimeout; + result.url = new URL(path.join(CHAT_URL, uri), WS_SERVER_URL); + return result; + }, + + processAppointmentConfig({ + enabled, + queue, + communicationType, + days, + duration, + availableAgents, + showDefaultHeading, + successTitle, + successSubtitle, + ...rest + }, uri) { + if (!enabled) return undefined; + if (!showDefaultHeading) { + // eslint-disable-next-line no-param-reassign + rest.successTitle = successTitle; + // eslint-disable-next-line no-param-reassign + rest.successSubtitle = successSubtitle; + } + const result = { ...filterEmptyValues(rest) }; + result.url = new URL(path.join(CHAT_URL.replace('chat', 'appointments'), uri), SCRIPT_URL); + return result; + }, + + processAlternativeChannelsConfig(channels) { + const minifyAltChannels = (altChannels) => ( + Object.entries(altChannels) + .reduce((channels, [channelName, { enabled, url }]) => ( + enabled && url ? { ...channels, [channelName]: url } : channels + ), {}) + ); + const result = minifyAltChannels(channels); + return isEmpty(result) ? undefined : result; + }, + + processCallConfig({ enabled, url, ...rest }) { + if (!enabled) return undefined; + const id = uuidv4(); + this.setItemProp({ path: 'metadata.call.id', value: id }); + return { url, id }; + }, }, }; diff --git a/src/modules/routing/modules/chat-gateways/modules/webchat/components/opened-chat-gateway-webchat-alternative-channels-tab.vue b/src/modules/routing/modules/chat-gateways/modules/webchat/components/opened-chat-gateway-webchat-alternative-channels-tab.vue index 4a8462430..82825daa8 100644 --- a/src/modules/routing/modules/chat-gateways/modules/webchat/components/opened-chat-gateway-webchat-alternative-channels-tab.vue +++ b/src/modules/routing/modules/chat-gateways/modules/webchat/components/opened-chat-gateway-webchat-alternative-channels-tab.vue @@ -66,7 +66,7 @@ import { mapActions } from 'vuex'; +import { EngineRoutingSchemaType } from 'webitel-sdk'; import openedTabComponentMixin from '../../../../../../../app/mixins/objectPagesMixins/openedObjectTabMixin/openedTabComponentMixin'; import FlowsAPI from '../../../../flow/api/flow'; @@ -92,15 +93,15 @@ export default { alternativeChannels: Object.values(WebchatAlternativeChannel), channelIcon: { ...Object.values(WebchatAlternativeChannel) - .reduce((channels, channel) => ({ ...channels, [channel]: `messenger-${channel}` }), {}), + .reduce((channels, channel) => ({ ...channels, [channel]: `messenger-${channel}` }), {}), [WebchatAlternativeChannel.EMAIL]: 'mail--color', }, channelUrlPlaceholder: { ...Object.values(WebchatAlternativeChannel) - .reduce((channels, channel) => ({ - ...channels, - [channel]: `objects.routing.chatGateways.${channel}.${channel}`, - }), {}), + .reduce((channels, channel) => ({ + ...channels, + [channel]: `objects.routing.chatGateways.${channel}.${channel}`, + }), {}), [WebchatAlternativeChannel.EMAIL]: 'objects.routing.chatGateways.webchat.alternativeChannels.email', [WebchatAlternativeChannel.WHATSAPP]: 'objects.routing.chatGateways.webchat.alternativeChannels.whatsapp', [WebchatAlternativeChannel.TELEGRAM]: 'objects.routing.chatGateways.webchat.alternativeChannels.telegram', @@ -113,7 +114,13 @@ export default { return dispatch(`${this.namespace}/SET_WEBCHAT_ALTERNATIVE_CHANNEL_VALUE`, payload); }, }), - loadFlows: FlowsAPI.getLookup, + loadCallFlows: (params) => FlowsAPI.getLookup({ + ...params, + type: [ + EngineRoutingSchemaType.Voice, + EngineRoutingSchemaType.Default, + ], + }), handleUrlInput({ channel, value }) { this.setAltChannelValue({ channel, prop: 'url', value }); if (!value) { diff --git a/src/modules/routing/modules/chat-gateways/store/_internals/providers/webChatGateway.js b/src/modules/routing/modules/chat-gateways/store/_internals/providers/webChatGateway.js index 56a514678..ebd45419a 100644 --- a/src/modules/routing/modules/chat-gateways/store/_internals/providers/webChatGateway.js +++ b/src/modules/routing/modules/chat-gateways/store/_internals/providers/webChatGateway.js @@ -48,6 +48,7 @@ const webChatGateway = (_btnCodeDirty = false) => ({ enabled: false, url: '', flow: {}, + id: '', }, alternativeChannels: Object .values(WebchatAlternativeChannel)