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({
|
defineExpose({
|
||||||
save,
|
save,
|
||||||
isLoading,
|
isLoading,
|
||||||
|
hasChanges,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -82,6 +82,11 @@ select:-webkit-autofill {
|
||||||
color: $white;
|
color: $white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card-width {
|
||||||
|
max-width: 800px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.vn-card {
|
.vn-card {
|
||||||
background-color: var(--vn-section-color);
|
background-color: var(--vn-section-color);
|
||||||
color: var(--vn-text-color);
|
color: var(--vn-text-color);
|
||||||
|
|
|
@ -851,12 +851,14 @@ export default {
|
||||||
pageTitles: {
|
pageTitles: {
|
||||||
workers: 'Workers',
|
workers: 'Workers',
|
||||||
list: 'List',
|
list: 'List',
|
||||||
basicData: 'Basic data',
|
|
||||||
summary: 'Summary',
|
summary: 'Summary',
|
||||||
notifications: 'Notifications',
|
|
||||||
workerCreate: 'New worker',
|
workerCreate: 'New worker',
|
||||||
department: 'Department',
|
department: 'Department',
|
||||||
|
basicData: 'Basic data',
|
||||||
|
notes: 'Notes',
|
||||||
pda: 'PDA',
|
pda: 'PDA',
|
||||||
|
notifications: 'Notifications',
|
||||||
|
pbx: 'Private Branch Exchange',
|
||||||
log: 'Log',
|
log: 'Log',
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
|
|
|
@ -850,12 +850,14 @@ export default {
|
||||||
pageTitles: {
|
pageTitles: {
|
||||||
workers: 'Trabajadores',
|
workers: 'Trabajadores',
|
||||||
list: 'Listado',
|
list: 'Listado',
|
||||||
basicData: 'Datos básicos',
|
|
||||||
summary: 'Resumen',
|
summary: 'Resumen',
|
||||||
notifications: 'Notificaciones',
|
|
||||||
workerCreate: 'Nuevo trabajador',
|
workerCreate: 'Nuevo trabajador',
|
||||||
department: 'Departamentos',
|
department: 'Departamentos',
|
||||||
|
basicData: 'Datos básicos',
|
||||||
|
notes: 'Notas',
|
||||||
pda: 'PDA',
|
pda: 'PDA',
|
||||||
|
notifications: 'Notificaciones',
|
||||||
|
pbx: 'Centralita',
|
||||||
log: 'Historial',
|
log: 'Historial',
|
||||||
},
|
},
|
||||||
list: {
|
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>
|
<script setup>
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useSession } from 'src/composables/useSession';
|
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 VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
|
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
|
||||||
import useCardDescription from 'src/composables/useCardDescription';
|
import useCardDescription from 'src/composables/useCardDescription';
|
||||||
|
import { useState } from 'src/composables/useState';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -23,6 +24,7 @@ const $props = defineProps({
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { getTokenMultimedia } = useSession();
|
const { getTokenMultimedia } = useSession();
|
||||||
|
const state = useState();
|
||||||
|
|
||||||
const entityId = computed(() => {
|
const entityId = computed(() => {
|
||||||
return $props.id || route.params.id;
|
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() {
|
function getWorkerAvatar() {
|
||||||
const token = getTokenMultimedia();
|
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' },
|
redirect: { name: 'WorkerMain' },
|
||||||
menus: {
|
menus: {
|
||||||
main: ['WorkerList', 'WorkerDepartment'],
|
main: ['WorkerList', 'WorkerDepartment'],
|
||||||
card: ['WorkerNotificationsManager', 'WorkerPda', 'WorkerLog'],
|
card: [
|
||||||
|
'WorkerBasicData',
|
||||||
|
'WorkerNotes',
|
||||||
|
'WorkerPda',
|
||||||
|
'WorkerNotificationsManager',
|
||||||
|
'WorkerPBX',
|
||||||
|
'WorkerLog',
|
||||||
|
],
|
||||||
departmentCard: ['BasicData'],
|
departmentCard: ['BasicData'],
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -66,6 +73,52 @@ export default {
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Worker/Card/WorkerSummary.vue'),
|
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',
|
name: 'WorkerNotificationsManager',
|
||||||
path: 'notifications',
|
path: 'notifications',
|
||||||
|
@ -77,13 +130,13 @@ export default {
|
||||||
import('src/pages/Worker/Card/WorkerNotificationsManager.vue'),
|
import('src/pages/Worker/Card/WorkerNotificationsManager.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'WorkerPda',
|
path: 'pbx',
|
||||||
path: 'pda',
|
name: 'WorkerPBX',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'pda',
|
title: 'pbx',
|
||||||
icon: 'phone_android',
|
icon: 'vn:pbx',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Worker/Card/WorkerPda.vue'),
|
component: () => import('src/pages/Worker/Card/WorkerPBX.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'WorkerLog',
|
name: 'WorkerLog',
|
||||||
|
|
Loading…
Reference in New Issue