Refactor markup and specs
This commit is contained in:
parent
56bb2a9121
commit
47d8c9335d
11 changed files with 267 additions and 101 deletions
71
app/javascript/dashboard/helper/specs/macrosFixtures.js
Normal file
71
app/javascript/dashboard/helper/specs/macrosFixtures.js
Normal file
|
@ -0,0 +1,71 @@
|
|||
export const teams = [
|
||||
{
|
||||
id: 1,
|
||||
name: '⚙️ sales team',
|
||||
description: 'This is our internal sales team',
|
||||
allow_auto_assign: true,
|
||||
account_id: 1,
|
||||
is_member: true,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '🤷♂️ fayaz',
|
||||
description: 'Test',
|
||||
allow_auto_assign: true,
|
||||
account_id: 1,
|
||||
is_member: true,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '🇮🇳 apac sales',
|
||||
description: 'Sales team for France Territory',
|
||||
allow_auto_assign: true,
|
||||
account_id: 1,
|
||||
is_member: true,
|
||||
},
|
||||
];
|
||||
|
||||
export const labels = [
|
||||
{
|
||||
id: 6,
|
||||
title: 'sales',
|
||||
description: 'sales team',
|
||||
color: '#8EA20F',
|
||||
show_on_sidebar: true,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'billing',
|
||||
description: 'billing',
|
||||
color: '#4077DA',
|
||||
show_on_sidebar: true,
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
title: 'snoozed',
|
||||
description: 'Items marked for later',
|
||||
color: '#D12F42',
|
||||
show_on_sidebar: true,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: 'mobile-app',
|
||||
description: 'tech team',
|
||||
color: '#2DB1CC',
|
||||
show_on_sidebar: true,
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
title: 'human-resources-department-with-long-title',
|
||||
description: 'Test',
|
||||
color: '#FF6E09',
|
||||
show_on_sidebar: true,
|
||||
},
|
||||
{
|
||||
id: 22,
|
||||
title: 'priority',
|
||||
description: 'For important sales leads',
|
||||
color: '#7E7CED',
|
||||
show_on_sidebar: true,
|
||||
},
|
||||
];
|
53
app/javascript/dashboard/helper/specs/macrosHelper.spec.js
Normal file
53
app/javascript/dashboard/helper/specs/macrosHelper.spec.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
import { MACRO_ACTION_TYPES } from '../../routes/dashboard/settings/macros/constants';
|
||||
|
||||
import { teams, labels } from './macrosFixtures';
|
||||
import {
|
||||
resolveActionName,
|
||||
emptyMacro,
|
||||
resolveLabels,
|
||||
resolveTeamIds,
|
||||
} from '../../routes/dashboard/settings/macros/macroHelper';
|
||||
|
||||
describe('#resolveActionName', () => {
|
||||
it('resolve action name from key and return the correct label', () => {
|
||||
expect(resolveActionName(MACRO_ACTION_TYPES[0].key)).toEqual(
|
||||
MACRO_ACTION_TYPES[0].label
|
||||
);
|
||||
expect(resolveActionName(MACRO_ACTION_TYPES[1].key)).toEqual(
|
||||
MACRO_ACTION_TYPES[1].label
|
||||
);
|
||||
expect(resolveActionName(MACRO_ACTION_TYPES[1].key)).not.toEqual(
|
||||
MACRO_ACTION_TYPES[0].label
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#emptyMacro', () => {
|
||||
const defaultMacro = {
|
||||
name: '',
|
||||
actions: [
|
||||
{
|
||||
action_name: 'assign_team',
|
||||
action_params: [],
|
||||
},
|
||||
],
|
||||
visibility: 'global',
|
||||
};
|
||||
it('returns the default macro', () => {
|
||||
expect(emptyMacro).toEqual(defaultMacro);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#resolveTeamIds', () => {
|
||||
it('resolves team names from ids, and returns a joined string', () => {
|
||||
const resolvedTeams = '⚙️ sales team, 🤷♂️ fayaz';
|
||||
expect(resolveTeamIds(teams, [1, 2])).toEqual(resolvedTeams);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#resolveLabels', () => {
|
||||
it('resolves labels names from ids and returns a joined string', () => {
|
||||
const resolvedLabels = 'sales, billing';
|
||||
expect(resolveLabels(labels, ['sales', 'billing'])).toEqual(resolvedLabels);
|
||||
});
|
||||
});
|
|
@ -88,12 +88,12 @@
|
|||
"VISIBILITY": {
|
||||
"LABEL": "Macro Visibility",
|
||||
"GLOBAL": {
|
||||
"LABEL": "Global",
|
||||
"DESCRIPTION": "This macro is available globally for all agents in this account."
|
||||
"LABEL": "Public",
|
||||
"DESCRIPTION": "This macro is available publicly for all agents in this account."
|
||||
},
|
||||
"PERSONAL": {
|
||||
"LABEL": "Personal",
|
||||
"DESCRIPTION": "This macro will be personal to you and not be available to others."
|
||||
"LABEL": "Private",
|
||||
"DESCRIPTION": "This macro will be private to you and not be available to others."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -15,8 +15,8 @@ import {
|
|||
resolveActionName,
|
||||
resolveTeamIds,
|
||||
resolveLabels,
|
||||
resolveSendEmailToTeam,
|
||||
} from 'dashboard/routes/dashboard/settings/macros/macroHelper.js';
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
|
@ -37,23 +37,25 @@ export default {
|
|||
};
|
||||
});
|
||||
},
|
||||
...mapGetters({
|
||||
labels: 'labels/getLabels',
|
||||
teams: 'teams/getTeams',
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
getActionValue(key, params) {
|
||||
switch (key) {
|
||||
case 'assign_team':
|
||||
return resolveTeamIds(this.$store, params);
|
||||
return resolveTeamIds(this.teams, params);
|
||||
case 'add_label':
|
||||
return resolveLabels(this.$store, params);
|
||||
case 'send_email_to_team':
|
||||
case 'send_email_transcript':
|
||||
return resolveSendEmailToTeam(params[0]);
|
||||
return resolveLabels(this.labels, params);
|
||||
case 'mute_conversation':
|
||||
case 'snooze_conversation':
|
||||
case 'resolve_conversation':
|
||||
return null;
|
||||
case 'send_webhook_event':
|
||||
case 'send_message':
|
||||
case 'send_email_transcript':
|
||||
return params[0];
|
||||
default:
|
||||
return '';
|
||||
|
|
|
@ -31,45 +31,12 @@
|
|||
</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(macro, index) in records" :key="index">
|
||||
<td>{{ macro.name }}</td>
|
||||
<td>
|
||||
<div class="avatar-container">
|
||||
<thumbnail :username="macro.created_by.name" size="24px" />
|
||||
<span class="ml-2">{{ macro.created_by.name }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="avatar-container">
|
||||
<thumbnail :username="macro.updated_by.name" size="24px" />
|
||||
<span class="ml-2">{{ macro.updated_by.name }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="macro-visibility">{{ macro.visibility }}</td>
|
||||
<td class="button-wrapper">
|
||||
<router-link
|
||||
:to="addAccountScoping(`settings/macros/${macro.id}/edit`)"
|
||||
>
|
||||
<woot-button
|
||||
v-tooltip.top="$t('MACROS.FORM.EDIT')"
|
||||
variant="smooth"
|
||||
size="tiny"
|
||||
color-scheme="secondary"
|
||||
class-names="grey-btn"
|
||||
icon="edit"
|
||||
<macros-table-row
|
||||
v-for="(macro, index) in records"
|
||||
:key="index"
|
||||
:macro="macro"
|
||||
@delete="openDeletePopup(macro, index)"
|
||||
/>
|
||||
</router-link>
|
||||
<woot-button
|
||||
v-tooltip.top="$t('MACROS.FORM.DELETE')"
|
||||
variant="smooth"
|
||||
color-scheme="alert"
|
||||
size="tiny"
|
||||
icon="dismiss-circle"
|
||||
class-names="grey-btn"
|
||||
@click="openDeletePopup(macro, index)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -93,11 +60,11 @@
|
|||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import Thumbnail from 'dashboard/components/widgets/Thumbnail';
|
||||
import accountMixin from 'dashboard/mixins/account.js';
|
||||
import MacrosTableRow from './MacrosTableRow';
|
||||
export default {
|
||||
components: {
|
||||
Thumbnail,
|
||||
MacrosTableRow,
|
||||
},
|
||||
mixins: [alertMixin, accountMixin],
|
||||
data() {
|
||||
|
@ -112,7 +79,6 @@ export default {
|
|||
records: ['macros/getMacros'],
|
||||
uiFlags: 'macros/getUIFlags',
|
||||
}),
|
||||
// Delete Modal
|
||||
deleteConfirmText() {
|
||||
return `${this.$t('MACROS.DELETE.CONFIRM.YES')} ${
|
||||
this.selectedResponse.name
|
||||
|
@ -155,18 +121,3 @@ export default {
|
|||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.avatar-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
margin-left: var(--space-one);
|
||||
}
|
||||
}
|
||||
|
||||
.macro-visibility {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -15,15 +15,16 @@
|
|||
import MacroForm from './MacroForm';
|
||||
import { MACRO_ACTION_TYPES } from './constants';
|
||||
import { mapGetters } from 'vuex';
|
||||
import { getDropdownValues, emptyMacro } from './macroHelper';
|
||||
import { emptyMacro } from './macroHelper';
|
||||
import actionQueryGenerator from 'dashboard/helper/actionQueryGenerator.js';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import macrosMixin from './macrosMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MacroForm,
|
||||
},
|
||||
mixins: [alertMixin],
|
||||
mixins: [alertMixin, macrosMixin],
|
||||
provide() {
|
||||
return {
|
||||
macroActionTypes: this.macroActionTypes,
|
||||
|
@ -39,6 +40,8 @@ export default {
|
|||
computed: {
|
||||
...mapGetters({
|
||||
uiFlags: 'macros/getUIFlags',
|
||||
labels: 'labels/getLabels',
|
||||
teams: 'teams/getTeams',
|
||||
}),
|
||||
macroId() {
|
||||
return this.$route.params.macroId;
|
||||
|
@ -86,12 +89,12 @@ export default {
|
|||
).inputType;
|
||||
if (inputType === 'multi_select') {
|
||||
actionParams = [
|
||||
...getDropdownValues(action.action_name, this.$store),
|
||||
...this.getDropdownValues(action.action_name, this.$store),
|
||||
].filter(item => [...action.action_params].includes(item.id));
|
||||
} else if (inputType === 'team_message') {
|
||||
actionParams = {
|
||||
team_ids: [
|
||||
...getDropdownValues(action.action_name, this.$store),
|
||||
...this.getDropdownValues(action.action_name, this.$store),
|
||||
].filter(item =>
|
||||
[...action.action_params[0].team_ids].includes(item.id)
|
||||
),
|
||||
|
|
|
@ -37,12 +37,15 @@
|
|||
<script>
|
||||
import ActionInput from 'dashboard/components/widgets/AutomationActionInput';
|
||||
import MacroActionButton from './ActionButton.vue';
|
||||
import { getDropdownValues } from './macroHelper';
|
||||
import macrosMixin from './macrosMixin';
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ActionInput,
|
||||
MacroActionButton,
|
||||
},
|
||||
mixins: [macrosMixin],
|
||||
inject: ['macroActionTypes', '$v'],
|
||||
props: {
|
||||
singleNode: {
|
||||
|
@ -59,6 +62,10 @@ export default {
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
labels: 'labels/getLabels',
|
||||
teams: 'teams/getTeams',
|
||||
}),
|
||||
actionData: {
|
||||
get() {
|
||||
return this.value;
|
||||
|
@ -81,7 +88,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
dropdownValues() {
|
||||
return getDropdownValues(this.value.action_name, this.$store);
|
||||
return this.getDropdownValues(this.value.action_name, this.$store);
|
||||
},
|
||||
hasError(v) {
|
||||
return !!(v.action_params.$dirty && v.action_params.$error);
|
||||
|
|
|
@ -134,6 +134,15 @@ export default {
|
|||
color: var(--s-500);
|
||||
}
|
||||
|
||||
.title {
|
||||
display: block;
|
||||
margin: 0;
|
||||
font-size: var(--font-size-small);
|
||||
font-weight: var(--font-weight-medium);
|
||||
line-height: 1.8;
|
||||
color: var(--color-body);
|
||||
}
|
||||
|
||||
.visibility-check {
|
||||
position: absolute;
|
||||
color: var(--w-500);
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<template>
|
||||
<tr>
|
||||
<td>{{ macro.name }}</td>
|
||||
<td>
|
||||
<div class="avatar-container">
|
||||
<thumbnail :username="macro.created_by.name" size="24px" />
|
||||
<span class="ml-2">{{ macro.created_by.name }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="avatar-container">
|
||||
<thumbnail :username="macro.updated_by.name" size="24px" />
|
||||
<span class="ml-2">{{ macro.updated_by.name }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ visibilityLabel }}</td>
|
||||
<td class="button-wrapper">
|
||||
<router-link :to="addAccountScoping(`settings/macros/${macro.id}/edit`)">
|
||||
<woot-button
|
||||
v-tooltip.top="$t('MACROS.FORM.EDIT')"
|
||||
variant="smooth"
|
||||
size="tiny"
|
||||
color-scheme="secondary"
|
||||
class-names="grey-btn"
|
||||
icon="edit"
|
||||
/>
|
||||
</router-link>
|
||||
<woot-button
|
||||
v-tooltip.top="$t('MACROS.FORM.DELETE')"
|
||||
variant="smooth"
|
||||
color-scheme="alert"
|
||||
size="tiny"
|
||||
icon="dismiss-circle"
|
||||
class-names="grey-btn"
|
||||
@click="$emit('delete')"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Thumbnail from 'dashboard/components/widgets/Thumbnail';
|
||||
import accountMixin from 'dashboard/mixins/account.js';
|
||||
export default {
|
||||
components: {
|
||||
Thumbnail,
|
||||
},
|
||||
mixins: [accountMixin],
|
||||
props: {
|
||||
macro: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
visibilityLabel() {
|
||||
return this.macro.visibility === 'global'
|
||||
? this.$t('MACROS.EDITOR.VISIBILITY.GLOBAL.LABEL')
|
||||
: this.$t('MACROS.EDITOR.VISIBILITY.PERSONAL.LABEL');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.avatar-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
margin-left: var(--space-one);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -4,48 +4,24 @@ export const resolveActionName = key => {
|
|||
return macroActionTypes.find(i => i.key === key).label;
|
||||
};
|
||||
|
||||
export const resolveTeamIds = (store, ids) => {
|
||||
const allTeams = store.getters['teams/getTeams'];
|
||||
export const resolveTeamIds = (teams, ids) => {
|
||||
return ids
|
||||
.map(id => {
|
||||
const team = allTeams.find(i => i.id === id);
|
||||
const team = teams.find(i => i.id === id);
|
||||
return team ? team.name : '';
|
||||
})
|
||||
.join(', ');
|
||||
};
|
||||
|
||||
export const resolveLabels = (store, ids) => {
|
||||
const allLabels = store.getters['labels/getLabels'];
|
||||
export const resolveLabels = (labels, ids) => {
|
||||
return ids
|
||||
.map(id => {
|
||||
const label = allLabels.find(i => i.title === id);
|
||||
const label = labels.find(i => i.title === id);
|
||||
return label ? label.title : '';
|
||||
})
|
||||
.join(', ');
|
||||
};
|
||||
|
||||
export const resolveSendEmailToTeam = obj => {
|
||||
return ` ${obj.message} -
|
||||
${resolveTeamIds(obj.team_ids)}`;
|
||||
};
|
||||
|
||||
export const getDropdownValues = (type, store) => {
|
||||
switch (type) {
|
||||
case 'assign_team':
|
||||
case 'send_email_to_team':
|
||||
return store.getters['teams/getTeams'];
|
||||
case 'add_label':
|
||||
return store.getters['labels/getLabels'].map(i => {
|
||||
return {
|
||||
id: i.title,
|
||||
name: i.title,
|
||||
};
|
||||
});
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
export const emptyMacro = {
|
||||
name: '',
|
||||
actions: [
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
export default {
|
||||
methods: {
|
||||
getDropdownValues(type) {
|
||||
switch (type) {
|
||||
case 'assign_team':
|
||||
case 'send_email_to_team':
|
||||
return this.teams;
|
||||
case 'add_label':
|
||||
return this.labels.map(i => {
|
||||
return {
|
||||
id: i.title,
|
||||
name: i.title,
|
||||
};
|
||||
});
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
Loading…
Reference in a new issue