forked from verdnatura/salix-front
Merge pull request 'Desarrollo de los submodulos basic data, notes y pbx' (!245) from hyervoni/salix-front-mindshore:features/ms_submodulos_worker into dev
Reviewed-on: verdnatura/salix-front#245 Reviewed-by: Javier Segarra <jsegarra@verdnatura.es> Reviewed-by: Alex Moreno <alexm@verdnatura.es>
This commit is contained in:
commit
dafc9f83b9
|
@ -227,6 +227,7 @@ watch(formUrl, async () => {
|
|||
defineExpose({
|
||||
save,
|
||||
isLoading,
|
||||
hasChanges,
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
|
|
|
@ -82,6 +82,11 @@ select:-webkit-autofill {
|
|||
color: $white;
|
||||
}
|
||||
|
||||
.card-width {
|
||||
max-width: 800px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.vn-card {
|
||||
background-color: var(--vn-section-color);
|
||||
color: var(--vn-text-color);
|
||||
|
|
|
@ -851,12 +851,14 @@ export default {
|
|||
pageTitles: {
|
||||
workers: 'Workers',
|
||||
list: 'List',
|
||||
basicData: 'Basic data',
|
||||
summary: 'Summary',
|
||||
notifications: 'Notifications',
|
||||
workerCreate: 'New worker',
|
||||
department: 'Department',
|
||||
basicData: 'Basic data',
|
||||
notes: 'Notes',
|
||||
pda: 'PDA',
|
||||
notifications: 'Notifications',
|
||||
pbx: 'Private Branch Exchange',
|
||||
log: 'Log',
|
||||
},
|
||||
list: {
|
||||
|
|
|
@ -850,12 +850,14 @@ export default {
|
|||
pageTitles: {
|
||||
workers: 'Trabajadores',
|
||||
list: 'Listado',
|
||||
basicData: 'Datos básicos',
|
||||
summary: 'Resumen',
|
||||
notifications: 'Notificaciones',
|
||||
workerCreate: 'Nuevo trabajador',
|
||||
department: 'Departamentos',
|
||||
basicData: 'Datos básicos',
|
||||
notes: 'Notas',
|
||||
pda: 'PDA',
|
||||
notifications: 'Notificaciones',
|
||||
pbx: 'Centralita',
|
||||
log: 'Historial',
|
||||
},
|
||||
list: {
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import FormModel from 'src/components/FormModel.vue';
|
||||
import VnRow from 'components/ui/VnRow.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
|
||||
const workersOptions = ref([]);
|
||||
const countriesOptions = ref([]);
|
||||
const educationLevelsOptions = ref([]);
|
||||
|
||||
const workerFilter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['name', 'emailVerified'],
|
||||
include: { relation: 'emailUser', scope: { fields: ['email'] } },
|
||||
},
|
||||
},
|
||||
{ relation: 'sip', scope: { fields: ['extension', 'secret'] } },
|
||||
{ relation: 'department', scope: { include: { relation: 'department' } } },
|
||||
],
|
||||
};
|
||||
const workersFilter = {
|
||||
fields: ['id', 'nickname'],
|
||||
order: 'nickname ASC',
|
||||
limit: 30,
|
||||
};
|
||||
const countriesFilter = {
|
||||
fields: ['id', 'country', 'code'],
|
||||
order: 'country ASC',
|
||||
limit: 30,
|
||||
};
|
||||
const educationLevelsFilter = { fields: ['id', 'name'], order: 'name ASC', limit: 30 };
|
||||
|
||||
const maritalStatus = [
|
||||
{ code: 'M', name: t('Married') },
|
||||
{ code: 'S', name: t('Single') },
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FetchData
|
||||
:filter="workersFilter"
|
||||
@on-fetch="(data) => (workersOptions = data)"
|
||||
auto-load
|
||||
url="Workers/search"
|
||||
/>
|
||||
<FetchData
|
||||
:filter="countriesFilter"
|
||||
@on-fetch="(data) => (countriesOptions = data)"
|
||||
auto-load
|
||||
url="Countries"
|
||||
/>
|
||||
<FetchData
|
||||
:filter="educationLevelsFilter"
|
||||
@on-fetch="(data) => (educationLevelsOptions = data)"
|
||||
auto-load
|
||||
url="EducationLevels"
|
||||
/>
|
||||
|
||||
<FormModel
|
||||
:filter="workerFilter"
|
||||
:url="`Workers/${route.params.id}`"
|
||||
auto-load
|
||||
model="Worker"
|
||||
>
|
||||
<template #form="{ data }">
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<VnInput :label="t('Name')" clearable v-model="data.firstName" />
|
||||
<VnInput :label="t('Last name')" clearable v-model="data.lastName" />
|
||||
</VnRow>
|
||||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<VnInput v-model="data.phone" :label="t('Business phone')" clearable />
|
||||
<VnInput
|
||||
v-model="data.mobileExtension"
|
||||
:label="t('Mobile extension')"
|
||||
clearable
|
||||
/>
|
||||
</VnRow>
|
||||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<VnSelectFilter
|
||||
:label="t('Boss')"
|
||||
:options="workersOptions"
|
||||
hide-selected
|
||||
option-label="nickname"
|
||||
option-value="id"
|
||||
v-model="data.bossFk"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ scope.opt?.nickname }},
|
||||
{{ scope.opt?.code }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelectFilter>
|
||||
<VnSelectFilter
|
||||
:label="t('Marital status')"
|
||||
:options="maritalStatus"
|
||||
hide-selected
|
||||
option-label="name"
|
||||
option-value="code"
|
||||
v-model="data.maritalStatus"
|
||||
/>
|
||||
</VnRow>
|
||||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<VnSelectFilter
|
||||
:label="t('Origin country')"
|
||||
:options="countriesOptions"
|
||||
hide-selected
|
||||
option-label="country"
|
||||
option-value="id"
|
||||
v-model="data.originCountryFk"
|
||||
/>
|
||||
<VnSelectFilter
|
||||
:label="t('Education level')"
|
||||
:options="educationLevelsOptions"
|
||||
hide-selected
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
v-model="data.educationLevelFk"
|
||||
/>
|
||||
</VnRow>
|
||||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<VnInput v-model="data.SSN" :label="t('SSN')" clearable />
|
||||
<VnInput
|
||||
v-model="data.locker"
|
||||
type="number"
|
||||
:label="t('Locker')"
|
||||
clearable
|
||||
/>
|
||||
</VnRow>
|
||||
</template>
|
||||
</FormModel>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Name: Nombre
|
||||
Last name: Apellidos
|
||||
Business phone: Teléfono de empresa
|
||||
Mobile extension: Extensión móvil
|
||||
Boss: Jefe
|
||||
Marital status: Estado civil
|
||||
Married: Casado/a
|
||||
Single: Soltero/a
|
||||
Origin country: País origen
|
||||
Education level: Nivel educación
|
||||
SSN: NSS
|
||||
Locker: Taquilla
|
||||
</i18n>
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useSession } from 'src/composables/useSession';
|
||||
|
@ -7,6 +7,7 @@ import CardDescriptor from 'src/components/ui/CardDescriptor.vue';
|
|||
import VnLv from 'src/components/ui/VnLv.vue';
|
||||
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
|
||||
import useCardDescription from 'src/composables/useCardDescription';
|
||||
import { useState } from 'src/composables/useState';
|
||||
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
|
@ -23,6 +24,7 @@ const $props = defineProps({
|
|||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
const { getTokenMultimedia } = useSession();
|
||||
const state = useState();
|
||||
|
||||
const entityId = computed(() => {
|
||||
return $props.id || route.params.id;
|
||||
|
@ -53,7 +55,18 @@ const filter = {
|
|||
],
|
||||
};
|
||||
|
||||
const sip = computed(() => worker.value?.sip && worker.value.sip.extension);
|
||||
const sip = ref(null);
|
||||
|
||||
watch(
|
||||
() => [worker.value?.sip?.extension, state.get('extension')],
|
||||
([newWorkerSip, newStateExtension], [oldWorkerSip, oldStateExtension]) => {
|
||||
if (newStateExtension !== oldStateExtension || sip.value === oldStateExtension) {
|
||||
sip.value = newStateExtension;
|
||||
} else if (newWorkerSip !== oldWorkerSip && sip.value !== newStateExtension) {
|
||||
sip.value = newWorkerSip;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function getWorkerAvatar() {
|
||||
const token = getTokenMultimedia();
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<script setup>
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import VnNotes from 'src/components/ui/VnNotes.vue';
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const filter = {
|
||||
order: 'created DESC',
|
||||
where: { workerFk: route.params.id },
|
||||
include: {
|
||||
relation: 'worker',
|
||||
scope: {
|
||||
fields: ['id', 'firstName', 'lastName'],
|
||||
include: {
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['id', 'nickname'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const body = {
|
||||
workerFk: route.params.id,
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VnNotes
|
||||
style="overflow-y: auto"
|
||||
:add-note="{ type: Boolean, default: true }"
|
||||
url="WorkerObservations"
|
||||
:filter="filter"
|
||||
:body="body"
|
||||
/>
|
||||
</template>
|
|
@ -0,0 +1,70 @@
|
|||
<script setup>
|
||||
import { watch, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { useState } from 'src/composables/useState';
|
||||
|
||||
import FormModel from 'src/components/FormModel.vue';
|
||||
import VnRow from 'components/ui/VnRow.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const state = useState();
|
||||
const route = useRoute();
|
||||
const workerPBXForm = ref();
|
||||
const extension = ref(null);
|
||||
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'sip',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
watch(
|
||||
() => route.params.id,
|
||||
() => state.set('extension', null)
|
||||
);
|
||||
|
||||
const onFetch = (data) => {
|
||||
state.set('extension', data?.sip?.extension);
|
||||
extension.value = state.get('extension');
|
||||
};
|
||||
|
||||
const updateModelValue = (data) => {
|
||||
state.set('extension', data);
|
||||
workerPBXForm.value.hasChanges = true;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FormModel
|
||||
ref="workerPBXForm"
|
||||
:filter="filter"
|
||||
:url="`Workers/${route.params.id}`"
|
||||
url-update="Sips"
|
||||
auto-load
|
||||
:mapper="
|
||||
() => ({
|
||||
userFk: +route.params.id,
|
||||
extension,
|
||||
})
|
||||
"
|
||||
model="DeviceProductionUser"
|
||||
@on-fetch="onFetch"
|
||||
>
|
||||
<template #form="{}">
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnInput
|
||||
:label="t('worker.summary.sipExtension')"
|
||||
v-model="extension"
|
||||
@update:model-value="updateModelValue"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
</template>
|
||||
</FormModel>
|
||||
</template>
|
|
@ -12,7 +12,14 @@ export default {
|
|||
redirect: { name: 'WorkerMain' },
|
||||
menus: {
|
||||
main: ['WorkerList', 'WorkerDepartment'],
|
||||
card: ['WorkerNotificationsManager', 'WorkerPda', 'WorkerLog'],
|
||||
card: [
|
||||
'WorkerBasicData',
|
||||
'WorkerNotes',
|
||||
'WorkerPda',
|
||||
'WorkerNotificationsManager',
|
||||
'WorkerPBX',
|
||||
'WorkerLog',
|
||||
],
|
||||
departmentCard: ['BasicData'],
|
||||
},
|
||||
children: [
|
||||
|
@ -66,6 +73,52 @@ export default {
|
|||
},
|
||||
component: () => import('src/pages/Worker/Card/WorkerSummary.vue'),
|
||||
},
|
||||
{
|
||||
path: 'basic-data',
|
||||
name: 'WorkerBasicData',
|
||||
meta: {
|
||||
title: 'basicData',
|
||||
icon: 'vn:settings',
|
||||
},
|
||||
component: () => import('src/pages/Worker/Card/WorkerBasicData.vue'),
|
||||
},
|
||||
{
|
||||
path: 'notes',
|
||||
name: 'NotesCard',
|
||||
redirect: { name: 'WorkerNotes' },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'WorkerNotes',
|
||||
meta: {
|
||||
title: 'notes',
|
||||
icon: 'vn:notes',
|
||||
},
|
||||
component: () =>
|
||||
import('src/pages/Worker/Card/WorkerNotes.vue'),
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
name: 'WorkerNoteCreate',
|
||||
meta: {
|
||||
title: 'note-create',
|
||||
},
|
||||
component: () =>
|
||||
import(
|
||||
'src/pages/Worker/components/WorkerNoteCreate.vue'
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'WorkerPda',
|
||||
path: 'pda',
|
||||
meta: {
|
||||
title: 'pda',
|
||||
icon: 'phone_android',
|
||||
},
|
||||
component: () => import('src/pages/Worker/Card/WorkerPda.vue'),
|
||||
},
|
||||
{
|
||||
name: 'WorkerNotificationsManager',
|
||||
path: 'notifications',
|
||||
|
@ -77,13 +130,13 @@ export default {
|
|||
import('src/pages/Worker/Card/WorkerNotificationsManager.vue'),
|
||||
},
|
||||
{
|
||||
name: 'WorkerPda',
|
||||
path: 'pda',
|
||||
path: 'pbx',
|
||||
name: 'WorkerPBX',
|
||||
meta: {
|
||||
title: 'pda',
|
||||
icon: 'phone_android',
|
||||
title: 'pbx',
|
||||
icon: 'vn:pbx',
|
||||
},
|
||||
component: () => import('src/pages/Worker/Card/WorkerPda.vue'),
|
||||
component: () => import('src/pages/Worker/Card/WorkerPBX.vue'),
|
||||
},
|
||||
{
|
||||
name: 'WorkerLog',
|
||||
|
|
Loading…
Reference in New Issue