Ported duplicate logic to a mixin

This commit is contained in:
Fayaz Ahmed 2022-05-09 22:12:04 +05:30
parent b97c5944d2
commit 9bfbd9e904
4 changed files with 529 additions and 728 deletions

View file

@ -138,72 +138,28 @@
<script> <script>
import alertMixin from 'shared/mixins/alertMixin'; import alertMixin from 'shared/mixins/alertMixin';
import { required, requiredIf } from 'vuelidate/lib/validators'; import automationMixin from 'shared/mixins/automationMixin';
import filterInputBox from 'dashboard/components/widgets/FilterInput/Index.vue'; import filterInputBox from 'dashboard/components/widgets/FilterInput/Index.vue';
import automationActionInput from 'dashboard/components/widgets/AutomationActionInput.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 { import {
AUTOMATION_RULE_EVENTS, AUTOMATION_RULE_EVENTS,
AUTOMATION_ACTION_TYPES, AUTOMATION_ACTION_TYPES,
AUTOMATIONS, AUTOMATIONS,
} from './constants'; } from './constants';
import filterQueryGenerator from 'dashboard/helper/filterQueryGenerator.js';
import actionQueryGenerator from 'dashboard/helper/actionQueryGenerator.js';
import * as OPERATORS from './operators';
export default { export default {
components: { components: {
filterInputBox, filterInputBox,
automationActionInput, automationActionInput,
}, },
mixins: [alertMixin], mixins: [alertMixin, automationMixin],
props: { props: {
onClose: { onClose: {
type: Function, type: Function,
default: () => {}, 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: requiredIf(prop => {
if (prop.action_name === 'send_email_to_team') return true;
return !(
prop.action_name === 'mute_conversation' ||
prop.action_name === 'snooze_conversation' ||
prop.action_name === 'resolve_conversation'
);
}),
},
},
},
},
},
data() { data() {
return { return {
automationTypes: AUTOMATIONS, automationTypes: AUTOMATIONS,
@ -233,6 +189,7 @@ export default {
}, },
showDeleteConfirmationModal: false, showDeleteConfirmationModal: false,
allCustomAttributes: [], allCustomAttributes: [],
mode: 'create',
}; };
}, },
computed: { computed: {
@ -261,274 +218,7 @@ export default {
}, },
}, },
mounted() { mounted() {
const customAttributesRaw = this.$store.getters['attributes/getAttributes']; this.manifestCustomAttributes();
const customAttributeTypes = customAttributesRaw.map(attr => {
return {
key: attr.attribute_key,
name: attr.attribute_display_name,
inputType: this.customAttributeInputType(attr.attribute_display_type),
filterOperators: this.getOperatorTypes(attr.attribute_display_type),
};
});
AUTOMATIONS.message_created.conditions.push(...customAttributeTypes);
AUTOMATIONS.conversation_created.conditions.push(...customAttributeTypes);
AUTOMATIONS.conversation_updated.conditions.push(...customAttributeTypes);
},
methods: {
customAttributeInputType(key) {
switch (key) {
case 'date':
return 'date';
case 'text':
return 'plain_text';
case 'list':
return 'search_select';
case 'checkbox':
return 'search_select';
default:
return 'plain_text';
}
},
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;
},
getOperatorTypes(key) {
switch (key) {
case 'list':
return OPERATORS.OPERATOR_TYPES_1;
case 'text':
return OPERATORS.OPERATOR_TYPES_3;
case 'number':
return OPERATORS.OPERATOR_TYPES_1;
case 'link':
return OPERATORS.OPERATOR_TYPES_1;
case 'date':
return OPERATORS.OPERATOR_TYPES_4;
case 'checkbox':
return OPERATORS.OPERATOR_TYPES_1;
default:
return OPERATORS.OPERATOR_TYPES_1;
}
},
getConditionDropdownValues(type) {
const statusFilters = this.$t('CHAT_LIST.CHAT_STATUS_FILTER_ITEMS');
const allCustomAttributes = this.$store.getters[
'attributes/getAttributes'
];
const isCustomAttributeCheckbox = allCustomAttributes.find(attr => {
return (
attr.attribute_key === type &&
attr.attribute_display_type === 'checkbox'
);
});
if (isCustomAttributeCheckbox) {
return [
{
id: true,
name: this.$t('FILTER.ATTRIBUTE_LABELS.TRUE'),
},
{
id: false,
name: this.$t('FILTER.ATTRIBUTE_LABELS.FALSE'),
},
];
}
const isCustomAttributeList = allCustomAttributes.find(attr => {
return (
attr.attribute_key === type && attr.attribute_display_type === 'list'
);
});
if (isCustomAttributeList) {
return allCustomAttributes
.find(attr => attr.attribute_key === type)
.attribute_values.map(item => {
return {
id: item,
name: item,
};
});
}
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.title,
name: i.title,
};
});
case 'browser_language':
return languages;
case 'country_code':
return countries;
default:
return undefined;
}
},
getActionDropdownValues(type) {
switch (type) {
case 'assign_team':
case 'send_email_to_team':
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() {
switch (this.automation.event_name) {
case 'message_created':
this.automation.conditions.push({
attribute_key: 'message_type',
filter_operator: 'equal_to',
values: '',
query_operator: 'and',
});
break;
default:
this.automation.conditions.push({
attribute_key: 'status',
filter_operator: 'equal_to',
values: '',
query_operator: 'and',
});
break;
}
},
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;
const automation = JSON.parse(JSON.stringify(this.automation));
automation.conditions[
automation.conditions.length - 1
].query_operator = null;
automation.conditions = filterQueryGenerator(
automation.conditions
).payload;
automation.actions = actionQueryGenerator(automation.actions);
this.$emit('saveAutomation', 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 = '';
},
resetAction(index) {
this.automation.actions[index].action_params = [];
},
showUserInput(operatorType) {
if (operatorType === 'is_present' || operatorType === 'is_not_present')
return false;
return true;
},
showActionInput(actionName) {
if (actionName === 'send_email_to_team' || actionName === 'send_message')
return false;
const type = AUTOMATION_ACTION_TYPES.find(
action => action.key === actionName
).inputType;
if (type === null) return false;
return true;
},
}, },
}; };
</script> </script>

View file

@ -144,25 +144,22 @@
<script> <script>
import alertMixin from 'shared/mixins/alertMixin'; import alertMixin from 'shared/mixins/alertMixin';
import { required, requiredIf } from 'vuelidate/lib/validators'; import automationMixin from 'shared/mixins/automationMixin';
import filterInputBox from 'dashboard/components/widgets/FilterInput/Index.vue'; import filterInputBox from 'dashboard/components/widgets/FilterInput/Index.vue';
import automationActionInput from 'dashboard/components/widgets/AutomationActionInput.vue'; import automationActionInput from 'dashboard/components/widgets/AutomationActionInput.vue';
import languages from 'dashboard/components/widgets/conversation/advancedFilterItems/languages';
import countries from 'shared/constants/countries.js';
import { import {
AUTOMATION_RULE_EVENTS, AUTOMATION_RULE_EVENTS,
AUTOMATION_ACTION_TYPES, AUTOMATION_ACTION_TYPES,
AUTOMATIONS, AUTOMATIONS,
} from './constants'; } from './constants';
import filterQueryGenerator from 'dashboard/helper/filterQueryGenerator.js';
import actionQueryGenerator from 'dashboard/helper/actionQueryGenerator.js';
import * as OPERATORS from './operators';
export default { export default {
components: { components: {
filterInputBox, filterInputBox,
automationActionInput, automationActionInput,
}, },
mixins: [alertMixin], mixins: [alertMixin, automationMixin],
props: { props: {
onClose: { onClose: {
type: Function, type: Function,
@ -173,46 +170,7 @@ export default {
default: () => {}, 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: requiredIf(prop => {
return !(
prop.action_name === 'mute_conversation' ||
prop.action_name === 'snooze_conversation' ||
prop.action_name === 'resolve_conversation'
);
}),
},
},
},
},
},
data() { data() {
return { return {
automationTypes: AUTOMATIONS, automationTypes: AUTOMATIONS,
@ -242,6 +200,7 @@ export default {
}, },
showDeleteConfirmationModal: false, showDeleteConfirmationModal: false,
allCustomAttributes: [], allCustomAttributes: [],
mode: 'edit',
}; };
}, },
computed: { computed: {
@ -262,374 +221,10 @@ export default {
}, },
}, },
mounted() { mounted() {
const customAttributesRaw = this.$store.getters['attributes/getAttributes']; this.manifestCustomAttributes();
const customAttributeTypes = customAttributesRaw.map(attr => {
return {
key: attr.attribute_key,
name: attr.attribute_display_name,
inputType: this.customAttributeInputType(attr.attribute_display_type),
filterOperators: this.getOperatorTypes(attr.attribute_display_type),
};
});
AUTOMATIONS.message_created.conditions.push(...customAttributeTypes);
AUTOMATIONS.conversation_created.conditions.push(...customAttributeTypes);
AUTOMATIONS.conversation_updated.conditions.push(...customAttributeTypes);
this.allCustomAttributes = this.$store.getters['attributes/getAttributes']; this.allCustomAttributes = this.$store.getters['attributes/getAttributes'];
this.formatAutomation(this.selectedResponse); this.formatAutomation(this.selectedResponse);
}, },
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;
},
isACustomAttribute(key) {
return this.allCustomAttributes.find(attr => {
return attr.attribute_key === key;
});
},
getInputType(key) {
const customAttribute = this.isACustomAttribute(key);
if (customAttribute) {
return this.customAttributeInputType(
customAttribute.attribute_display_type
);
}
const type = this.automationTypes[
this.automation.event_name
].conditions.find(condition => condition.key === key);
return type.inputType;
},
getOperators(key) {
const customAttribute = this.isACustomAttribute(key);
if (customAttribute) {
return this.getOperatorTypes(customAttribute.attribute_display_type);
}
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');
const allCustomAttributes = this.$store.getters[
'attributes/getAttributes'
];
const isCustomAttributeCheckbox = allCustomAttributes.find(attr => {
return (
attr.attribute_key === type &&
attr.attribute_display_type === 'checkbox'
);
});
if (isCustomAttributeCheckbox) {
return [
{
id: true,
name: this.$t('FILTER.ATTRIBUTE_LABELS.TRUE'),
},
{
id: false,
name: this.$t('FILTER.ATTRIBUTE_LABELS.FALSE'),
},
];
}
const isCustomAttributeList = allCustomAttributes.find(attr => {
return (
attr.attribute_key === type && attr.attribute_display_type === 'list'
);
});
if (isCustomAttributeList) {
return allCustomAttributes
.find(attr => attr.attribute_key === type)
.attribute_values.map(item => {
return {
id: item,
name: item,
};
});
}
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.title,
name: i.title,
};
});
case 'browser_language':
return languages;
case 'country_code':
return countries;
default:
return undefined;
}
},
getActionDropdownValues(type) {
switch (type) {
case 'assign_team':
case 'send_email_to_team':
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() {
if (
!this.automation.conditions[this.automation.conditions.length - 1]
.query_operator
) {
this.automation.conditions[
this.automation.conditions.length - 1
].query_operator = 'and';
}
switch (this.automation.event_name) {
case 'message_created':
this.automation.conditions.push({
attribute_key: 'message_type',
filter_operator: 'equal_to',
values: '',
query_operator: 'and',
});
break;
default:
this.automation.conditions.push({
attribute_key: 'status',
filter_operator: 'equal_to',
values: '',
query_operator: 'and',
});
break;
}
},
appendNewAction() {
this.automation.actions.push({
action_name: 'assign_team',
action_params: [],
});
},
removeFilter(index) {
if (this.automation.conditions.length <= 1) {
this.showAlert(this.$t('AUTOMATION.CONDITION.DELETE_MESSAGE'));
} else {
this.automation.conditions.splice(index, 1);
}
},
removeAction(index) {
if (this.automation.actions.length <= 1) {
this.showAlert(this.$t('AUTOMATION.ACTION.DELETE_MESSAGE'));
} else {
this.automation.actions.splice(index, 1);
}
},
submitAutomation() {
this.$v.$touch();
if (this.$v.$invalid) return;
const automation = JSON.parse(JSON.stringify(this.automation));
automation.conditions[
automation.conditions.length - 1
].query_operator = null;
automation.conditions = filterQueryGenerator(
automation.conditions
).payload;
automation.actions = actionQueryGenerator(automation.actions);
this.$emit('saveAutomation', automation, 'EDIT');
},
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;
},
formatAutomation(automation) {
const allCustomAttributes = this.$store.getters[
'attributes/getAttributes'
];
const customAttributes = allCustomAttributes.map(attr => {
return {
key: attr.attribute_key,
name: attr.attribute_display_name,
type: attr.attribute_display_type,
};
});
const formattedConditions = automation.conditions.map(condition => {
const isCustomAttribute = customAttributes.find(
attr => attr.key === condition.attribute_key
);
let inputType = 'plain_text';
if (isCustomAttribute) {
inputType = this.customAttributeInputType(isCustomAttribute.type);
} else {
inputType = this.automationTypes[
automation.event_name
].conditions.find(item => item.key === condition.attribute_key)
.inputType;
}
if (inputType === 'plain_text') {
return {
...condition,
values: condition.values[0],
};
}
return {
...condition,
values: [
...this.getConditionDropdownValues(condition.attribute_key),
].filter(item => [...condition.values].includes(item.id)),
};
});
const formattedActions = automation.actions.map(action => {
let actionParams = [];
if (action.action_params.length) {
const inputType = AUTOMATION_ACTION_TYPES.find(
item => item.key === action.action_name
).inputType;
if (inputType === 'multi_select') {
actionParams = [
...this.getActionDropdownValues(action.action_name),
].filter(item => [...action.action_params].includes(item.id));
} else if (inputType === 'team_message') {
actionParams = {
team_ids: [
...this.getActionDropdownValues(action.action_name),
].filter(item =>
[...action.action_params[0].team_ids].includes(item.id)
),
message: action.action_params[0].message,
};
} else actionParams = [...action.action_params];
}
return {
...action,
action_params: actionParams,
};
});
this.automation = {
...automation,
conditions: formattedConditions,
actions: formattedActions,
};
},
showActionInput(actionName) {
if (actionName === 'send_email_to_team' || actionName === 'send_message')
return false;
const type = AUTOMATION_ACTION_TYPES.find(
action => action.key === actionName
).inputType;
if (type === null) return false;
return true;
},
getOperatorTypes(key) {
switch (key) {
case 'list':
return OPERATORS.OPERATOR_TYPES_1;
case 'text':
return OPERATORS.OPERATOR_TYPES_3;
case 'number':
return OPERATORS.OPERATOR_TYPES_1;
case 'link':
return OPERATORS.OPERATOR_TYPES_1;
case 'date':
return OPERATORS.OPERATOR_TYPES_4;
case 'checkbox':
return OPERATORS.OPERATOR_TYPES_1;
default:
return OPERATORS.OPERATOR_TYPES_1;
}
},
customAttributeInputType(key) {
switch (key) {
case 'date':
return 'date';
case 'text':
return 'plain_text';
case 'list':
return 'search_select';
case 'checkbox':
return 'search_select';
default:
return 'plain_text';
}
},
getFileName(id, actionType) {
if (!id) return '';
if (actionType === 'send_attachment') {
const file = this.automation.files.find(item => item.blob_id === id);
if (file) return file.filename.toString();
}
return '';
},
},
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View file

@ -0,0 +1,446 @@
import * as OPERATORS from '../../dashboard/routes/dashboard/settings/automation/operators';
import languages from '../../dashboard/components/widgets/conversation/advancedFilterItems/languages';
import countries from '../../shared/constants/countries';
import filterQueryGenerator from '../../dashboard/helper/filterQueryGenerator.js';
import actionQueryGenerator from '../../dashboard/helper/actionQueryGenerator.js';
import { required, requiredIf } from 'vuelidate/lib/validators';
export 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: requiredIf(prop => {
return !(
prop.action_name === 'mute_conversation' ||
prop.action_name === 'snooze_conversation' ||
prop.action_name === 'resolve_conversation'
);
}),
},
},
},
},
},
methods: {
customAttributeInputType(key) {
switch (key) {
case 'date':
return 'date';
case 'text':
return 'plain_text';
case 'list':
return 'search_select';
case 'checkbox':
return 'search_select';
default:
return 'plain_text';
}
},
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;
},
isACustomAttribute(key) {
return this.allCustomAttributes.find(attr => {
return attr.attribute_key === key;
});
},
getInputType(key) {
const customAttribute = this.isACustomAttribute(key);
if (customAttribute) {
return this.customAttributeInputType(
customAttribute.attribute_display_type
);
}
const type = this.automationTypes[
this.automation.event_name
].conditions.find(condition => condition.key === key);
return type.inputType;
},
getOperators(key) {
if (this.mode === 'edit') {
const customAttribute = this.isACustomAttribute(key);
if (customAttribute) {
return this.getOperatorTypes(customAttribute.attribute_display_type);
}
}
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');
const allCustomAttributes = this.$store.getters[
'attributes/getAttributes'
];
const isCustomAttributeCheckbox = allCustomAttributes.find(attr => {
return (
attr.attribute_key === type &&
attr.attribute_display_type === 'checkbox'
);
});
if (isCustomAttributeCheckbox) {
return [
{
id: true,
name: this.$t('FILTER.ATTRIBUTE_LABELS.TRUE'),
},
{
id: false,
name: this.$t('FILTER.ATTRIBUTE_LABELS.FALSE'),
},
];
}
const isCustomAttributeList = allCustomAttributes.find(attr => {
return (
attr.attribute_key === type && attr.attribute_display_type === 'list'
);
});
if (isCustomAttributeList) {
return allCustomAttributes
.find(attr => attr.attribute_key === type)
.attribute_values.map(item => {
return {
id: item,
name: item,
};
});
}
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;
}
},
appendNewCondition() {
if (this.mode === 'edit') {
if (
!this.automation.conditions[this.automation.conditions.length - 1]
.query_operator
) {
this.automation.conditions[
this.automation.conditions.length - 1
].query_operator = 'and';
}
}
switch (this.automation.event_name) {
case 'message_created':
this.automation.conditions.push({
attribute_key: 'message_type',
filter_operator: 'equal_to',
values: '',
query_operator: 'and',
});
break;
default:
this.automation.conditions.push({
attribute_key: 'status',
filter_operator: 'equal_to',
values: '',
query_operator: 'and',
});
break;
}
},
appendNewAction() {
this.automation.actions.push({
action_name: 'assign_team',
action_params: [],
});
},
removeFilter(index) {
if (this.automation.conditions.length <= 1) {
this.showAlert(this.$t('AUTOMATION.CONDITION.DELETE_MESSAGE'));
} else {
this.automation.conditions.splice(index, 1);
}
},
removeAction(index) {
if (this.automation.actions.length <= 1) {
this.showAlert(this.$t('AUTOMATION.ACTION.DELETE_MESSAGE'));
} else {
this.automation.actions.splice(index, 1);
}
},
submitAutomation() {
this.$v.$touch();
if (this.$v.$invalid) return;
const automation = JSON.parse(JSON.stringify(this.automation));
automation.conditions[
automation.conditions.length - 1
].query_operator = null;
automation.conditions = filterQueryGenerator(
automation.conditions
).payload;
automation.actions = actionQueryGenerator(automation.actions);
this.$emit(
'saveAutomation',
automation,
this.mode === 'edit' ? 'EDIT' : null
);
},
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;
},
showActionInput(actionName) {
if (actionName === 'send_email_to_team' || actionName === 'send_message')
return false;
const type = this.automationActionTypes.find(
action => action.key === actionName
).inputType;
if (type === null) return false;
return true;
},
resetAction(index) {
this.automation.actions[index].action_params = [];
},
formatAutomation(automation) {
const allCustomAttributes = this.$store.getters[
'attributes/getAttributes'
];
const customAttributes = allCustomAttributes.map(attr => {
return {
key: attr.attribute_key,
name: attr.attribute_display_name,
type: attr.attribute_display_type,
};
});
const formattedConditions = automation.conditions.map(condition => {
const isCustomAttribute = customAttributes.find(
attr => attr.key === condition.attribute_key
);
let inputType = 'plain_text';
if (isCustomAttribute) {
inputType = this.customAttributeInputType(isCustomAttribute.type);
} else {
inputType = this.automationTypes[
automation.event_name
].conditions.find(item => item.key === condition.attribute_key)
.inputType;
}
if (inputType === 'plain_text') {
return {
...condition,
values: condition.values[0],
};
}
return {
...condition,
values: [
...this.getConditionDropdownValues(condition.attribute_key),
].filter(item => [...condition.values].includes(item.id)),
};
});
const formattedActions = automation.actions.map(action => {
let actionParams = [];
if (action.action_params.length) {
const inputType = this.automationActionTypes.find(
item => item.key === action.action_name
).inputType;
if (inputType === 'multi_select') {
actionParams = [
...this.getActionDropdownValues(action.action_name),
].filter(item => [...action.action_params].includes(item.id));
} else if (inputType === 'team_message') {
actionParams = {
team_ids: [
...this.getActionDropdownValues(action.action_name),
].filter(item =>
[...action.action_params[0].team_ids].includes(item.id)
),
message: action.action_params[0].message,
};
} else actionParams = [...action.action_params];
}
return {
...action,
action_params: actionParams,
};
});
this.automation = {
...automation,
conditions: formattedConditions,
actions: formattedActions,
};
},
getOperatorTypes(key) {
switch (key) {
case 'list':
return OPERATORS.OPERATOR_TYPES_1;
case 'text':
return OPERATORS.OPERATOR_TYPES_3;
case 'number':
return OPERATORS.OPERATOR_TYPES_1;
case 'link':
return OPERATORS.OPERATOR_TYPES_1;
case 'date':
return OPERATORS.OPERATOR_TYPES_4;
case 'checkbox':
return OPERATORS.OPERATOR_TYPES_1;
default:
return OPERATORS.OPERATOR_TYPES_1;
}
},
getFileName(id, actionType) {
if (!id) return '';
if (actionType === 'send_attachment') {
const file = this.automation.files.find(item => item.blob_id === id);
if (file) return file.filename.toString();
}
return '';
},
getActionDropdownValues(type) {
switch (type) {
case 'assign_team':
case 'send_email_to_team':
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;
}
},
manifestCustomAttributes() {
const customAttributesRaw = this.$store.getters[
'attributes/getAttributes'
];
const customAttributeTypes = customAttributesRaw.map(attr => {
return {
key: attr.attribute_key,
name: attr.attribute_display_name,
inputType: this.customAttributeInputType(attr.attribute_display_type),
filterOperators: this.getOperatorTypes(attr.attribute_display_type),
};
});
this.automationTypes.message_created.conditions.push(
...customAttributeTypes
);
this.automationTypes.conversation_created.conditions.push(
...customAttributeTypes
);
this.automationTypes.conversation_updated.conditions.push(
...customAttributeTypes
);
},
},
};

View file

@ -0,0 +1,70 @@
import automationMixin from '../automationMixin';
import { shallowMount } from '@vue/test-utils';
import MockComponent from './MockComponent.vue';
describe('Automation Mixin function', () => {
const wrapper = shallowMount(MockComponent, {
mixins: [automationMixin],
});
it('customAttributeInputType should be defined', () => {
expect(wrapper.vm.customAttributeInputType).toBeTruthy();
});
it('onEventChange should be defined', () => {
expect(wrapper.vm.onEventChange).toBeTruthy();
});
it('getAttributes should be defined', () => {
expect(wrapper.vm.getAttributes).toBeTruthy();
});
it('isACustomAttribute should be defined', () => {
expect(wrapper.vm.isACustomAttribute).toBeTruthy();
});
it('getOperators should be defined', () => {
expect(wrapper.vm.getOperators).toBeTruthy();
});
it('getConditionDropdownValues should be defined', () => {
expect(wrapper.vm.getConditionDropdownValues).toBeTruthy();
});
it('appendNewCondition should be defined', () => {
expect(wrapper.vm.appendNewCondition).toBeTruthy();
});
it('appendNewAction should be defined', () => {
expect(wrapper.vm.appendNewAction).toBeTruthy();
});
it('removeFilter should be defined', () => {
expect(wrapper.vm.removeFilter).toBeTruthy();
});
it('removeAction should be defined', () => {
expect(wrapper.vm.removeAction).toBeTruthy();
});
it('submitAutomation should be defined', () => {
expect(wrapper.vm.submitAutomation).toBeTruthy();
});
it('resetFilter should be defined', () => {
expect(wrapper.vm.resetFilter).toBeTruthy();
});
it('showUserInput should be defined', () => {
expect(wrapper.vm.showUserInput).toBeTruthy();
});
it('showActionInput should be defined', () => {
expect(wrapper.vm.showActionInput).toBeTruthy();
});
it('resetAction should be defined', () => {
expect(wrapper.vm.resetAction).toBeTruthy();
});
it('formatAutomation should be defined', () => {
expect(wrapper.vm.formatAutomation).toBeTruthy();
});
it('getOperatorTypes should be defined', () => {
expect(wrapper.vm.getOperatorTypes).toBeTruthy();
});
it('getFileName should be defined', () => {
expect(wrapper.vm.getFileName).toBeTruthy();
});
it('getActionDropdownValues should be defined', () => {
expect(wrapper.vm.getActionDropdownValues).toBeTruthy();
});
it('manifestCustomAttributes should be defined', () => {
expect(wrapper.vm.manifestCustomAttributes).toBeTruthy();
});
});