forked from verdnatura/salix-front
Create route list
This commit is contained in:
parent
3905dd05df
commit
3d98bf578e
|
@ -0,0 +1,108 @@
|
|||
<script setup>
|
||||
import {computed, ref} from 'vue';
|
||||
import { toHour} from 'src/filters';
|
||||
import {useI18n} from "vue-i18n";
|
||||
import isValidDate from "filters/isValidDate";
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isOutlined: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const value = computed({
|
||||
get() {
|
||||
return props.modelValue;
|
||||
},
|
||||
set(value) {
|
||||
const [hours, minutes] = value.split(':')
|
||||
const date = new Date()
|
||||
date.setUTCHours(Number.parseInt(hours) || 0, Number.parseInt(minutes) || 0, 0, 0)
|
||||
emit('update:modelValue', value ? date.toISOString() : null);
|
||||
},
|
||||
});
|
||||
|
||||
const onDateUpdate = (date) => {
|
||||
internalValue.value = date;
|
||||
};
|
||||
|
||||
const save = () => {
|
||||
value.value = internalValue.value;
|
||||
};
|
||||
const formatTime = (dateString) => {
|
||||
if (!isValidDate(dateString)){
|
||||
return ''
|
||||
}
|
||||
const date = new Date(dateString || '');
|
||||
return `${date.getUTCHours().toString().padStart(2, '0')}:${date.getUTCMinutes().toString().padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
const internalValue = ref(formatTime(value))
|
||||
|
||||
const styleAttrs = computed(() => {
|
||||
return props.isOutlined
|
||||
? {
|
||||
dense: true,
|
||||
outlined: true,
|
||||
rounded: true,
|
||||
}
|
||||
: {};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QInput
|
||||
class="vn-input-time"
|
||||
rounded
|
||||
readonly
|
||||
:model-value="toHour(value)"
|
||||
v-bind="{ ...$attrs, ...styleAttrs }"
|
||||
>
|
||||
<template #append>
|
||||
<QIcon name="event" class="cursor-pointer">
|
||||
<QPopupProxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
:no-parent-event="props.readonly"
|
||||
>
|
||||
<QTime
|
||||
:format24h="false"
|
||||
:model-value="formatTime(value)"
|
||||
@update:model-value="onDateUpdate"
|
||||
>
|
||||
<div class="row items-center justify-end q-gutter-sm">
|
||||
<QBtn :label="t('Cancel')" color="primary" flat v-close-popup />
|
||||
<QBtn label="Ok" color="primary" flat @click="save" v-close-popup />
|
||||
</div>
|
||||
</QTime>
|
||||
</QPopupProxy>
|
||||
</QIcon>
|
||||
</template>
|
||||
</QInput>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.vn-input-time.q-field--standard.q-field--readonly .q-field__control:before {
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
|
||||
.vn-input-time.q-field--outlined.q-field--readonly .q-field__control:before {
|
||||
border-style: solid;
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Cancel: Cancelar
|
||||
</i18n>
|
|
@ -8,11 +8,13 @@ import toPercentage from './toPercentage';
|
|||
import toLowerCamel from './toLowerCamel';
|
||||
import dashIfEmpty from './dashIfEmpty';
|
||||
import dateRange from './dateRange';
|
||||
import toHour from './toHour';
|
||||
|
||||
export {
|
||||
toLowerCase,
|
||||
toLowerCamel,
|
||||
toDate,
|
||||
toHour,
|
||||
toDateString,
|
||||
toDateHour,
|
||||
toRelativeDate,
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
export default function isValidDate(date) {
|
||||
return !isNaN(new Date(date).getTime());
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import isValidDate from 'filters/isValidDate';
|
||||
|
||||
export default function toHour(date) {
|
||||
if (!isValidDate(date)) {
|
||||
return '--:--';
|
||||
}
|
||||
const dateHour = new Date(date);
|
||||
let hours = dateHour.getUTCHours();
|
||||
hours = hours % 12;
|
||||
hours = hours ? hours : 12;
|
||||
|
||||
let minutes = dateHour.getUTCMinutes();
|
||||
minutes = minutes < 10 ? minutes.toString().padStart(2, '0') : minutes;
|
||||
|
||||
return `${hours}:${minutes} ${dateHour.getUTCHours() >= 12 ? 'PM' : 'AM'}`;
|
||||
}
|
|
@ -807,6 +807,7 @@ export default {
|
|||
pageTitles: {
|
||||
routes: 'Routes',
|
||||
cmrsList: 'External CMRs list',
|
||||
RouteList: 'List'
|
||||
},
|
||||
cmr: {
|
||||
list: {
|
||||
|
|
|
@ -806,6 +806,7 @@ export default {
|
|||
pageTitles: {
|
||||
routes: 'Rutas',
|
||||
cmrsList: 'Listado de CMRs externos',
|
||||
RouteList: 'Listado'
|
||||
},
|
||||
cmr: {
|
||||
list: {
|
||||
|
|
|
@ -0,0 +1,407 @@
|
|||
<script setup>
|
||||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
||||
import {dashIfEmpty, toDate, toHour} from 'src/filters';
|
||||
import VnSelectFilter from 'components/common/VnSelectFilter.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import { useValidator } from 'composables/useValidator';
|
||||
import VnInputDate from "components/common/VnInputDate.vue";
|
||||
import VnInput from "components/common/VnInput.vue";
|
||||
import VnInputTime from "components/common/VnInputTime.vue";
|
||||
import axios from "axios";
|
||||
|
||||
const stateStore = useStateStore();
|
||||
// const router = useRouter();
|
||||
// const quasar = useQuasar();
|
||||
const { t } = useI18n();
|
||||
const { validate } = useValidator();
|
||||
|
||||
const to = Date.vnNew();
|
||||
to.setDate(to.getDate() + 1);
|
||||
to.setHours(0, 0, 0, 0);
|
||||
|
||||
const from = Date.vnNew();
|
||||
from.setDate(from.getDate());
|
||||
from.setHours(0, 0, 0, 0);
|
||||
|
||||
const params = ref({ from, to });
|
||||
|
||||
onMounted(() => (stateStore.rightDrawer = true));
|
||||
onUnmounted(() => (stateStore.rightDrawer = false));
|
||||
|
||||
const selectedRows = ref([]);
|
||||
const columns = computed(() => [
|
||||
{
|
||||
name: 'ID',
|
||||
label: t('ID'),
|
||||
field: (row) => row.id,
|
||||
sortable: true,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
name: 'worker',
|
||||
label: t('Worker'),
|
||||
field: (row) => row.workerUserName,
|
||||
sortable: true,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
name: 'agency',
|
||||
label: t('Agency'),
|
||||
field: (row) => row.agencyName,
|
||||
sortable: true,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
name: 'vehicle',
|
||||
label: t('Vehicle'),
|
||||
field: (row) => row.vehiclePlateNumber,
|
||||
sortable: true,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
name: 'date',
|
||||
label: t('Date'),
|
||||
field: (row) => row.created,
|
||||
sortable: true,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
name: 'volume',
|
||||
label: 'm³',
|
||||
field: (row) => dashIfEmpty(row.m3),
|
||||
sortable: true,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: t('Description'),
|
||||
field: (row) => row.description,
|
||||
sortable: true,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
name: 'started',
|
||||
label: t('Hour started'),
|
||||
field: (row) => toHour(row.started),
|
||||
sortable: true,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
name: 'finished',
|
||||
label: t('Hour finished'),
|
||||
field: (row) => toHour(row.finished),
|
||||
sortable: true,
|
||||
align: 'left',
|
||||
},
|
||||
]);
|
||||
|
||||
const refreshKey = ref(0)
|
||||
const workers = ref([]);
|
||||
const agencyList = ref([]);
|
||||
const vehicleList = ref([]);
|
||||
const updateRoute = async (route) => {
|
||||
try {
|
||||
return await axios.patch(`Routes/${route.id}`, route);
|
||||
} catch (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
const updateVehicle = (row, vehicle) => {
|
||||
row.vehicleFk = vehicle.id
|
||||
row.vehiclePlateNumber = vehicle.numberPlate
|
||||
updateRoute(row)
|
||||
}
|
||||
|
||||
const updateAgency = (row, agency) => {
|
||||
row.agencyModeFk = agency.id
|
||||
row.agencyName = agency.name
|
||||
updateRoute(row)
|
||||
}
|
||||
|
||||
const updateWorker = (row, worker) => {
|
||||
row.workerFk = worker.id
|
||||
row.workerUserName = worker.name
|
||||
updateRoute(row)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-if="stateStore.isHeaderMounted()">
|
||||
<!-- <Teleport to="#searchbar">-->
|
||||
<!-- <ShelvingSearchbar />-->
|
||||
<!-- </Teleport>-->
|
||||
<!-- <Teleport to="#actions-append">-->
|
||||
<!-- <div class="row q-gutter-x-sm">-->
|
||||
<!-- <QBtn-->
|
||||
<!-- flat-->
|
||||
<!-- @click="stateStore.toggleRightDrawer()"-->
|
||||
<!-- round-->
|
||||
<!-- dense-->
|
||||
<!-- icon="menu"-->
|
||||
<!-- >-->
|
||||
<!-- <QTooltip bottom anchor="bottom right">-->
|
||||
<!-- {{ t('globals.collapseMenu') }}-->
|
||||
<!-- </QTooltip>-->
|
||||
<!-- </QBtn>-->
|
||||
<!-- </div>-->
|
||||
<!-- </Teleport>-->
|
||||
</template>
|
||||
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<!-- <QScrollArea class="fit text-grey-8">-->
|
||||
<!-- <ShelvingFilter data-key="ShelvingList" />-->
|
||||
<!-- </QScrollArea>-->
|
||||
</QDrawer>
|
||||
<FetchData
|
||||
url="Workers/activeWithInheritedRole"
|
||||
@on-fetch="(data) => (workers = data)"
|
||||
auto-load
|
||||
/>
|
||||
<FetchData
|
||||
url="AgencyModes"
|
||||
@on-fetch="(data) => (agencyList = data)"
|
||||
auto-load
|
||||
/>
|
||||
<FetchData
|
||||
url="Vehicles"
|
||||
@on-fetch="(data) => (vehicleList = data)"
|
||||
auto-load
|
||||
/>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
<QToolbar class="q-pa-none q-mb-sm justify-end">
|
||||
<QBtn
|
||||
icon="refresh"
|
||||
color="primary"
|
||||
class="q-mr-sm"
|
||||
@click="refreshKey++"
|
||||
/>
|
||||
</QToolbar>
|
||||
<VnPaginate
|
||||
:key="refreshKey"
|
||||
data-key="RouteList"
|
||||
url="Routes/filter"
|
||||
:order="['created DESC', 'id DESC']"
|
||||
:limit="20"
|
||||
:user-params="params"
|
||||
auto-load
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<QTable
|
||||
v-model:selected="selectedRows"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
flat
|
||||
row-key="id"
|
||||
hide-pagination
|
||||
selection="multiple"
|
||||
>
|
||||
<template #body-cell-worker="props">
|
||||
<QTd :props="props">
|
||||
{{ props.row?.workerUserName }}
|
||||
<QPopupEdit
|
||||
:model-value="props.row.workerFk"
|
||||
v-slot="scope"
|
||||
buttons
|
||||
@update:model-value="(worker) => updateWorker(props.row, worker)"
|
||||
>
|
||||
<VnSelectFilter
|
||||
:label="t('Worker')"
|
||||
v-model="scope.value"
|
||||
:options="workers"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
autofocus
|
||||
:emit-value="false"
|
||||
:rules="validate('Route.workerFk')"
|
||||
:is-clearable="false"
|
||||
@keyup.enter="scope.set"
|
||||
@focus="($event) => $event.target.select()"
|
||||
>
|
||||
<template #option="{ opt, itemProps }">
|
||||
<QItem
|
||||
v-bind="itemProps"
|
||||
class="q-pa-xs row items-center"
|
||||
>
|
||||
<QItemSection class="col-9 justify-center">
|
||||
<span>{{ opt.name }}</span>
|
||||
<span class="text-grey">{{
|
||||
opt.nickname
|
||||
}}</span>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelectFilter>
|
||||
</QPopupEdit>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-agency="props">
|
||||
<QTd :props="props">
|
||||
{{ props.row?.agencyName }}
|
||||
<QPopupEdit
|
||||
:model-value="props.row.agencyModeFk"
|
||||
v-slot="scope"
|
||||
buttons
|
||||
@update:model-value="(agency) => updateAgency(props.row, agency)"
|
||||
>
|
||||
<VnSelectFilter
|
||||
:label="t('Agency')"
|
||||
v-model="scope.value"
|
||||
:options="agencyList"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
autofocus
|
||||
:emit-value="false"
|
||||
:rules="validate('route.agencyFk')"
|
||||
:is-clearable="false"
|
||||
@keyup.enter="scope.set"
|
||||
@focus="($event) => $event.target.select()"
|
||||
/>
|
||||
</QPopupEdit>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-vehicle="props">
|
||||
<QTd :props="props">
|
||||
{{ props.row?.vehiclePlateNumber }}
|
||||
<QPopupEdit
|
||||
:model-value="props.row.vehicleFk"
|
||||
v-slot="scope"
|
||||
buttons
|
||||
@update:model-value="(vehicle) => updateVehicle(props.row, vehicle)"
|
||||
>
|
||||
<VnSelectFilter
|
||||
:label="t('Vehicle')"
|
||||
v-model="scope.value"
|
||||
:options="vehicleList"
|
||||
option-value="id"
|
||||
option-label="numberPlate"
|
||||
hide-selected
|
||||
autofocus
|
||||
:emit-value="false"
|
||||
:rules="validate('route.vehicleFk')"
|
||||
:is-clearable="false"
|
||||
@keyup.enter="scope.set"
|
||||
@focus="($event) => $event.target.select()"
|
||||
/>
|
||||
</QPopupEdit>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-date="props">
|
||||
<QTd :props="props">
|
||||
{{ toDate(props.row?.created) }}
|
||||
<QPopupEdit
|
||||
v-model="props.row.created"
|
||||
v-slot="scope"
|
||||
@update:model-value="updateRoute(props.row)"
|
||||
buttons
|
||||
>
|
||||
<VnInputDate
|
||||
v-model="scope.value"
|
||||
autofocus
|
||||
:label="t('Date')"
|
||||
:rules="validate('route.created')"
|
||||
:is-clearable="false"
|
||||
@keyup.enter="scope.set"
|
||||
@focus="($event) => $event.target.select()"
|
||||
/>
|
||||
</QPopupEdit>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-description="props">
|
||||
<QTd :props="props">
|
||||
{{ props.row?.description }}
|
||||
<QPopupEdit
|
||||
v-model="props.row.description"
|
||||
v-slot="scope"
|
||||
@update:model-value="updateRoute(props.row)"
|
||||
buttons
|
||||
>
|
||||
<VnInput
|
||||
v-model="scope.value"
|
||||
autofocus
|
||||
:label="t('Description')"
|
||||
:rules="validate('route.description')"
|
||||
:is-clearable="false"
|
||||
@keyup.enter="scope.set"
|
||||
@focus="($event) => $event.target.select()"
|
||||
/>
|
||||
</QPopupEdit>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-started="props">
|
||||
<QTd :props="props">
|
||||
{{ toHour(props.row.started) }}
|
||||
<QPopupEdit
|
||||
v-model="props.row.started"
|
||||
v-slot="scope"
|
||||
buttons
|
||||
@update:model-value="updateRoute(props.row)"
|
||||
>
|
||||
<VnInputTime
|
||||
v-model="scope.value"
|
||||
autofocus
|
||||
:label="t('Hour started')"
|
||||
:rules="validate('route.started')"
|
||||
:is-clearable="false"
|
||||
@keyup.enter="scope.set"
|
||||
@focus="($event) => $event.target.select()"
|
||||
/>
|
||||
</QPopupEdit>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-finished="props">
|
||||
<QTd :props="props">
|
||||
{{ toHour(props.row.finished) }}
|
||||
<QPopupEdit
|
||||
v-model="props.row.finished"
|
||||
v-slot="scope"
|
||||
buttons
|
||||
@update:model-value="updateRoute(props.row)"
|
||||
>
|
||||
<VnInputTime
|
||||
v-model="scope.value"
|
||||
autofocus
|
||||
:label="t('Hour finished')"
|
||||
:rules="validate('route.finished')"
|
||||
:is-clearable="false"
|
||||
@keyup.enter="scope.set"
|
||||
@focus="($event) => $event.target.select()"
|
||||
/>
|
||||
</QPopupEdit>
|
||||
</QTd>
|
||||
</template>
|
||||
</QTable>
|
||||
</template>
|
||||
</VnPaginate>
|
||||
<!-- <QPageSticky :offset="[20, 20]">-->
|
||||
<!-- <RouterLink :to="{ name: 'ShelvingCreate' }">-->
|
||||
<!-- <QBtn fab icon="add" color="primary" />-->
|
||||
<!-- <QTooltip>-->
|
||||
<!-- {{ t('shelving.list.newShelving') }}-->
|
||||
<!-- </QTooltip>-->
|
||||
<!-- </RouterLink>-->
|
||||
<!-- </QPageSticky>-->
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
width: 100%;
|
||||
max-width: 60em;
|
||||
}
|
||||
</style>
|
||||
<i18n>
|
||||
es:
|
||||
ID: ID
|
||||
Worker: Trabajador
|
||||
Agency: Agencia
|
||||
Vehicle: Vehículo
|
||||
Date: Fecha
|
||||
Description: Descripción
|
||||
Hour started: Hora inicio
|
||||
Hour finished: Hora fin
|
||||
</i18n>
|
|
@ -10,7 +10,7 @@ export default {
|
|||
component: RouterView,
|
||||
redirect: { name: 'RouteMain' },
|
||||
menus: {
|
||||
main: ['CmrList'],
|
||||
main: ['RouteList', 'CmrList'],
|
||||
card: [],
|
||||
},
|
||||
children: [
|
||||
|
@ -29,6 +29,15 @@ export default {
|
|||
},
|
||||
component: () => import('src/pages/Route/Cmr/CmrList.vue'),
|
||||
},
|
||||
{
|
||||
path: 'list',
|
||||
name: 'RouteList',
|
||||
meta: {
|
||||
title: 'RouteList',
|
||||
icon: 'vn:delivery',
|
||||
},
|
||||
component: () => import('src/pages/Route/RouteList.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue