Merge branch 'develop' into fix/CW-3385
This commit is contained in:
@@ -2,11 +2,10 @@
|
||||
import { useVuelidate } from '@vuelidate/core';
|
||||
import { useAlert } from 'dashboard/composables';
|
||||
import { required, minLength } from '@vuelidate/validators';
|
||||
import { getRegexp } from 'shared/helpers/Validators';
|
||||
import { ATTRIBUTE_TYPES } from './constants';
|
||||
import customAttributeMixin from '../../../../mixins/customAttributeMixin';
|
||||
export default {
|
||||
components: {},
|
||||
mixins: [customAttributeMixin],
|
||||
props: {
|
||||
selectedAttribute: {
|
||||
type: Object,
|
||||
@@ -116,7 +115,7 @@ export default {
|
||||
},
|
||||
setFormValues() {
|
||||
const regexPattern = this.selectedAttribute.regex_pattern
|
||||
? this.getRegexp(this.selectedAttribute.regex_pattern).source
|
||||
? getRegexp(this.selectedAttribute.regex_pattern).source
|
||||
: null;
|
||||
this.displayName = this.selectedAttribute.attribute_display_name;
|
||||
this.description = this.selectedAttribute.attribute_description;
|
||||
|
||||
@@ -1,126 +1,123 @@
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, computed, watch, provide } from 'vue';
|
||||
import { useRoute, useRouter } from 'dashboard/composables/route';
|
||||
import { useI18n } from 'dashboard/composables/useI18n';
|
||||
import { useStore, useStoreGetters } from 'dashboard/composables/store';
|
||||
import MacroForm from './MacroForm.vue';
|
||||
import { MACRO_ACTION_TYPES } from './constants';
|
||||
import { mapGetters } from 'vuex';
|
||||
import { useAlert } from 'dashboard/composables';
|
||||
import actionQueryGenerator from 'dashboard/helper/actionQueryGenerator.js';
|
||||
import macrosMixin from 'dashboard/mixins/macrosMixin';
|
||||
import { useMacros } from 'dashboard/composables/useMacros';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MacroForm,
|
||||
},
|
||||
mixins: [macrosMixin],
|
||||
provide() {
|
||||
return {
|
||||
macroActionTypes: this.macroActionTypes,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
macro: null,
|
||||
mode: 'CREATE',
|
||||
macroActionTypes: MACRO_ACTION_TYPES,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
uiFlags: 'macros/getUIFlags',
|
||||
}),
|
||||
macroId() {
|
||||
return this.$route.params.macroId;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler() {
|
||||
this.fetchDropdownData();
|
||||
if (this.$route.params.macroId) {
|
||||
this.fetchMacro();
|
||||
} else {
|
||||
this.initNewMacro();
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
fetchDropdownData() {
|
||||
this.$store.dispatch('agents/get');
|
||||
this.$store.dispatch('teams/get');
|
||||
this.$store.dispatch('labels/get');
|
||||
},
|
||||
fetchMacro() {
|
||||
this.mode = 'EDIT';
|
||||
this.manifestMacro();
|
||||
},
|
||||
async manifestMacro() {
|
||||
await this.$store.dispatch('macros/getSingleMacro', this.macroId);
|
||||
const singleMacro = this.$store.getters['macros/getMacro'](this.macroId);
|
||||
this.macro = this.formatMacro(singleMacro);
|
||||
},
|
||||
formatMacro(macro) {
|
||||
const formattedActions = macro.actions.map(action => {
|
||||
let actionParams = [];
|
||||
if (action.action_params.length) {
|
||||
const inputType = this.macroActionTypes.find(
|
||||
item => item.key === action.action_name
|
||||
).inputType;
|
||||
if (inputType === 'multi_select' || inputType === 'search_select') {
|
||||
actionParams = [
|
||||
...this.getDropdownValues(action.action_name, this.$store),
|
||||
].filter(item => [...action.action_params].includes(item.id));
|
||||
} else if (inputType === 'team_message') {
|
||||
actionParams = {
|
||||
team_ids: [
|
||||
...this.getDropdownValues(action.action_name, this.$store),
|
||||
].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,
|
||||
const store = useStore();
|
||||
const getters = useStoreGetters();
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const { getMacroDropdownValues } = useMacros();
|
||||
|
||||
const macro = ref(null);
|
||||
const mode = ref('CREATE');
|
||||
const macroActionTypes = MACRO_ACTION_TYPES;
|
||||
|
||||
provide('macroActionTypes', macroActionTypes);
|
||||
|
||||
const uiFlags = computed(() => getters['macros/getUIFlags'].value);
|
||||
const macroId = computed(() => route.params.macroId);
|
||||
|
||||
const fetchDropdownData = () => {
|
||||
store.dispatch('agents/get');
|
||||
store.dispatch('teams/get');
|
||||
store.dispatch('labels/get');
|
||||
};
|
||||
|
||||
const formatMacro = macroData => {
|
||||
const formattedActions = macroData.actions.map(action => {
|
||||
let actionParams = [];
|
||||
if (action.action_params.length) {
|
||||
const inputType = macroActionTypes.find(
|
||||
item => item.key === action.action_name
|
||||
).inputType;
|
||||
if (inputType === 'multi_select' || inputType === 'search_select') {
|
||||
actionParams = getMacroDropdownValues(action.action_name).filter(item =>
|
||||
[...action.action_params].includes(item.id)
|
||||
);
|
||||
} else if (inputType === 'team_message') {
|
||||
actionParams = {
|
||||
team_ids: getMacroDropdownValues(action.action_name).filter(item =>
|
||||
[...action.action_params[0].team_ids].includes(item.id)
|
||||
),
|
||||
message: action.action_params[0].message,
|
||||
};
|
||||
});
|
||||
return {
|
||||
...macro,
|
||||
actions: formattedActions,
|
||||
};
|
||||
},
|
||||
initNewMacro() {
|
||||
this.mode = 'CREATE';
|
||||
this.macro = {
|
||||
name: '',
|
||||
actions: [
|
||||
{
|
||||
action_name: 'assign_team',
|
||||
action_params: [],
|
||||
},
|
||||
],
|
||||
visibility: 'global',
|
||||
};
|
||||
},
|
||||
async saveMacro(macro) {
|
||||
try {
|
||||
const action = this.mode === 'EDIT' ? 'macros/update' : 'macros/create';
|
||||
let successMessage =
|
||||
this.mode === 'EDIT'
|
||||
? this.$t('MACROS.EDIT.API.SUCCESS_MESSAGE')
|
||||
: this.$t('MACROS.ADD.API.SUCCESS_MESSAGE');
|
||||
let serializedMacro = JSON.parse(JSON.stringify(macro));
|
||||
serializedMacro.actions = actionQueryGenerator(serializedMacro.actions);
|
||||
await this.$store.dispatch(action, serializedMacro);
|
||||
useAlert(successMessage);
|
||||
this.$router.push({ name: 'macros_wrapper' });
|
||||
} catch (error) {
|
||||
useAlert(this.$t('MACROS.ERROR'));
|
||||
}
|
||||
},
|
||||
} else actionParams = [...action.action_params];
|
||||
}
|
||||
return {
|
||||
...action,
|
||||
action_params: actionParams,
|
||||
};
|
||||
});
|
||||
return {
|
||||
...macroData,
|
||||
actions: formattedActions,
|
||||
};
|
||||
};
|
||||
|
||||
const manifestMacro = async () => {
|
||||
await store.dispatch('macros/getSingleMacro', macroId.value);
|
||||
const singleMacro = store.getters['macros/getMacro'](macroId.value);
|
||||
macro.value = formatMacro(singleMacro);
|
||||
};
|
||||
|
||||
const fetchMacro = () => {
|
||||
mode.value = 'EDIT';
|
||||
manifestMacro();
|
||||
};
|
||||
|
||||
const initNewMacro = () => {
|
||||
mode.value = 'CREATE';
|
||||
macro.value = {
|
||||
name: '',
|
||||
actions: [
|
||||
{
|
||||
action_name: 'assign_team',
|
||||
action_params: [],
|
||||
},
|
||||
],
|
||||
visibility: 'global',
|
||||
};
|
||||
};
|
||||
|
||||
watch(
|
||||
() => route,
|
||||
() => {
|
||||
fetchDropdownData();
|
||||
if (route.params.macroId) {
|
||||
fetchMacro();
|
||||
} else {
|
||||
initNewMacro();
|
||||
}
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
|
||||
const saveMacro = async macroData => {
|
||||
try {
|
||||
const action = mode.value === 'EDIT' ? 'macros/update' : 'macros/create';
|
||||
const successMessage =
|
||||
mode.value === 'EDIT'
|
||||
? t('MACROS.EDIT.API.SUCCESS_MESSAGE')
|
||||
: t('MACROS.ADD.API.SUCCESS_MESSAGE');
|
||||
let serializedMacro = JSON.parse(JSON.stringify(macroData));
|
||||
serializedMacro.actions = actionQueryGenerator(serializedMacro.actions);
|
||||
await store.dispatch(action, serializedMacro);
|
||||
useAlert(successMessage);
|
||||
router.push({ name: 'macros_wrapper' });
|
||||
} catch (error) {
|
||||
useAlert(t('MACROS.ERROR'));
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -128,11 +125,12 @@ export default {
|
||||
<div class="flex flex-col flex-1 h-full overflow-auto">
|
||||
<woot-loading-state
|
||||
v-if="uiFlags.isFetchingItem"
|
||||
:message="$t('MACROS.EDITOR.LOADING')"
|
||||
:message="t('MACROS.EDITOR.LOADING')"
|
||||
/>
|
||||
<MacroForm
|
||||
v-if="macro && !uiFlags.isFetchingItem"
|
||||
:macro-data.sync="macro"
|
||||
:macro-data="macro"
|
||||
@update:macro-data="macro = $event"
|
||||
@submit="saveMacro"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,84 +1,80 @@
|
||||
<script>
|
||||
import { inject } from 'vue';
|
||||
<script setup>
|
||||
import { computed, inject } from 'vue';
|
||||
import { useMacros } from 'dashboard/composables/useMacros';
|
||||
import { useI18n } from 'dashboard/composables/useI18n';
|
||||
import ActionInput from 'dashboard/components/widgets/AutomationActionInput.vue';
|
||||
import macrosMixin from 'dashboard/mixins/macrosMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ActionInput,
|
||||
const props = defineProps({
|
||||
singleNode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
mixins: [macrosMixin],
|
||||
props: {
|
||||
singleNode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
errorKey: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
fileName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
setup() {
|
||||
const macroActionTypes = inject('macroActionTypes');
|
||||
return { macroActionTypes };
|
||||
errorKey: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
computed: {
|
||||
actionData: {
|
||||
get() {
|
||||
return this.value;
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('input', value);
|
||||
},
|
||||
},
|
||||
errorMessage() {
|
||||
if (!this.errorKey) return '';
|
||||
fileName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
return this.$t(`MACROS.ERRORS.${this.errorKey}`);
|
||||
},
|
||||
showActionInput() {
|
||||
if (
|
||||
this.actionData.action_name === 'send_email_to_team' ||
|
||||
this.actionData.action_name === 'send_message'
|
||||
)
|
||||
return false;
|
||||
const type = this.macroActionTypes.find(
|
||||
action => action.key === this.actionData.action_name
|
||||
).inputType;
|
||||
return !!type;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
dropdownValues() {
|
||||
return this.getDropdownValues(this.value.action_name, this.$store);
|
||||
},
|
||||
},
|
||||
const emit = defineEmits(['input', 'resetAction', 'deleteNode']);
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const macroActionTypes = inject('macroActionTypes');
|
||||
|
||||
const { getMacroDropdownValues } = useMacros();
|
||||
|
||||
const actionData = computed({
|
||||
get: () => props.value,
|
||||
set: value => emit('input', value),
|
||||
});
|
||||
|
||||
const errorMessage = computed(() => {
|
||||
if (!props.errorKey) return '';
|
||||
return t(`MACROS.ERRORS.${props.errorKey}`);
|
||||
});
|
||||
|
||||
const showActionInput = computed(() => {
|
||||
if (
|
||||
actionData.value.action_name === 'send_email_to_team' ||
|
||||
actionData.value.action_name === 'send_message'
|
||||
)
|
||||
return false;
|
||||
const type = macroActionTypes.find(
|
||||
action => action.key === actionData.value.action_name
|
||||
).inputType;
|
||||
return !!type;
|
||||
});
|
||||
|
||||
const dropdownValues = () => {
|
||||
return getMacroDropdownValues(props.value.action_name);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="macro__node-action-container">
|
||||
<div class="relative flex items-center w-full min-w-0 basis-full">
|
||||
<woot-button
|
||||
v-if="!singleNode"
|
||||
size="small"
|
||||
variant="clear"
|
||||
color-scheme="secondary"
|
||||
icon="navigation"
|
||||
class="macros__node-drag-handle"
|
||||
class="absolute cursor-move -left-8 macros__node-drag-handle"
|
||||
/>
|
||||
<div
|
||||
class="macro__node-action-item"
|
||||
:class="{
|
||||
'has-error': errorKey,
|
||||
}"
|
||||
class="flex-grow p-2 mr-2 rounded-md shadow-sm"
|
||||
:class="
|
||||
errorKey
|
||||
? 'bg-red-50 animate-shake dark:bg-red-800'
|
||||
: 'bg-white dark:bg-slate-700'
|
||||
"
|
||||
>
|
||||
<ActionInput
|
||||
v-model="actionData"
|
||||
@@ -103,39 +99,3 @@ export default {
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.macros__node-drag-handle {
|
||||
@apply cursor-move -left-8 absolute;
|
||||
}
|
||||
.macro__node-action-container {
|
||||
@apply w-full min-w-0 basis-full items-center flex relative;
|
||||
|
||||
.macro__node-action-item {
|
||||
@apply flex-grow bg-white dark:bg-slate-700 p-2 mr-2 rounded-md shadow-sm;
|
||||
|
||||
&.has-error {
|
||||
animation: shake 0.3s ease-in-out 0s 2;
|
||||
@apply bg-red-50 dark:bg-red-800;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
25% {
|
||||
transform: translateX(0.234375rem);
|
||||
}
|
||||
50% {
|
||||
transform: translateX(-0.234375rem);
|
||||
}
|
||||
75% {
|
||||
transform: translateX(0.234375rem);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user