# Pull Request Template ## Description This PR includes: 1. Removes multiselect usage from the Merge Contact modal (Conversation sidebar) and replaces it with the existing component used on the Contact Details page. 2. Replaces legacy form and multiselect elements in Add and Edit automations flows with next components.**(Also check Macros)** 3. Replace multiselect with ComboBox in contact form country field. 4. Replace multiselect with TagInput in create/edit attribute form. 5. Replace multiselect with TagInput for agent selection in inbox creation. 6. Replace multiselect with ComboBox in Facebook channel page selection ## Type of change - [x] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? **Screenshots** 1. **Merge modal** <img width="741" height="449" alt="image" src="https://github.com/user-attachments/assets/a05a96ec-0692-4d94-9e27-d3e85fd143e4" /> <img width="741" height="449" alt="image" src="https://github.com/user-attachments/assets/fc1dc977-689d-4440-869d-2124e4ca9083" /> 2. **Automations** <img width="849" height="1089" alt="image" src="https://github.com/user-attachments/assets/b0155f06-ab21-4f90-a2c8-5bfbd97b08f7" /> <img width="813" height="879" alt="image" src="https://github.com/user-attachments/assets/0921ac4a-88f5-49ac-a776-cc02941b479c" /> <img width="849" height="826" alt="image" src="https://github.com/user-attachments/assets/44358dae-a076-4e10-b7ba-a4e40ccd817f" /> 3. **Country field** <img width="462" height="483" alt="image" src="https://github.com/user-attachments/assets/d5db9aa1-b859-4327-9960-957d7091678f" /> 4. **Add/Edit attribute form** <img width="619" height="646" alt="image" src="https://github.com/user-attachments/assets/6ab2ea94-73e5-40b8-ac29-399c0543fa7b" /> <img width="619" height="646" alt="image" src="https://github.com/user-attachments/assets/b4c5bb0e-baa0-4ef7-a6a2-adb0f0203243" /> <img width="635" height="731" alt="image" src="https://github.com/user-attachments/assets/74890c80-b213-4567-bf5f-4789dda39d2d" /> 5. **Agent selection in inbox creation** <img width="635" height="534" alt="image" src="https://github.com/user-attachments/assets/0003bad1-1a75-4f20-b014-587e1c19a620" /> <img width="809" height="602" alt="image" src="https://github.com/user-attachments/assets/5e7ab635-7340-420a-a191-e6cd49c02704" /> 7. **Facebook channel page selection** <img width="597" height="444" alt="image" src="https://github.com/user-attachments/assets/f7ec8d84-0a7d-4bc6-92a1-a1365178e319" /> <img width="597" height="444" alt="image" src="https://github.com/user-attachments/assets/d0596c4d-94c1-4544-8b50-e7103ff207a6" /> <img width="597" height="444" alt="image" src="https://github.com/user-attachments/assets/be097921-011b-4dbe-b5f1-5d1306e25349" /> ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
210 lines
5.8 KiB
JavaScript
210 lines
5.8 KiB
JavaScript
import { ref, reactive, computed } from 'vue';
|
|
import { useStoreGetters } from 'dashboard/composables/store';
|
|
import { useAlert } from 'dashboard/composables';
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
import {
|
|
generateCustomAttributeTypes,
|
|
getDefaultConditions,
|
|
getDefaultActions,
|
|
generateCustomAttributes,
|
|
} from 'dashboard/helper/automationHelper';
|
|
import useAutomationValues from './useAutomationValues';
|
|
|
|
import {
|
|
// AUTOMATION_RULE_EVENTS,
|
|
// AUTOMATION_ACTION_TYPES,
|
|
AUTOMATIONS,
|
|
} from 'dashboard/routes/dashboard/settings/automation/constants.js';
|
|
|
|
/**
|
|
* Composable for handling automation-related functionality.
|
|
* @returns {Object} An object containing various automation-related functions and computed properties.
|
|
*/
|
|
export function useAutomation(startValue = null) {
|
|
const getters = useStoreGetters();
|
|
const { t } = useI18n();
|
|
|
|
const {
|
|
booleanFilterOptions,
|
|
statusFilterOptions,
|
|
getConditionDropdownValues,
|
|
getActionDropdownValues,
|
|
agents,
|
|
campaigns,
|
|
contacts,
|
|
inboxes,
|
|
labels,
|
|
teams,
|
|
slaPolicies,
|
|
} = useAutomationValues();
|
|
|
|
const automation = ref(startValue);
|
|
const automationTypes = reactive(structuredClone(AUTOMATIONS));
|
|
const eventName = computed(() => automation.value?.event_name);
|
|
|
|
/**
|
|
* Handles the event change for an automation.value.
|
|
*/
|
|
const onEventChange = () => {
|
|
automation.value.conditions = getDefaultConditions(eventName.value);
|
|
automation.value.actions = getDefaultActions();
|
|
};
|
|
|
|
/**
|
|
* Appends a new condition to the automation.value.
|
|
*/
|
|
const appendNewCondition = () => {
|
|
const defaultCondition = getDefaultConditions(eventName.value);
|
|
automation.value.conditions = [
|
|
...automation.value.conditions,
|
|
...defaultCondition,
|
|
];
|
|
};
|
|
|
|
/**
|
|
* Appends a new action to the automation.value.
|
|
*/
|
|
const appendNewAction = () => {
|
|
const defaultAction = getDefaultActions();
|
|
automation.value.actions = [...automation.value.actions, ...defaultAction];
|
|
};
|
|
|
|
/**
|
|
* Removes a filter from the automation.value.
|
|
* @param {number} index - The index of the filter to remove.
|
|
*/
|
|
const removeFilter = index => {
|
|
if (automation.value.conditions.length <= 1) {
|
|
useAlert(t('AUTOMATION.CONDITION.DELETE_MESSAGE'));
|
|
} else {
|
|
automation.value.conditions = automation.value.conditions.filter(
|
|
(_, i) => i !== index
|
|
);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Removes an action from the automation.value.
|
|
* @param {number} index - The index of the action to remove.
|
|
*/
|
|
const removeAction = index => {
|
|
if (automation.value.actions.length <= 1) {
|
|
useAlert(t('AUTOMATION.ACTION.DELETE_MESSAGE'));
|
|
} else {
|
|
automation.value.actions = automation.value.actions.filter(
|
|
(_, i) => i !== index
|
|
);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Resets a filter in the automation.value.
|
|
* @param {Object} automationTypes - The automation types object.
|
|
* @param {number} index - The index of the filter to reset.
|
|
* @param {Object} currentCondition - The current condition object.
|
|
*/
|
|
const resetFilter = (index, currentCondition) => {
|
|
const newConditions = [...automation.value.conditions];
|
|
|
|
newConditions[index] = {
|
|
...newConditions[index],
|
|
filter_operator: automationTypes[eventName.value].conditions.find(
|
|
condition => condition.key === currentCondition.attribute_key
|
|
).filterOperators[0].value,
|
|
values: '',
|
|
};
|
|
|
|
automation.value.conditions = newConditions;
|
|
};
|
|
|
|
/**
|
|
* Resets an action in the automation.value.
|
|
* @param {number} index - The index of the action to reset.
|
|
*/
|
|
const resetAction = index => {
|
|
const newActions = [...automation.value.actions];
|
|
newActions[index] = {
|
|
...newActions[index],
|
|
action_params: [],
|
|
};
|
|
|
|
automation.value.actions = newActions;
|
|
};
|
|
|
|
/**
|
|
* This function formats the custom attributes for automation types.
|
|
* It retrieves custom attributes for conversations and contacts,
|
|
* generates custom attribute types, and adds them to the relevant automation types.
|
|
*/
|
|
const manifestCustomAttributes = () => {
|
|
const conversationCustomAttributesRaw = getters[
|
|
'attributes/getAttributesByModel'
|
|
].value('conversation_attribute');
|
|
const contactCustomAttributesRaw =
|
|
getters['attributes/getAttributesByModel'].value('contact_attribute');
|
|
|
|
const conversationCustomAttributeTypes = generateCustomAttributeTypes(
|
|
conversationCustomAttributesRaw,
|
|
'conversation_attribute'
|
|
);
|
|
const contactCustomAttributeTypes = generateCustomAttributeTypes(
|
|
contactCustomAttributesRaw,
|
|
'contact_attribute'
|
|
);
|
|
|
|
const manifestedCustomAttributes = generateCustomAttributes(
|
|
conversationCustomAttributeTypes,
|
|
contactCustomAttributeTypes,
|
|
t('AUTOMATION.CONDITION.CONVERSATION_CUSTOM_ATTR_LABEL'),
|
|
t('AUTOMATION.CONDITION.CONTACT_CUSTOM_ATTR_LABEL')
|
|
);
|
|
|
|
const CUSTOM_ATTR_HEADER_KEYS = new Set([
|
|
'conversation_custom_attribute',
|
|
'contact_custom_attribute',
|
|
]);
|
|
|
|
[
|
|
'message_created',
|
|
'conversation_created',
|
|
'conversation_updated',
|
|
'conversation_opened',
|
|
].forEach(eventToUpdate => {
|
|
const standardConditions = automationTypes[
|
|
eventToUpdate
|
|
].conditions.filter(
|
|
c => !c.customAttributeType && !CUSTOM_ATTR_HEADER_KEYS.has(c.key)
|
|
);
|
|
automationTypes[eventToUpdate].conditions = [
|
|
...standardConditions,
|
|
...manifestedCustomAttributes,
|
|
];
|
|
});
|
|
};
|
|
|
|
return {
|
|
automation,
|
|
automationTypes,
|
|
agents,
|
|
campaigns,
|
|
contacts,
|
|
inboxes,
|
|
labels,
|
|
teams,
|
|
slaPolicies,
|
|
booleanFilterOptions,
|
|
statusFilterOptions,
|
|
onEventChange,
|
|
getConditionDropdownValues,
|
|
appendNewCondition,
|
|
appendNewAction,
|
|
removeFilter,
|
|
removeAction,
|
|
resetFilter,
|
|
resetAction,
|
|
getActionDropdownValues,
|
|
manifestCustomAttributes,
|
|
};
|
|
}
|