Skip to content

Commit

Permalink
feature: add shift template page[WTEL-5079]
Browse files Browse the repository at this point in the history
  • Loading branch information
Lera24 committed Sep 24, 2024
1 parent 89bc77c commit a0acfbe
Show file tree
Hide file tree
Showing 20 changed files with 1,323 additions and 16 deletions.
621 changes: 610 additions & 11 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"@vuelidate/validators": "^2.0.4",
"@vueuse/core": "^11.0.3",
"@webitel/flow-ui-sdk": "^0.1.14",
"@webitel/ui-sdk": "^24.10.11",
"@webitel/ui-sdk": "^24.10.20",
"axios": "^1.7.7",
"clipboard-copy": "^4.0.1",
"cron-validator": "^1.3.1",
Expand All @@ -40,7 +40,7 @@
"vue-router": "^4.4.3",
"vue2-dropzone": "^3.6.0",
"vuex": "^4.1.0",
"webitel-sdk": "^24.8.1"
"webitel-sdk": "^24.8.3"
},
"devDependencies": {
"@biomejs/biome": "^1.8.3",
Expand Down
5 changes: 4 additions & 1 deletion src/app/locale/en/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,9 @@ export default {
allowSupervisor: 'Supervisor can change this status',
allowAgent: 'Agent can change this status',
},
shiftTemplates: {
shiftTemplates: 'Shift template | Shift templates',
},
},
routing: {
routing: 'Routing',
Expand Down Expand Up @@ -534,7 +537,7 @@ export default {
},
chatGateways: {
templates: {
templates: 'Templates',
templates: 'Template | Templates',
title: "Workspace member's name",
close: 'Chat complete message',
join: 'Agent joining message',
Expand Down
3 changes: 3 additions & 0 deletions src/app/locale/ru/ru.js
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,9 @@ export default {
allowSupervisor: 'Супервизор может изменять этот статус',
allowAgent: 'Оператор может изменять этот статус',
},
shiftTemplates: {
shiftTemplates: 'Шаблон смен | Шаблоны смен',
},
},
routing: {
routing: 'Маршрутизация',
Expand Down
3 changes: 3 additions & 0 deletions src/app/locale/ua/ua.js
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,9 @@ export default {
allowSupervisor: 'Супервізор може змінювати статус',
allowAgent: 'Оператор може змінювати статус',
},
shiftTemplates: {
shiftTemplates: 'Шаблон змін | Шаблони змін',
},
},
routing: {
routing: 'Маршрутизація',
Expand Down
5 changes: 5 additions & 0 deletions src/app/router/_internals/NavigationPages.lookup.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ const nav = Object.freeze([
locale: `WebitelApplications.${WebitelApplications.ADMIN}.sections.${AdminSections.MEDIA}`,
route: 'media',
},
{
value: AdminSections.SHIFT_TEMPLATES,
locale: `WebitelApplications.${WebitelApplications.ADMIN}.sections.${AdminSections.SHIFT_TEMPLATES}`,
route: 'shift-templates',
},
],
},
{
Expand Down
1 change: 1 addition & 0 deletions src/app/router/_internals/RouteNames.enum.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default Object.freeze({
COMMUNICATIONS: 'communications',
PAUSE_CAUSE: 'agent-pause-cause',
MEDIA: 'media',
SHIFT_TEMPLATES: 'shift-templates',

// CONTACT-CENTER
AGENTS: 'agents',
Expand Down
3 changes: 3 additions & 0 deletions src/app/router/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import AgentSkillsRoutes from "../../modules/lookups/modules/agent-skills/router
import BucketsRoutes from "../../modules/lookups/modules/buckets/router/buckets.js";
import BlacklistsRoutes from "../../modules/lookups/modules/blacklists/router/blacklists.js";
import MediaRoutes from "../../modules/lookups/modules/media/router/media.js";
import ShiftTemplates
from '../../modules/lookups/modules/shift-templates/router/shift-templates.js';
import CalendarsRoutes from "../../modules/lookups/modules/calendars/router/calendars.js";
import CommunicationsRoutes from "../../modules/lookups/modules/communications/router/communications.js";
import RegionsRoutes from "../../modules/lookups/modules/regions/router/regions.js";
Expand Down Expand Up @@ -107,6 +109,7 @@ const router = createRouter({
...CommunicationsRoutes,
...RegionsRoutes,
...AgentPauseCauseRoutes,
...ShiftTemplates,
// ----------LOOKUPS END------------

// --------------CONTACT CENTER-------------
Expand Down
107 changes: 107 additions & 0 deletions src/modules/lookups/modules/shift-templates/api/shiftTemplates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { getDefaultGetListResponse, getDefaultGetParams } from '@webitel/ui-sdk/src/api/defaults/index.js';
import applyTransform, {
camelToSnake,
merge,
notify,
sanitize,
snakeToCamel,
starToSearch,
} from '@webitel/ui-sdk/src/api/transformers/index.js';
import { ShiftTemplateServiceApiFactory } from 'webitel-sdk';

import instance from '../../../../../app/api/instance';
import configuration from '../../../../../app/api/openAPIConfig';

const shiftTemplateService = new ShiftTemplateServiceApiFactory(configuration, '', instance);

const getShiftTemplateList = async (params) => {
const { search: q, page, size, sort, fields } = applyTransform(params, [
merge(getDefaultGetParams()),
starToSearch(),
]);

try {
const response = await shiftTemplateService.searchShiftTemplate(q, page, size, sort, fields);
const { items, next } = applyTransform(response.data, [
snakeToCamel(),
merge(getDefaultGetListResponse()),
]);
return {
items,
next,
};
} catch (err) {
throw applyTransform(err, [notify]);
}
};

const itemResponseHandler = (item) => {
const copy = {
...item.item,
};

copy.times = copy.times.map((time) => ({
...time,
duration: time.end - time.start,
}), []);

return copy;
};

const getShiftTemplate = async ({ itemId: id }) => {

try {
const response = await shiftTemplateService.readShiftTemplate(id);
return applyTransform(response.data, [snakeToCamel(), itemResponseHandler]);
} catch (err) {
throw applyTransform(err, [notify]);
}
};

const fieldsToSend = ['name', 'description', 'times'];

const addShiftTemplate = async ({ itemInstance }) => {
const item = applyTransform(itemInstance, [sanitize(fieldsToSend), camelToSnake()]);
try {
const response = await shiftTemplateService.createShiftTemplate({ item: { ...item } });
return applyTransform(response.data, [snakeToCamel()]);
} catch (err) {
throw applyTransform(err, [notify]);
}
};

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

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

const getShiftTemplatesLookup = (params) =>
getShiftTemplateList({
...params,
fields: params.fields || ['id', 'name'],
});

const ShiftTemplatesAPI = {
getList: getShiftTemplateList,
get: getShiftTemplate,
add: addShiftTemplate,
update: updateShiftTemplate,
delete: deleteShiftTemplate,
getLookup: getShiftTemplatesLookup,
}

export default ShiftTemplatesAPI;
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template>
<section>
<header class="content-header">
<h3 class="content-title">
{{ $t('objects.generalInfo') }}
</h3>
</header>
<div class="object-input-grid object-input-grid__1-col object-input-grid__w50">
<wt-input
:disabled="disableUserInput"
:label="$t('objects.name')"
:v="v.itemInstance.name"
:value="itemInstance.name"
required
@input="setItemProp({ prop: 'name', value: $event })"
/>
<wt-textarea
:disabled="disableUserInput"
:label="$t('objects.description')"
:value="itemInstance.description"
@input="setItemProp({ prop: 'description', value: $event })"
/>
</div>
</section>
</template>

<script>
import openedTabComponentMixin from '../../../../../app/mixins/objectPagesMixins/openedObjectTabMixin/openedTabComponentMixin';
export default {
name: 'OpenedShiftTemplateGeneral',
mixins: [openedTabComponentMixin],
};
</script>

<style scoped>
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<template>
<section class="opened-calendar-work-week">
<header class="content-header">
<h3 class="content-title">
{{ $tc('objects.routing.chatGateways.templates.templates', 1) }}
</h3>

<div class="content-header__actions-wrap">
<wt-icon-btn
v-if="!disableUserInput"
class="icon-action"
icon="plus"
@click="addTemplate"
/>
</div>
</header>

<div class="table-wrapper">
<div class="table-wrapper__visible-scroll-wrapper">
<wt-table
:data="itemInstance.times"
:grid-actions="!disableUserInput"
:headers="headers"
:selectable="false"
>
<template #start="{ item, index }">
<wt-timepicker
:disabled="disableUserInput"
:value="minToSec(item.start)"
:v="v.itemInstance.times.$each.$response.$data[index].start"
format="hh:mm"
@input="setStartTime({ index, value: secToMin($event) })"
/>
</template>
<template #end="{ item, index }">
<wt-timepicker
:disabled="disableUserInput"
:value="minToSec(item.end)"
format="hh:mm"
:v="v.itemInstance.times.$each.$response.$data[index].end"
@input="setEndTime({ index, value: secToMin($event) })"
/>
</template>
<template #duration="{ item, index }">
<wt-timepicker
:value="minToSec(item.duration)"
format="hh:mm"
type="number"
@input="setDuration({ index, value: secToMin($event) })"
/>
</template>
<template #actions="{ item, index }">
<wt-icon-action
action="delete"
@click="deleteTemplate(index)"
/>
</template>
</wt-table>
</div>
</div>
</section>
</template>

<script>
import { mapActions, mapState } from 'vuex';
import openedTabComponentMixin from '../../../../../app/mixins/objectPagesMixins/openedObjectTabMixin/openedTabComponentMixin';
export default {
name: 'OpenedShiftTemplateTemplate',
mixins: [openedTabComponentMixin],
computed: {
headers() {
return [
{
value: 'start',
text: this.$t('objects.lookups.calendars.start'),
},
{
value: 'end',
text: this.$t('objects.lookups.calendars.end'),
},
{
value: 'duration',
text: this.$t('objects.ccenter.queues.logs.duration'),
},
];
},
},
methods: {
...mapActions('lookups/shiftTemplates', {
addTemplate: 'ADD_TEMPLATE',
setTemplate: 'SET_TEMPLATE',
deleteTemplate: 'DELETE_TEMPLATE',
}),
minToSec(min) {
return min * 60;
},
secToMin(sec) {
return sec / 60;
},
setStartTime({ index, value }) {
this.setTemplate({ prop: 'start', index, value });
this.setTemplate({ prop: 'duration', index, value: this.itemInstance.times[index].end - this.itemInstance.times[index].start });
},
setEndTime({ index, value }) {
this.setTemplate({ prop: 'end', index, value });
this.setTemplate({ prop: 'duration', index, value: this.itemInstance.times[index].end - this.itemInstance.times[index].start });
},
setDuration({ index, value }) {
this.setTemplate({ prop: 'duration', index, value });
this.setTemplate({ prop: 'end', index, value: this.itemInstance.times[index].start + this.itemInstance.times[index].duration });
},
},
};
</script>

<style lang="scss" scoped>
.wt-timepicker :deep(.wt-label) {
display: none;
}
</style>

Loading

0 comments on commit a0acfbe

Please sign in to comment.