feat: Add the ability to add new automation rule (#3459)
* Add automation modal * Fix the v-model for automations * Actions and Condition dropdowns for automations * Fix merge conflicts * Handle event change and confirmation * Appends new action * Removes actions * Automation api integration * Api integration for creating automations * Registers vuex module to the global store * Automations table * Updarted labels and actions * Integrate automation api * Fixes the mutation error - removed the data key wrapper * Fixed the automation condition models to work with respective event types * Remove temporary fixes added to the api request * Displa timestamp and automation status values * Added the clone buton * Removed uncessary helper method * Specs for automations * Handle WIP code * Remove the payload wrap * Fix the action query payload * Removed unnecessary files * Disabled Automations routes * Ability to delete automations * Fix specs * Fixed merge conflicts Co-authored-by: Fayaz Ahmed <15716057+fayazara@users.noreply.github.com> Co-authored-by: fayazara <fayazara@gmail.com> Co-authored-by: Nithin David Thomas <1277421+nithindavid@users.noreply.github.com> Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,446 @@
|
||||
<template>
|
||||
<div class="column">
|
||||
<woot-modal-header :header-title="$t('AUTOMATION.ADD.TITLE')" />
|
||||
<div class="row modal-content">
|
||||
<div class="medium-12 columns">
|
||||
<woot-input
|
||||
v-model="automation.name"
|
||||
:label="$t('AUTOMATION.ADD.FORM.NAME.LABEL')"
|
||||
type="text"
|
||||
:class="{ error: $v.automation.name.$error }"
|
||||
:error="
|
||||
$v.automation.name.$error
|
||||
? $t('AUTOMATION.ADD.FORM.NAME.ERROR')
|
||||
: ''
|
||||
"
|
||||
:placeholder="$t('AUTOMATION.ADD.FORM.NAME.PLACEHOLDER')"
|
||||
@blur="$v.automation.name.$touch"
|
||||
/>
|
||||
<woot-input
|
||||
v-model="automation.description"
|
||||
:label="$t('AUTOMATION.ADD.FORM.DESC.LABEL')"
|
||||
type="text"
|
||||
:class="{ error: $v.automation.description.$error }"
|
||||
:error="
|
||||
$v.automation.description.$error
|
||||
? $t('AUTOMATION.ADD.FORM.DESC.ERROR')
|
||||
: ''
|
||||
"
|
||||
:placeholder="$t('AUTOMATION.ADD.FORM.DESC.PLACEHOLDER')"
|
||||
@blur="$v.automation.description.$touch"
|
||||
/>
|
||||
<div class="event_wrapper">
|
||||
<label :class="{ error: $v.automation.event_name.$error }">
|
||||
{{ $t('AUTOMATION.ADD.FORM.EVENT.LABEL') }}
|
||||
<select v-model="automation.event_name" @change="onEventChange()">
|
||||
<option
|
||||
v-for="event in automationRuleEvents"
|
||||
:key="event.key"
|
||||
:value="event.key"
|
||||
>
|
||||
{{ event.value }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-if="$v.automation.event_name.$error" class="message">
|
||||
{{ $t('AUTOMATION.ADD.FORM.EVENT.ERROR') }}
|
||||
</span>
|
||||
</label>
|
||||
<p v-if="hasAutomationMutated" class="info-message">
|
||||
{{ $t('AUTOMATION.FORM.RESET_MESSAGE') }}
|
||||
</p>
|
||||
</div>
|
||||
<!-- // Conditions Start -->
|
||||
<section>
|
||||
<label>
|
||||
{{ $t('AUTOMATION.ADD.FORM.CONDITIONS.LABEL') }}
|
||||
</label>
|
||||
<div class="medium-12 columns filters-wrap">
|
||||
<filter-input-box
|
||||
v-for="(condition, i) in automation.conditions"
|
||||
:key="i"
|
||||
v-model="automation.conditions[i]"
|
||||
:filter-attributes="getAttributes(automation.event_name)"
|
||||
:input-type="getInputType(automation.conditions[i].attribute_key)"
|
||||
:operators="getOperators(automation.conditions[i].attribute_key)"
|
||||
:dropdown-values="
|
||||
getConditionDropdownValues(
|
||||
automation.conditions[i].attribute_key
|
||||
)
|
||||
"
|
||||
:show-query-operator="i !== automation.conditions.length - 1"
|
||||
:v="$v.automation.conditions.$each[i]"
|
||||
@resetFilter="resetFilter(i, automation.conditions[i])"
|
||||
@removeFilter="removeFilter(i)"
|
||||
/>
|
||||
<div class="filter-actions">
|
||||
<woot-button
|
||||
icon="add"
|
||||
color-scheme="success"
|
||||
variant="smooth"
|
||||
size="small"
|
||||
@click="appendNewCondition"
|
||||
>
|
||||
{{ $t('AUTOMATION.ADD.CONDITION_BUTTON_LABEL') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- // Conditions End -->
|
||||
<!-- // Actions Start -->
|
||||
<section>
|
||||
<label>
|
||||
{{ $t('AUTOMATION.ADD.FORM.ACTIONS.LABEL') }}
|
||||
</label>
|
||||
<div class="medium-12 columns filters-wrap">
|
||||
<automation-action-input
|
||||
v-for="(action, i) in automation.actions"
|
||||
:key="i"
|
||||
v-model="automation.actions[i]"
|
||||
:action-types="automationActionTypes"
|
||||
:dropdown-values="
|
||||
getActionDropdownValues(automation.actions[i].action_name)
|
||||
"
|
||||
:v="$v.automation.actions.$each[i]"
|
||||
@removeAction="removeAction(i)"
|
||||
/>
|
||||
<div class="filter-actions">
|
||||
<woot-button
|
||||
icon="add"
|
||||
color-scheme="success"
|
||||
variant="smooth"
|
||||
size="small"
|
||||
@click="appendNewAction"
|
||||
>
|
||||
{{ $t('AUTOMATION.ADD.ACTION_BUTTON_LABEL') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- // Actions End -->
|
||||
<div class="medium-12 columns">
|
||||
<div class="modal-footer justify-content-end w-full">
|
||||
<woot-button class="button clear" @click.prevent="onClose">
|
||||
{{ $t('AUTOMATION.ADD.CANCEL_BUTTON_TEXT') }}
|
||||
</woot-button>
|
||||
<woot-button @click="submitAutomation">
|
||||
{{ $t('AUTOMATION.ADD.SUBMIT') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import { required, requiredIf } from 'vuelidate/lib/validators';
|
||||
import filterInputBox from 'dashboard/components/widgets/FilterInput/Index.vue';
|
||||
import automationActionInput from 'dashboard/components/widgets/AutomationActionInput.vue';
|
||||
import languages from 'dashboard/components/widgets/conversation/advancedFilterItems/languages';
|
||||
import countries from '/app/javascript/shared/constants/countries.js';
|
||||
import {
|
||||
AUTOMATION_RULE_EVENTS,
|
||||
AUTOMATION_ACTION_TYPES,
|
||||
AUTOMATIONS,
|
||||
} from './constants';
|
||||
import filterQueryGenerator from 'dashboard/helper/filterQueryGenerator.js';
|
||||
import actionQueryGenerator from 'dashboard/helper/actionQueryGenerator.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
filterInputBox,
|
||||
automationActionInput,
|
||||
},
|
||||
mixins: [alertMixin],
|
||||
props: {
|
||||
onClose: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
validations: {
|
||||
automation: {
|
||||
name: {
|
||||
required,
|
||||
},
|
||||
description: {
|
||||
required,
|
||||
},
|
||||
event_name: {
|
||||
required,
|
||||
},
|
||||
conditions: {
|
||||
required,
|
||||
$each: {
|
||||
values: {
|
||||
required: requiredIf(prop => {
|
||||
return !(
|
||||
prop.filter_operator === 'is_present' ||
|
||||
prop.filter_operator === 'is_not_present'
|
||||
);
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
required,
|
||||
$each: {
|
||||
action_params: {
|
||||
required,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
automationTypes: AUTOMATIONS,
|
||||
automationRuleEvent: AUTOMATION_RULE_EVENTS[0].key,
|
||||
automationRuleEvents: AUTOMATION_RULE_EVENTS,
|
||||
automationActionTypes: AUTOMATION_ACTION_TYPES,
|
||||
automationMutated: false,
|
||||
show: true,
|
||||
automation: {
|
||||
name: null,
|
||||
description: null,
|
||||
event_name: 'conversation_created',
|
||||
conditions: [
|
||||
{
|
||||
attribute_key: 'status',
|
||||
filter_operator: 'equal_to',
|
||||
values: '',
|
||||
query_operator: 'and',
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
action_name: 'assign_team',
|
||||
action_params: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
showDeleteConfirmationModal: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
conditions() {
|
||||
return this.automationTypes[this.automation.event_name].conditions;
|
||||
},
|
||||
actions() {
|
||||
return this.automationTypes[this.automation.event_name].actions;
|
||||
},
|
||||
filterAttributes() {
|
||||
return this.filterTypes.map(type => {
|
||||
return {
|
||||
key: type.attributeKey,
|
||||
name: type.attributeName,
|
||||
attributeI18nKey: type.attributeI18nKey,
|
||||
};
|
||||
});
|
||||
},
|
||||
hasAutomationMutated() {
|
||||
if (
|
||||
this.automation.conditions[0].values ||
|
||||
this.automation.actions[0].action_params.length
|
||||
)
|
||||
return true;
|
||||
return false;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onEventChange() {
|
||||
if (this.automation.event_name === 'message_created') {
|
||||
this.automation.conditions = [
|
||||
{
|
||||
attribute_key: 'message_type',
|
||||
filter_operator: 'equal_to',
|
||||
values: '',
|
||||
query_operator: 'and',
|
||||
},
|
||||
];
|
||||
} else {
|
||||
this.automation.conditions = [
|
||||
{
|
||||
attribute_key: 'status',
|
||||
filter_operator: 'equal_to',
|
||||
values: '',
|
||||
query_operator: 'and',
|
||||
},
|
||||
];
|
||||
}
|
||||
this.automation.actions = [
|
||||
{
|
||||
action_name: 'assign_team',
|
||||
action_params: [],
|
||||
},
|
||||
];
|
||||
},
|
||||
getAttributes(key) {
|
||||
return this.automationTypes[key].conditions;
|
||||
},
|
||||
getInputType(key) {
|
||||
const type = this.automationTypes[
|
||||
this.automation.event_name
|
||||
].conditions.find(condition => condition.key === key);
|
||||
return type.inputType;
|
||||
},
|
||||
getOperators(key) {
|
||||
const type = this.automationTypes[
|
||||
this.automation.event_name
|
||||
].conditions.find(condition => condition.key === key);
|
||||
return type.filterOperators;
|
||||
},
|
||||
getConditionDropdownValues(type) {
|
||||
const statusFilters = this.$t('CHAT_LIST.CHAT_STATUS_FILTER_ITEMS');
|
||||
switch (type) {
|
||||
case 'status':
|
||||
return [
|
||||
...Object.keys(statusFilters).map(status => {
|
||||
return {
|
||||
id: status,
|
||||
name: statusFilters[status].TEXT,
|
||||
};
|
||||
}),
|
||||
{
|
||||
id: 'all',
|
||||
name: this.$t('CHAT_LIST.FILTER_ALL'),
|
||||
},
|
||||
];
|
||||
case 'assignee_id':
|
||||
return this.$store.getters['agents/getAgents'];
|
||||
case 'contact':
|
||||
return this.$store.getters['contacts/getContacts'];
|
||||
case 'inbox_id':
|
||||
return this.$store.getters['inboxes/getInboxes'];
|
||||
case 'team_id':
|
||||
return this.$store.getters['teams/getTeams'];
|
||||
case 'campaign_id':
|
||||
return this.$store.getters['campaigns/getAllCampaigns'].map(i => {
|
||||
return {
|
||||
id: i.id,
|
||||
name: i.title,
|
||||
};
|
||||
});
|
||||
case 'labels':
|
||||
return this.$store.getters['labels/getLabels'].map(i => {
|
||||
return {
|
||||
id: i.id,
|
||||
name: i.title,
|
||||
};
|
||||
});
|
||||
case 'browser_language':
|
||||
return languages;
|
||||
case 'country_code':
|
||||
return countries;
|
||||
case 'message_type':
|
||||
return [
|
||||
{
|
||||
id: 'incoming',
|
||||
name: 'Incoming Message',
|
||||
},
|
||||
{
|
||||
id: 'outgoing',
|
||||
name: 'Outgoing Message',
|
||||
},
|
||||
];
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
getActionDropdownValues(type) {
|
||||
switch (type) {
|
||||
case 'assign_team':
|
||||
case 'send_message':
|
||||
return this.$store.getters['teams/getTeams'];
|
||||
case 'add_label':
|
||||
return this.$store.getters['labels/getLabels'].map(i => {
|
||||
return {
|
||||
id: i.title,
|
||||
name: i.title,
|
||||
};
|
||||
});
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
appendNewCondition() {
|
||||
this.automation.conditions.push({
|
||||
attribute_key: 'status',
|
||||
filter_operator: 'equal_to',
|
||||
values: '',
|
||||
query_operator: 'and',
|
||||
});
|
||||
},
|
||||
appendNewAction() {
|
||||
this.automation.actions.push({
|
||||
action_name: 'assign_team',
|
||||
action_params: [],
|
||||
});
|
||||
},
|
||||
removeFilter(index) {
|
||||
if (this.automation.conditions.length <= 1) {
|
||||
this.showAlert(this.$t('FILTER.FILTER_DELETE_ERROR'));
|
||||
} else {
|
||||
this.automation.conditions.splice(index, 1);
|
||||
}
|
||||
},
|
||||
removeAction(index) {
|
||||
if (this.automation.actions.length <= 1) {
|
||||
this.showAlert(this.$t('FILTER.FILTER_DELETE_ERROR'));
|
||||
} else {
|
||||
this.automation.actions.splice(index, 1);
|
||||
}
|
||||
},
|
||||
submitAutomation() {
|
||||
this.$v.$touch();
|
||||
if (this.$v.$invalid) return;
|
||||
this.automation.conditions[
|
||||
this.automation.conditions.length - 1
|
||||
].query_operator = null;
|
||||
this.automation.conditions = filterQueryGenerator(
|
||||
this.automation.conditions
|
||||
).payload;
|
||||
this.automation.actions = actionQueryGenerator(this.automation.actions);
|
||||
this.$emit('saveAutomation', this.automation);
|
||||
},
|
||||
resetFilter(index, currentCondition) {
|
||||
this.automation.conditions[index].filter_operator = this.automationTypes[
|
||||
this.automation.event_name
|
||||
].conditions.find(
|
||||
condition => condition.key === currentCondition.attribute_key
|
||||
).filterOperators[0].value;
|
||||
this.automation.conditions[index].values = '';
|
||||
},
|
||||
showUserInput(operatorType) {
|
||||
if (operatorType === 'is_present' || operatorType === 'is_not_present')
|
||||
return false;
|
||||
return true;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.filters-wrap {
|
||||
padding: var(--space-normal);
|
||||
border-radius: var(--border-radius-large);
|
||||
border: 1px solid var(--color-border);
|
||||
background: var(--color-background-light);
|
||||
margin-bottom: var(--space-normal);
|
||||
}
|
||||
|
||||
.filter-actions {
|
||||
margin-top: var(--space-normal);
|
||||
}
|
||||
.event_wrapper {
|
||||
select {
|
||||
margin: 0;
|
||||
}
|
||||
.info-message {
|
||||
font-size: var(--font-size-mini);
|
||||
color: #868686;
|
||||
text-align: right;
|
||||
}
|
||||
margin-bottom: 1.6rem;
|
||||
}
|
||||
</style>
|
||||
@@ -4,9 +4,209 @@
|
||||
color-scheme="success"
|
||||
class-names="button--fixed-right-top"
|
||||
icon="add-circle"
|
||||
@click="openAddPopup()"
|
||||
>
|
||||
{{ $t('AUTOMATION.HEADER_BTN_TXT') }}
|
||||
</woot-button>
|
||||
<div class="row">
|
||||
<div class="small-8 columns with-right-space">
|
||||
<p
|
||||
v-if="!uiFlags.isFetching && !records.length"
|
||||
class="no-items-error-message"
|
||||
>
|
||||
{{ $t('AUTOMATION.LIST.404') }}
|
||||
</p>
|
||||
<woot-loading-state
|
||||
v-if="uiFlags.isFetching"
|
||||
:message="$t('AUTOMATION.LOADING')"
|
||||
/>
|
||||
<table v-if="!uiFlags.isFetching && records.length" class="woot-table">
|
||||
<thead>
|
||||
<th
|
||||
v-for="thHeader in $t('AUTOMATION.LIST.TABLE_HEADER')"
|
||||
:key="thHeader"
|
||||
>
|
||||
{{ thHeader }}
|
||||
</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(automation, index) in records" :key="index">
|
||||
<td>{{ automation.name }}</td>
|
||||
<td>{{ automation.description }}</td>
|
||||
<td>
|
||||
<fluent-icon
|
||||
v-if="automation.active"
|
||||
icon="checkmark-square"
|
||||
type="solid"
|
||||
/>
|
||||
<fluent-icon v-else icon="square" />
|
||||
</td>
|
||||
<td>{{ readableTime(automation.created_on) }}</td>
|
||||
<td class="button-wrapper">
|
||||
<!-- <woot-button
|
||||
v-tooltip.top="$t('AUTOMATION.FORM.EDIT')"
|
||||
variant="smooth"
|
||||
size="tiny"
|
||||
color-scheme="secondary"
|
||||
class-names="grey-btn"
|
||||
:is-loading="loading[automation.id]"
|
||||
icon="edit"
|
||||
@click="openEditPopup(automation)"
|
||||
>
|
||||
</woot-button>
|
||||
<woot-button
|
||||
v-tooltip.top="'Clone'"
|
||||
variant="smooth"
|
||||
size="tiny"
|
||||
color-scheme="primary"
|
||||
class-names="grey-btn"
|
||||
:is-loading="loading[automation.id]"
|
||||
icon="copy"
|
||||
@click="openEditPopup(automation)"
|
||||
>
|
||||
</woot-button> -->
|
||||
<woot-button
|
||||
v-tooltip.top="$t('AUTOMATION.FORM.DELETE')"
|
||||
variant="smooth"
|
||||
color-scheme="alert"
|
||||
size="tiny"
|
||||
icon="dismiss-circle"
|
||||
class-names="grey-btn"
|
||||
:is-loading="loading[automation.id]"
|
||||
@click="openDeletePopup(automation, index)"
|
||||
>
|
||||
</woot-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="small-4 columns">
|
||||
<span v-html="$t('AUTOMATION.SIDEBAR_TXT')"></span>
|
||||
</div>
|
||||
</div>
|
||||
<woot-modal
|
||||
:show.sync="showAddPopup"
|
||||
size="medium"
|
||||
:on-close="hideAddPopup"
|
||||
>
|
||||
<add-automation-rule
|
||||
v-if="showAddPopup"
|
||||
:on-close="hideAddPopup"
|
||||
@saveAutomation="onCreateAutomation"
|
||||
/>
|
||||
</woot-modal>
|
||||
|
||||
<woot-delete-modal
|
||||
:show.sync="showDeleteConfirmationPopup"
|
||||
:on-close="closeDeletePopup"
|
||||
:on-confirm="confirmDeletion"
|
||||
:title="$t('LABEL_MGMT.DELETE.CONFIRM.TITLE')"
|
||||
:message="deleteMessage"
|
||||
:confirm-text="deleteConfirmText"
|
||||
:reject-text="deleteRejectText"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script></script>
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import AddAutomationRule from './AddAutomationRule.vue';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import timeMixin from 'dashboard/mixins/time';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AddAutomationRule,
|
||||
},
|
||||
mixins: [alertMixin, timeMixin],
|
||||
data() {
|
||||
return {
|
||||
loading: {},
|
||||
showAddPopup: false,
|
||||
showEditPopup: false,
|
||||
showDeleteConfirmationPopup: false,
|
||||
selectedResponse: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
records: ['automations/getAutomations'],
|
||||
uiFlags: 'automations/getUIFlags',
|
||||
}),
|
||||
// Delete Modal
|
||||
deleteConfirmText() {
|
||||
return `${this.$t('AUTOMATION.DELETE.CONFIRM.YES')} ${
|
||||
this.selectedResponse.name
|
||||
}`;
|
||||
},
|
||||
deleteRejectText() {
|
||||
return `${this.$t('AUTOMATION.DELETE.CONFIRM.NO')} ${
|
||||
this.selectedResponse.name
|
||||
}`;
|
||||
},
|
||||
deleteMessage() {
|
||||
return `${this.$t('AUTOMATION.DELETE.CONFIRM.MESSAGE')} ${
|
||||
this.selectedResponse.name
|
||||
} ?`;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('automations/get');
|
||||
},
|
||||
methods: {
|
||||
openAddPopup() {
|
||||
this.showAddPopup = true;
|
||||
},
|
||||
hideAddPopup() {
|
||||
this.showAddPopup = false;
|
||||
},
|
||||
openEditPopup(response) {
|
||||
this.showEditPopup = true;
|
||||
this.selectedResponse = response;
|
||||
},
|
||||
hideEditPopup() {
|
||||
this.showEditPopup = false;
|
||||
},
|
||||
openDeletePopup(response) {
|
||||
this.showDeleteConfirmationPopup = true;
|
||||
this.selectedResponse = response;
|
||||
},
|
||||
closeDeletePopup() {
|
||||
this.showDeleteConfirmationPopup = false;
|
||||
},
|
||||
confirmDeletion() {
|
||||
this.loading[this.selectedResponse.id] = true;
|
||||
this.closeDeletePopup();
|
||||
this.deleteAutomation(this.selectedResponse.id);
|
||||
},
|
||||
async deleteAutomation(id) {
|
||||
try {
|
||||
await this.$store.dispatch('automations/delete', id);
|
||||
this.showAlert(this.$t('AUTOMATION.DELETE.API.SUCCESS_MESSAGE'));
|
||||
this.loading[this.selectedResponse.id] = false;
|
||||
} catch (error) {
|
||||
this.showAlert(this.$t('AUTOMATION.DELETE.API.ERROR_MESSAGE'));
|
||||
}
|
||||
},
|
||||
async onCreateAutomation(payload) {
|
||||
try {
|
||||
await await this.$store.dispatch('automations/create', payload);
|
||||
this.showAlert(this.$t('AUTOMATION.ADD.API.SUCCESS_MESSAGE'));
|
||||
this.hideAddPopup();
|
||||
} catch (error) {
|
||||
this.showAlert(this.$t('AUTOMATION.ADD.API.ERROR_MESSAGE'));
|
||||
}
|
||||
},
|
||||
readableTime(date) {
|
||||
return this.messageStamp(new Date(date), 'LLL d, h:mm a');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.automation__status-checkbox {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -9,7 +9,7 @@ export default {
|
||||
component: SettingsContent,
|
||||
props: {
|
||||
headerTitle: 'AUTOMATION.HEADER',
|
||||
icon: 'autocorrect',
|
||||
icon: 'automation',
|
||||
showNewButton: false,
|
||||
},
|
||||
children: [
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
const OPERATOR_TYPES_1 = [
|
||||
{
|
||||
value: 'equal_to',
|
||||
label: 'Equal to',
|
||||
},
|
||||
{
|
||||
value: 'not_equal_to',
|
||||
label: 'Not equal to',
|
||||
},
|
||||
];
|
||||
|
||||
const OPERATOR_TYPES_2 = [
|
||||
{
|
||||
value: 'equal_to',
|
||||
label: 'Equal to',
|
||||
},
|
||||
{
|
||||
value: 'not_equal_to',
|
||||
label: 'Not equal to',
|
||||
},
|
||||
{
|
||||
value: 'contains',
|
||||
label: 'Contains',
|
||||
},
|
||||
{
|
||||
value: 'does_not_contain',
|
||||
label: 'Does not contain',
|
||||
},
|
||||
];
|
||||
|
||||
const OPERATOR_TYPES_3 = [
|
||||
{
|
||||
value: 'equal_to',
|
||||
label: 'Equal to',
|
||||
},
|
||||
{
|
||||
value: 'not_equal_to',
|
||||
label: 'Not equal to',
|
||||
},
|
||||
{
|
||||
value: 'is_present',
|
||||
label: 'Is present',
|
||||
},
|
||||
{
|
||||
value: 'is_not_present',
|
||||
label: 'Is not present',
|
||||
},
|
||||
];
|
||||
|
||||
export const AUTOMATIONS = {
|
||||
message_created: {
|
||||
conditions: [
|
||||
{
|
||||
key: 'message_type',
|
||||
name: 'Message Type',
|
||||
attributeI18nKey: 'MESSAGE_TYPE',
|
||||
inputType: 'search_select',
|
||||
filterOperators: OPERATOR_TYPES_1,
|
||||
},
|
||||
{
|
||||
key: 'message_contains',
|
||||
name: 'Message Contains',
|
||||
attributeI18nKey: 'MESSAGE_CONTAINS',
|
||||
inputType: 'plain_text',
|
||||
filterOperators: OPERATOR_TYPES_2,
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
key: 'assign_team',
|
||||
name: 'Assign a team',
|
||||
attributeI18nKey: 'ASSIGN_TEAM',
|
||||
},
|
||||
{
|
||||
key: 'add_label',
|
||||
name: 'Add a label',
|
||||
attributeI18nKey: 'ADD_LABEL',
|
||||
},
|
||||
{
|
||||
key: 'send_message',
|
||||
name: 'Send an email to team',
|
||||
attributeI18nKey: 'SEND_MESSAGE',
|
||||
},
|
||||
],
|
||||
},
|
||||
conversation_created: {
|
||||
conditions: [
|
||||
{
|
||||
key: 'status',
|
||||
name: 'Status',
|
||||
attributeI18nKey: 'STATUS',
|
||||
inputType: 'multi_select',
|
||||
filterOperators: OPERATOR_TYPES_1,
|
||||
},
|
||||
{
|
||||
key: 'browser_language',
|
||||
name: 'Browser Language',
|
||||
attributeI18nKey: 'BROWSER_LANGUAGE',
|
||||
inputType: 'search_select',
|
||||
filterOperators: OPERATOR_TYPES_1,
|
||||
},
|
||||
{
|
||||
key: 'country_code',
|
||||
name: 'Country',
|
||||
attributeI18nKey: 'COUNTRY_NAME',
|
||||
inputType: 'search_select',
|
||||
filterOperators: OPERATOR_TYPES_1,
|
||||
},
|
||||
{
|
||||
key: 'referrer',
|
||||
name: 'Referrer Link',
|
||||
attributeI18nKey: 'REFERER_LINK',
|
||||
inputType: 'plain_text',
|
||||
filterOperators: OPERATOR_TYPES_2,
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
key: 'assign_team',
|
||||
name: 'Assign a team',
|
||||
attributeI18nKey: 'ASSIGN_TEAM',
|
||||
},
|
||||
{
|
||||
key: 'send_message',
|
||||
name: 'Send an email to team',
|
||||
attributeI18nKey: 'SEND_MESSAGE',
|
||||
},
|
||||
{
|
||||
key: 'assign_agent',
|
||||
name: 'Assign an agent',
|
||||
attributeI18nKey: 'ASSIGN_AGENT',
|
||||
},
|
||||
],
|
||||
},
|
||||
conversation_updated: {
|
||||
conditions: [
|
||||
{
|
||||
key: 'status',
|
||||
name: 'Status',
|
||||
attributeI18nKey: 'STATUS',
|
||||
inputType: 'multi_select',
|
||||
filterOperators: OPERATOR_TYPES_1,
|
||||
},
|
||||
{
|
||||
key: 'browser_language',
|
||||
name: 'Browser Language',
|
||||
attributeI18nKey: 'BROWSER_LANGUAGE',
|
||||
inputType: 'search_select',
|
||||
filterOperators: OPERATOR_TYPES_1,
|
||||
},
|
||||
{
|
||||
key: 'country_code',
|
||||
name: 'Country',
|
||||
attributeI18nKey: 'COUNTRY_NAME',
|
||||
inputType: 'search_select',
|
||||
filterOperators: OPERATOR_TYPES_1,
|
||||
},
|
||||
{
|
||||
key: 'referer',
|
||||
name: 'Referrer Link',
|
||||
attributeI18nKey: 'REFERER_LINK',
|
||||
inputType: 'plain_text',
|
||||
filterOperators: OPERATOR_TYPES_2,
|
||||
},
|
||||
{
|
||||
key: 'assignee_id',
|
||||
name: 'Assignee',
|
||||
attributeI18nKey: 'ASSIGNEE_NAME',
|
||||
inputType: 'search_select',
|
||||
filterOperators: OPERATOR_TYPES_3,
|
||||
},
|
||||
{
|
||||
key: 'team_id',
|
||||
name: 'Team',
|
||||
attributeI18nKey: 'TEAM_NAME',
|
||||
inputType: 'search_select',
|
||||
filterOperators: OPERATOR_TYPES_3,
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
key: 'assign_team',
|
||||
name: 'Assign a team',
|
||||
attributeI18nKey: 'ASSIGN_TEAM',
|
||||
},
|
||||
{
|
||||
key: 'send_message',
|
||||
name: 'Send an email to team',
|
||||
attributeI18nKey: 'SEND_MESSAGE',
|
||||
},
|
||||
{
|
||||
key: 'assign_agent',
|
||||
name: 'Assign an agent',
|
||||
attributeI18nKey: 'ASSIGN_AGENT',
|
||||
attributeKey: 'assignee_id',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const AUTOMATION_RULE_EVENTS = [
|
||||
{
|
||||
key: 'conversation_created',
|
||||
value: 'Conversation Created',
|
||||
},
|
||||
{
|
||||
key: 'conversation_updated',
|
||||
value: 'Conversation Updated',
|
||||
},
|
||||
{
|
||||
key: 'message_created',
|
||||
value: 'Message Created',
|
||||
},
|
||||
];
|
||||
|
||||
export const AUTOMATION_ACTION_TYPES = [
|
||||
{
|
||||
key: 'assign_team',
|
||||
label: 'Assign a team',
|
||||
},
|
||||
{
|
||||
key: 'add_label',
|
||||
label: 'Add a label',
|
||||
},
|
||||
{
|
||||
key: 'send_message',
|
||||
label: 'Send an email to team',
|
||||
},
|
||||
];
|
||||
@@ -11,6 +11,7 @@ import reports from './reports/reports.routes';
|
||||
import campaigns from './campaigns/campaigns.routes';
|
||||
import teams from './teams/teams.routes';
|
||||
import attributes from './attributes/attributes.routes';
|
||||
import automation from './automation/automation.routes';
|
||||
import store from '../../../store';
|
||||
|
||||
export default {
|
||||
@@ -38,5 +39,6 @@ export default {
|
||||
...campaigns.routes,
|
||||
...integrationapps.routes,
|
||||
...attributes.routes,
|
||||
...automation.routes,
|
||||
],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user