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:
parent
1f3c5002b3
commit
91b9168fae
23 changed files with 1593 additions and 11 deletions
|
@ -47,4 +47,5 @@ exclude_patterns:
|
|||
- 'app/javascript/shared/constants/countries.js'
|
||||
- 'app/javascript/dashboard/components/widgets/conversation/advancedFilterItems/languages.js'
|
||||
- 'app/javascript/dashboard/routes/dashboard/contacts/contactFilterItems/index.js'
|
||||
- 'app/javascript/dashboard/routes/dashboard/settings/automation/constants.js'
|
||||
- 'app/javascript/dashboard/components/widgets/FilterInput/FilterOperatorTypes.js'
|
||||
|
|
9
app/javascript/dashboard/api/automation.js
Normal file
9
app/javascript/dashboard/api/automation.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import ApiClient from './ApiClient';
|
||||
|
||||
class AutomationsAPI extends ApiClient {
|
||||
constructor() {
|
||||
super('automation_rules', { accountScoped: true });
|
||||
}
|
||||
}
|
||||
|
||||
export default new AutomationsAPI();
|
14
app/javascript/dashboard/api/specs/automation.spec.js
Normal file
14
app/javascript/dashboard/api/specs/automation.spec.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import automations from '../automation';
|
||||
import ApiClient from '../ApiClient';
|
||||
|
||||
describe('#AutomationsAPI', () => {
|
||||
it('creates correct instance', () => {
|
||||
expect(automations).toBeInstanceOf(ApiClient);
|
||||
expect(automations).toHaveProperty('get');
|
||||
expect(automations).toHaveProperty('show');
|
||||
expect(automations).toHaveProperty('create');
|
||||
expect(automations).toHaveProperty('update');
|
||||
expect(automations).toHaveProperty('delete');
|
||||
expect(automations.url).toBe('/api/v1/automation_rules');
|
||||
});
|
||||
});
|
|
@ -70,7 +70,7 @@ const settings = accountId => ({
|
|||
toStateName: 'attributes_list',
|
||||
},
|
||||
{
|
||||
icon: 'autocorrect',
|
||||
icon: 'automation',
|
||||
label: 'AUTOMATION',
|
||||
hasSubMenu: false,
|
||||
toState: frontendURL(`accounts/${accountId}/settings/automation/list`),
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
<template>
|
||||
<div
|
||||
class="filter"
|
||||
:class="{ error: v.action_params.$dirty && v.action_params.$error }"
|
||||
>
|
||||
<div class="filter-inputs">
|
||||
<select
|
||||
v-model="action_name"
|
||||
class="action__question"
|
||||
@change="resetFilter()"
|
||||
>
|
||||
<option
|
||||
v-for="attribute in actionTypes"
|
||||
:key="attribute.key"
|
||||
:value="attribute.key"
|
||||
>
|
||||
{{ attribute.label }}
|
||||
</option>
|
||||
</select>
|
||||
<div class="filter__answer--wrap">
|
||||
<div class="multiselect-wrap--small">
|
||||
<multiselect
|
||||
v-model="action_params"
|
||||
track-by="id"
|
||||
label="name"
|
||||
:placeholder="'Select'"
|
||||
:multiple="true"
|
||||
selected-label
|
||||
:select-label="$t('FORMS.MULTISELECT.ENTER_TO_SELECT')"
|
||||
deselect-label=""
|
||||
:max-height="160"
|
||||
:options="dropdownValues"
|
||||
:allow-empty="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<woot-button
|
||||
icon="dismiss"
|
||||
variant="clear"
|
||||
color-scheme="secondary"
|
||||
@click="removeAction"
|
||||
/>
|
||||
</div>
|
||||
<p
|
||||
v-if="v.action_params.$dirty && v.action_params.$error"
|
||||
class="filter-error"
|
||||
>
|
||||
{{ $t('FILTER.EMPTY_VALUE_ERROR') }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
actionTypes: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
dropdownValues: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
v: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
action_name: {
|
||||
get() {
|
||||
if (!this.value) return null;
|
||||
return this.value.action_name;
|
||||
},
|
||||
set(value) {
|
||||
const payload = this.value || {};
|
||||
this.$emit('input', { ...payload, action_name: value });
|
||||
},
|
||||
},
|
||||
action_params: {
|
||||
get() {
|
||||
if (!this.value) return null;
|
||||
return this.value.action_params;
|
||||
},
|
||||
set(value) {
|
||||
const payload = this.value || {};
|
||||
this.$emit('input', { ...payload, action_params: value });
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
removeAction() {
|
||||
this.$emit('removeAction');
|
||||
},
|
||||
resetFilter() {
|
||||
this.$emit('resetFilter');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.filter {
|
||||
background: var(--color-background);
|
||||
padding: var(--space-small);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-medium);
|
||||
margin-bottom: var(--space-small);
|
||||
}
|
||||
|
||||
.filter.error {
|
||||
background: var(--r-50);
|
||||
}
|
||||
|
||||
.filter-inputs {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.filter-error {
|
||||
color: var(--r-500);
|
||||
display: block;
|
||||
margin: var(--space-smaller) 0;
|
||||
}
|
||||
|
||||
.action__question,
|
||||
.filter__operator {
|
||||
margin-bottom: var(--space-zero);
|
||||
margin-right: var(--space-smaller);
|
||||
}
|
||||
|
||||
.action__question {
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
.filter__answer--wrap {
|
||||
margin-right: var(--space-smaller);
|
||||
flex-grow: 1;
|
||||
|
||||
input {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.filter__answer {
|
||||
&.answer--text-input {
|
||||
margin-bottom: var(--space-zero);
|
||||
}
|
||||
}
|
||||
|
||||
.filter__join-operator-wrap {
|
||||
position: relative;
|
||||
z-index: var(--z-index-twenty);
|
||||
margin: var(--space-zero);
|
||||
}
|
||||
|
||||
.filter__join-operator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin: var(--space-one) var(--space-zero);
|
||||
|
||||
.operator__line {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.operator__select {
|
||||
position: relative;
|
||||
width: auto;
|
||||
margin-bottom: var(--space-zero) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect {
|
||||
margin-bottom: var(--space-zero);
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="filters">
|
||||
<div class="filter">
|
||||
<div class="filter" :class="{ error: v.values.$dirty && v.values.$error }">
|
||||
<div class="filter-inputs">
|
||||
<select
|
||||
v-if="groupedFilters"
|
||||
|
@ -163,7 +163,7 @@ export default {
|
|||
},
|
||||
groupedFilters: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
default: false,
|
||||
},
|
||||
filterGroups: {
|
||||
type: Array,
|
||||
|
@ -230,6 +230,10 @@ export default {
|
|||
border-radius: var(--border-radius-medium);
|
||||
}
|
||||
|
||||
.filter.error {
|
||||
background: var(--r-50);
|
||||
}
|
||||
|
||||
.filter-inputs {
|
||||
display: flex;
|
||||
}
|
||||
|
|
17
app/javascript/dashboard/helper/actionQueryGenerator.js
Normal file
17
app/javascript/dashboard/helper/actionQueryGenerator.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
const generatePayload = data => {
|
||||
let payload = data.map(item => {
|
||||
if (Array.isArray(item.action_params)) {
|
||||
item.action_params = item.action_params.map(val => val.id);
|
||||
} else if (typeof item.values === 'object') {
|
||||
item.action_params = [item.action_params.id];
|
||||
} else if (!item.action_params) {
|
||||
item.action_params = [];
|
||||
} else {
|
||||
item.action_params = [item.action_params];
|
||||
}
|
||||
return item;
|
||||
});
|
||||
return payload;
|
||||
};
|
||||
|
||||
export default generatePayload;
|
|
@ -0,0 +1,41 @@
|
|||
import actionQueryGenerator from '../actionQueryGenerator';
|
||||
|
||||
const testData = [
|
||||
{
|
||||
action_name: 'add_label',
|
||||
action_params: [{ id: 'testlabel', name: 'testlabel' }],
|
||||
},
|
||||
{
|
||||
action_name: 'assign_team',
|
||||
action_params: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'sales team',
|
||||
description: 'This is our internal sales team',
|
||||
allow_auto_assign: true,
|
||||
account_id: 1,
|
||||
is_member: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const finalResult = [
|
||||
{
|
||||
action_name: 'add_label',
|
||||
action_params: ['testlabel'],
|
||||
},
|
||||
{
|
||||
action_name: 'assign_team',
|
||||
action_params: [1],
|
||||
},
|
||||
];
|
||||
|
||||
describe('#actionQueryGenerator', () => {
|
||||
it('returns the correct format of filter query', () => {
|
||||
expect(actionQueryGenerator(testData)).toEqual(finalResult);
|
||||
expect(
|
||||
actionQueryGenerator(testData).every(i => Array.isArray(i.action_params))
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
|
@ -1,6 +1,82 @@
|
|||
{
|
||||
"AUTOMATION": {
|
||||
"HEADER": "Automation",
|
||||
"HEADER_BTN_TXT": "Add Automation Rule"
|
||||
"HEADER_BTN_TXT": "Add Automation Rule",
|
||||
"LOADING": "Fetching automation rules",
|
||||
"SIDEBAR_TXT": "<p><b>Automation Rules</b> <p>Automation can replace and automate existing processes that require manual effort. You can do many things with automation, including adding labels and assigning conversation to the best agent. So the team focuses on what they do best and spends more little time on manual tasks.</p>",
|
||||
"ADD": {
|
||||
"TITLE": "Add Automation Rule",
|
||||
"SUBMIT": "Create",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"FORM": {
|
||||
"NAME": {
|
||||
"LABEL": "Rule Name",
|
||||
"PLACEHOLDER": "Enter rule name",
|
||||
"ERROR": "Name is required"
|
||||
},
|
||||
"DESC": {
|
||||
"LABEL": "Description",
|
||||
"PLACEHOLDER": "Enter rule description",
|
||||
"ERROR": "Description is required"
|
||||
},
|
||||
"EVENT": {
|
||||
"LABEL": "Event",
|
||||
"PLACEHOLDER": "Please select one",
|
||||
"ERROR": "Event is required"
|
||||
},
|
||||
"CONDITIONS": {
|
||||
"LABEL": "Conditions"
|
||||
},
|
||||
"ACTIONS": {
|
||||
"LABEL": "Actions"
|
||||
}
|
||||
},
|
||||
"CONDITION_BUTTON_LABEL": "Add Condition",
|
||||
"ACTION_BUTTON_LABEL": "Add Action",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Automation rule added successfully",
|
||||
"ERROR_MESSAGE": "Could not able to create a automation rule, Please try again later"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"TABLE_HEADER": [
|
||||
"Name",
|
||||
"Description",
|
||||
"Active",
|
||||
"Created on"
|
||||
],
|
||||
"404": "No automation rules found"
|
||||
},
|
||||
"DELETE": {
|
||||
"TITLE": "Delete Automation Rule",
|
||||
"SUBMIT": "Delete",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirm Deletion",
|
||||
"MESSAGE": "Are you sure to delete ",
|
||||
"YES": "Yes, Delete ",
|
||||
"NO": "No, Keep "
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Automation rule deleted successfully",
|
||||
"ERROR_MESSAGE": "Could not able to delete a automation rule, Please try again later"
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit Automation Rule",
|
||||
"SUBMIT": "Edit",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Automation rule updated successfully",
|
||||
"ERROR_MESSAGE": "Could not update automation rule, Please try again later"
|
||||
}
|
||||
},
|
||||
"FORM": {
|
||||
"EDIT": "Edit",
|
||||
"CREATE": "Create",
|
||||
"DELETE": "Delete",
|
||||
"CANCEL": "Cancel",
|
||||
"RESET_MESSAGE": "Changing event type will reset the conditions and events you have added below"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
],
|
||||
};
|
||||
|
|
|
@ -31,6 +31,7 @@ import teams from './modules/teams';
|
|||
import userNotificationSettings from './modules/userNotificationSettings';
|
||||
import webhooks from './modules/webhooks';
|
||||
import attributes from './modules/attributes';
|
||||
import automations from './modules/automations';
|
||||
import customViews from './modules/customViews';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
@ -66,6 +67,7 @@ export default new Vuex.Store({
|
|||
userNotificationSettings,
|
||||
webhooks,
|
||||
attributes,
|
||||
automations,
|
||||
customViews,
|
||||
},
|
||||
});
|
||||
|
|
89
app/javascript/dashboard/store/modules/automations.js
Normal file
89
app/javascript/dashboard/store/modules/automations.js
Normal file
|
@ -0,0 +1,89 @@
|
|||
import * as MutationHelpers from 'shared/helpers/vuex/mutationHelpers';
|
||||
import types from '../mutation-types';
|
||||
import AutomationAPI from '../../api/automation';
|
||||
|
||||
export const state = {
|
||||
records: [],
|
||||
uiFlags: {
|
||||
isFetching: false,
|
||||
isCreating: false,
|
||||
isDeleting: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const getters = {
|
||||
getAutomations(_state) {
|
||||
return _state.records;
|
||||
},
|
||||
getUIFlags(_state) {
|
||||
return _state.uiFlags;
|
||||
},
|
||||
};
|
||||
|
||||
export const actions = {
|
||||
get: async function getAutomations({ commit }) {
|
||||
commit(types.SET_AUTOMATION_UI_FLAG, { isFetching: true });
|
||||
try {
|
||||
const response = await AutomationAPI.get();
|
||||
commit(types.SET_AUTOMATIONS, response.data.payload);
|
||||
} catch (error) {
|
||||
// Ignore error
|
||||
} finally {
|
||||
commit(types.SET_AUTOMATION_UI_FLAG, { isFetching: false });
|
||||
}
|
||||
},
|
||||
create: async function createAutomation({ commit }, automationObj) {
|
||||
commit(types.SET_AUTOMATION_UI_FLAG, { isCreating: true });
|
||||
try {
|
||||
const response = await AutomationAPI.create(automationObj);
|
||||
commit(types.ADD_AUTOMATION, response.data);
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
} finally {
|
||||
commit(types.SET_AUTOMATION_UI_FLAG, { isCreating: false });
|
||||
}
|
||||
},
|
||||
update: async ({ commit }, { id, ...updateObj }) => {
|
||||
commit(types.SET_AUTOMATION_UI_FLAG, { isUpdating: true });
|
||||
try {
|
||||
const response = await AutomationAPI.update(id, updateObj);
|
||||
commit(types.EDIT_AUTOMATION, response.data);
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
} finally {
|
||||
commit(types.SET_AUTOMATION_UI_FLAG, { isUpdating: false });
|
||||
}
|
||||
},
|
||||
delete: async ({ commit }, id) => {
|
||||
commit(types.SET_AUTOMATION_UI_FLAG, { isDeleting: true });
|
||||
try {
|
||||
await AutomationAPI.delete(id);
|
||||
commit(types.DELETE_AUTOMATION, id);
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
} finally {
|
||||
commit(types.SET_AUTOMATION_UI_FLAG, { isDeleting: false });
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const mutations = {
|
||||
[types.SET_AUTOMATION_UI_FLAG](_state, data) {
|
||||
_state.uiFlags = {
|
||||
..._state.uiFlags,
|
||||
...data,
|
||||
};
|
||||
},
|
||||
[types.ADD_AUTOMATION]: MutationHelpers.create,
|
||||
[types.SET_AUTOMATIONS]: MutationHelpers.set,
|
||||
// [types.EDIT_AUTOMATION]: MutationHelpers.update,
|
||||
[types.DELETE_AUTOMATION]: MutationHelpers.destroy,
|
||||
};
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
actions,
|
||||
state,
|
||||
getters,
|
||||
mutations,
|
||||
};
|
|
@ -0,0 +1,94 @@
|
|||
import axios from 'axios';
|
||||
import { actions } from '../../automations';
|
||||
import * as types from '../../../mutation-types';
|
||||
import automationsList from './fixtures';
|
||||
|
||||
const commit = jest.fn();
|
||||
global.axios = axios;
|
||||
jest.mock('axios');
|
||||
|
||||
describe('#actions', () => {
|
||||
describe('#get', () => {
|
||||
it('sends correct actions if API is success', async () => {
|
||||
axios.get.mockResolvedValue({ data: { payload: automationsList } });
|
||||
await actions.get({ commit });
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.default.SET_AUTOMATION_UI_FLAG, { isFetching: true }],
|
||||
[types.default.SET_AUTOMATIONS, automationsList],
|
||||
[types.default.SET_AUTOMATION_UI_FLAG, { isFetching: false }],
|
||||
]);
|
||||
});
|
||||
it('sends correct actions if API is error', async () => {
|
||||
axios.get.mockRejectedValue({ message: 'Incorrect header' });
|
||||
await actions.get({ commit });
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.default.SET_AUTOMATION_UI_FLAG, { isFetching: true }],
|
||||
[types.default.SET_AUTOMATION_UI_FLAG, { isFetching: false }],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#create', () => {
|
||||
it('sends correct actions if API is success', async () => {
|
||||
axios.post.mockResolvedValue({ data: automationsList[0] });
|
||||
await actions.create({ commit }, automationsList[0]);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.default.SET_AUTOMATION_UI_FLAG, { isCreating: true }],
|
||||
[types.default.ADD_AUTOMATION, automationsList[0]],
|
||||
[types.default.SET_AUTOMATION_UI_FLAG, { isCreating: false }],
|
||||
]);
|
||||
});
|
||||
it('sends correct actions if API is error', async () => {
|
||||
axios.post.mockRejectedValue({ message: 'Incorrect header' });
|
||||
await expect(actions.create({ commit })).rejects.toThrow(Error);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.default.SET_AUTOMATION_UI_FLAG, { isCreating: true }],
|
||||
[types.default.SET_AUTOMATION_UI_FLAG, { isCreating: false }],
|
||||
]);
|
||||
});
|
||||
});
|
||||
// API Work in progress
|
||||
// describe('#update', () => {
|
||||
// it('sends correct actions if API is success', async () => {
|
||||
// axios.patch.mockResolvedValue({ data: automationsList[0] });
|
||||
// await actions.update({ commit }, automationsList[0]);
|
||||
// expect(commit.mock.calls).toEqual([
|
||||
// [types.default.SET_AUTOMATION_UI_FLAG, { isUpdating: true }],
|
||||
// [types.default.EDIT_AUTOMATION, automationsList[0]],
|
||||
// [types.default.SET_AUTOMATION_UI_FLAG, { isUpdating: false }],
|
||||
// ]);
|
||||
// });
|
||||
// it('sends correct actions if API is error', async () => {
|
||||
// axios.patch.mockRejectedValue({ message: 'Incorrect header' });
|
||||
// await expect(
|
||||
// actions.update({ commit }, automationsList[0])
|
||||
// ).rejects.toThrow(Error);
|
||||
// expect(commit.mock.calls).toEqual([
|
||||
// [types.default.SET_AUTOMATION_UI_FLAG, { isUpdating: true }],
|
||||
// [types.default.SET_AUTOMATION_UI_FLAG, { isUpdating: false }],
|
||||
// ]);
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('#delete', () => {
|
||||
it('sends correct actions if API is success', async () => {
|
||||
axios.delete.mockResolvedValue({ data: automationsList[0] });
|
||||
await actions.delete({ commit }, automationsList[0].id);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.default.SET_AUTOMATION_UI_FLAG, { isDeleting: true }],
|
||||
[types.default.DELETE_AUTOMATION, automationsList[0].id],
|
||||
[types.default.SET_AUTOMATION_UI_FLAG, { isDeleting: false }],
|
||||
]);
|
||||
});
|
||||
it('sends correct actions if API is error', async () => {
|
||||
axios.delete.mockRejectedValue({ message: 'Incorrect header' });
|
||||
await expect(
|
||||
actions.delete({ commit }, automationsList[0].id)
|
||||
).rejects.toThrow(Error);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.default.SET_AUTOMATION_UI_FLAG, { isDeleting: true }],
|
||||
[types.default.SET_AUTOMATION_UI_FLAG, { isDeleting: false }],
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,64 @@
|
|||
export default [
|
||||
{
|
||||
id: 12,
|
||||
account_id: 1,
|
||||
name: 'Test',
|
||||
description: 'This is a test',
|
||||
event_name: 'conversation_created',
|
||||
conditions: [
|
||||
{
|
||||
values: ['open'],
|
||||
attribute_key: 'status',
|
||||
query_operator: null,
|
||||
filter_operator: 'equal_to',
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
action_name: 'add_label',
|
||||
action_params: [{}],
|
||||
},
|
||||
],
|
||||
created_on: '2022-01-14T09:17:55.689Z',
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
account_id: 1,
|
||||
name: 'Auto resolve conversation',
|
||||
description: 'Auto resolves conversation',
|
||||
event_name: 'conversation_updated',
|
||||
conditions: [
|
||||
{
|
||||
values: ['resolved'],
|
||||
attribute_key: 'status',
|
||||
query_operator: null,
|
||||
filter_operator: 'equal_to',
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
action_name: 'add_label',
|
||||
action_params: [{}],
|
||||
},
|
||||
],
|
||||
created_on: '2022-01-14T13:06:31.843Z',
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
account_id: 1,
|
||||
name: 'Fayaz',
|
||||
description: 'This is a test',
|
||||
event_name: 'conversation_created',
|
||||
conditions: {},
|
||||
actions: [
|
||||
{
|
||||
action_name: 'add_label',
|
||||
action_params: [{}],
|
||||
},
|
||||
],
|
||||
created_on: '2022-01-17T06:46:08.098Z',
|
||||
active: true,
|
||||
},
|
||||
];
|
|
@ -0,0 +1,25 @@
|
|||
import { getters } from '../../automations';
|
||||
import automations from './fixtures';
|
||||
describe('#getters', () => {
|
||||
it('getAutomations', () => {
|
||||
const state = { records: automations };
|
||||
expect(getters.getAutomations(state)).toEqual(automations);
|
||||
});
|
||||
|
||||
it('getUIFlags', () => {
|
||||
const state = {
|
||||
uiFlags: {
|
||||
isFetching: true,
|
||||
isCreating: false,
|
||||
isUpdating: false,
|
||||
isDeleting: false,
|
||||
},
|
||||
};
|
||||
expect(getters.getUIFlags(state)).toEqual({
|
||||
isFetching: true,
|
||||
isCreating: false,
|
||||
isUpdating: false,
|
||||
isDeleting: false,
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,58 @@
|
|||
import types from '../../../mutation-types';
|
||||
import { mutations } from '../../automations';
|
||||
import automations from './fixtures';
|
||||
describe('#mutations', () => {
|
||||
describe('#SET_automations', () => {
|
||||
it('set autonmation records', () => {
|
||||
const state = { records: [] };
|
||||
mutations[types.SET_AUTOMATIONS](state, automations);
|
||||
expect(state.records).toEqual(automations);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#ADD_AUTOMATION', () => {
|
||||
it('push newly created automatuion to the store', () => {
|
||||
const state = { records: [automations[0]] };
|
||||
mutations[types.ADD_AUTOMATION](state, automations[1]);
|
||||
expect(state.records).toEqual([automations[0], automations[1]]);
|
||||
});
|
||||
});
|
||||
|
||||
// describe('#EDIT_AUTOMATION', () => {
|
||||
// it('update automation record', () => {
|
||||
// const state = { records: [automations[0]] };
|
||||
// mutations[types.EDIT_AUTOMATION](state, {
|
||||
// id: 12,
|
||||
// account_id: 1,
|
||||
// name: 'Test Automation',
|
||||
// description: 'This is a test',
|
||||
// event_name: 'conversation_created',
|
||||
// conditions: [
|
||||
// {
|
||||
// values: ['open'],
|
||||
// attribute_key: 'status',
|
||||
// query_operator: null,
|
||||
// filter_operator: 'equal_to',
|
||||
// },
|
||||
// ],
|
||||
// actions: [
|
||||
// {
|
||||
// action_name: 'add_label',
|
||||
// action_params: [{}],
|
||||
// },
|
||||
// ],
|
||||
// created_on: '2022-01-14T09:17:55.689Z',
|
||||
// active: true,
|
||||
// });
|
||||
// expect(state.records[0].name).toEqual('Test Automation');
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('#DELETE_AUTOMATION', () => {
|
||||
it('delete automation record', () => {
|
||||
const state = { records: [automations[0]] };
|
||||
mutations[types.DELETE_AUTOMATION](state, 12);
|
||||
expect(state.records).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -189,6 +189,13 @@ export default {
|
|||
EDIT_CUSTOM_ATTRIBUTE: 'EDIT_CUSTOM_ATTRIBUTE',
|
||||
DELETE_CUSTOM_ATTRIBUTE: 'DELETE_CUSTOM_ATTRIBUTE',
|
||||
|
||||
// Automations
|
||||
SET_AUTOMATION_UI_FLAG: 'SET_AUTOMATION_UI_FLAG',
|
||||
SET_AUTOMATIONS: 'SET_AUTOMATIONS',
|
||||
ADD_AUTOMATION: 'ADD_AUTOMATION',
|
||||
EDIT_AUTOMATION: 'EDIT_AUTOMATION',
|
||||
DELETE_AUTOMATION: 'DELETE_AUTOMATION',
|
||||
|
||||
// Custom Views
|
||||
SET_CUSTOM_VIEW_UI_FLAG: 'SET_CUSTOM_VIEW_UI_FLAG',
|
||||
SET_CUSTOM_VIEW: 'SET_CUSTOM_VIEW',
|
||||
|
|
|
@ -14,16 +14,28 @@
|
|||
"arrow-up-outline": "M4.21 10.733a.75.75 0 0 0 1.086 1.034l5.954-6.251V20.25a.75.75 0 0 0 1.5 0V5.516l5.955 6.251a.75.75 0 0 0 1.086-1.034l-7.067-7.42a.995.995 0 0 0-.58-.3.754.754 0 0 0-.29.001.995.995 0 0 0-.578.3L4.21 10.733Z",
|
||||
"attach-outline": "M11.772 3.743a6 6 0 0 1 8.66 8.302l-.19.197-8.8 8.798-.036.03a3.723 3.723 0 0 1-5.489-4.973.764.764 0 0 1 .085-.13l.054-.06.086-.088.142-.148.002.003 7.436-7.454a.75.75 0 0 1 .977-.074l.084.073a.75.75 0 0 1 .074.976l-.073.084-7.594 7.613a2.23 2.23 0 0 0 3.174 3.106l8.832-8.83A4.502 4.502 0 0 0 13 4.644l-.168.16-.013.014-9.536 9.536a.75.75 0 0 1-1.133-.977l.072-.084 9.549-9.55h.002Z",
|
||||
"autocorrect-outline": "M13.461 4.934c.293.184.548.42.752.698l.117.171 2.945 4.696H21.5a.75.75 0 0 1 .743.649l.007.102a.75.75 0 0 1-.75.75l-3.284-.001.006.009-.009-.01a4.75 4.75 0 1 1-3.463-1.5h.756L13.059 6.6a1.25 1.25 0 0 0-2.04-.112l-.078.112-7.556 12.048a.75.75 0 0 1-1.322-.699l.052-.098L9.67 5.803a2.75 2.75 0 0 1 3.791-.869ZM14.751 12a3.25 3.25 0 1 0 0 6.5 3.25 3.25 0 0 0 0-6.5Z",
|
||||
"automation-outline": [
|
||||
"M21.78 3.28a.75.75 0 0 0-1.06-1.06l-2.012 2.012a4.251 4.251 0 0 0-5.463.462l-1.068 1.069a1.75 1.75 0 0 0 0 2.474l3.585 3.586a1.75 1.75 0 0 0 2.475 0l1.068-1.068a4.251 4.251 0 0 0 .463-5.463L21.78 3.28zm-3.585 2.475l.022.023l.003.002l.002.003l.023.022a2.75 2.75 0 0 1 0 3.89l-1.068 1.067a.25.25 0 0 1-.354 0l-3.586-3.585a.25.25 0 0 1 0-.354l1.068-1.068a2.75 2.75 0 0 1 3.89 0z",
|
||||
"M10.78 11.28a.75.75 0 1 0-1.06-1.06L8 11.94l-.47-.47a.75.75 0 0 0-1.06 0l-1.775 1.775a4.251 4.251 0 0 0-.463 5.463L2.22 20.72a.75.75 0 1 0 1.06 1.06l2.012-2.012a4.251 4.251 0 0 0 5.463-.463l1.775-1.775a.75.75 0 0 0 0-1.06l-.47-.47l1.72-1.72a.75.75 0 1 0-1.06-1.06L11 14.94L9.06 13l1.72-1.72zm-3.314 2.247l.004.003l.003.004l2.993 2.993l.004.003l.003.004l.466.466l-1.244 1.245a2.75 2.75 0 0 1-3.89 0l-.05-.05a2.75 2.75 0 0 1 0-3.89L7 13.062l.466.466z"
|
||||
],
|
||||
"book-contacts-outline": "M15.5 12.25a.75.75 0 0 0-.75-.75h-5a.75.75 0 0 0-.75.75v.5c0 1 1.383 1.75 3.25 1.75s3.25-.75 3.25-1.75v-.5ZM14 8.745C14 7.78 13.217 7 12.25 7s-1.75.779-1.75 1.745a1.75 1.75 0 1 0 3.5 0ZM4 4.5A2.5 2.5 0 0 1 6.5 2H18a2.5 2.5 0 0 1 2.5 2.5v14.25a.75.75 0 0 1-.75.75H5.5a1 1 0 0 0 1 1h13.25a.75.75 0 0 1 0 1.5H6.5A2.5 2.5 0 0 1 4 19.5v-15Zm1.5 0V18H19V4.5a1 1 0 0 0-1-1H6.5a1 1 0 0 0-1 1Z",
|
||||
"book-clock-outline": ["M13 9.125v1.625h.75a.625.625 0 1 1 0 1.25H12.5a.615.615 0 0 1-.063-.003.625.625 0 0 1-.688-.622v-2.25a.625.625 0 1 1 1.251 0Z", "M12.375 6.005a4.75 4.75 0 1 0 0 9.5 4.75 4.75 0 0 0 0-9.5Zm-3.5 4.75a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0Z", "M6.5 2A2.5 2.5 0 0 0 4 4.5v15A2.5 2.5 0 0 0 6.5 22h13.25a.75.75 0 0 0 0-1.5H6.5a1 1 0 0 1-1-1h14.25a.75.75 0 0 0 .75-.75V4.5A2.5 2.5 0 0 0 18 2H6.5ZM19 18H5.5V4.5a1 1 0 0 1 1-1H18a1 1 0 0 1 1 1V18Z"],
|
||||
"book-clock-outline": [
|
||||
"M13 9.125v1.625h.75a.625.625 0 1 1 0 1.25H12.5a.615.615 0 0 1-.063-.003.625.625 0 0 1-.688-.622v-2.25a.625.625 0 1 1 1.251 0Z",
|
||||
"M12.375 6.005a4.75 4.75 0 1 0 0 9.5 4.75 4.75 0 0 0 0-9.5Zm-3.5 4.75a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0Z",
|
||||
"M6.5 2A2.5 2.5 0 0 0 4 4.5v15A2.5 2.5 0 0 0 6.5 22h13.25a.75.75 0 0 0 0-1.5H6.5a1 1 0 0 1-1-1h14.25a.75.75 0 0 0 .75-.75V4.5A2.5 2.5 0 0 0 18 2H6.5ZM19 18H5.5V4.5a1 1 0 0 1 1-1H18a1 1 0 0 1 1 1V18Z"
|
||||
],
|
||||
"building-bank-outline": "M13.032 2.325a1.75 1.75 0 0 0-2.064 0L3.547 7.74c-.978.713-.473 2.26.736 2.26H4.5v5.8A2.75 2.75 0 0 0 3 18.25v1.5c0 .413.336.75.75.75h16.5a.75.75 0 0 0 .75-.75v-1.5a2.75 2.75 0 0 0-1.5-2.45V10h.217c1.21 0 1.713-1.547.736-2.26l-7.421-5.416Zm-1.18 1.211a.25.25 0 0 1 .295 0L18.95 8.5H5.05l6.803-4.964ZM18 10v5.5h-2V10h2Zm-3.5 0v5.5h-1.75V10h1.75Zm-3.25 0v5.5H9.5V10h1.75Zm-5.5 7h12.5c.69 0 1.25.56 1.25 1.25V19h-15v-.75c0-.69.56-1.25 1.25-1.25ZM6 15.5V10h2v5.5H6Z",
|
||||
"calendar-clock-outline": ["M21 6.25A3.25 3.25 0 0 0 17.75 3H6.25A3.25 3.25 0 0 0 3 6.25v11.5A3.25 3.25 0 0 0 6.25 21h5.772a6.471 6.471 0 0 1-.709-1.5H6.25a1.75 1.75 0 0 1-1.75-1.75V8.5h15v2.813a6.471 6.471 0 0 1 1.5.709V6.25ZM6.25 4.5h11.5c.966 0 1.75.784 1.75 1.75V7h-15v-.75c0-.966.784-1.75 1.75-1.75Z", "M23 17.5a5.5 5.5 0 1 0-11 0 5.5 5.5 0 0 0 11 0Zm-5.5 0h2a.5.5 0 0 1 0 1H17a.5.5 0 0 1-.5-.491v-3.01a.5.5 0 0 1 1 0V17.5Z"],
|
||||
"calendar-clock-outline": [
|
||||
"M21 6.25A3.25 3.25 0 0 0 17.75 3H6.25A3.25 3.25 0 0 0 3 6.25v11.5A3.25 3.25 0 0 0 6.25 21h5.772a6.471 6.471 0 0 1-.709-1.5H6.25a1.75 1.75 0 0 1-1.75-1.75V8.5h15v2.813a6.471 6.471 0 0 1 1.5.709V6.25ZM6.25 4.5h11.5c.966 0 1.75.784 1.75 1.75V7h-15v-.75c0-.966.784-1.75 1.75-1.75Z",
|
||||
"M23 17.5a5.5 5.5 0 1 0-11 0 5.5 5.5 0 0 0 11 0Zm-5.5 0h2a.5.5 0 0 1 0 1H17a.5.5 0 0 1-.5-.491v-3.01a.5.5 0 0 1 1 0V17.5Z"
|
||||
],
|
||||
"call-outline": "m7.056 2.418 1.167-.351a2.75 2.75 0 0 1 3.302 1.505l.902 2.006a2.75 2.75 0 0 1-.633 3.139L10.3 10.11a.25.25 0 0 0-.078.155c-.044.397.225 1.17.845 2.245.451.781.86 1.33 1.207 1.637.242.215.375.261.432.245l2.01-.615a2.75 2.75 0 0 1 3.034 1.02l1.281 1.776a2.75 2.75 0 0 1-.339 3.605l-.886.84a3.75 3.75 0 0 1-3.587.889c-2.754-.769-5.223-3.093-7.435-6.924-2.215-3.836-2.992-7.14-2.276-9.913a3.75 3.75 0 0 1 2.548-2.652Zm.433 1.437a2.25 2.25 0 0 0-1.529 1.59c-.602 2.332.087 5.261 2.123 8.788 2.033 3.522 4.222 5.582 6.54 6.23a2.25 2.25 0 0 0 2.151-.534l.887-.84a1.25 1.25 0 0 0 .154-1.639l-1.28-1.775a1.25 1.25 0 0 0-1.38-.464l-2.015.617c-1.17.348-2.232-.593-3.372-2.568C9 11.93 8.642 10.9 8.731 10.099c.047-.416.24-.8.546-1.086l1.494-1.393a1.25 1.25 0 0 0 .288-1.427l-.902-2.006a1.25 1.25 0 0 0-1.5-.684l-1.168.352Z",
|
||||
"chat-help-outline": "M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10a9.96 9.96 0 0 1-4.587-1.112l-3.826 1.067a1.25 1.25 0 0 1-1.54-1.54l1.068-3.823A9.96 9.96 0 0 1 2 12C2 6.477 6.477 2 12 2Zm0 1.5A8.5 8.5 0 0 0 3.5 12c0 1.47.373 2.883 1.073 4.137l.15.27-1.112 3.984 3.987-1.112.27.15A8.5 8.5 0 1 0 12 3.5Zm0 12a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm0-8.75a2.75 2.75 0 0 1 2.75 2.75c0 1.01-.297 1.574-1.051 2.359l-.169.171c-.622.622-.78.886-.78 1.47a.75.75 0 0 1-1.5 0c0-1.01.297-1.574 1.051-2.359l.169-.171c.622-.622.78-.886.78-1.47a1.25 1.25 0 0 0-2.493-.128l-.007.128a.75.75 0 0 1-1.5 0A2.75 2.75 0 0 1 12 6.75Z",
|
||||
"chat-multiple-outline": "M9.562 3a7.5 7.5 0 0 0-6.798 10.673l-.724 2.842a1.25 1.25 0 0 0 1.504 1.524c.75-.18 1.903-.457 2.93-.702A7.5 7.5 0 1 0 9.561 3Zm-6 7.5a6 6 0 1 1 3.33 5.375l-.244-.121-.264.063c-.923.22-1.99.475-2.788.667l.69-2.708.07-.276-.13-.253a5.971 5.971 0 0 1-.664-2.747Zm11 10.5c-1.97 0-3.762-.759-5.1-2h.1c.718 0 1.415-.089 2.08-.257.865.482 1.86.757 2.92.757.96 0 1.866-.225 2.67-.625l.243-.121.264.063c.922.22 1.966.445 2.74.61-.175-.751-.414-1.756-.642-2.651l-.07-.276.13-.253a5.971 5.971 0 0 0 .665-2.747 5.995 5.995 0 0 0-2.747-5.042 8.44 8.44 0 0 0-.8-2.047 7.503 7.503 0 0 1 4.344 10.263c.253 1.008.509 2.1.671 2.803a1.244 1.244 0 0 1-1.467 1.5 132.62 132.62 0 0 1-2.913-.64 7.476 7.476 0 0 1-3.088.663Z",
|
||||
"chat-outline": "M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10a9.96 9.96 0 0 1-4.587-1.112l-3.826 1.067a1.25 1.25 0 0 1-1.54-1.54l1.068-3.823A9.96 9.96 0 0 1 2 12C2 6.477 6.477 2 12 2Zm0 1.5A8.5 8.5 0 0 0 3.5 12c0 1.47.373 2.883 1.073 4.137l.15.27-1.112 3.984 3.987-1.112.27.15A8.5 8.5 0 1 0 12 3.5ZM8.75 13h4.498a.75.75 0 0 1 .102 1.493l-.102.007H8.75a.75.75 0 0 1-.102-1.493L8.75 13h4.498H8.75Zm0-3.5h6.505a.75.75 0 0 1 .101 1.493l-.101.007H8.75a.75.75 0 0 1-.102-1.493L8.75 9.5h6.505H8.75Z",
|
||||
"checkmark-circle-outline": "M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2Zm0 1.5a8.5 8.5 0 1 0 0 17 8.5 8.5 0 0 0 0-17Zm-1.25 9.94 4.47-4.47a.75.75 0 0 1 1.133.976l-.073.084-5 5a.75.75 0 0 1-.976.073l-.084-.073-2.5-2.5a.75.75 0 0 1 .976-1.133l.084.073 1.97 1.97 4.47-4.47-4.47 4.47Z",
|
||||
"checkmark-circle-solid": "M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2Zm3.22 6.97-4.47 4.47-1.97-1.97a.75.75 0 0 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l5-5a.75.75 0 1 0-1.06-1.06Z",
|
||||
"checkmark-square-solid": "M18 3a3 3 0 0 1 3 3v12a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3h12zm-1.53 4.97L10 14.44l-2.47-2.47a.75.75 0 0 0-1.06 1.06l3 3a.75.75 0 0 0 1.06 0l7-7a.75.75 0 0 0-1.06-1.06z",
|
||||
"checkmark-outline": "M4.53 12.97a.75.75 0 0 0-1.06 1.06l4.5 4.5a.75.75 0 0 0 1.06 0l11-11a.75.75 0 0 0-1.06-1.06L8.5 16.94l-3.97-3.97Z",
|
||||
"chevron-down-outline": "M4.22 8.47a.75.75 0 0 1 1.06 0L12 15.19l6.72-6.72a.75.75 0 1 1 1.06 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L4.22 9.53a.75.75 0 0 1 0-1.06Z",
|
||||
"chevron-left-outline": "M15.53 4.22a.75.75 0 0 1 0 1.06L8.81 12l6.72 6.72a.75.75 0 1 1-1.06 1.06l-7.25-7.25a.75.75 0 0 1 0-1.06l7.25-7.25a.75.75 0 0 1 1.06 0Z",
|
||||
|
@ -34,6 +46,17 @@
|
|||
"cloud-outline": "M6.087 9.75a5.752 5.752 0 0 1 11.326 0h.087a4 4 0 0 1 0 8H6a4 4 0 0 1 0-8h.087ZM11.75 6.5a4.25 4.25 0 0 0-4.245 4.037.75.75 0 0 1-.749.713H6a2.5 2.5 0 0 0 0 5h11.5a2.5 2.5 0 0 0 0-5h-.756a.75.75 0 0 1-.75-.713A4.25 4.25 0 0 0 11.75 6.5Z",
|
||||
"code-outline": "m8.066 18.943 6.5-14.5a.75.75 0 0 1 1.404.518l-.036.096-6.5 14.5a.75.75 0 0 1-1.404-.518l.036-.096 6.5-14.5-6.5 14.5ZM2.22 11.47l4.25-4.25a.75.75 0 0 1 1.133.976l-.073.085L3.81 12l3.72 3.719a.75.75 0 0 1-.976 1.133l-.084-.073-4.25-4.25a.75.75 0 0 1-.073-.976l.073-.084 4.25-4.25-4.25 4.25Zm14.25-4.25a.75.75 0 0 1 .976-.073l.084.073 4.25 4.25a.75.75 0 0 1 .073.976l-.073.085-4.25 4.25a.75.75 0 0 1-1.133-.977l.073-.084L20.19 12l-3.72-3.72a.75.75 0 0 1 0-1.06Z",
|
||||
"contact-card-group-outline": "M18.75 4A3.25 3.25 0 0 1 22 7.25v9.505a3.25 3.25 0 0 1-3.25 3.25H5.25A3.25 3.25 0 0 1 2 16.755V7.25a3.25 3.25 0 0 1 3.066-3.245L5.25 4h13.5Zm0 1.5H5.25l-.144.006A1.75 1.75 0 0 0 3.5 7.25v9.505c0 .966.784 1.75 1.75 1.75h13.5a1.75 1.75 0 0 0 1.75-1.75V7.25a1.75 1.75 0 0 0-1.75-1.75Zm-9.497 7a.75.75 0 0 1 .75.75v.582c0 1.272-.969 1.918-2.502 1.918S5 15.104 5 13.831v-.581a.75.75 0 0 1 .75-.75h3.503Zm1.58-.001 1.417.001a.75.75 0 0 1 .75.75v.333c0 .963-.765 1.417-1.875 1.417-.116 0-.229-.005-.337-.015a2.85 2.85 0 0 0 .206-.9l.009-.253v-.582c0-.269-.061-.524-.17-.751Zm4.417.001h3a.75.75 0 0 1 .102 1.493L18.25 14h-3a.75.75 0 0 1-.102-1.493l.102-.007h3-3Zm-7.75-4a1.5 1.5 0 1 1 0 3.001 1.5 1.5 0 0 1 0-3.001Zm3.87.502a1.248 1.248 0 1 1 0 2.496 1.248 1.248 0 0 1 0-2.496Zm3.88.498h3a.75.75 0 0 1 .102 1.493L18.25 11h-3a.75.75 0 0 1-.102-1.493l.102-.007h3-3Z",
|
||||
"copy-outline": [
|
||||
"M8 3a1 1 0 0 0-1 1v.5a.5.5 0 0 1-1 0V4a2 2 0 0 1 2-2h.5a.5.5 0 0 1 0 1H8z",
|
||||
"M7 12a1 1 0 0 0 1 1h.5a.5.5 0 0 1 0 1H8a2 2 0 0 1-2-2v-.5a.5.5 0 0 1 1 0v.5z",
|
||||
"M7 6.5a.5.5 0 0 0-1 0v3a.5.5 0 0 0 1 0v-3z",
|
||||
"M16 3a1 1 0 0 1 1 1v.5a.5.5 0 0 0 1 0V4a2 2 0 0 0-2-2h-.5a.5.5 0 0 0 0 1h.5z",
|
||||
"M16 13a1 1 0 0 0 1-1v-.5a.5.5 0 0 1 1 0v.5a2 2 0 0 1-2 2h-.5a.5.5 0 0 1 0-1h.5z",
|
||||
"M17.5 6a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 1 0v-3a.5.5 0 0 0-.5-.5z",
|
||||
"M10.5 2a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1h-3z",
|
||||
"M10 13.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5z",
|
||||
"M4 6h1v6.5A2.5 2.5 0 0 0 7.5 15H14v1a2 2 0 0 1-2 2H5.5A3.5 3.5 0 0 1 2 14.5V8a2 2 0 0 1 2-2z"
|
||||
],
|
||||
"delete-outline": "M12 1.75a3.25 3.25 0 0 1 3.245 3.066L15.25 5h5.25a.75.75 0 0 1 .102 1.493L20.5 6.5h-.796l-1.28 13.02a2.75 2.75 0 0 1-2.561 2.474l-.176.006H8.313a2.75 2.75 0 0 1-2.714-2.307l-.023-.174L4.295 6.5H3.5a.75.75 0 0 1-.743-.648L2.75 5.75a.75.75 0 0 1 .648-.743L3.5 5h5.25A3.25 3.25 0 0 1 12 1.75Zm6.197 4.75H5.802l1.267 12.872a1.25 1.25 0 0 0 1.117 1.122l.127.006h7.374c.6 0 1.109-.425 1.225-1.002l.02-.126L18.196 6.5ZM13.75 9.25a.75.75 0 0 1 .743.648L14.5 10v7a.75.75 0 0 1-1.493.102L13 17v-7a.75.75 0 0 1 .75-.75Zm-3.5 0a.75.75 0 0 1 .743.648L11 10v7a.75.75 0 0 1-1.493.102L9.5 17v-7a.75.75 0 0 1 .75-.75Zm1.75-6a1.75 1.75 0 0 0-1.744 1.606L10.25 5h3.5A1.75 1.75 0 0 0 12 3.25Z",
|
||||
"dismiss-circle-outline": "M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2Zm0 1.5a8.5 8.5 0 1 0 0 17 8.5 8.5 0 0 0 0-17Zm3.446 4.897.084.073a.75.75 0 0 1 .073.976l-.073.084L13.061 12l2.47 2.47a.75.75 0 0 1 .072.976l-.073.084a.75.75 0 0 1-.976.073l-.084-.073L12 13.061l-2.47 2.47a.75.75 0 0 1-.976.072l-.084-.073a.75.75 0 0 1-.073-.976l.073-.084L10.939 12l-2.47-2.47a.75.75 0 0 1-.072-.976l.073-.084a.75.75 0 0 1 .976-.073l.084.073L12 10.939l2.47-2.47a.75.75 0 0 1 .976-.072Z",
|
||||
"dismiss-outline": "m4.397 4.554.073-.084a.75.75 0 0 1 .976-.073l.084.073L12 10.939l6.47-6.47a.75.75 0 1 1 1.06 1.061L13.061 12l6.47 6.47a.75.75 0 0 1 .072.976l-.073.084a.75.75 0 0 1-.976.073l-.084-.073L12 13.061l-6.47 6.47a.75.75 0 0 1-1.06-1.061L10.939 12l-6.47-6.47a.75.75 0 0 1-.072-.976l.073-.084-.073.084Z",
|
||||
|
@ -80,6 +103,7 @@
|
|||
"sound-source-outline": "M3.5 12a8.5 8.5 0 1 1 14.762 5.748l.992 1.135A9.966 9.966 0 0 0 22 12c0-5.523-4.477-10-10-10S2 6.477 2 12a9.966 9.966 0 0 0 2.746 6.883l.993-1.134A8.47 8.47 0 0 1 3.5 12Z M19.25 12.125a7.098 7.098 0 0 1-1.783 4.715l-.998-1.14a5.625 5.625 0 1 0-8.806-.15l-1.004 1.146a7.125 7.125 0 1 1 12.59-4.571Z M16.25 12a4.23 4.23 0 0 1-.821 2.511l-1.026-1.172a2.75 2.75 0 1 0-4.806 0L8.571 14.51A4.25 4.25 0 1 1 16.25 12Z M12.564 12.756a.75.75 0 0 0-1.128 0l-7 8A.75.75 0 0 0 5 22h14a.75.75 0 0 0 .564-1.244l-7-8Zm4.783 7.744H6.653L12 14.389l5.347 6.111Z",
|
||||
"speaker-1-outline": "M14.704 3.442c.191.226.296.512.296.808v15.502a1.25 1.25 0 0 1-2.058.954L7.975 16.5H4.25A2.25 2.25 0 0 1 2 14.25v-4.5A2.25 2.25 0 0 1 4.25 7.5h3.725l4.968-4.204a1.25 1.25 0 0 1 1.761.147ZM13.5 4.79 8.525 9H4.25a.75.75 0 0 0-.75.75v4.5c0 .415.336.75.75.75h4.275l4.975 4.213V4.79Zm3.604 3.851a.75.75 0 0 1 1.03.25c.574.94.862 1.992.862 3.14 0 1.149-.288 2.201-.862 3.141a.75.75 0 1 1-1.28-.781c.428-.702.642-1.483.642-2.36 0-.876-.214-1.657-.642-2.359a.75.75 0 0 1 .25-1.03Z",
|
||||
"speaker-mute-outline": "M12.92 3.316c.806-.717 2.08-.145 2.08.934v15.496c0 1.078-1.274 1.65-2.08.934l-4.492-3.994a.75.75 0 0 0-.498-.19H4.25A2.25 2.25 0 0 1 2 14.247V9.75a2.25 2.25 0 0 1 2.25-2.25h3.68a.75.75 0 0 0 .498-.19l4.491-3.993Zm.58 1.49L9.425 8.43A2.25 2.25 0 0 1 7.93 9H4.25a.75.75 0 0 0-.75.75v4.497c0 .415.336.75.75.75h3.68a2.25 2.25 0 0 1 1.495.57l4.075 3.623V4.807ZM16.22 9.22a.75.75 0 0 1 1.06 0L19 10.94l1.72-1.72a.75.75 0 1 1 1.06 1.06L20.06 12l1.72 1.72a.75.75 0 1 1-1.06 1.06L19 13.06l-1.72 1.72a.75.75 0 1 1-1.06-1.06L17.94 12l-1.72-1.72a.75.75 0 0 1 0-1.06Z",
|
||||
"square-outline": "M3 6a3 3 0 0 1 3-3h8a3 3 0 0 1 3 3v8a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3V6zm3-2a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H6z",
|
||||
"star-emphasis-outline": "M13.209 3.103c-.495-1.004-1.926-1.004-2.421 0L8.43 7.88l-5.273.766c-1.107.161-1.55 1.522-.748 2.303l3.815 3.72-.9 5.25c-.19 1.103.968 1.944 1.959 1.424l4.715-2.48 4.716 2.48c.99.52 2.148-.32 1.96-1.424l-.902-5.25 3.816-3.72c.8-.78.359-2.142-.748-2.303l-5.273-.766-2.358-4.777ZM9.74 8.615l2.258-4.576 2.259 4.576a1.35 1.35 0 0 0 1.016.738l5.05.734-3.654 3.562a1.35 1.35 0 0 0-.388 1.195l.862 5.03-4.516-2.375a1.35 1.35 0 0 0-1.257 0l-4.516 2.374.862-5.029a1.35 1.35 0 0 0-.388-1.195l-3.654-3.562 5.05-.734c.44-.063.82-.34 1.016-.738ZM1.164 3.782a.75.75 0 0 0 .118 1.054l2.5 2a.75.75 0 1 0 .937-1.172l-2.5-2a.75.75 0 0 0-1.055.118Z M22.836 18.218a.75.75 0 0 0-.117-1.054l-2.5-2a.75.75 0 0 0-.938 1.172l2.5 2a.75.75 0 0 0 1.055-.117ZM1.282 17.164a.75.75 0 1 0 .937 1.172l2.5-2a.75.75 0 0 0-.937-1.172l-2.5 2ZM22.836 3.782a.75.75 0 0 1-.117 1.054l-2.5 2a.75.75 0 0 1-.938-1.172l2.5-2a.75.75 0 0 1 1.055.118Z",
|
||||
"subtract-outline": "M3.997 13H20a1 1 0 1 0 0-2H3.997a1 1 0 1 0 0 2Z",
|
||||
"tag-outline": "M19.75 2A2.25 2.25 0 0 1 22 4.25v5.462a3.25 3.25 0 0 1-.952 2.298l-8.5 8.503a3.255 3.255 0 0 1-4.597.001L3.489 16.06a3.25 3.25 0 0 1-.003-4.596l8.5-8.51A3.25 3.25 0 0 1 14.284 2h5.465Zm0 1.5h-5.465c-.465 0-.91.185-1.239.513l-8.512 8.523a1.75 1.75 0 0 0 .015 2.462l4.461 4.454a1.755 1.755 0 0 0 2.477 0l8.5-8.503a1.75 1.75 0 0 0 .513-1.237V4.25a.75.75 0 0 0-.75-.75ZM17 5.502a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3Z",
|
||||
|
@ -87,7 +111,6 @@
|
|||
"video-outline": "M13.75 4.5A3.25 3.25 0 0 1 17 7.75v.173l3.864-2.318A.75.75 0 0 1 22 6.248V17.75a.75.75 0 0 1-1.136.643L17 16.075v.175a3.25 3.25 0 0 1-3.25 3.25h-8.5A3.25 3.25 0 0 1 2 16.25v-8.5A3.25 3.25 0 0 1 5.25 4.5h8.5Zm0 1.5h-8.5A1.75 1.75 0 0 0 3.5 7.75v8.5c0 .966.784 1.75 1.75 1.75h8.5a1.75 1.75 0 0 0 1.75-1.75v-8.5A1.75 1.75 0 0 0 13.75 6Zm6.75 1.573L17 9.674v4.651l3.5 2.1V7.573Z",
|
||||
"warning-outline": "M10.91 2.782a2.25 2.25 0 0 1 2.975.74l.083.138 7.759 14.009a2.25 2.25 0 0 1-1.814 3.334l-.154.006H4.243a2.25 2.25 0 0 1-2.041-3.197l.072-.143L10.031 3.66a2.25 2.25 0 0 1 .878-.878Zm9.505 15.613-7.76-14.008a.75.75 0 0 0-1.254-.088l-.057.088-7.757 14.008a.75.75 0 0 0 .561 1.108l.095.006h15.516a.75.75 0 0 0 .696-1.028l-.04-.086-7.76-14.008 7.76 14.008ZM12 16.002a.999.999 0 1 1 0 1.997.999.999 0 0 1 0-1.997ZM11.995 8.5a.75.75 0 0 1 .744.647l.007.102.004 4.502a.75.75 0 0 1-1.494.103l-.006-.102-.004-4.502a.75.75 0 0 1 .75-.75Z",
|
||||
"wifi-off-outline": "m12.858 14.273 7.434 7.434a1 1 0 0 0 1.414-1.414l-17.999-18a1 1 0 1 0-1.414 1.414L5.39 6.804c-.643.429-1.254.927-1.821 1.495a12.382 12.382 0 0 0-1.39 1.683 1 1 0 0 0 1.644 1.14c.363-.524.761-1.01 1.16-1.41a9.94 9.94 0 0 1 1.855-1.46L7.99 9.405a8.14 8.14 0 0 0-3.203 3.377 1 1 0 0 0 1.784.903 6.08 6.08 0 0 1 1.133-1.563 6.116 6.116 0 0 1 1.77-1.234l1.407 1.407A5.208 5.208 0 0 0 8.336 13.7a5.25 5.25 0 0 0-1.09 1.612 1 1 0 0 0 1.832.802c.167-.381.394-.722.672-1a3.23 3.23 0 0 1 3.108-.841Zm-1.332-5.93 2.228 2.229a6.1 6.1 0 0 1 2.616 1.55c.444.444.837.995 1.137 1.582a1 1 0 1 0 1.78-.911 8.353 8.353 0 0 0-1.503-2.085 8.108 8.108 0 0 0-6.258-2.365ZM8.51 5.327l1.651 1.651a9.904 9.904 0 0 1 10.016 4.148 1 1 0 1 0 1.646-1.136A11.912 11.912 0 0 0 8.51 5.327Zm4.552 11.114a1.501 1.501 0 1 1-2.123 2.123 1.501 1.501 0 0 1 2.123-2.123Z",
|
||||
|
||||
"brand-facebook-outline": "M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z",
|
||||
"brand-line-outline": "M19.365 9.863c.349 0 .63.285.63.631 0 .345-.281.63-.63.63H17.61v1.125h1.755c.349 0 .63.283.63.63 0 .344-.281.629-.63.629h-2.386c-.345 0-.627-.285-.627-.629V8.108c0-.345.282-.63.63-.63h2.386c.346 0 .627.285.627.63 0 .349-.281.63-.63.63H17.61v1.125h1.755zm-3.855 3.016c0 .27-.174.51-.432.596-.064.021-.133.031-.199.031-.211 0-.391-.09-.51-.25l-2.443-3.317v2.94c0 .344-.279.629-.631.629-.346 0-.626-.285-.626-.629V8.108c0-.27.173-.51.43-.595.06-.023.136-.033.194-.033.195 0 .375.104.495.254l2.462 3.33V8.108c0-.345.282-.63.63-.63.345 0 .63.285.63.63v4.771zm-5.741 0c0 .344-.282.629-.631.629-.345 0-.627-.285-.627-.629V8.108c0-.345.282-.63.63-.63.346 0 .628.285.628.63v4.771zm-2.466.629H4.917c-.345 0-.63-.285-.63-.629V8.108c0-.345.285-.63.63-.63.348 0 .63.285.63.63v4.141h1.756c.348 0 .629.283.629.63 0 .344-.282.629-.629.629M24 10.314C24 4.943 18.615.572 12 .572S0 4.943 0 10.314c0 4.811 4.27 8.842 10.035 9.608.391.082.923.258 1.058.59.12.301.079.766.038 1.08l-.164 1.02c-.045.301-.24 1.186 1.049.645 1.291-.539 6.916-4.078 9.436-6.975C23.176 14.393 24 12.458 24 10.314",
|
||||
"brand-linkedin-outline": "M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z",
|
||||
|
@ -95,7 +118,6 @@
|
|||
"brand-telegram-outline": "M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z",
|
||||
"brand-twitter-outline": "M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z",
|
||||
"brand-whatsapp-outline": "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413Z",
|
||||
|
||||
"add-solid": "M11.883 3.007 12 3a1 1 0 0 1 .993.883L13 4v7h7a1 1 0 0 1 .993.883L21 12a1 1 0 0 1-.883.993L20 13h-7v7a1 1 0 0 1-.883.993L12 21a1 1 0 0 1-.993-.883L11 20v-7H4a1 1 0 0 1-.993-.883L3 12a1 1 0 0 1 .883-.993L4 11h7V4a1 1 0 0 1 .883-.993L12 3l-.117.007Z",
|
||||
"subtract-solid": "M3.997 13H20a1 1 0 1 0 0-2H3.997a1 1 0 1 0 0 2Z"
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class AutomationRuleListener < BaseListener
|
|||
return unless rule_present?('conversation_created', conversation)
|
||||
|
||||
@rules.each do |rule|
|
||||
conditions_match = ::AutomationRule::ConditionsFilterService.new(rule, conversation).perform
|
||||
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform
|
||||
::AutomationRules::ActionService.new(rule, conversation).perform if conditions_match.present?
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue