Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/teams hooks [WTEL-4246] #642

Merged
merged 9 commits into from
Mar 27, 2024
5 changes: 5 additions & 0 deletions src/app/locale/en/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,11 @@ export default {
longestIdleAgent: 'Agent with longest idle time',
skillCapacity: 'By skill level',
},
hooks: {
eventTypes: {
agentStatus: 'Agent status changed',
}
},
},

members: {
Expand Down
5 changes: 5 additions & 0 deletions src/app/locale/ru/ru.js
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,11 @@ export default {
longestIdleAgent: 'Агент с наибольшим временем простоя',
skillCapacity: 'По уровню навыка',
},
hooks: {
eventTypes: {
agentStatus: 'Изменение статуса оператора',
}
},
},

members: {
Expand Down
5 changes: 5 additions & 0 deletions src/app/locale/ua/ua.js
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,11 @@ export default {
longestIdleAgent: 'Оператор з найбільшим часом простою',
skillCapacity: 'По рівню навички',
},
hooks: {
eventTypes: {
agentStatus: 'Зміна статуту оператора',
}
},
},

members: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import { useVuelidate } from '@vuelidate/core';
import { required } from '@vuelidate/validators';
import nestedObjectMixin from '../../../../../../../app/mixins/objectPagesMixins/openedObjectMixin/nestedObjectMixin';
import FlowsAPI from '../../../../../../routing/modules/flow/api/flow';
import HookEvent from '../enum/HookEvent.enum';
import HookEvent from '../enum/HookQueueEvent.enum';

export default {
name: 'OpenedQueueHooksPopup',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@ export default {
data: () => ({
subNamespace: 'hooks',
isHookPopup: false,

isDeleteConfirmation: false,
}),

methods: {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export default [
value: 'state',
locale: 'reusable.state',
field: 'enabled',
width: '100px',
sort: SortSymbols.NONE,
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import Agents from '../modules/agents/components/opened-team-agents.vue';
import Supervisors from '../modules/supervisors/components/opened-team-supervisors.vue';
import General from './opened-team-general.vue';
import Parameters from './opened-team-parameters.vue';
import Hooks from '../modules/hooks/components/opened-team-hooks.vue';

export default {
name: 'OpenedTeam',
Expand All @@ -50,6 +51,7 @@ export default {
Supervisors,
Agents,
Parameters,
Hooks,
},
mixins: [openedObjectMixin],

Expand Down Expand Up @@ -87,7 +89,10 @@ export default {
}, {
text: this.$tc('objects.ccenter.agents.agents', 2),
value: 'agents',
},
}, {
text: this.$tc('objects.ccenter.queues.hooks.hooks', 2),
value: 'hooks',
}
];

if (this.id) tabs.push(this.permissionsTab);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import {

Check failure on line 1 in src/modules/contact-center/modules/teams/modules/hooks/api/teamHooks.js

View workflow job for this annotation

GitHub Actions / Qodana for JS

ESLint

ESLint: Install the 'eslint' package
getDefaultGetListResponse,
getDefaultGetParams,
} from '@webitel/ui-sdk/src/api/defaults';
import applyTransform, {
camelToSnake,
merge,
mergeEach,
notify,
sanitize,
snakeToCamel,
starToSearch,
} from '@webitel/ui-sdk/src/api/transformers';
import { TeamHookServiceApiFactory } from 'webitel-sdk';
import instance from '../../../../../../../app/api/instance';
import configuration from '../../../../../../../app/api/openAPIConfig';

const teamHookService = new TeamHookServiceApiFactory(configuration, '', instance);

const fieldsToSend = ['event', 'properties', 'schema', 'enabled'];

const preRequestHandler = (parentId) => (item) => ({
...item,
teamId: parentId,
});

const getTeamHooksList = async (params) => {
const defaultObject = {
enabled: false,
};

const {
page,
size,
search,
sort,
fields,
id,
parentId,
} = applyTransform(params, [
merge(getDefaultGetParams()),
starToSearch('search'),
]);

try {
const response = await teamHookService.searchTeamHook(
parentId,
page,
size,
search,
sort,
fields,
id,
);
const { items, next } = applyTransform(response.data, [
snakeToCamel(),
merge(getDefaultGetListResponse()),
]);
return {
items: applyTransform(items, [
mergeEach(defaultObject),
]),
next,
};
} catch (err) {
throw applyTransform(err, [
notify,
]);
}
};

const getTeamHook = async ({ parentId, itemId: id }) => {
const defaultObject = {
event: '',
properties: [],
schema: {},
enabled: false,
};

try {
const response = await teamHookService.readTeamHook(parentId, id);
return applyTransform(response.data, [
snakeToCamel(),
merge(defaultObject),
]);
} catch (err) {
throw applyTransform(err, [
notify,
]);
}
};

const addTeamHook = async ({ parentId, itemInstance }) => {
const item = applyTransform(itemInstance, [
preRequestHandler(parentId),
sanitize(fieldsToSend),
camelToSnake(),
]);
try {
const response = await teamHookService.createTeamHook(parentId, item);
return applyTransform(response.data, [
snakeToCamel(),
]);
} catch (err) {
throw applyTransform(err, [
notify,
]);
}
};

const patchTeamHook = async ({ changes, id, parentId }) => {
const body = applyTransform(changes, [
sanitize(fieldsToSend),
camelToSnake(),
]);

try {
const response = await teamHookService.patchTeamHook(parentId, id, body);
return applyTransform(response.data, [
snakeToCamel(),
]);
} catch (err) {
throw applyTransform(err, [
notify,
]);
}
};

const updateTeamHook = async ({ itemInstance, itemId: id, parentId }) => {
const item = applyTransform(itemInstance, [
preRequestHandler(parentId),
sanitize(fieldsToSend),
camelToSnake(),
]);
try {
const response = await teamHookService.updateTeamHook(parentId, id, item);
return applyTransform(response.data, [
snakeToCamel(),
]);
} catch (err) {
throw applyTransform(err, [
notify,
]);
}
};

const deleteTeamHook = async ({ parentId, id }) => {
try {
const response = await teamHookService.deleteTeamHook(parentId, id);
return applyTransform(response.data, []);
} catch (err) {
throw applyTransform(err, [
notify,
]);
}
};

const TeamHooksAPI = {
getList: getTeamHooksList,
get: getTeamHook,
add: addTeamHook,
patch: patchTeamHook,
update: updateTeamHook,
delete: deleteTeamHook,
};

export default TeamHooksAPI;
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<template>

Check failure on line 1 in src/modules/contact-center/modules/teams/modules/hooks/components/opened-team-hooks-popup.vue

View workflow job for this annotation

GitHub Actions / Qodana for JS

ESLint

ESLint: Install the 'eslint' package
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А цей попап чимось відрізняється від того що в чергах?
Може винести один загальний компонент, ніж дублювати?

<wt-popup
min-width="480"
overflow
@close="close"
>
<template #title>
{{ $tc('objects.ccenter.queues.hooks.hooks', 1) }}
</template>
<template #main>
<form>
<wt-select
:value="event"
:clearable="false"
:label="$t('objects.ccenter.queues.hooks.event')"
:options="eventOptions"
:v="v$.itemInstance.event"
required
track-by="value"
@input="setItemProp({ prop: 'event', value: $event.value })"
/>
<wt-select
:clearable="false"
:label="$tc('objects.routing.flow.flow', 1)"
:search-method="loadFlowOptions"
:v="v$.itemInstance.schema"
:value="itemInstance.schema"
required
@input="setItemProp({ prop: 'schema', value: $event })"
/>
</form>
</template>
<template #actions>
<wt-button
:disabled="disabledSave"
@click="save"
>
{{ $t('objects.save') }}
</wt-button>
<wt-button
color="secondary"
@click="close"
>
{{ $t('objects.close') }}
</wt-button>
</template>
</wt-popup>
</template>

<script>
import { EngineRoutingSchemaType } from 'webitel-sdk';
import { snakeToCamel } from '@webitel/ui-sdk/src/scripts/caseConverters';
import { useVuelidate } from '@vuelidate/core';
import { required } from '@vuelidate/validators';
import nestedObjectMixin from '../../../../../../../app/mixins/objectPagesMixins/openedObjectMixin/nestedObjectMixin';
import FlowsAPI from '../../../../../../routing/modules/flow/api/flow';
import HookEvent from '../enum/HookTeamEvent.enum';

export default {
name: 'OpenedQueueHooksPopup',
mixins: [nestedObjectMixin],

setup: () => ({
v$: useVuelidate(),
}),
data: () => ({
namespace: 'ccenter/teams/hooks',
}),
validations: {
itemInstance: {
event: { required },
schema: { required },
},
},

computed: {
eventOptions() {
return Object.values(HookEvent).map((event) => ({
name: this.$t(`objects.ccenter.teams.hooks.eventTypes.${this.snakeToCamel(event)}`),
value: event,
}));
},
event() {
const { event } = this.itemInstance;
return event ? {
name: this.$t(`objects.ccenter.teams.hooks.eventTypes.${this.snakeToCamel(event)}`),
value: event,
} : {};
}
},

methods: {
loadFlowOptions(params) {
return FlowsAPI.getLookup({ ...params, type: [EngineRoutingSchemaType.Service] });
},
snakeToCamel,
},
};
</script>

<style lang="scss" scoped>

</style>
Loading
Loading