0
0
Fork 0

Merge branch 'dev' into 7406-workerFormation

This commit is contained in:
Carlos Satorres 2024-06-25 11:18:05 +00:00
commit 49b86672f5
22 changed files with 203 additions and 150 deletions

View File

@ -1,11 +1,10 @@
import axios from 'axios'; import axios from 'axios';
import { Notify } from 'quasar';
import { useSession } from 'src/composables/useSession'; import { useSession } from 'src/composables/useSession';
import { Router } from 'src/router'; import { Router } from 'src/router';
import { i18n } from './i18n'; import useNotify from 'src/composables/useNotify.js';
const session = useSession(); const session = useSession();
const { t } = i18n.global; const { notify } = useNotify();
axios.defaults.baseURL = '/api/'; axios.defaults.baseURL = '/api/';
@ -27,10 +26,7 @@ const onResponse = (response) => {
const isSaveRequest = method === 'patch'; const isSaveRequest = method === 'patch';
if (isSaveRequest) { if (isSaveRequest) {
Notify.create({ notify('globals.dataSaved', 'positive');
message: t('globals.dataSaved'),
type: 'positive',
});
} }
return response; return response;
@ -67,10 +63,7 @@ const onResponseError = (error) => {
return Promise.reject(error); return Promise.reject(error);
} }
Notify.create({ notify(message, 'negative');
message: t(message),
type: 'negative',
});
return Promise.reject(error); return Promise.reject(error);
}; };

View File

@ -148,7 +148,7 @@ async function onSubmit() {
await saveChanges($props.saveFn ? formData.value : null); await saveChanges($props.saveFn ? formData.value : null);
} }
async function onSumbitAndGo() { async function onSubmitAndGo() {
await onSubmit(); await onSubmit();
push({ path: $props.goTo }); push({ path: $props.goTo });
} }
@ -339,7 +339,7 @@ watch(formUrl, async () => {
/> />
<QBtnDropdown <QBtnDropdown
v-if="$props.goTo && $props.defaultSave" v-if="$props.goTo && $props.defaultSave"
@click="onSumbitAndGo" @click="onSubmitAndGo"
:label="tMobile('globals.saveAndContinue')" :label="tMobile('globals.saveAndContinue')"
:title="t('globals.saveAndContinue')" :title="t('globals.saveAndContinue')"
:disable="!hasChanges" :disable="!hasChanges"

View File

@ -83,6 +83,10 @@ const $props = defineProps({
default: '', default: '',
description: 'It is used for redirect on click "save and continue"', description: 'It is used for redirect on click "save and continue"',
}, },
reload: {
type: Boolean,
default: false,
},
}); });
const emit = defineEmits(['onFetch', 'onDataSaved']); const emit = defineEmits(['onFetch', 'onDataSaved']);
const modelValue = computed( const modelValue = computed(
@ -201,6 +205,7 @@ async function save() {
if ($props.urlCreate) notify('globals.dataCreated', 'positive'); if ($props.urlCreate) notify('globals.dataCreated', 'positive');
updateAndEmit('onDataSaved', formData.value, response?.data); updateAndEmit('onDataSaved', formData.value, response?.data);
if ($props.reload) await arrayData.fetch({});
} catch (err) { } catch (err) {
console.error(err); console.error(err);
notify('errors.writeRequest', 'negative'); notify('errors.writeRequest', 'negative');

View File

@ -0,0 +1,23 @@
<script setup>
defineProps({
title: { type: String, default: null },
content: { type: [String, Number], default: null },
});
</script>
<template>
<QPopupProxy>
<QCard>
<slot name="title">
<div
class="header q-px-sm q-py-xs q-ma-none text-white text-bold bg-primary"
v-text="title"
/>
</slot>
<slot name="content">
<QCardSection class="change-detail q-pa-sm">
{{ content }}
</QCardSection>
</slot>
</QCard>
</QPopupProxy>
</template>

View File

@ -39,6 +39,7 @@ const $props = defineProps({
}); });
const state = useState(); const state = useState();
const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const { viewSummary } = useSummaryDialog(); const { viewSummary } = useSummaryDialog();
let arrayData; let arrayData;
@ -57,7 +58,7 @@ onBeforeMount(async () => {
store = arrayData.store; store = arrayData.store;
entity = computed(() => (Array.isArray(store.data) ? store.data[0] : store.data)); entity = computed(() => (Array.isArray(store.data) ? store.data[0] : store.data));
// It enables to load data only once if the module is the same as the dataKey // It enables to load data only once if the module is the same as the dataKey
if ($props.dataKey !== useRoute().meta.moduleName) await getData(); if ($props.dataKey !== route.meta.moduleName || !route.params.id) await getData();
watch( watch(
() => [$props.url, $props.filter], () => [$props.url, $props.filter],
async () => await getData() async () => await getData()

View File

@ -22,6 +22,10 @@ const props = defineProps({
type: String, type: String,
default: '', default: '',
}, },
moduleName: {
type: String,
default: null,
},
}); });
const emit = defineEmits(['onFetch']); const emit = defineEmits(['onFetch']);
const route = useRoute(); const route = useRoute();
@ -83,7 +87,7 @@ function existSummary(routes) {
v-if="showRedirectToSummaryIcon" v-if="showRedirectToSummaryIcon"
class="header link" class="header link"
:to="{ :to="{
name: `${route.meta.moduleName}Summary`, name: `${moduleName ?? route.meta.moduleName}Summary`,
params: { id: entityId || entity.id }, params: { id: entityId || entity.id },
}" }"
> >

View File

@ -113,6 +113,7 @@ globals:
name: Name name: Name
new: New new: New
comment: Comment comment: Comment
observations: Observations
errors: errors:
statusUnauthorized: Access denied statusUnauthorized: Access denied
statusInternalServerError: An internal server error has ocurred statusInternalServerError: An internal server error has ocurred

View File

@ -114,6 +114,7 @@ globals:
name: Nombre name: Nombre
new: Nuevo new: Nuevo
comment: Comentario comment: Comentario
observations: Observaciones
errors: errors:
statusUnauthorized: Acceso denegado statusUnauthorized: Acceso denegado
statusInternalServerError: Ha ocurrido un error interno del servidor statusInternalServerError: Ha ocurrido un error interno del servidor

View File

@ -17,26 +17,6 @@ const { t } = useI18n();
const { getTokenMultimedia } = useSession(); const { getTokenMultimedia } = useSession();
const token = getTokenMultimedia(); const token = getTokenMultimedia();
const claimFilter = {
fields: [
'id',
'clientFk',
'created',
'workerFk',
'claimStateFk',
'packages',
'pickup',
],
include: [
{
relation: 'client',
scope: {
fields: ['name'],
},
},
],
};
const claimStates = ref([]); const claimStates = ref([]);
const claimStatesCopy = ref([]); const claimStatesCopy = ref([]);
const optionsList = ref([]); const optionsList = ref([]);
@ -87,11 +67,10 @@ const statesFilter = {
/> />
<FetchData url="ClaimStates" @on-fetch="setClaimStates" auto-load /> <FetchData url="ClaimStates" @on-fetch="setClaimStates" auto-load />
<FormModel <FormModel
:url="`Claims/${route.params.id}`" model="Claim"
:url-update="`Claims/updateClaim/${route.params.id}`" :url-update="`Claims/updateClaim/${route.params.id}`"
:filter="claimFilter"
model="claim"
auto-load auto-load
:reload="true"
> >
<template #form="{ data, validate, filter }"> <template #form="{ data, validate, filter }">
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">

View File

@ -2,6 +2,7 @@
import VnCard from 'components/common/VnCard.vue'; import VnCard from 'components/common/VnCard.vue';
import ClaimDescriptor from './ClaimDescriptor.vue'; import ClaimDescriptor from './ClaimDescriptor.vue';
import ClaimFilter from '../ClaimFilter.vue'; import ClaimFilter from '../ClaimFilter.vue';
import filter from './ClaimFilter.js';
</script> </script>
<template> <template>
<VnCard <VnCard
@ -13,5 +14,6 @@ import ClaimFilter from '../ClaimFilter.vue';
search-url="Claims/filter" search-url="Claims/filter"
searchbar-label="Search claim" searchbar-label="Search claim"
searchbar-info="You can search by claim id or customer name" searchbar-info="You can search by claim id or customer name"
:filter="filter"
/> />
</template> </template>

View File

@ -12,6 +12,7 @@ import useCardDescription from 'src/composables/useCardDescription';
import VnUserLink from 'src/components/ui/VnUserLink.vue'; import VnUserLink from 'src/components/ui/VnUserLink.vue';
import { getUrl } from 'src/composables/getUrl'; import { getUrl } from 'src/composables/getUrl';
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue'; import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
import filter from './ClaimFilter.js';
const $props = defineProps({ const $props = defineProps({
id: { id: {
@ -29,49 +30,6 @@ const entityId = computed(() => {
return $props.id || route.params.id; return $props.id || route.params.id;
}); });
const filter = {
include: [
{
relation: 'client',
scope: {
include: [
{ relation: 'salesPersonUser' },
{
relation: 'claimsRatio',
scope: {
fields: ['claimingRate'],
limit: 1,
},
},
],
},
},
{
relation: 'claimState',
},
{
relation: 'ticket',
scope: {
include: [
{ relation: 'zone' },
{
relation: 'address',
scope: {
include: { relation: 'province' },
},
},
],
},
},
{
relation: 'worker',
scope: {
include: { relation: 'user' },
},
},
],
};
const STATE_COLOR = { const STATE_COLOR = {
pending: 'warning', pending: 'warning',
incomplete: 'info', incomplete: 'info',
@ -101,7 +59,7 @@ onMounted(async () => {
:title="data.title" :title="data.title"
:subtitle="data.subtitle" :subtitle="data.subtitle"
@on-fetch="setData" @on-fetch="setData"
data-key="claimData" data-key="Claim"
> >
<template #menu="{ entity }"> <template #menu="{ entity }">
<ClaimDescriptorMenu :claim="entity" /> <ClaimDescriptorMenu :claim="entity" />

View File

@ -0,0 +1,52 @@
export default {
fields: [
'id',
'clientFk',
'created',
'workerFk',
'claimStateFk',
'packages',
'pickup',
'ticketFk',
],
include: [
{
relation: 'client',
scope: {
include: [
{ relation: 'salesPersonUser' },
{
relation: 'claimsRatio',
scope: {
fields: ['claimingRate'],
limit: 1,
},
},
],
},
},
{
relation: 'claimState',
},
{
relation: 'ticket',
scope: {
include: [
{ relation: 'zone' },
{
relation: 'address',
scope: {
include: { relation: 'province' },
},
},
],
},
},
{
relation: 'worker',
scope: {
include: { relation: 'user' },
},
},
],
};

View File

@ -22,7 +22,7 @@ const balanceDueTotal = ref(0);
const selected = ref([]); const selected = ref([]);
const tableColumnComponents = { const tableColumnComponents = {
client: { clientFk: {
component: QBtn, component: QBtn,
props: () => ({ flat: true, class: 'link', noCaps: true }), props: () => ({ flat: true, class: 'link', noCaps: true }),
event: () => {}, event: () => {},
@ -40,7 +40,7 @@ const tableColumnComponents = {
props: () => ({ flat: true, class: 'link', noCaps: true }), props: () => ({ flat: true, class: 'link', noCaps: true }),
event: () => {}, event: () => {},
}, },
department: { departmentName: {
component: 'span', component: 'span',
props: () => {}, props: () => {},
event: () => {}, event: () => {},
@ -102,12 +102,12 @@ const columns = computed(() => [
align: 'left', align: 'left',
field: 'clientName', field: 'clientName',
label: t('Client'), label: t('Client'),
name: 'client', name: 'clientFk',
sortable: true, sortable: true,
}, },
{ {
align: 'left', align: 'left',
field: 'isWorker', field: ({ isWorker }) => Boolean(isWorker),
label: t('Is worker'), label: t('Is worker'),
name: 'isWorker', name: 'isWorker',
}, },
@ -122,7 +122,7 @@ const columns = computed(() => [
align: 'left', align: 'left',
field: 'departmentName', field: 'departmentName',
label: t('Department'), label: t('Department'),
name: 'department', name: 'departmentName',
sortable: true, sortable: true,
}, },
{ {
@ -204,48 +204,24 @@ const viewAddObservation = (rowsSelected) => {
}); });
}; };
const departments = ref(new Map());
const onFetch = async (data) => { const onFetch = async (data) => {
const salesPersonFks = data.map((item) => item.salesPersonFk);
const departmentNames = salesPersonFks.map(async (salesPersonFk) => {
try {
const { data: workerDepartment } = await axios.get(
`WorkerDepartments/${salesPersonFk}`
);
const { data: department } = await axios.get(
`Departments/${workerDepartment.departmentFk}`
);
departments.value.set(salesPersonFk, department.name);
} catch (error) {
console.error('Err: ', error);
}
});
const recoveryData = await axios.get('Recoveries'); const recoveryData = await axios.get('Recoveries');
const recoveries = recoveryData.data.map(({ clientFk, finished }) => ({ const recoveries = recoveryData.data.map(({ clientFk, finished }) => ({
clientFk, clientFk,
finished, finished,
})); }));
await Promise.all(departmentNames);
data.forEach((item) => { data.forEach((item) => {
item.departmentName = departments.value.get(item.salesPersonFk);
item.isWorker = item.businessTypeFk === 'worker';
const recovery = recoveries.find(({ clientFk }) => clientFk === item.clientFk); const recovery = recoveries.find(({ clientFk }) => clientFk === item.clientFk);
item.finished = recovery?.finished === null; item.finished = recovery?.finished === null;
}); });
for (const element of data) element.isWorker = element.businessTypeFk === 'worker';
balanceDueTotal.value = data.reduce((acc, { amount = 0 }) => acc + amount, 0); balanceDueTotal.value = data.reduce((acc, { amount = 0 }) => acc + amount, 0);
}; };
function exprBuilder(param, value) { function exprBuilder(param, value) {
switch (param) { switch (param) {
case 'clientFk': case 'clientFk':
return { [`d.${param}`]: value?.id }; return { [`d.${param}`]: value };
case 'creditInsurance': case 'creditInsurance':
case 'amount': case 'amount':
case 'workerFk': case 'workerFk':

View File

@ -1,7 +1,6 @@
<script setup> <script setup>
import { ref } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
@ -16,14 +15,13 @@ const props = defineProps({
}, },
}); });
const clients = ref();
const salespersons = ref(); const salespersons = ref();
const countries = ref(); const countries = ref();
const authors = ref(); const authors = ref();
const departments = ref();
</script> </script>
<template> <template>
<FetchData @on-fetch="(data) => (clients = data)" auto-load url="Clients" />
<FetchData <FetchData
:filter="{ where: { role: 'salesPerson' } }" :filter="{ where: { role: 'salesPerson' } }"
@on-fetch="(data) => (salespersons = data)" @on-fetch="(data) => (salespersons = data)"
@ -36,6 +34,7 @@ const authors = ref();
auto-load auto-load
url="Workers/activeWithInheritedRole" url="Workers/activeWithInheritedRole"
/> />
<FetchData @on-fetch="(data) => (departments = data)" auto-load url="Departments" />
<VnFilterPanel :data-key="props.dataKey" :search-button="true"> <VnFilterPanel :data-key="props.dataKey" :search-button="true">
<template #tags="{ tag, formatFn }"> <template #tags="{ tag, formatFn }">
@ -47,29 +46,22 @@ const authors = ref();
<template #body="{ params, searchFn }"> <template #body="{ params, searchFn }">
<QItem class="q-mb-sm"> <QItem class="q-mb-sm">
<QItemSection v-if="clients">
<VnSelect <VnSelect
:label="t('Client')" :label="t('Client')"
:options="clients" url="Clients"
dense dense
emit-value
hide-selected
map-options
option-label="name" option-label="name"
option-value="id" option-value="id"
outlined outlined
rounded rounded
use-input emit-value
hide-selected
map-options
v-model="params.clientFk" v-model="params.clientFk"
use-input
@update:model-value="searchFn()" @update:model-value="searchFn()"
auto-load
/> />
</QItemSection>
<QItemSection v-else>
<QSkeleton class="full-width" type="QInput" />
</QItemSection>
</QItem> </QItem>
<QItem class="q-mb-sm"> <QItem class="q-mb-sm">
<QItemSection v-if="salespersons"> <QItemSection v-if="salespersons">
<VnSelect <VnSelect
@ -93,6 +85,29 @@ const authors = ref();
<QSkeleton class="full-width" type="QInput" /> <QSkeleton class="full-width" type="QInput" />
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem class="q-mb-sm">
<QItemSection v-if="departments">
<VnSelect
:input-debounce="0"
:label="t('Departments')"
:options="departments"
dense
emit-value
hide-selected
map-options
option-label="name"
option-value="id"
outlined
rounded
use-input
v-model="params.departmentFk"
@update:model-value="searchFn()"
/>
</QItemSection>
<QItemSection v-else>
<QSkeleton class="full-width" type="QInput" />
</QItemSection>
</QItem>
<QItem class="q-mb-sm"> <QItem class="q-mb-sm">
<QItemSection v-if="countries"> <QItemSection v-if="countries">

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import DepartmentDescriptor from './DepartmentDescriptor.vue'; import DepartmentDescriptor from './DepartmentDescriptor.vue';
import DepartmentSummaryDialog from './DepartmentSummaryDialog.vue'; import DepartmentSummary from './DepartmentSummary.vue';
const $props = defineProps({ const $props = defineProps({
id: { id: {
@ -15,7 +15,7 @@ const $props = defineProps({
<DepartmentDescriptor <DepartmentDescriptor
v-if="$props.id" v-if="$props.id"
:id="$props.id" :id="$props.id"
:summary="DepartmentSummaryDialog" :summary="DepartmentSummary"
/> />
</QPopupProxy> </QPopupProxy>
</template> </template>

View File

@ -32,6 +32,7 @@ onMounted(async () => {
:url="`Departments/${entityId}`" :url="`Departments/${entityId}`"
class="full-width" class="full-width"
style="max-width: 900px" style="max-width: 900px"
module-name="Department"
> >
<template #header="{ entity }"> <template #header="{ entity }">
<div>{{ entity.name }}</div> <div>{{ entity.name }}</div>

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { onBeforeMount, computed, ref } from 'vue'; import { onBeforeMount, onMounted, computed, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { Notify } from 'quasar'; import { Notify } from 'quasar';
import axios from 'axios'; import axios from 'axios';
@ -10,10 +10,12 @@ import CmrFilter from './CmrFilter.vue';
import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue'; import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue'; import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
import RightMenu from 'src/components/common/RightMenu.vue'; import RightMenu from 'src/components/common/RightMenu.vue';
import { useStateStore } from 'src/stores/useStateStore';
const { t } = useI18n(); const { t } = useI18n();
const { getTokenMultimedia } = useSession(); const { getTokenMultimedia } = useSession();
const token = getTokenMultimedia(); const token = getTokenMultimedia();
const state = useStateStore();
const selected = ref([]); const selected = ref([]);
const warehouses = ref([]); const warehouses = ref([]);
@ -81,6 +83,9 @@ onBeforeMount(async () => {
const { data } = await axios.get('Warehouses'); const { data } = await axios.get('Warehouses');
warehouses.value = data; warehouses.value = data;
}); });
onMounted(() => (state.rightDrawer = true));
function getApiUrl() { function getApiUrl() {
return new URL(window.location).origin; return new URL(window.location).origin;
} }

View File

@ -0,0 +1,7 @@
<script setup>
import VnLog from 'src/components/common/VnLog.vue';
</script>
<template>
<VnLog model="Ticket" url="/TicketLogs"></VnLog>
</template>

View File

@ -2,5 +2,5 @@
import VnLog from 'src/components/common/VnLog.vue'; import VnLog from 'src/components/common/VnLog.vue';
</script> </script>
<template> <template>
<VnLog model="Entry" url="/TravelLogs"></VnLog> <VnLog model="Travel" url="/TravelLogs"></VnLog>
</template> </template>

View File

@ -2,7 +2,6 @@
import { onMounted, ref, computed, watch } from 'vue'; import { onMounted, ref, computed, watch } from 'vue';
import { QBtn } from 'quasar'; import { QBtn } from 'quasar';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue'; import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue'; import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
@ -19,8 +18,8 @@ import { usePrintService } from 'composables/usePrintService';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import axios from 'axios'; import axios from 'axios';
import RightMenu from 'src/components/common/RightMenu.vue'; import RightMenu from 'src/components/common/RightMenu.vue';
import VnPopup from 'src/components/common/VnPopup.vue';
const router = useRouter();
const stateStore = useStateStore(); const stateStore = useStateStore();
const { t } = useI18n(); const { t } = useI18n();
const { openReport } = usePrintService(); const { openReport } = usePrintService();
@ -125,6 +124,10 @@ const tableColumnComponents = {
component: 'span', component: 'span',
attrs: {}, attrs: {},
}, },
notes: {
component: 'span',
attrs: {},
},
}; };
const columns = computed(() => [ const columns = computed(() => [
@ -250,6 +253,14 @@ const columns = computed(() => [
sortable: true, sortable: true,
format: (value) => toDate(value), format: (value) => toDate(value),
}, },
{
label: t('notes'),
field: '',
name: 'notes',
align: 'center',
showValue: false,
sortable: true,
},
]); ]);
async function getData() { async function getData() {
@ -298,10 +309,6 @@ const saveFieldValue = async (val, field, index) => {
} }
}; };
const navigateToTravelId = (id) => {
router.push({ path: `/travel/${id}` });
};
const stopEventPropagation = (event, col) => { const stopEventPropagation = (event, col) => {
// Detener la propagación del evento de los siguientes elementos para evitar el click sobre la row que dispararía la función navigateToTravelId // Detener la propagación del evento de los siguientes elementos para evitar el click sobre la row que dispararía la función navigateToTravelId
if (!['ref', 'id', 'cargoSupplierNickname', 'kg'].includes(col.name)) return; if (!['ref', 'id', 'cargoSupplierNickname', 'kg'].includes(col.name)) return;
@ -486,7 +493,7 @@ const getColor = (percentage) => {
<QTr <QTr
:props="props" :props="props"
class="cursor-pointer bg-travel" class="cursor-pointer bg-travel"
@click="navigateToTravelId(props.row.id)" @click="$router.push({ path: `/travel/${props.row.id}` })"
@dragenter="handleDragEnter($event, props.rowIndex)" @dragenter="handleDragEnter($event, props.rowIndex)"
@dragover.prevent @dragover.prevent
@drop="handleDrop()" @drop="handleDrop()"
@ -607,6 +614,20 @@ const getColor = (percentage) => {
<QTd /> <QTd />
<QTd /> <QTd />
<QTd /> <QTd />
<QTd>
<QBtn
v-if="entry.evaNotes"
icon="comment"
size="sm"
flat
color="primary"
>
<VnPopup
:title="t('globals.observations')"
:content="entry.evaNotes"
/>
</QBtn>
</QTd>
</QTr> </QTr>
</template> </template>
</QTable> </QTable>

View File

@ -9,7 +9,7 @@ export default {
moduleName: 'Department', moduleName: 'Department',
}, },
component: RouterView, component: RouterView,
redirect: { name: 'DepartmentCard' }, redirect: { name: 'WorkerDepartment' },
menus: { menus: {
main: [], main: [],
card: ['DepartmentBasicData'], card: ['DepartmentBasicData'],

View File

@ -12,7 +12,7 @@ export default {
redirect: { name: 'TicketMain' }, redirect: { name: 'TicketMain' },
menus: { menus: {
main: ['TicketList'], main: ['TicketList'],
card: ['TicketBoxing', 'TicketSms', 'TicketSale'], card: ['TicketBoxing', 'TicketSms', 'TicketSale', 'TicketLog'],
}, },
children: [ children: [
{ {
@ -93,6 +93,15 @@ export default {
}, },
component: () => import('src/pages/Ticket/Card/TicketSms.vue'), component: () => import('src/pages/Ticket/Card/TicketSms.vue'),
}, },
{
path: 'log',
name: 'TicketLog',
meta: {
title: 'log',
icon: 'history',
},
component: () => import('src/pages/Ticket/Card/TicketLog.vue'),
},
], ],
}, },
], ],