diff --git a/app/builders/account_builder.rb b/app/builders/account_builder.rb index a3a90451d..ff67eefc5 100644 --- a/app/builders/account_builder.rb +++ b/app/builders/account_builder.rb @@ -32,6 +32,8 @@ class AccountBuilder end def validate_email + raise InvalidEmail.new({ domain_blocked: domain_blocked }) if domain_blocked? + address = ValidEmail2::Address.new(@email) if address.valid? && !address.disposable? true @@ -79,4 +81,21 @@ class AccountBuilder @user.confirm if @confirmed @user.save! end + + def domain_blocked? + domain = @email.split('@').last + + blocked_domains.each do |blocked_domain| + return true if domain.match?(blocked_domain) + end + + false + end + + def blocked_domains + domains = GlobalConfigService.load('BLOCKED_EMAIL_DOMAINS', '') + domains.split("\n").map(&:strip) if domains.present? + + [] + end end diff --git a/app/javascript/dashboard/components/buttons/ResolveAction.vue b/app/javascript/dashboard/components/buttons/ResolveAction.vue index 0626ced59..0ff363874 100644 --- a/app/javascript/dashboard/components/buttons/ResolveAction.vue +++ b/app/javascript/dashboard/components/buttons/ResolveAction.vue @@ -13,7 +13,7 @@ import wootConstants from 'dashboard/constants/globals'; import { CMD_REOPEN_CONVERSATION, CMD_RESOLVE_CONVERSATION, -} from 'dashboard/routes/dashboard/commands/commandBarBusEvents'; +} from 'dashboard/helper/commandbar/events'; const store = useStore(); const getters = useStoreGetters(); diff --git a/app/javascript/dashboard/components/widgets/AIAssistanceButton.vue b/app/javascript/dashboard/components/widgets/AIAssistanceButton.vue index 360599631..96fe2830a 100644 --- a/app/javascript/dashboard/components/widgets/AIAssistanceButton.vue +++ b/app/javascript/dashboard/components/widgets/AIAssistanceButton.vue @@ -7,7 +7,7 @@ import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents'; import { useAI } from 'dashboard/composables/useAI'; import AICTAModal from './AICTAModal.vue'; import AIAssistanceModal from './AIAssistanceModal.vue'; -import { CMD_AI_ASSIST } from 'dashboard/routes/dashboard/commands/commandBarBusEvents'; +import { CMD_AI_ASSIST } from 'dashboard/helper/commandbar/events'; import AIAssistanceCTAButton from './AIAssistanceCTAButton.vue'; export default { diff --git a/app/javascript/dashboard/components/widgets/AIAssistanceModal.vue b/app/javascript/dashboard/components/widgets/AIAssistanceModal.vue index 547746131..8f3100d80 100644 --- a/app/javascript/dashboard/components/widgets/AIAssistanceModal.vue +++ b/app/javascript/dashboard/components/widgets/AIAssistanceModal.vue @@ -1,13 +1,12 @@ diff --git a/app/javascript/dashboard/routes/dashboard/commands/conversationHotKeys.js b/app/javascript/dashboard/routes/dashboard/commands/conversationHotKeys.js deleted file mode 100644 index 652624872..000000000 --- a/app/javascript/dashboard/routes/dashboard/commands/conversationHotKeys.js +++ /dev/null @@ -1,413 +0,0 @@ -import { mapGetters } from 'vuex'; -import wootConstants from 'dashboard/constants/globals'; -import { emitter } from 'shared/helpers/mitt'; - -import { CMD_AI_ASSIST } from './commandBarBusEvents'; -import { REPLY_EDITOR_MODES } from 'dashboard/components/widgets/WootWriter/constants'; -import { - ICON_ADD_LABEL, - ICON_ASSIGN_AGENT, - ICON_ASSIGN_PRIORITY, - ICON_ASSIGN_TEAM, - ICON_REMOVE_LABEL, - ICON_PRIORITY_URGENT, - ICON_PRIORITY_HIGH, - ICON_PRIORITY_LOW, - ICON_PRIORITY_MEDIUM, - ICON_PRIORITY_NONE, - ICON_AI_ASSIST, - ICON_AI_SUMMARY, - ICON_AI_SHORTEN, - ICON_AI_EXPAND, - ICON_AI_GRAMMAR, -} from './CommandBarIcons'; - -import { - OPEN_CONVERSATION_ACTIONS, - SNOOZE_CONVERSATION_ACTIONS, - RESOLVED_CONVERSATION_ACTIONS, - SEND_TRANSCRIPT_ACTION, - UNMUTE_ACTION, - MUTE_ACTION, -} from './commandBarActions'; -import { - isAConversationRoute, - isAInboxViewRoute, -} from '../../../helper/routeHelpers'; -export default { - watch: { - assignableAgents() { - this.setCommandbarData(); - }, - currentChat() { - this.setCommandbarData(); - }, - teamsList() { - this.setCommandbarData(); - }, - activeLabels() { - this.setCommandbarData(); - }, - draftMessage() { - this.setCommandbarData(); - }, - replyMode() { - this.setCommandbarData(); - }, - contextMenuChatId() { - this.setCommandbarData(); - }, - }, - computed: { - ...mapGetters({ - currentChat: 'getSelectedChat', - replyMode: 'draftMessages/getReplyEditorMode', - contextMenuChatId: 'getContextMenuChatId', - teams: 'teams/getTeams', - }), - draftMessage() { - return this.$store.getters['draftMessages/get'](this.draftKey); - }, - draftKey() { - return `draft-${this.conversationId}-${this.replyMode}`; - }, - inboxId() { - return this.currentChat?.inbox_id; - }, - conversationId() { - return this.currentChat?.id; - }, - hasAnAssignedTeam() { - return !!this.currentChat?.meta?.team; - }, - teamsList() { - if (this.hasAnAssignedTeam) { - return [ - { id: 0, name: this.$t('TEAMS_SETTINGS.LIST.NONE') }, - ...this.teams, - ]; - } - return this.teams; - }, - statusActions() { - const isOpen = - this.currentChat?.status === wootConstants.STATUS_TYPE.OPEN; - const isSnoozed = - this.currentChat?.status === wootConstants.STATUS_TYPE.SNOOZED; - const isResolved = - this.currentChat?.status === wootConstants.STATUS_TYPE.RESOLVED; - - let actions = []; - if (isOpen) { - actions = [ - ...OPEN_CONVERSATION_ACTIONS, - ...SNOOZE_CONVERSATION_ACTIONS, - ]; - } else if (isResolved || isSnoozed) { - actions = RESOLVED_CONVERSATION_ACTIONS; - } - return this.prepareActions(actions); - }, - - priorityOptions() { - return [ - { - label: this.$t('CONVERSATION.PRIORITY.OPTIONS.NONE'), - key: null, - icon: ICON_PRIORITY_NONE, - }, - { - label: this.$t('CONVERSATION.PRIORITY.OPTIONS.URGENT'), - key: 'urgent', - icon: ICON_PRIORITY_URGENT, - }, - { - label: this.$t('CONVERSATION.PRIORITY.OPTIONS.HIGH'), - key: 'high', - icon: ICON_PRIORITY_HIGH, - }, - { - label: this.$t('CONVERSATION.PRIORITY.OPTIONS.MEDIUM'), - key: 'medium', - icon: ICON_PRIORITY_MEDIUM, - }, - { - label: this.$t('CONVERSATION.PRIORITY.OPTIONS.LOW'), - key: 'low', - icon: ICON_PRIORITY_LOW, - }, - ].filter(item => item.key !== this.currentChat?.priority); - }, - assignAgentActions() { - const agentOptions = this.agentsList.map(agent => ({ - id: `agent-${agent.id}`, - title: agent.name, - parent: 'assign_an_agent', - section: this.$t('COMMAND_BAR.SECTIONS.CHANGE_ASSIGNEE'), - agentInfo: agent, - icon: ICON_ASSIGN_AGENT, - handler: this.onChangeAssignee, - })); - return [ - { - id: 'assign_an_agent', - title: this.$t('COMMAND_BAR.COMMANDS.ASSIGN_AN_AGENT'), - section: this.$t('COMMAND_BAR.SECTIONS.CONVERSATION'), - icon: ICON_ASSIGN_AGENT, - children: agentOptions.map(option => option.id), - }, - ...agentOptions, - ]; - }, - assignPriorityActions() { - const options = this.priorityOptions.map(priority => ({ - id: `priority-${priority.key}`, - title: priority.label, - parent: 'assign_priority', - section: this.$t('COMMAND_BAR.SECTIONS.CHANGE_PRIORITY'), - priority: priority, - icon: priority.icon, - handler: this.onChangePriority, - })); - return [ - { - id: 'assign_priority', - title: this.$t('COMMAND_BAR.COMMANDS.ASSIGN_PRIORITY'), - section: this.$t('COMMAND_BAR.SECTIONS.CONVERSATION'), - icon: ICON_ASSIGN_PRIORITY, - children: options.map(option => option.id), - }, - ...options, - ]; - }, - assignTeamActions() { - const teamOptions = this.teamsList.map(team => ({ - id: `team-${team.id}`, - title: team.name, - parent: 'assign_a_team', - section: this.$t('COMMAND_BAR.SECTIONS.CHANGE_TEAM'), - teamInfo: team, - icon: ICON_ASSIGN_TEAM, - handler: this.onChangeTeam, - })); - return [ - { - id: 'assign_a_team', - title: this.$t('COMMAND_BAR.COMMANDS.ASSIGN_A_TEAM'), - section: this.$t('COMMAND_BAR.SECTIONS.CONVERSATION'), - icon: ICON_ASSIGN_TEAM, - children: teamOptions.map(option => option.id), - }, - ...teamOptions, - ]; - }, - - addLabelActions() { - const availableLabels = this.inactiveLabels.map(label => ({ - id: label.title, - title: `#${label.title}`, - parent: 'add_a_label_to_the_conversation', - section: this.$t('COMMAND_BAR.SECTIONS.ADD_LABEL'), - icon: ICON_ADD_LABEL, - handler: action => this.addLabelToConversation({ title: action.id }), - })); - return [ - ...availableLabels, - { - id: 'add_a_label_to_the_conversation', - title: this.$t('COMMAND_BAR.COMMANDS.ADD_LABELS_TO_CONVERSATION'), - section: this.$t('COMMAND_BAR.SECTIONS.CONVERSATION'), - icon: ICON_ADD_LABEL, - children: this.inactiveLabels.map(label => label.title), - }, - ]; - }, - removeLabelActions() { - const activeLabels = this.activeLabels.map(label => ({ - id: label.title, - title: `#${label.title}`, - parent: 'remove_a_label_to_the_conversation', - section: this.$t('COMMAND_BAR.SECTIONS.REMOVE_LABEL'), - icon: ICON_REMOVE_LABEL, - handler: action => this.removeLabelFromConversation(action.id), - })); - return [ - ...activeLabels, - { - id: 'remove_a_label_to_the_conversation', - title: this.$t('COMMAND_BAR.COMMANDS.REMOVE_LABEL_FROM_CONVERSATION'), - section: this.$t('COMMAND_BAR.SECTIONS.CONVERSATION'), - icon: ICON_REMOVE_LABEL, - children: this.activeLabels.map(label => label.title), - }, - ]; - }, - labelActions() { - if (this.activeLabels.length) { - return [...this.addLabelActions, ...this.removeLabelActions]; - } - return this.addLabelActions; - }, - conversationAdditionalActions() { - return this.prepareActions([ - this.currentChat.muted ? UNMUTE_ACTION : MUTE_ACTION, - SEND_TRANSCRIPT_ACTION, - ]); - }, - - nonDraftMessageAIAssistActions() { - if (this.replyMode === REPLY_EDITOR_MODES.REPLY) { - return [ - { - label: this.$t( - 'INTEGRATION_SETTINGS.OPEN_AI.OPTIONS.REPLY_SUGGESTION' - ), - key: 'reply_suggestion', - icon: ICON_AI_ASSIST, - }, - ]; - } - return [ - { - label: this.$t('INTEGRATION_SETTINGS.OPEN_AI.OPTIONS.SUMMARIZE'), - key: 'summarize', - icon: ICON_AI_SUMMARY, - }, - ]; - }, - - draftMessageAIAssistActions() { - return [ - { - label: this.$t('INTEGRATION_SETTINGS.OPEN_AI.OPTIONS.REPHRASE'), - key: 'rephrase', - icon: ICON_AI_ASSIST, - }, - { - label: this.$t( - 'INTEGRATION_SETTINGS.OPEN_AI.OPTIONS.FIX_SPELLING_GRAMMAR' - ), - key: 'fix_spelling_grammar', - icon: ICON_AI_GRAMMAR, - }, - { - label: this.$t('INTEGRATION_SETTINGS.OPEN_AI.OPTIONS.EXPAND'), - key: 'expand', - icon: ICON_AI_EXPAND, - }, - { - label: this.$t('INTEGRATION_SETTINGS.OPEN_AI.OPTIONS.SHORTEN'), - key: 'shorten', - icon: ICON_AI_SHORTEN, - }, - { - label: this.$t('INTEGRATION_SETTINGS.OPEN_AI.OPTIONS.MAKE_FRIENDLY'), - key: 'make_friendly', - icon: ICON_AI_ASSIST, - }, - { - label: this.$t('INTEGRATION_SETTINGS.OPEN_AI.OPTIONS.MAKE_FORMAL'), - key: 'make_formal', - icon: ICON_AI_ASSIST, - }, - { - label: this.$t('INTEGRATION_SETTINGS.OPEN_AI.OPTIONS.SIMPLIFY'), - key: 'simplify', - icon: ICON_AI_ASSIST, - }, - ]; - }, - - AIAssistActions() { - const aiOptions = this.draftMessage - ? this.draftMessageAIAssistActions - : this.nonDraftMessageAIAssistActions; - const options = aiOptions.map(item => ({ - id: `ai-assist-${item.key}`, - title: item.label, - parent: 'ai_assist', - section: this.$t('COMMAND_BAR.SECTIONS.AI_ASSIST'), - priority: item, - icon: item.icon, - handler: () => emitter.emit(CMD_AI_ASSIST, item.key), - })); - return [ - { - id: 'ai_assist', - title: this.$t('COMMAND_BAR.COMMANDS.AI_ASSIST'), - section: this.$t('COMMAND_BAR.SECTIONS.AI_ASSIST'), - icon: ICON_AI_ASSIST, - children: options.map(option => option.id), - }, - ...options, - ]; - }, - - isConversationOrInboxRoute() { - return ( - isAConversationRoute(this.$route.name) || - isAInboxViewRoute(this.$route.name) - ); - }, - - shouldShowSnoozeOption() { - return ( - isAConversationRoute(this.$route.name, true, false) && - this.contextMenuChatId - ); - }, - - getDefaultConversationHotKeys() { - const defaultConversationHotKeys = [ - ...this.statusActions, - ...this.conversationAdditionalActions, - ...this.assignAgentActions, - ...this.assignTeamActions, - ...this.labelActions, - ...this.assignPriorityActions, - ]; - if (this.isAIIntegrationEnabled) { - return [...defaultConversationHotKeys, ...this.AIAssistActions]; - } - return defaultConversationHotKeys; - }, - - conversationHotKeys() { - if (this.shouldShowSnoozeOption) { - return this.prepareActions(SNOOZE_CONVERSATION_ACTIONS); - } - if (this.isConversationOrInboxRoute) { - return this.getDefaultConversationHotKeys; - } - return []; - }, - }, - - methods: { - onChangeAssignee(action) { - this.$store.dispatch('assignAgent', { - conversationId: this.currentChat.id, - agentId: action.agentInfo.id, - }); - }, - onChangePriority(action) { - this.$store.dispatch('assignPriority', { - conversationId: this.currentChat.id, - priority: action.priority.key, - }); - }, - onChangeTeam(action) { - this.$store.dispatch('assignTeam', { - conversationId: this.currentChat.id, - teamId: action.teamInfo.id, - }); - }, - prepareActions(actions) { - return actions.map(action => ({ - ...action, - title: this.$t(action.title), - section: this.$t(action.section), - })); - }, - }, -}; diff --git a/app/javascript/dashboard/routes/dashboard/conversation/search/PopOverSearch.vue b/app/javascript/dashboard/routes/dashboard/conversation/search/PopOverSearch.vue index b7d5e17dd..03d41a778 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/search/PopOverSearch.vue +++ b/app/javascript/dashboard/routes/dashboard/conversation/search/PopOverSearch.vue @@ -1,6 +1,5 @@ diff --git a/app/javascript/dashboard/routes/dashboard/settings/reports/BotReports.vue b/app/javascript/dashboard/routes/dashboard/settings/reports/BotReports.vue index 492775542..78b433a42 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/reports/BotReports.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/reports/BotReports.vue @@ -3,7 +3,6 @@ import { useAlert } from 'dashboard/composables'; import BotMetrics from './components/BotMetrics.vue'; import ReportFilterSelector from './components/FilterSelector.vue'; import { GROUP_BY_FILTER } from './constants'; -import reportMixin from 'dashboard/mixins/reportMixin'; import ReportContainer from './ReportContainer.vue'; import { REPORTS_EVENTS } from '../../../../helper/AnalyticsHelper/events'; @@ -14,7 +13,6 @@ export default { ReportFilterSelector, ReportContainer, }, - mixins: [reportMixin], data() { return { from: 0, diff --git a/app/javascript/dashboard/routes/dashboard/settings/reports/Index.vue b/app/javascript/dashboard/routes/dashboard/settings/reports/Index.vue index 1f96b161f..da2f2f232 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/reports/Index.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/reports/Index.vue @@ -4,7 +4,6 @@ import fromUnixTime from 'date-fns/fromUnixTime'; import format from 'date-fns/format'; import ReportFilterSelector from './components/FilterSelector.vue'; import { GROUP_BY_FILTER } from './constants'; -import reportMixin from 'dashboard/mixins/reportMixin'; import { REPORTS_EVENTS } from '../../../../helper/AnalyticsHelper/events'; import ReportContainer from './ReportContainer.vue'; @@ -24,7 +23,6 @@ export default { ReportFilterSelector, ReportContainer, }, - mixins: [reportMixin], data() { return { from: 0, diff --git a/app/javascript/dashboard/routes/dashboard/settings/reports/ReportContainer.vue b/app/javascript/dashboard/routes/dashboard/settings/reports/ReportContainer.vue index f90c3730c..fc323d037 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/reports/ReportContainer.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/reports/ReportContainer.vue @@ -1,19 +1,23 @@ @@ -29,7 +34,7 @@ export default { {{ metric.NAME }}