From 35e883a591c6c0f1afeb793109a71a2ec087f0d2 Mon Sep 17 00:00:00 2001 From: Lera24 Date: Mon, 30 Sep 2024 16:57:33 +0300 Subject: [PATCH 1/3] feature: add working conditions page[WTEL-5078] --- src/app/locale/en/en.js | 11 +- src/app/locale/ru/ru.js | 11 +- src/app/locale/ua/ua.js | 11 +- .../_internals/NavigationPages.lookup.js | 5 + src/app/router/_internals/RouteNames.enum.js | 1 + src/app/router/router.js | 6 +- .../components/the-pause-templates.vue | 2 +- .../api/workingConditions.js | 99 ++++++++++ .../opened-working-condition-general.vue | 115 +++++++++++ .../components/opened-working-condition.vue | 107 +++++++++++ .../components/the-working-conditions.vue | 179 ++++++++++++++++++ .../WorkingConditionsRouteNames.enum.js | 5 + .../router/workingConditions.js | 34 ++++ .../store/_internals/headers.js | 16 ++ .../store/working-conditions.js | 25 +++ src/modules/lookups/store/lookups.js | 3 + 16 files changed, 624 insertions(+), 6 deletions(-) create mode 100644 src/modules/lookups/modules/working-conditions/api/workingConditions.js create mode 100644 src/modules/lookups/modules/working-conditions/components/opened-working-condition-general.vue create mode 100644 src/modules/lookups/modules/working-conditions/components/opened-working-condition.vue create mode 100644 src/modules/lookups/modules/working-conditions/components/the-working-conditions.vue create mode 100644 src/modules/lookups/modules/working-conditions/router/_internals/WorkingConditionsRouteNames.enum.js create mode 100644 src/modules/lookups/modules/working-conditions/router/workingConditions.js create mode 100644 src/modules/lookups/modules/working-conditions/store/_internals/headers.js create mode 100644 src/modules/lookups/modules/working-conditions/store/working-conditions.js diff --git a/src/app/locale/en/en.js b/src/app/locale/en/en.js index d9b127547..62e3db82e 100644 --- a/src/app/locale/en/en.js +++ b/src/app/locale/en/en.js @@ -471,10 +471,19 @@ export default { duration: 'Duration (hh:mm)', }, pauseTemplates: { - pauseTemplates: 'Pause templates', + pauseTemplates: 'Pause templates | Pause templates', pauseReason: 'Pause reason', duration: 'Duration (mm)', }, + workingConditions: { + workingConditions: 'Working Conditions', + workdayDuration: 'Workday duration (hrs)', + workdaysPerMonth: 'Workdays per month', + vacationDaysPerYear: 'Vacation days per year', + sickLeavesPerYear: 'Sick leaves per year', + daysOffPerYear: 'Days-off per year', + pauseDuration: 'Pause duration', + }, }, routing: { routing: 'Routing', diff --git a/src/app/locale/ru/ru.js b/src/app/locale/ru/ru.js index 963a2fcea..b8073d333 100644 --- a/src/app/locale/ru/ru.js +++ b/src/app/locale/ru/ru.js @@ -477,10 +477,19 @@ export default { duration: 'Длительность (чч:мм)', }, pauseTemplates: { - pauseTemplates: 'Шаблоны пауз', + pauseTemplates: 'Шаблон пауз | Шаблоны пауз', pauseReason: 'Причина паузы', duration: 'Длительность (мм)', }, + workingConditions: { + workingConditions: 'Условия работы', + workdayDuration: 'Длительность рабочего дня (час.)', + workdaysPerMonth: 'Количество рабочих дней в месяц', + vacationDaysPerYear: 'Количество дней отпуска в год', + sickLeavesPerYear: 'Количество дней больничного в год', + daysOffPerYear: 'Количество выходных дней в год', + pauseDuration: 'Длительность перерыва', + }, }, routing: { routing: 'Маршрутизация', diff --git a/src/app/locale/ua/ua.js b/src/app/locale/ua/ua.js index 23faf1366..44ef2cbb1 100644 --- a/src/app/locale/ua/ua.js +++ b/src/app/locale/ua/ua.js @@ -472,10 +472,19 @@ export default { duration: 'Тривалість (гг:хх)', }, pauseTemplates: { - pauseTemplates: 'Шаблони пауз', + pauseTemplates: 'Шаблон пауз | Шаблони пауз', pauseReason: 'Причина паузи', duration: 'Тривалість (хх)', }, + workingConditions: { + workingConditions: 'Умови роботи', + workdayDuration: 'Тривалість робочого дня (год.)', + workdaysPerMonth: 'Кількість робочих днів на місяць', + vacationDaysPerYear: 'Кількість днів відпустки на рік', + sickLeavesPerYear: 'Кількість днів лікарняного на рік', + daysOffPerYear: 'Кількість вихідних днів на рік', + pauseDuration: 'Тривалість перерви', + }, }, routing: { routing: 'Маршрутизація', diff --git a/src/app/router/_internals/NavigationPages.lookup.js b/src/app/router/_internals/NavigationPages.lookup.js index d92f441cc..3809d40e3 100644 --- a/src/app/router/_internals/NavigationPages.lookup.js +++ b/src/app/router/_internals/NavigationPages.lookup.js @@ -111,6 +111,11 @@ const nav = Object.freeze([ locale: `WebitelApplications.${WebitelApplications.ADMIN}.sections.${AdminSections.PAUSE_TEMPLATES}`, route: 'pause-templates', }, + { + value: AdminSections.WORKING_CONDITIONS, + locale: `WebitelApplications.${WebitelApplications.ADMIN}.sections.${AdminSections.WORKING_CONDITIONS}`, + route: 'working-conditions', + }, ], }, { diff --git a/src/app/router/_internals/RouteNames.enum.js b/src/app/router/_internals/RouteNames.enum.js index 33484e672..c4eeff07b 100644 --- a/src/app/router/_internals/RouteNames.enum.js +++ b/src/app/router/_internals/RouteNames.enum.js @@ -27,6 +27,7 @@ export default Object.freeze({ MEDIA: 'media', SHIFT_TEMPLATES: 'shift-templates', PAUSE_TEMPLATES: 'pause-templates', + WORKING_CONDITIONS: 'working-conditions', // CONTACT-CENTER AGENTS: 'agents', diff --git a/src/app/router/router.js b/src/app/router/router.js index a8030d07c..f6be064bd 100755 --- a/src/app/router/router.js +++ b/src/app/router/router.js @@ -29,13 +29,14 @@ 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 ShiftTemplatesRoutes - from '../../modules/lookups/modules/shift-templates/router/shiftTemplates.js'; +import ShiftTemplatesRoutes from "../../modules/lookups/modules/shift-templates/router/shiftTemplates.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"; import AgentPauseCauseRoutes from "../../modules/lookups/modules/agent-pause-cause/router/agentPauseCause.js"; import PauseTemplatesRoutes from "../../modules/lookups/modules/pause-templates/router/pauseTemplates.js"; +import WorkingConditionsRoutes + from '../../modules/lookups/modules/working-conditions/router/workingConditions.js'; const ApplicationHub = () => import('../../modules/application-hub/components/application-hub.vue'); const ModuleWrap = () => import('../../modules/_shared/object-wrap/the-object-wrap.vue'); @@ -112,6 +113,7 @@ const router = createRouter({ ...AgentPauseCauseRoutes, ...ShiftTemplatesRoutes, ...PauseTemplatesRoutes, + ...WorkingConditionsRoutes, // ----------LOOKUPS END------------ // --------------CONTACT CENTER------------- diff --git a/src/modules/lookups/modules/pause-templates/components/the-pause-templates.vue b/src/modules/lookups/modules/pause-templates/components/the-pause-templates.vue index 202e13ab8..2035e2397 100644 --- a/src/modules/lookups/modules/pause-templates/components/the-pause-templates.vue +++ b/src/modules/lookups/modules/pause-templates/components/the-pause-templates.vue @@ -164,7 +164,7 @@ export default { name: this.$t('objects.lookups.lookups'), }, { - name: this.$t('objects.lookups.pauseTemplates.pauseTemplates'), + name: this.$tc('objects.lookups.pauseTemplates.pauseTemplates', 2), route: '/lookups/pause-templates', }, ]; diff --git a/src/modules/lookups/modules/working-conditions/api/workingConditions.js b/src/modules/lookups/modules/working-conditions/api/workingConditions.js new file mode 100644 index 000000000..2d93bb86e --- /dev/null +++ b/src/modules/lookups/modules/working-conditions/api/workingConditions.js @@ -0,0 +1,99 @@ +import applyTransform, { + camelToSnake, + merge, + notify, + sanitize, + snakeToCamel, +} from '@webitel/ui-sdk/src/api/transformers/index.js'; +import { WorkingConditionServiceApi } from 'webitel-sdk'; +import { + getDefaultGetParams, + getDefaultGetListResponse +} from '@webitel/ui-sdk/src/api/defaults/index.js'; + +import instance from '../../../../../app/api/instance'; +import configuration from '../../../../../app/api/openAPIConfig'; + +const workingConditionService = new WorkingConditionServiceApi(configuration, '', instance); + +const getWorkingConditionList = async (params) => { + const { search: q, page, size, sort, fields } = applyTransform(params, [ + merge(getDefaultGetParams()), + ]); + + try { + const response = await workingConditionService.searchWorkingCondition(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) => { + return { ...item.item } +}; + +const getWorkingCondition = async ({ itemId: id }) => { + + try { + const response = await workingConditionService.readWorkingCondition(id); + return applyTransform(response.data, [snakeToCamel(), itemResponseHandler]); + } catch (err) { + throw applyTransform(err, [notify]); + } +}; + +const fieldsToSend = ['name', 'description', 'workdayHours', 'workdayPerMonth', 'pauseDuration', 'vacation', 'pauseTemplate', 'sickLeaves', 'shiftTemplate', 'daysOff']; + +const addWorkingCondition = async ({ itemInstance }) => { + const item = applyTransform(itemInstance, [sanitize(fieldsToSend), camelToSnake()]); + try { + const response = await workingConditionService.createWorkingCondition({ item: { ...item } }); + return applyTransform(response.data, [snakeToCamel(), itemResponseHandler]); + } catch (err) { + throw applyTransform(err, [notify]); + } +}; + +const updateWorkingCondition = async ({ itemInstance, itemId: id }) => { + const item = applyTransform(itemInstance, [sanitize(fieldsToSend), camelToSnake()]); + try { + const response = await workingConditionService.updateWorkingCondition(id, { item: { ...item }}); + return applyTransform(response.data, [snakeToCamel(), itemResponseHandler]); + } catch (err) { + throw applyTransform(err, [notify]); + } +}; + +const deleteWorkingCondition = async ({ id }) => { + try { + const response = await workingConditionService.deleteWorkingCondition(id); + return applyTransform(response.data, []); + } catch (err) { + throw applyTransform(err, [notify]); + } +}; + +const getWorkingConditionLookup = (params) => + getWorkingConditionList({ + ...params, + fields: params.fields || ['id', 'name'], + }); + +const WorkingConditionsAPI = { + getList: getWorkingConditionList, + get: getWorkingCondition, + add: addWorkingCondition, + update: updateWorkingCondition, + delete: deleteWorkingCondition, + getLookup: getWorkingConditionLookup, +} + +export default WorkingConditionsAPI; diff --git a/src/modules/lookups/modules/working-conditions/components/opened-working-condition-general.vue b/src/modules/lookups/modules/working-conditions/components/opened-working-condition-general.vue new file mode 100644 index 000000000..ed17a5ffa --- /dev/null +++ b/src/modules/lookups/modules/working-conditions/components/opened-working-condition-general.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/src/modules/lookups/modules/working-conditions/components/opened-working-condition.vue b/src/modules/lookups/modules/working-conditions/components/opened-working-condition.vue new file mode 100644 index 000000000..d39b7ca4d --- /dev/null +++ b/src/modules/lookups/modules/working-conditions/components/opened-working-condition.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/src/modules/lookups/modules/working-conditions/components/the-working-conditions.vue b/src/modules/lookups/modules/working-conditions/components/the-working-conditions.vue new file mode 100644 index 000000000..306270052 --- /dev/null +++ b/src/modules/lookups/modules/working-conditions/components/the-working-conditions.vue @@ -0,0 +1,179 @@ + + + diff --git a/src/modules/lookups/modules/working-conditions/router/_internals/WorkingConditionsRouteNames.enum.js b/src/modules/lookups/modules/working-conditions/router/_internals/WorkingConditionsRouteNames.enum.js new file mode 100644 index 000000000..f4e469d77 --- /dev/null +++ b/src/modules/lookups/modules/working-conditions/router/_internals/WorkingConditionsRouteNames.enum.js @@ -0,0 +1,5 @@ +import RouteNames from '../../../../../../app/router/_internals/RouteNames.enum.js'; + +export default Object.freeze({ + GENERAL: `${RouteNames.WORKING_CONDITIONS}-general`, +}); diff --git a/src/modules/lookups/modules/working-conditions/router/workingConditions.js b/src/modules/lookups/modules/working-conditions/router/workingConditions.js new file mode 100644 index 000000000..94992c6e6 --- /dev/null +++ b/src/modules/lookups/modules/working-conditions/router/workingConditions.js @@ -0,0 +1,34 @@ +import RouteNames from "../../../../../app/router/_internals/RouteNames.enum.js"; +import {checkRouteAccess} from "../../../../../app/router/_internals/guards.js"; +import WorkingConditionsRouteNamesEnum + from './_internals/WorkingConditionsRouteNames.enum.js'; + +const WorkingConditions = () => import('../components/the-working-conditions.vue'); +const OpenedWorkingCondition = () => import('../components/opened-working-condition.vue'); + +const OpenedWorkingConditionGeneral = () => import('../components/opened-working-condition-general.vue'); + + +const WorkingConditionsRoutes = [ + { + path: '/lookups/working-conditions', + name: RouteNames.WORKING_CONDITIONS, + component: WorkingConditions, + beforeEnter: checkRouteAccess, + }, + { + path: '/lookups/working-conditions/:id', + name: `${RouteNames.WORKING_CONDITIONS}-card`, + redirect: {name: WorkingConditionsRouteNamesEnum.GENERAL}, + component: OpenedWorkingCondition, + beforeEnter: checkRouteAccess, + children: [ + { + path: 'general', + name: WorkingConditionsRouteNamesEnum.GENERAL, + component: OpenedWorkingConditionGeneral, + } + ], + }, +]; +export default WorkingConditionsRoutes; diff --git a/src/modules/lookups/modules/working-conditions/store/_internals/headers.js b/src/modules/lookups/modules/working-conditions/store/_internals/headers.js new file mode 100644 index 000000000..ff2ea4fd7 --- /dev/null +++ b/src/modules/lookups/modules/working-conditions/store/_internals/headers.js @@ -0,0 +1,16 @@ +import { SortSymbols } from '@webitel/ui-sdk/src/scripts/sortQueryAdapters'; + +export default [ + { + value: 'name', + locale: 'objects.name', + field: 'name', + sort: SortSymbols.NONE, + }, + { + value: 'description', + locale: 'objects.description', + field: 'description', + sort: SortSymbols.NONE, + }, +]; diff --git a/src/modules/lookups/modules/working-conditions/store/working-conditions.js b/src/modules/lookups/modules/working-conditions/store/working-conditions.js new file mode 100644 index 000000000..c7c03cdf8 --- /dev/null +++ b/src/modules/lookups/modules/working-conditions/store/working-conditions.js @@ -0,0 +1,25 @@ +import ObjectStoreModule from '../../../../../app/store/BaseStoreModules/StoreModules/ObjectStoreModule'; +import WorkingConditionsAPI from '../api/workingConditions.js'; +import headers from './_internals/headers'; + +const resettableState = { + itemInstance: { + name: '', + description: '', + workdayHours: 0, + workdayPerMonth: 0, + pauseDuration: 0, + vacation: 0, + pauseTemplate: {}, + sickLeaves: 0, + shiftTemplate: {}, + daysOff: 0, + }, +}; + +const WorkingConditions = new ObjectStoreModule({ resettableState, headers }) +.attachAPIModule(WorkingConditionsAPI) +.generateAPIActions() +.getModule(); + +export default WorkingConditions; diff --git a/src/modules/lookups/store/lookups.js b/src/modules/lookups/store/lookups.js index 6985235ae..3e510e85c 100644 --- a/src/modules/lookups/store/lookups.js +++ b/src/modules/lookups/store/lookups.js @@ -9,6 +9,8 @@ import regions from '../modules/regions/store/regions'; import shiftTemplates from '../modules/shift-templates/store/shift-templates.js'; import pauseTemplates from '../modules/pause-templates/store/pause-templates.js'; +import workingConditions + from '../modules/working-conditions/store/working-conditions.js'; const modules = { skills, @@ -21,6 +23,7 @@ const modules = { media, shiftTemplates, pauseTemplates, + workingConditions, }; export default { From 05c822b6cd8e06330e86fee1fee0fc0006f28a43 Mon Sep 17 00:00:00 2001 From: Lera24 Date: Mon, 30 Sep 2024 17:22:40 +0300 Subject: [PATCH 2/3] feature: add feildsToSend in WorkConditionsAPI[WTEL-5078] --- .../modules/working-conditions/api/workingConditions.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/modules/lookups/modules/working-conditions/api/workingConditions.js b/src/modules/lookups/modules/working-conditions/api/workingConditions.js index 2d93bb86e..354b0c3cd 100644 --- a/src/modules/lookups/modules/working-conditions/api/workingConditions.js +++ b/src/modules/lookups/modules/working-conditions/api/workingConditions.js @@ -50,7 +50,8 @@ const getWorkingCondition = async ({ itemId: id }) => { } }; -const fieldsToSend = ['name', 'description', 'workdayHours', 'workdayPerMonth', 'pauseDuration', 'vacation', 'pauseTemplate', 'sickLeaves', 'shiftTemplate', 'daysOff']; +const fieldsToSend = ['name', 'description', 'workdayHours', 'workdayPerMonth', 'pauseDuration', 'vacation', 'pauseTemplate', 'sickLeaves', 'shiftTemplate', 'daysOff', 'createdAt', 'createdBy', 'domainId', 'id', '\n' + +'updatedAt', 'updatedBy']; const addWorkingCondition = async ({ itemInstance }) => { const item = applyTransform(itemInstance, [sanitize(fieldsToSend), camelToSnake()]); @@ -66,7 +67,7 @@ const updateWorkingCondition = async ({ itemInstance, itemId: id }) => { const item = applyTransform(itemInstance, [sanitize(fieldsToSend), camelToSnake()]); try { const response = await workingConditionService.updateWorkingCondition(id, { item: { ...item }}); - return applyTransform(response.data, [snakeToCamel(), itemResponseHandler]); + return applyTransform(response.data, [snakeToCamel()]); } catch (err) { throw applyTransform(err, [notify]); } From f65cc39019a584b60fe8490fdd1c8043e1e0712b Mon Sep 17 00:00:00 2001 From: Lera24 Date: Mon, 30 Sep 2024 17:24:13 +0300 Subject: [PATCH 3/3] fix: fieldsToSend in API[WTEL-5078] --- .../modules/working-conditions/api/workingConditions.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/modules/lookups/modules/working-conditions/api/workingConditions.js b/src/modules/lookups/modules/working-conditions/api/workingConditions.js index 354b0c3cd..956b4fb7f 100644 --- a/src/modules/lookups/modules/working-conditions/api/workingConditions.js +++ b/src/modules/lookups/modules/working-conditions/api/workingConditions.js @@ -50,8 +50,7 @@ const getWorkingCondition = async ({ itemId: id }) => { } }; -const fieldsToSend = ['name', 'description', 'workdayHours', 'workdayPerMonth', 'pauseDuration', 'vacation', 'pauseTemplate', 'sickLeaves', 'shiftTemplate', 'daysOff', 'createdAt', 'createdBy', 'domainId', 'id', '\n' + -'updatedAt', 'updatedBy']; +const fieldsToSend = ['name', 'description', 'workdayHours', 'workdayPerMonth', 'pauseDuration', 'vacation', 'pauseTemplate', 'sickLeaves', 'shiftTemplate', 'daysOff', 'createdAt', 'createdBy', 'domainId', 'id', 'updatedAt', 'updatedBy']; const addWorkingCondition = async ({ itemInstance }) => { const item = applyTransform(itemInstance, [sanitize(fieldsToSend), camelToSnake()]);