refactor: refs #7129 refactor with vnTable
This commit is contained in:
parent
36fc988df2
commit
9098e63793
|
@ -14,5 +14,5 @@
|
||||||
"[vue]": {
|
"[vue]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"cSpell.words": ["axios"]
|
"cSpell.words": ["axios", "composables"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ const closeForm = async () => {
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
isLoading,
|
isLoading,
|
||||||
|
onDataSaved,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { dashIfEmpty } from 'src/filters';
|
||||||
import VnSelect from 'components/common/VnSelect.vue';
|
import VnSelect from 'components/common/VnSelect.vue';
|
||||||
import VnInput from 'components/common/VnInput.vue';
|
import VnInput from 'components/common/VnInput.vue';
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
|
import VnInputTime from 'components/common/VnInputTime.vue';
|
||||||
import VnComponent from 'components/common/VnComponent.vue';
|
import VnComponent from 'components/common/VnComponent.vue';
|
||||||
|
|
||||||
const model = defineModel(undefined, { required: true });
|
const model = defineModel(undefined, { required: true });
|
||||||
|
@ -74,6 +75,15 @@ const defaultComponents = {
|
||||||
label: $props.showLabel && $props.column.label,
|
label: $props.showLabel && $props.column.label,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
time: {
|
||||||
|
component: markRaw(VnInputTime),
|
||||||
|
attrs: {
|
||||||
|
disable: !$props.isEditable,
|
||||||
|
},
|
||||||
|
forceAttrs: {
|
||||||
|
label: $props.showLabel && $props.column.label,
|
||||||
|
},
|
||||||
|
},
|
||||||
checkbox: {
|
checkbox: {
|
||||||
component: markRaw(QCheckbox),
|
component: markRaw(QCheckbox),
|
||||||
attrs: (prop) => {
|
attrs: (prop) => {
|
||||||
|
|
|
@ -3,17 +3,17 @@ import { ref, onMounted, computed, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import FormModelPopup from 'components/FormModelPopup.vue';
|
|
||||||
import CrudModel from 'src/components/CrudModel.vue';
|
|
||||||
import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
|
|
||||||
import VnLv from 'components/ui/VnLv.vue';
|
|
||||||
|
|
||||||
|
import CrudModel from 'src/components/CrudModel.vue';
|
||||||
|
import FormModelPopup from 'components/FormModelPopup.vue';
|
||||||
|
|
||||||
|
import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
|
||||||
import VnTableColumn from 'components/VnTable/VnColumn.vue';
|
import VnTableColumn from 'components/VnTable/VnColumn.vue';
|
||||||
import VnTableFilter from 'components/VnTable/VnFilter.vue';
|
import VnTableFilter from 'components/VnTable/VnFilter.vue';
|
||||||
import VnTableChip from 'components/VnTable/VnChip.vue';
|
import VnTableChip from 'components/VnTable/VnChip.vue';
|
||||||
import TableVisibleColumns from 'src/components/VnTable/VnVisibleColumn.vue';
|
import TableVisibleColumns from 'src/components/VnTable/VnVisibleColumn.vue';
|
||||||
|
import VnLv from 'components/ui/VnLv.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
columns: {
|
columns: {
|
||||||
|
@ -33,7 +33,7 @@ const $props = defineProps({
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
rowClick: {
|
rowClick: {
|
||||||
type: Function,
|
type: [Function, Boolean],
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
redirect: {
|
redirect: {
|
||||||
|
@ -80,6 +80,10 @@ const $props = defineProps({
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
|
tableHeight: {
|
||||||
|
type: String,
|
||||||
|
default: '90vh',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
|
@ -128,12 +132,6 @@ watch(
|
||||||
(val) => setUserParams(val)
|
(val) => setUserParams(val)
|
||||||
);
|
);
|
||||||
|
|
||||||
const rowClickFunction = computed(() => {
|
|
||||||
if ($props.rowClick) return $props.rowClick;
|
|
||||||
if ($props.redirect) return ({ id }) => redirectFn(id);
|
|
||||||
return () => {};
|
|
||||||
});
|
|
||||||
|
|
||||||
const isTableMode = computed(() => mode.value == TABLE_MODE);
|
const isTableMode = computed(() => mode.value == TABLE_MODE);
|
||||||
|
|
||||||
function setUserParams(watchedParams) {
|
function setUserParams(watchedParams) {
|
||||||
|
@ -180,6 +178,12 @@ function splitColumns(columns) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rowClickFunction = computed(() => {
|
||||||
|
if ($props.rowClick != undefined) return $props.rowClick;
|
||||||
|
if ($props.redirect) return ({ id }) => redirectFn(id);
|
||||||
|
return () => {};
|
||||||
|
});
|
||||||
|
|
||||||
function redirectFn(id) {
|
function redirectFn(id) {
|
||||||
router.push({ path: `/${$props.redirect}/${id}` });
|
router.push({ path: `/${$props.redirect}/${id}` });
|
||||||
}
|
}
|
||||||
|
@ -224,7 +228,6 @@ defineExpose({
|
||||||
:data-key="$attrs['data-key']"
|
:data-key="$attrs['data-key']"
|
||||||
:search-button="true"
|
:search-button="true"
|
||||||
v-model="params"
|
v-model="params"
|
||||||
:disable-submit-event="true"
|
|
||||||
:search-url="searchUrl"
|
:search-url="searchUrl"
|
||||||
:redirect="!!redirect"
|
:redirect="!!redirect"
|
||||||
>
|
>
|
||||||
|
@ -275,14 +278,14 @@ defineExpose({
|
||||||
table-header-class="bg-header"
|
table-header-class="bg-header"
|
||||||
card-container-class="grid-three"
|
card-container-class="grid-three"
|
||||||
flat
|
flat
|
||||||
:style="isTableMode && 'max-height: 90vh'"
|
:style="isTableMode && `max-height: ${tableHeight}`"
|
||||||
virtual-scroll
|
virtual-scroll
|
||||||
@virtual-scroll="
|
@virtual-scroll="
|
||||||
(event) =>
|
(event) =>
|
||||||
event.index > rows.length - 2 &&
|
event.index > rows.length - 2 &&
|
||||||
CrudModelRef.vnPaginateRef.paginate()
|
CrudModelRef.vnPaginateRef.paginate()
|
||||||
"
|
"
|
||||||
@row-click="(_, row) => rowClickFunction(row)"
|
@row-click="(_, row) => rowClickFunction && rowClickFunction(row)"
|
||||||
@update:selected="emit('update:selected', $event)"
|
@update:selected="emit('update:selected', $event)"
|
||||||
>
|
>
|
||||||
<template #top-left v-if="!$props.withoutHeader">
|
<template #top-left v-if="!$props.withoutHeader">
|
||||||
|
@ -546,8 +549,12 @@ defineExpose({
|
||||||
<i18n>
|
<i18n>
|
||||||
en:
|
en:
|
||||||
status: Status
|
status: Status
|
||||||
|
table view: Table view
|
||||||
|
grid view: Grid view
|
||||||
es:
|
es:
|
||||||
status: Estados
|
status: Estados
|
||||||
|
table view: Vista en tabla
|
||||||
|
grid view: Vista en cuadrícula
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
@ -557,7 +564,7 @@ es:
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-header {
|
.bg-header {
|
||||||
background-color: #5d5d5d;
|
background-color: var(--vn-section-color);
|
||||||
color: var(--vn-text-color);
|
color: var(--vn-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,7 +573,7 @@ es:
|
||||||
.q-table--dark tr,
|
.q-table--dark tr,
|
||||||
.q-table--dark th,
|
.q-table--dark th,
|
||||||
.q-table--dark td {
|
.q-table--dark td {
|
||||||
border-color: #222222;
|
border-color: var(--vn-section-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.q-table__container > div:first-child {
|
.q-table__container > div:first-child {
|
||||||
|
@ -636,7 +643,7 @@ es:
|
||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
td.sticky {
|
td.sticky {
|
||||||
background-color: var(--q-dark);
|
background-color: var(--vn-section-color);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,7 @@ watch(
|
||||||
>
|
>
|
||||||
<QDate
|
<QDate
|
||||||
v-model="popupDate"
|
v-model="popupDate"
|
||||||
|
:landscape="true"
|
||||||
:today-btn="true"
|
:today-btn="true"
|
||||||
@update:model-value="
|
@update:model-value="
|
||||||
(date) => {
|
(date) => {
|
||||||
|
|
|
@ -43,7 +43,7 @@ const formattedTime = computed({
|
||||||
if (time?.length > 5) time = dateToTime(time);
|
if (time?.length > 5) time = dateToTime(time);
|
||||||
if (!props.timeOnly) {
|
if (!props.timeOnly) {
|
||||||
const hours = time.split(':');
|
const hours = time.split(':');
|
||||||
const date = new Date();
|
const date = new Date(model.value);
|
||||||
date.setHours(hours[0], hours[1], 0);
|
date.setHours(hours[0], hours[1], 0);
|
||||||
time = date.toISOString();
|
time = date.toISOString();
|
||||||
}
|
}
|
||||||
|
@ -100,13 +100,7 @@ watch(
|
||||||
self="top start"
|
self="top start"
|
||||||
:no-focus="true"
|
:no-focus="true"
|
||||||
>
|
>
|
||||||
<QTime
|
<QTime v-model="formattedTime" mask="HH:mm" landscape now-btn />
|
||||||
:format24h="false"
|
|
||||||
v-model="formattedTime"
|
|
||||||
mask="HH:mm"
|
|
||||||
landscape
|
|
||||||
now-btn
|
|
||||||
/>
|
|
||||||
</QMenu>
|
</QMenu>
|
||||||
</QInput>
|
</QInput>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -18,19 +18,18 @@ const $props = defineProps({
|
||||||
},
|
},
|
||||||
searchButton: {
|
searchButton: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
showAll: {
|
showAll: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
unremovableParams: {
|
unRemovableParams: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: false,
|
required: false,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
description:
|
description: `Some filters come with default search parameters and require a value.
|
||||||
'Algunos filtros vienen con parametros de búsqueda por default y necesitan tener si o si un valor, por eso de ser necesario, esta prop nos sirve para saber que filtros podemos remover y cuales no',
|
This prop helps us determine which filters can be removed and which cannot.`,
|
||||||
},
|
},
|
||||||
exprBuilder: {
|
exprBuilder: {
|
||||||
type: Function,
|
type: Function,
|
||||||
|
@ -113,7 +112,7 @@ async function search(evt) {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
const filter = { ...userParams.value };
|
const filter = { ...userParams.value };
|
||||||
store.userParamsChanged = true;
|
store.userParamsChanged = true;
|
||||||
arrayData.reset(['skip', 'filter.skip', 'page']);
|
console.log('userParams.value: ', userParams.value);
|
||||||
const { params: newParams } = await arrayData.addFilter({ params: userParams.value });
|
const { params: newParams } = await arrayData.addFilter({ params: userParams.value });
|
||||||
userParams.value = newParams;
|
userParams.value = newParams;
|
||||||
|
|
||||||
|
@ -140,7 +139,7 @@ async function clearFilters() {
|
||||||
arrayData.reset(['skip', 'filter.skip', 'page']);
|
arrayData.reset(['skip', 'filter.skip', 'page']);
|
||||||
// Filtrar los params no removibles
|
// Filtrar los params no removibles
|
||||||
const removableFilters = Object.keys(userParams.value).filter((param) =>
|
const removableFilters = Object.keys(userParams.value).filter((param) =>
|
||||||
$props.unremovableParams.includes(param)
|
$props.unRemovableParams.includes(param)
|
||||||
);
|
);
|
||||||
const newParams = {};
|
const newParams = {};
|
||||||
// Conservar solo los params que no son removibles
|
// Conservar solo los params que no son removibles
|
||||||
|
@ -249,7 +248,7 @@ function formatValue(value) {
|
||||||
<VnFilterPanelChip
|
<VnFilterPanelChip
|
||||||
v-for="chip of tags"
|
v-for="chip of tags"
|
||||||
:key="chip.label"
|
:key="chip.label"
|
||||||
:removable="!unremovableParams.includes(chip.label)"
|
:removable="!unRemovableParams.includes(chip.label)"
|
||||||
@remove="remove(chip.label)"
|
@remove="remove(chip.label)"
|
||||||
>
|
>
|
||||||
<slot name="tags" :tag="chip" :format-fn="formatValue">
|
<slot name="tags" :tag="chip" :format-fn="formatValue">
|
||||||
|
|
|
@ -30,6 +30,7 @@ onBeforeUnmount(() => stateStore.toggleSubToolbar());
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QToolbar
|
<QToolbar
|
||||||
|
id="subToolbar"
|
||||||
class="justify-end sticky"
|
class="justify-end sticky"
|
||||||
v-show="hasContent || $slots['st-actions'] || $slots['st-data']"
|
v-show="hasContent || $slots['st-actions'] || $slots['st-data']"
|
||||||
>
|
>
|
||||||
|
|
|
@ -74,7 +74,11 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
};
|
};
|
||||||
|
|
||||||
let exprFilter;
|
let exprFilter;
|
||||||
|
console.log('AQUIII: ', typeof store.userParams, store.userParams);
|
||||||
|
|
||||||
let userParams = { ...store.userParams };
|
let userParams = { ...store.userParams };
|
||||||
|
console.log('AQUIII: ', typeof userParams, userParams);
|
||||||
|
|
||||||
if (store?.exprBuilder) {
|
if (store?.exprBuilder) {
|
||||||
const where = buildFilter(userParams, (param, value) => {
|
const where = buildFilter(userParams, (param, value) => {
|
||||||
const res = store.exprBuilder(param, value);
|
const res = store.exprBuilder(param, value);
|
||||||
|
@ -92,6 +96,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
filter.where = where;
|
filter.where = where;
|
||||||
const params = { filter };
|
const params = { filter };
|
||||||
|
|
||||||
|
console.log('AQUIII: ', typeof userParams, userParams);
|
||||||
Object.assign(params, userParams);
|
Object.assign(params, userParams);
|
||||||
params.filter.skip = store.skip;
|
params.filter.skip = store.skip;
|
||||||
|
|
||||||
|
@ -152,12 +157,18 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addFilter({ filter, params }) {
|
async function addFilter({ filter, params }) {
|
||||||
|
console.log('addFilter params: ', params);
|
||||||
if (filter) store.filter = filter;
|
if (filter) store.filter = filter;
|
||||||
|
|
||||||
|
console.log('addFilter: ', store.userParams);
|
||||||
let userParams = { ...store.userParams, ...params };
|
let userParams = { ...store.userParams, ...params };
|
||||||
|
console.log('addFilter 2: ', userParams, store.userParams);
|
||||||
|
|
||||||
userParams = sanitizerParams(userParams, store?.exprBuilder);
|
userParams = sanitizerParams(userParams, store?.exprBuilder);
|
||||||
|
console.log('addFilter 2.5: ', userParams);
|
||||||
|
|
||||||
store.userParams = userParams;
|
store.userParams = userParams;
|
||||||
|
console.log('addFilter: 3', store.userParams);
|
||||||
arrayDataStore.reset(['skip', 'filter.skip', 'page']);
|
arrayDataStore.reset(['skip', 'filter.skip', 'page']);
|
||||||
|
|
||||||
await fetch({ append: false });
|
await fetch({ append: false });
|
||||||
|
@ -173,6 +184,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
|
|
||||||
function sanitizerParams(params, exprBuilder) {
|
function sanitizerParams(params, exprBuilder) {
|
||||||
for (const param in params) {
|
for (const param in params) {
|
||||||
|
console.log('param: ', param);
|
||||||
if (params[param] === '' || params[param] === null) {
|
if (params[param] === '' || params[param] === null) {
|
||||||
delete store.userParams[param];
|
delete store.userParams[param];
|
||||||
delete params[param];
|
delete params[param];
|
||||||
|
|
|
@ -407,7 +407,6 @@ function handleLocation(data, location) {
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
default-mode="table"
|
default-mode="table"
|
||||||
redirect="customer"
|
redirect="customer"
|
||||||
auto-load
|
|
||||||
>
|
>
|
||||||
<template #more-create-dialog="{ data }">
|
<template #more-create-dialog="{ data }">
|
||||||
<VnLocation
|
<VnLocation
|
||||||
|
|
|
@ -78,6 +78,7 @@ const columns = computed(() => [
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
:use-model="true"
|
:use-model="true"
|
||||||
|
redirect="agency"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<i18n>
|
<i18n>
|
||||||
|
|
|
@ -1,162 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
const props = defineProps({
|
|
||||||
dataKey: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const countries = ref();
|
|
||||||
const warehouses = ref();
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<FetchData url="Countries" @on-fetch="(data) => (countries = data)" auto-load />
|
|
||||||
<FetchData url="Warehouses" @on-fetch="(data) => (warehouses = data)" auto-load />
|
|
||||||
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
|
|
||||||
<template #tags="{ tag, formatFn }">
|
|
||||||
<div class="q-gutter-x-xs">
|
|
||||||
<strong>{{ t(`params.${tag.label}`) }}: </strong>
|
|
||||||
<span>{{ formatFn(tag.value) }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template #body="{ params }">
|
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<VnInput
|
|
||||||
:label="t('route.cmr.list.cmrFk')"
|
|
||||||
v-model="params.cmrFk"
|
|
||||||
is-outlined
|
|
||||||
>
|
|
||||||
<template #prepend>
|
|
||||||
<QIcon name="article" size="sm"></QIcon>
|
|
||||||
</template>
|
|
||||||
</VnInput>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<QCheckbox
|
|
||||||
:label="t('route.cmr.list.hasCmrDms')"
|
|
||||||
v-model="params.hasCmrDms"
|
|
||||||
lazy-rules
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<VnInput
|
|
||||||
:label="t('route.cmr.list.ticketFk')"
|
|
||||||
v-model="params.ticketFk"
|
|
||||||
is-outlined
|
|
||||||
>
|
|
||||||
<template #prepend>
|
|
||||||
<QIcon name="vn:ticket" size="sm"></QIcon>
|
|
||||||
</template>
|
|
||||||
</VnInput>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<VnInput
|
|
||||||
:label="t('route.cmr.list.routeFk')"
|
|
||||||
v-model="params.routeFk"
|
|
||||||
is-outlined
|
|
||||||
>
|
|
||||||
<template #prepend>
|
|
||||||
<QIcon name="vn:delivery" size="sm"></QIcon>
|
|
||||||
</template>
|
|
||||||
</VnInput>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<VnInput
|
|
||||||
:label="t('route.cmr.list.clientFk')"
|
|
||||||
v-model="params.clientFk"
|
|
||||||
is-outlined
|
|
||||||
>
|
|
||||||
<template #prepend>
|
|
||||||
<QIcon name="vn:client" size="sm"></QIcon>
|
|
||||||
</template>
|
|
||||||
</VnInput>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
|
||||||
<QItemSection v-if="!countries">
|
|
||||||
<QSkeleton type="QInput" class="full-width" />
|
|
||||||
</QItemSection>
|
|
||||||
<QItemSection v-if="countries">
|
|
||||||
<VnSelect
|
|
||||||
:label="t('route.cmr.list.country')"
|
|
||||||
v-model="params.country"
|
|
||||||
:options="countries"
|
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
transition-show="jump-down"
|
|
||||||
transition-hide="jump-up"
|
|
||||||
emit-value
|
|
||||||
map-options
|
|
||||||
dense
|
|
||||||
outlined
|
|
||||||
rounded
|
|
||||||
>
|
|
||||||
<template #prepend>
|
|
||||||
<QIcon name="flag" size="sm"></QIcon>
|
|
||||||
</template>
|
|
||||||
</VnSelect>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
|
||||||
<VnSelect
|
|
||||||
:label="t('globals.warehouse')"
|
|
||||||
:options="warehouses"
|
|
||||||
hide-selected
|
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
v-model="params.warehouseFk"
|
|
||||||
rounded
|
|
||||||
dense
|
|
||||||
outlined
|
|
||||||
>
|
|
||||||
</VnSelect>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<VnInputDate
|
|
||||||
v-model="params.shipped"
|
|
||||||
:label="t('route.cmr.list.shipped')"
|
|
||||||
is-outlined
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
|
||||||
</VnFilterPanel>
|
|
||||||
</template>
|
|
||||||
<i18n>
|
|
||||||
en:
|
|
||||||
params:
|
|
||||||
cmrFk: Cmr id
|
|
||||||
hasCmrDms: Attached in gestdoc
|
|
||||||
ticketFk: Ticketd id
|
|
||||||
country: Country
|
|
||||||
clientFk: Client id
|
|
||||||
shipped: Preparation date
|
|
||||||
|
|
||||||
es:
|
|
||||||
params:
|
|
||||||
cmrFk: Id cmr
|
|
||||||
hasCmrDms: Gestdoc
|
|
||||||
ticketFk: Id ticket
|
|
||||||
country: País
|
|
||||||
clientFk: Id cliente
|
|
||||||
shipped: Fecha preparación
|
|
||||||
</i18n>
|
|
|
@ -2,82 +2,93 @@
|
||||||
import { onBeforeMount, onMounted, 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 VnPaginate from 'components/ui/VnPaginate.vue';
|
|
||||||
import { useSession } from 'src/composables/useSession';
|
import { useSession } from 'src/composables/useSession';
|
||||||
import { toDate } from 'filters/index';
|
import { toDate } from 'filters/index';
|
||||||
import CmrFilter from './CmrFilter.vue';
|
|
||||||
import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
|
|
||||||
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
|
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
|
||||||
import { useStateStore } from 'src/stores/useStateStore';
|
import { useStateStore } from 'src/stores/useStateStore';
|
||||||
|
|
||||||
|
import axios from 'axios';
|
||||||
|
import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
|
||||||
|
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
|
||||||
|
|
||||||
|
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||||
import VnTable from 'components/VnTable/VnTable.vue';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { getTokenMultimedia } = useSession();
|
const { getTokenMultimedia } = useSession();
|
||||||
const token = getTokenMultimedia();
|
const token = getTokenMultimedia();
|
||||||
const state = useStateStore();
|
const state = useStateStore();
|
||||||
const selected = ref([]);
|
|
||||||
const warehouses = ref([]);
|
const warehouses = ref([]);
|
||||||
|
const selectedRows = ref([]);
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
name: 'cmrFk',
|
name: 'cmrFk',
|
||||||
label: t('route.cmr.list.cmrFk'),
|
label: t('route.cmr.list.cmrFk'),
|
||||||
field: (row) => row.cmrFk,
|
chip: {
|
||||||
sortable: true,
|
condition: () => true,
|
||||||
|
},
|
||||||
|
isId: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
name: 'hasCmrDms',
|
name: 'hasCmrDms',
|
||||||
label: t('route.cmr.list.hasCmrDms'),
|
label: t('route.cmr.list.hasCmrDms'),
|
||||||
field: (row) => row.hasCmrDms,
|
component: 'checkbox',
|
||||||
align: 'center',
|
cardVisible: true,
|
||||||
sortable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ticketFk',
|
|
||||||
label: t('route.cmr.list.ticketFk'),
|
label: t('route.cmr.list.ticketFk'),
|
||||||
field: (row) => row.ticketFk,
|
name: 'ticketFk',
|
||||||
sortable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'routeFkFk',
|
|
||||||
label: t('route.cmr.list.routeFk'),
|
label: t('route.cmr.list.routeFk'),
|
||||||
field: (row) => row.routeFk,
|
name: 'routeFk',
|
||||||
sortable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'clientFk',
|
|
||||||
label: t('route.cmr.list.clientFk'),
|
label: t('route.cmr.list.clientFk'),
|
||||||
field: (row) => row.clientFk,
|
name: 'clientFk',
|
||||||
sortable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'country',
|
|
||||||
label: t('route.cmr.list.country'),
|
|
||||||
field: (row) => row.country,
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
sortable: true,
|
label: t('route.cmr.list.country'),
|
||||||
|
name: 'country',
|
||||||
|
cardVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'shipped',
|
|
||||||
label: t('route.cmr.list.shipped'),
|
|
||||||
field: (row) => toDate(row.shipped),
|
|
||||||
align: 'center',
|
align: 'center',
|
||||||
sortable: true,
|
label: t('route.cmr.list.shipped'),
|
||||||
|
name: 'shipped',
|
||||||
|
cardVisible: true,
|
||||||
|
component: 'date',
|
||||||
|
columnFilter: {
|
||||||
|
alias: 'c',
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
format: ({ date }) => toDate(date),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'center',
|
||||||
name: 'warehouseFk',
|
name: 'warehouseFk',
|
||||||
label: t('globals.warehouse'),
|
label: t('globals.warehouse'),
|
||||||
field: ({ warehouseFk }) => warehouseFk,
|
component: 'select',
|
||||||
align: 'center',
|
attrs: {
|
||||||
sortable: true,
|
url: 'warehouses',
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
optionLabel: 'name',
|
||||||
|
optionValue: 'id',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'icons',
|
align: 'right',
|
||||||
align: 'center',
|
name: 'tableActions',
|
||||||
field: (row) => row.cmrFk,
|
actions: [
|
||||||
|
{
|
||||||
|
title: t('Ver cmr'),
|
||||||
|
icon: 'visibility',
|
||||||
|
isPrimary: true,
|
||||||
|
action: (row) => window.open(getCmrUrl(row?.cmrFk), '_blank'),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -95,7 +106,7 @@ function getCmrUrl(value) {
|
||||||
return `${getApiUrl()}/api/Routes/${value}/cmr?access_token=${token}`;
|
return `${getApiUrl()}/api/Routes/${value}/cmr?access_token=${token}`;
|
||||||
}
|
}
|
||||||
function downloadPdfs() {
|
function downloadPdfs() {
|
||||||
if (!selected.value.length) {
|
if (!selectedRows.value.length) {
|
||||||
Notify.create({
|
Notify.create({
|
||||||
message: t('globals.noSelectedRows'),
|
message: t('globals.noSelectedRows'),
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
|
@ -103,42 +114,51 @@ function downloadPdfs() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let cmrs = [];
|
let cmrs = [];
|
||||||
for (let value of selected.value) cmrs.push(value.cmrFk);
|
for (let value of selectedRows.value) cmrs.push(value.cmrFk);
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return window.open(`${getApiUrl()}/api/Routes/downloadCmrsZip?ids=${cmrs.join(',')}&access_token=${token}`);
|
return window.open(`${getApiUrl()}/api/Routes/downloadCmrsZip?ids=${cmrs.join(',')}&access_token=${token}`);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
<VnSubToolbar>
|
||||||
|
<template #st-actions>
|
||||||
|
<QBtn
|
||||||
|
icon="cloud_download"
|
||||||
|
color="primary"
|
||||||
|
class="q-mr-sm"
|
||||||
|
:disable="!selectedRows?.length"
|
||||||
|
@click="downloadPdfs"
|
||||||
|
>
|
||||||
|
<QTooltip>{{ t('route.cmr.list.downloadCmrs') }}</QTooltip>
|
||||||
|
</QBtn>
|
||||||
|
</template>
|
||||||
|
</VnSubToolbar>
|
||||||
<VnTable
|
<VnTable
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="CmrList"
|
data-key="CmrList"
|
||||||
url="Routes/cmrs"
|
url="Routes/cmrs"
|
||||||
order="cmrFk DESC"
|
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:right-search="true"
|
:right-search="true"
|
||||||
:use-model="true"
|
default-mode="table"
|
||||||
/>
|
v-model:selected="selectedRows"
|
||||||
|
table-height="85vh"
|
||||||
|
:table="{
|
||||||
|
'row-key': 'cmrFk',
|
||||||
|
selection: 'multiple',
|
||||||
|
}"
|
||||||
|
:disable-option="{ card: true }"
|
||||||
|
>
|
||||||
|
<template #column-ticketFk="{ row }">
|
||||||
|
<span class="link" @click.stop>
|
||||||
|
{{ row.ticketFk }}
|
||||||
|
<TicketDescriptorProxy :id="row.ticketFk" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #column-clientFk="{ row }">
|
||||||
|
<span class="link" @click.stop>
|
||||||
|
{{ row.ticketFk }}
|
||||||
|
<CustomerDescriptorProxy :id="row.clientFk" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</VnTable>
|
||||||
</template>
|
</template>
|
||||||
<style lang="scss" scoped>
|
|
||||||
.list {
|
|
||||||
padding-top: 15px;
|
|
||||||
padding-bottom: 15px;
|
|
||||||
max-width: 1000px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.grid-style-transition {
|
|
||||||
transition: transform 0.28s, background-color 0.28s;
|
|
||||||
}
|
|
||||||
#true {
|
|
||||||
background-color: $positive;
|
|
||||||
}
|
|
||||||
#false {
|
|
||||||
background-color: $negative;
|
|
||||||
}
|
|
||||||
:deep(.q-table th) {
|
|
||||||
max-width: 80px;
|
|
||||||
}
|
|
||||||
:deep(.q-table th:nth-child(3)) {
|
|
||||||
max-width: 100px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { useDialogPluginComponent } from 'quasar';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { reactive, ref } from 'vue';
|
|
||||||
import axios from 'axios';
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import RoadmapAddStopForm from 'pages/Route/Roadmap/RoadmapAddStopForm.vue';
|
|
||||||
|
|
||||||
const emit = defineEmits([...useDialogPluginComponent.emits]);
|
|
||||||
const { dialogRef, onDialogHide } = useDialogPluginComponent();
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
const props = defineProps({
|
|
||||||
roadmapFk: {
|
|
||||||
type: Number,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const isLoading = ref(false);
|
|
||||||
const roadmapStopForm = reactive({
|
|
||||||
roadmapFk: Number(props.roadmapFk) || 0,
|
|
||||||
warehouseFk: null,
|
|
||||||
eta: new Date().toISOString(),
|
|
||||||
description: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
const updateDefaultStop = (data) => {
|
|
||||||
const eta = new Date(data.etd);
|
|
||||||
eta.setDate(eta.getDate() + 1);
|
|
||||||
roadmapStopForm.eta = eta.toISOString();
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSave = async () => {
|
|
||||||
isLoading.value = true;
|
|
||||||
try {
|
|
||||||
await axios.post('RoadmapStops', { ...roadmapStopForm });
|
|
||||||
emit('ok');
|
|
||||||
} finally {
|
|
||||||
isLoading.value = false;
|
|
||||||
emit('hide');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<FetchData
|
|
||||||
:url="`Roadmaps/${roadmapFk}`"
|
|
||||||
auto-load
|
|
||||||
:filter="{ fields: ['etd'] }"
|
|
||||||
@on-fetch="updateDefaultStop"
|
|
||||||
/>
|
|
||||||
<QDialog ref="dialogRef" @hide="onDialogHide">
|
|
||||||
<QCard class="q-pa-lg">
|
|
||||||
<QCardSection class="row absolute absolute-top z-fullscreen">
|
|
||||||
<QSpace />
|
|
||||||
<QBtn icon="close" flat round dense v-close-popup />
|
|
||||||
</QCardSection>
|
|
||||||
<RoadmapAddStopForm
|
|
||||||
:roadmap-fk="roadmapFk"
|
|
||||||
:form-data="roadmapStopForm"
|
|
||||||
layout="dialog"
|
|
||||||
/>
|
|
||||||
<QCardActions align="right">
|
|
||||||
<QBtn :label="t('globals.cancel')" color="primary" flat v-close-popup />
|
|
||||||
<QBtn
|
|
||||||
:label="t('globals.confirm')"
|
|
||||||
color="primary"
|
|
||||||
:loading="isLoading"
|
|
||||||
@click="onSave"
|
|
||||||
unelevated
|
|
||||||
/>
|
|
||||||
</QCardActions>
|
|
||||||
</QCard>
|
|
||||||
</QDialog>
|
|
||||||
</template>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.card-section {
|
|
||||||
gap: 16px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<i18n>
|
|
||||||
es:
|
|
||||||
Warehouse: Almacén
|
|
||||||
ETA date: Fecha ETA
|
|
||||||
ETA time: Hora ETA
|
|
||||||
Description: Descripción
|
|
||||||
</i18n>
|
|
|
@ -1,45 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
|
||||||
import FormModel from 'components/FormModel.vue';
|
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
|
||||||
import VnInput from 'components/common/VnInput.vue';
|
|
||||||
import VnInputTime from 'components/common/VnInputTime.vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
const router = useRouter();
|
|
||||||
const defaultInitialData = {
|
|
||||||
etd: Date.vnNew().toISOString(),
|
|
||||||
};
|
|
||||||
const onSave = (data, response) => {
|
|
||||||
router.push({ name: 'RoadmapSummary', params: { id: response?.id } });
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<VnSubToolbar />
|
|
||||||
<FormModel
|
|
||||||
:url="null"
|
|
||||||
url-create="Roadmaps"
|
|
||||||
model="roadmap"
|
|
||||||
:observe-form-changes="false"
|
|
||||||
:auto-load="false"
|
|
||||||
:form-initial-data="defaultInitialData"
|
|
||||||
@on-data-saved="onSave"
|
|
||||||
>
|
|
||||||
<template #form="{ data }">
|
|
||||||
<VnRow class="row q-gutter-md q-mb-md">
|
|
||||||
<VnInput v-model="data.name" :label="t('Roadmap')" clearable />
|
|
||||||
<VnInputDate v-model="data.etd" :label="t('ETD date')" />
|
|
||||||
<VnInputTime v-model="data.etd" :label="t('ETD hour')" />
|
|
||||||
</VnRow>
|
|
||||||
</template>
|
|
||||||
</FormModel>
|
|
||||||
</template>
|
|
||||||
<i18n>
|
|
||||||
es:
|
|
||||||
Roadmap: Troncal
|
|
||||||
ETD date: Fecha ETD
|
|
||||||
ETD hour: Hora ETD
|
|
||||||
</i18n>
|
|
|
@ -2,14 +2,14 @@
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { QIcon, useQuasar } from 'quasar';
|
import { QIcon } from 'quasar';
|
||||||
import { dashIfEmpty, toDateHourMin } from 'src/filters';
|
import { dashIfEmpty, toDateHourMin } from 'src/filters';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import VnLv from 'components/ui/VnLv.vue';
|
import VnLv from 'components/ui/VnLv.vue';
|
||||||
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
import CardSummary from 'components/ui/CardSummary.vue';
|
import CardSummary from 'components/ui/CardSummary.vue';
|
||||||
import SupplierDescriptorProxy from 'pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
import SupplierDescriptorProxy from 'pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
||||||
import VnLinkPhone from 'components/ui/VnLinkPhone.vue';
|
import VnLinkPhone from 'components/ui/VnLinkPhone.vue';
|
||||||
import RoadmapAddStopDialog from 'pages/Route/Roadmap/RoadmapAddStopDialog.vue';
|
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -20,7 +20,6 @@ const $props = defineProps({
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const quasar = useQuasar();
|
|
||||||
|
|
||||||
const summary = ref(null);
|
const summary = ref(null);
|
||||||
const entityId = computed(() => $props.id || route.params.id);
|
const entityId = computed(() => $props.id || route.params.id);
|
||||||
|
@ -37,7 +36,7 @@ const columns = ref([
|
||||||
{
|
{
|
||||||
name: 'address',
|
name: 'address',
|
||||||
label: t('Address'),
|
label: t('Address'),
|
||||||
field: (row) => dashIfEmpty(row?.address?.nickname),
|
field: (row) => dashIfEmpty(row?.address?.addressFk),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
},
|
},
|
||||||
|
@ -69,15 +68,6 @@ const filter = {
|
||||||
],
|
],
|
||||||
where: { id: entityId },
|
where: { id: entityId },
|
||||||
};
|
};
|
||||||
|
|
||||||
const openAddStopDialog = () => {
|
|
||||||
quasar
|
|
||||||
.dialog({
|
|
||||||
component: RoadmapAddStopDialog,
|
|
||||||
componentProps: { roadmapFk: entityId.value },
|
|
||||||
})
|
|
||||||
.onOk(() => summary.value.fetch());
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -98,6 +88,10 @@ const openAddStopDialog = () => {
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
|
<VnTitle
|
||||||
|
:url="`#/route/roadmap/${entityId}/basic-data`"
|
||||||
|
:text="t('Basic Data')"
|
||||||
|
/>
|
||||||
<VnLv :label="t('Carrier')">
|
<VnLv :label="t('Carrier')">
|
||||||
<template #value>
|
<template #value>
|
||||||
<span class="link" v-if="entity?.supplier?.id">
|
<span class="link" v-if="entity?.supplier?.id">
|
||||||
|
@ -115,8 +109,6 @@ const openAddStopDialog = () => {
|
||||||
:label="t('Trailer Plate')"
|
:label="t('Trailer Plate')"
|
||||||
:value="dashIfEmpty(entity?.trailerPlate)"
|
:value="dashIfEmpty(entity?.trailerPlate)"
|
||||||
/>
|
/>
|
||||||
</QCard>
|
|
||||||
<QCard class="vn-one">
|
|
||||||
<VnLv :label="t('Phone')" :value="dashIfEmpty(entity?.phone)">
|
<VnLv :label="t('Phone')" :value="dashIfEmpty(entity?.phone)">
|
||||||
<template #value>
|
<template #value>
|
||||||
<span>
|
<span>
|
||||||
|
@ -139,26 +131,10 @@ const openAddStopDialog = () => {
|
||||||
/>
|
/>
|
||||||
</QCard>
|
</QCard>
|
||||||
<QCard class="vn-max">
|
<QCard class="vn-max">
|
||||||
<div class="flex items-center">
|
<VnTitle
|
||||||
<a class="header" :href="`#/route/roadmap/${entityId}/stops`">
|
:url="`#/route/roadmap/${entityId}/stops`"
|
||||||
{{ t('Stops') }}
|
:text="t('Stops')"
|
||||||
<QIcon name="open_in_new" color="primary">
|
/>
|
||||||
<QTooltip>
|
|
||||||
{{ t('Go to stops') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</a>
|
|
||||||
<QIcon
|
|
||||||
name="add_circle"
|
|
||||||
color="primary"
|
|
||||||
class="q-ml-lg header cursor-pointer"
|
|
||||||
@click.stop="openAddStopDialog"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('Add stop') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</div>
|
|
||||||
<QTable
|
<QTable
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:rows="entity?.roadmapStop"
|
:rows="entity?.roadmapStop"
|
||||||
|
|
|
@ -1,33 +1,29 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
||||||
import { dashIfEmpty, toCurrency, toDate } from 'src/filters';
|
import { toCurrency, toDate } from 'src/filters';
|
||||||
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
import { useSummaryDialog } from 'composables/useSummaryDialog';
|
||||||
|
import { useState } from 'composables/useState';
|
||||||
|
|
||||||
|
import useNotify from 'composables/useNotify';
|
||||||
|
import axios from 'axios';
|
||||||
|
import RouteSummary from 'pages/Route/Card/RouteSummary.vue';
|
||||||
|
|
||||||
import RouteDescriptorProxy from 'pages/Route/Card/RouteDescriptorProxy.vue';
|
import RouteDescriptorProxy from 'pages/Route/Card/RouteDescriptorProxy.vue';
|
||||||
import InvoiceInDescriptorProxy from 'pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue';
|
import InvoiceInDescriptorProxy from 'pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue';
|
||||||
import SupplierDescriptorProxy from 'pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
import SupplierDescriptorProxy from 'pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
||||||
import VnLv from 'components/ui/VnLv.vue';
|
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
||||||
import useNotify from 'composables/useNotify';
|
|
||||||
import RouteAutonomousFilter from 'pages/Route/Card/RouteAutonomousFilter.vue';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
import RouteSummary from 'pages/Route/Card/RouteSummary.vue';
|
|
||||||
import { useSummaryDialog } from 'composables/useSummaryDialog';
|
|
||||||
import VnDms from 'components/common/VnDms.vue';
|
import VnDms from 'components/common/VnDms.vue';
|
||||||
import { useState } from 'composables/useState';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
import axios from 'axios';
|
import VnLv from 'components/ui/VnLv.vue';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
|
||||||
|
const { viewSummary } = useSummaryDialog();
|
||||||
|
const { notify } = useNotify();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const { t } = useI18n();
|
const refreshKey = ref(0);
|
||||||
const { notify } = useNotify();
|
|
||||||
const router = useRouter();
|
|
||||||
const { viewSummary } = useSummaryDialog();
|
|
||||||
|
|
||||||
onMounted(() => (stateStore.rightDrawer = true));
|
|
||||||
onUnmounted(() => (stateStore.rightDrawer = false));
|
|
||||||
|
|
||||||
const state = useState();
|
const state = useState();
|
||||||
const user = state.getUser();
|
const user = state.getUser();
|
||||||
const dmsDialog = ref({
|
const dmsDialog = ref({
|
||||||
|
@ -36,87 +32,89 @@ const dmsDialog = ref({
|
||||||
rowsToCreateInvoiceIn: [],
|
rowsToCreateInvoiceIn: [],
|
||||||
});
|
});
|
||||||
const selectedRows = ref([]);
|
const selectedRows = ref([]);
|
||||||
|
const tableRef = ref();
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
name: 'ID',
|
align: 'left',
|
||||||
|
name: 'id',
|
||||||
label: 'Id',
|
label: 'Id',
|
||||||
field: (row) => row.routeFk,
|
chip: {
|
||||||
sortable: true,
|
condition: () => true,
|
||||||
align: 'left',
|
},
|
||||||
|
isId: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'date',
|
align: 'left',
|
||||||
|
name: 'created',
|
||||||
label: t('Date'),
|
label: t('Date'),
|
||||||
field: (row) => toDate(row.created),
|
component: 'date',
|
||||||
sortable: true,
|
columnFilter: {
|
||||||
align: 'left',
|
alias: 'c',
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
format: ({ date }) => toDate(date),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'agency-route',
|
align: 'left',
|
||||||
|
name: 'agencyModeName',
|
||||||
label: t('Agency route'),
|
label: t('Agency route'),
|
||||||
field: (row) => row?.agencyModeName,
|
cardVisible: true,
|
||||||
sortable: true,
|
|
||||||
align: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'agency-agreement',
|
align: 'left',
|
||||||
|
name: 'agencyAgreement',
|
||||||
label: t('Agency agreement'),
|
label: t('Agency agreement'),
|
||||||
field: (row) => row?.agencyAgreement,
|
cardVisible: true,
|
||||||
sortable: true,
|
|
||||||
align: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
name: 'packages',
|
name: 'packages',
|
||||||
label: t('Packages'),
|
label: t('Packages'),
|
||||||
field: (row) => dashIfEmpty(row.packages),
|
|
||||||
sortable: true,
|
|
||||||
align: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'volume',
|
align: 'left',
|
||||||
|
name: 'm3',
|
||||||
label: 'm³',
|
label: 'm³',
|
||||||
field: (row) => dashIfEmpty(row.m3),
|
cardVisible: true,
|
||||||
sortable: true,
|
columnFilter: {
|
||||||
align: 'left',
|
inWhere: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'km',
|
align: 'left',
|
||||||
|
name: 'kmTotal',
|
||||||
label: t('Km'),
|
label: t('Km'),
|
||||||
field: (row) => dashIfEmpty(row?.kmTotal),
|
cardVisible: true,
|
||||||
sortable: true,
|
|
||||||
align: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
name: 'price',
|
name: 'price',
|
||||||
label: t('Price'),
|
label: t('Price'),
|
||||||
field: (row) => (row?.price ? toCurrency(row.price) : '-'),
|
|
||||||
sortable: true,
|
|
||||||
align: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'received',
|
align: 'left',
|
||||||
|
name: 'invoiceInFk',
|
||||||
label: t('Received'),
|
label: t('Received'),
|
||||||
field: (row) => row?.invoiceInFk,
|
|
||||||
sortable: true,
|
|
||||||
align: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'autonomous',
|
align: 'left',
|
||||||
|
name: 'supplierName',
|
||||||
label: t('Autonomous'),
|
label: t('Autonomous'),
|
||||||
field: (row) => row?.supplierName,
|
|
||||||
sortable: true,
|
|
||||||
align: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'actions',
|
|
||||||
label: '',
|
|
||||||
sortable: false,
|
|
||||||
align: 'right',
|
align: 'right',
|
||||||
|
name: 'tableActions',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
title: t('Preview'),
|
||||||
|
icon: 'preview',
|
||||||
|
isPrimary: true,
|
||||||
|
action: (row) => viewSummary(row?.routeFk, RouteSummary),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const refreshKey = ref(0);
|
|
||||||
|
|
||||||
const total = computed(() => {
|
const total = computed(() => {
|
||||||
return selectedRows.value.reduce((sum, item) => sum + item.price, 0);
|
return selectedRows.value.reduce((sum, item) => sum + item.price, 0);
|
||||||
});
|
});
|
||||||
|
@ -169,9 +167,8 @@ const onDmsSaved = async (dms, response) => {
|
||||||
refreshKey.value++;
|
refreshKey.value++;
|
||||||
};
|
};
|
||||||
|
|
||||||
function navigateToRouteSummary(event, row) {
|
onMounted(() => (stateStore.rightDrawer = true));
|
||||||
router.push({ name: 'RouteSummary', params: { id: row.routeFk } });
|
onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -180,13 +177,6 @@ function navigateToRouteSummary(event, row) {
|
||||||
:label="t('Search autonomous')"
|
:label="t('Search autonomous')"
|
||||||
:info="t('You can search by autonomous reference')"
|
:info="t('You can search by autonomous reference')"
|
||||||
/>
|
/>
|
||||||
<RightMenu>
|
|
||||||
<template #right-panel>
|
|
||||||
<RouteAutonomousFilter data-key="RouteAutonomousList" />
|
|
||||||
</template>
|
|
||||||
</RightMenu>
|
|
||||||
<QPage class="column items-center">
|
|
||||||
<div class="route-list">
|
|
||||||
<div class="q-pa-md">
|
<div class="q-pa-md">
|
||||||
<QCard class="vn-one q-py-sm q-px-lg flex justify-between">
|
<QCard class="vn-one q-py-sm q-px-lg flex justify-between">
|
||||||
<VnLv class="flex">
|
<VnLv class="flex">
|
||||||
|
@ -209,80 +199,41 @@ function navigateToRouteSummary(event, row) {
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</QCard>
|
</QCard>
|
||||||
</div>
|
</div>
|
||||||
<VnPaginate
|
<VnTable
|
||||||
:key="refreshKey"
|
ref="tableRef"
|
||||||
data-key="RouteAutonomousList"
|
data-key="RouteAutonomousList"
|
||||||
url="AgencyTerms/filter"
|
url="AgencyTerms/filter"
|
||||||
:limit="20"
|
|
||||||
>
|
|
||||||
<template #body="{ rows }">
|
|
||||||
<div class="q-pa-md">
|
|
||||||
<QTable
|
|
||||||
v-model:selected="selectedRows"
|
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:rows="rows"
|
:right-search="true"
|
||||||
flat
|
default-mode="table"
|
||||||
row-key="routeFk"
|
v-model:selected="selectedRows"
|
||||||
selection="multiple"
|
table-height="85vh"
|
||||||
:rows-per-page-options="[0]"
|
redirect="route"
|
||||||
hide-pagination
|
:row-click="({ routeFk }) => tableRef.redirect(routeFk)"
|
||||||
@row-click="navigateToRouteSummary"
|
:table="{
|
||||||
|
'row-key': '$index',
|
||||||
|
selection: 'multiple',
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<template #body-cell-ID="props">
|
<template #column-id="{ row }">
|
||||||
<QTd :props="props">
|
|
||||||
<span class="link" @click.stop>
|
<span class="link" @click.stop>
|
||||||
{{ props.value }}
|
{{ row.routeFk }}
|
||||||
<RouteDescriptorProxy :id="props.value" />
|
<RouteDescriptorProxy :id="row.route.id" />
|
||||||
</span>
|
</span>
|
||||||
</QTd>
|
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-received="props">
|
<template #column-invoiceInFk="{ row }">
|
||||||
<QTd :props="props">
|
|
||||||
<span :class="props.value && 'link'" @click.stop>
|
|
||||||
{{ dashIfEmpty(props.value) }}
|
|
||||||
<InvoiceInDescriptorProxy
|
|
||||||
v-if="props.value"
|
|
||||||
:id="props.value"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-autonomous="props">
|
|
||||||
<QTd :props="props">
|
|
||||||
<span class="link" @click.stop>
|
<span class="link" @click.stop>
|
||||||
{{ props.value }}
|
{{ row.invoiceInFk }}
|
||||||
<SupplierDescriptorProxy
|
<InvoiceInDescriptorProxy v-if="row.invoiceInFk" :id="row.invoiceInFk" />
|
||||||
v-if="props.row?.supplierFk"
|
|
||||||
:id="props.row?.supplierFk"
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
</QTd>
|
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-actions="props">
|
<template #column-supplierName="{ row }">
|
||||||
<QTd :props="props">
|
<span class="link" @click.stop>
|
||||||
<div class="table-actions">
|
{{ row.supplierName }}
|
||||||
<QIcon
|
<SupplierDescriptorProxy :id="row.supplierFk" />
|
||||||
name="preview"
|
</span>
|
||||||
size="sm"
|
|
||||||
color="primary"
|
|
||||||
@click.stop="
|
|
||||||
viewSummary(
|
|
||||||
props?.row?.routeFk,
|
|
||||||
RouteSummary
|
|
||||||
)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<QTooltip>{{ t('Preview') }}</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</div>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
</template>
|
||||||
</QTable>
|
</VnTable>
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</VnPaginate>
|
|
||||||
</div>
|
|
||||||
</QPage>
|
|
||||||
<QDialog v-model="dmsDialog.show">
|
<QDialog v-model="dmsDialog.show">
|
||||||
<VnDms
|
<VnDms
|
||||||
url="dms/uploadFile"
|
url="dms/uploadFile"
|
||||||
|
@ -292,29 +243,6 @@ function navigateToRouteSummary(event, row) {
|
||||||
/>
|
/>
|
||||||
</QDialog>
|
</QDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.route-list {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-actions {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
|
|
||||||
i {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
th:last-child,
|
|
||||||
td:last-child {
|
|
||||||
background-color: var(--vn-section-color);
|
|
||||||
position: sticky;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Search autonomous: Buscar autónomos
|
Search autonomous: Buscar autónomos
|
||||||
|
|
|
@ -1,50 +1,41 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useArrayData } from 'composables/useArrayData';
|
import { computed, ref } from 'vue';
|
||||||
import { dashIfEmpty, toHour } from 'src/filters';
|
|
||||||
import { computed, onMounted, ref } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useValidator } from 'composables/useValidator';
|
|
||||||
import { useSession } from 'composables/useSession';
|
import { useSession } from 'composables/useSession';
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
|
import { toDate } from 'src/filters';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import RouteSearchbar from 'pages/Route/Card/RouteSearchbar.vue';
|
import RouteSearchbar from 'pages/Route/Card/RouteSearchbar.vue';
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import RouteListTicketsDialog from 'pages/Route/Card/RouteListTicketsDialog.vue';
|
import RouteListTicketsDialog from 'pages/Route/Card/RouteListTicketsDialog.vue';
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
import TableVisibleColumns from 'src/components/common/TableVisibleColumns.vue';
|
|
||||||
import RouteFilter from 'pages/Route/Card/RouteFilter.vue';
|
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
|
||||||
import RouteSummary from 'pages/Route/Card/RouteSummary.vue';
|
import RouteSummary from 'pages/Route/Card/RouteSummary.vue';
|
||||||
|
|
||||||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
|
||||||
import VnInput from 'components/common/VnInput.vue';
|
|
||||||
import VnInputTime from 'components/common/VnInputTime.vue';
|
|
||||||
import VnSelect from 'components/common/VnSelect.vue';
|
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
|
||||||
import VnTable from 'components/VnTable/VnTable.vue';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
import { useStateStore } from 'src/stores/useStateStore';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { validate } = useValidator();
|
|
||||||
const { viewSummary } = useSummaryDialog();
|
const { viewSummary } = useSummaryDialog();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const paginate = ref();
|
|
||||||
const visibleColumns = ref([]);
|
|
||||||
const selectedRows = ref([]);
|
const selectedRows = ref([]);
|
||||||
const workers = ref([]);
|
const tableRef = ref([]);
|
||||||
const agencyList = ref([]);
|
|
||||||
const vehicleList = ref([]);
|
|
||||||
const allColumnNames = ref([]);
|
|
||||||
const confirmationDialog = ref(false);
|
const confirmationDialog = ref(false);
|
||||||
const startingDate = ref(null);
|
const startingDate = ref(null);
|
||||||
const refreshKey = ref(0);
|
const refreshKey = ref(0);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const stateStore = useStateStore();
|
const routeFilter = {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'workers',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'firstName'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -60,75 +51,114 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'worker',
|
name: 'workerFk',
|
||||||
label: t('Worker'),
|
label: t('Worker'),
|
||||||
create: true,
|
create: true,
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'payrollComponents',
|
url: 'Workers/activeWithInheritedRole',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'nickname'],
|
||||||
|
optionValue: 'id',
|
||||||
|
optionLabel: 'nickname',
|
||||||
},
|
},
|
||||||
|
useLike: false,
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'agency',
|
|
||||||
label: t('Agency'),
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
name: 'agencyModeFk',
|
||||||
|
label: t('Agency'),
|
||||||
isTitle: true,
|
isTitle: true,
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'agencyModes',
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
optionLabel: 'name',
|
||||||
|
optionValue: 'id',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'vehicle',
|
align: 'left',
|
||||||
|
name: 'vehicleFk',
|
||||||
label: t('Vehicle'),
|
label: t('Vehicle'),
|
||||||
align: 'left',
|
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'vehicles',
|
||||||
|
fields: ['id', 'numberPlate'],
|
||||||
|
optionLabel: 'numberPlate',
|
||||||
|
optionValue: 'id',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'date',
|
align: 'left',
|
||||||
|
name: 'created',
|
||||||
label: t('Date'),
|
label: t('Date'),
|
||||||
align: 'left',
|
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
component: 'date',
|
||||||
|
columnFilter: {
|
||||||
|
alias: 'c',
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
format: ({ date }) => toDate(date),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'volume',
|
|
||||||
label: 'm³',
|
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
name: 'm3',
|
||||||
|
label: 'volume',
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
name: 'description',
|
name: 'description',
|
||||||
label: t('Description'),
|
label: t('Description'),
|
||||||
align: 'left',
|
|
||||||
isTitle: true,
|
isTitle: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
component: 'input',
|
||||||
|
field: 'description',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
name: 'started',
|
name: 'started',
|
||||||
label: t('hourStarted'),
|
label: t('hourStarted'),
|
||||||
align: 'left',
|
component: 'time',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
name: 'finished',
|
name: 'finished',
|
||||||
label: t('hourFinished'),
|
label: t('hourFinished'),
|
||||||
align: 'left',
|
component: 'time',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'isServed',
|
|
||||||
label: t('Served'),
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
name: 'isOk',
|
||||||
|
label: t('Served'),
|
||||||
|
component: 'checkbox',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'right',
|
align: 'right',
|
||||||
label: 'asdasd',
|
|
||||||
name: 'tableActions',
|
name: 'tableActions',
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
title: t('Client ticket list'),
|
title: t('Add tickets'),
|
||||||
|
icon: 'vn:ticketAdd',
|
||||||
|
action: (row) => openTicketsDialog(row?.id),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('Preview'),
|
||||||
icon: 'preview',
|
icon: 'preview',
|
||||||
action: (row) => navigate(row.id),
|
action: (row) => viewSummary(row?.id, RouteSummary),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('Route summary'),
|
||||||
|
icon: 'arrow_forward',
|
||||||
|
isPrimary: true,
|
||||||
|
action: (row) => navigate(row?.id),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -138,22 +168,14 @@ function navigate(id) {
|
||||||
router.push({ path: `/route/${id}` });
|
router.push({ path: `/route/${id}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateRoute = async (route) => {
|
|
||||||
try {
|
|
||||||
return await axios.patch(`Routes/${route.id}`, route);
|
|
||||||
} catch (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const cloneRoutes = () => {
|
const cloneRoutes = () => {
|
||||||
|
if (!selectedRows.value.length || !startingDate.value) return;
|
||||||
axios.post('Routes/clone', {
|
axios.post('Routes/clone', {
|
||||||
created: startingDate.value,
|
created: startingDate.value,
|
||||||
ids: selectedRows.value.map((row) => row?.id),
|
ids: selectedRows.value.map((row) => row?.id),
|
||||||
});
|
});
|
||||||
refreshKey.value++;
|
tableRef.value.reload();
|
||||||
startingDate.value = null;
|
startingDate.value = null;
|
||||||
paginate.value.fetch();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const showRouteReport = () => {
|
const showRouteReport = () => {
|
||||||
|
@ -175,16 +197,13 @@ const showRouteReport = () => {
|
||||||
|
|
||||||
function markAsServed() {
|
function markAsServed() {
|
||||||
selectedRows.value.forEach(async (row) => {
|
selectedRows.value.forEach(async (row) => {
|
||||||
if (row?.id) await axios.patch(`Routes/${row?.id}`, { isOk: true });
|
await axios.patch(`Routes/${row?.id}`, { isOk: true });
|
||||||
});
|
});
|
||||||
refreshKey.value++;
|
tableRef.value.reload();
|
||||||
startingDate.value = null;
|
startingDate.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const openTicketsDialog = (id) => {
|
const openTicketsDialog = (id) => {
|
||||||
if (!id) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
quasar
|
quasar
|
||||||
.dialog({
|
.dialog({
|
||||||
component: RouteListTicketsDialog,
|
component: RouteListTicketsDialog,
|
||||||
|
@ -215,21 +234,10 @@ const openTicketsDialog = (id) => {
|
||||||
<QBtn flat :label="t('Cancel')" v-close-popup class="text-primary" />
|
<QBtn flat :label="t('Cancel')" v-close-popup class="text-primary" />
|
||||||
<QBtn color="primary" v-close-popup @click="cloneRoutes">
|
<QBtn color="primary" v-close-popup @click="cloneRoutes">
|
||||||
{{ t('globals.clone') }}
|
{{ t('globals.clone') }}
|
||||||
<VnLv
|
|
||||||
:label="t('route.summary.packages')"
|
|
||||||
:value="getTotalPackages(entity.tickets)"
|
|
||||||
/>
|
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</QCardActions>
|
</QCardActions>
|
||||||
</QCard>
|
</QCard>
|
||||||
</QDialog>
|
</QDialog>
|
||||||
<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 />
|
|
||||||
<VnSubToolbar />
|
<VnSubToolbar />
|
||||||
<VnTable
|
<VnTable
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
|
@ -239,13 +247,23 @@ const openTicketsDialog = (id) => {
|
||||||
:right-search="true"
|
:right-search="true"
|
||||||
default-mode="table"
|
default-mode="table"
|
||||||
:is-editable="true"
|
:is-editable="true"
|
||||||
|
:filter="routeFilter"
|
||||||
|
redirect="route"
|
||||||
:create="{
|
:create="{
|
||||||
urlCreate: 'Routes',
|
urlCreate: 'Routes',
|
||||||
title: t('Create route'),
|
title: t('Create route'),
|
||||||
onDataSaved: () => tableRef.reload(),
|
onDataSaved: ({ id }) => tableRef.redirect(id),
|
||||||
|
formInitialData: {},
|
||||||
}"
|
}"
|
||||||
save-url="routes"
|
save-url="Routes/crud"
|
||||||
:disable-option="{ card: true }"
|
:disable-option="{ card: true }"
|
||||||
|
:use-model="true"
|
||||||
|
table-height="85vh"
|
||||||
|
v-model:selected="selectedRows"
|
||||||
|
:table="{
|
||||||
|
'row-key': 'id',
|
||||||
|
selection: 'multiple',
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<template #moreBeforeActions>
|
<template #moreBeforeActions>
|
||||||
<QBtn
|
<QBtn
|
||||||
|
|
|
@ -1,65 +1,68 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { dashIfEmpty, toDateHourMin } from 'src/filters';
|
import { dashIfEmpty } from 'src/filters';
|
||||||
|
import { toDate } from 'filters/index';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
import toCurrency from 'filters/toCurrency';
|
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
|
||||||
import SupplierDescriptorProxy from 'pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
|
||||||
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
|
||||||
import RoadmapFilter from 'pages/Route/Roadmap/RoadmapFilter.vue';
|
|
||||||
import VnConfirm from 'components/ui/VnConfirm.vue';
|
|
||||||
import axios from 'axios';
|
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
|
||||||
import { useSummaryDialog } from 'composables/useSummaryDialog';
|
import { useSummaryDialog } from 'composables/useSummaryDialog';
|
||||||
import RoadmapSummary from 'pages/Route/Roadmap/RoadmapSummary.vue';
|
import toCurrency from 'filters/toCurrency';
|
||||||
import { useRouter } from 'vue-router';
|
import axios from 'axios';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
|
||||||
|
|
||||||
const stateStore = useStateStore();
|
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
||||||
|
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||||
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
|
import RoadmapSummary from 'pages/Route/Roadmap/RoadmapSummary.vue';
|
||||||
|
import VnConfirm from 'components/ui/VnConfirm.vue';
|
||||||
|
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
|
import VnInputTime from 'src/components/common/VnInputTime.vue';
|
||||||
|
|
||||||
|
const { viewSummary } = useSummaryDialog();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const router = useRouter();
|
|
||||||
const { viewSummary } = useSummaryDialog();
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
onMounted(() => (stateStore.rightDrawer = true));
|
|
||||||
onUnmounted(() => (stateStore.rightDrawer = false));
|
|
||||||
|
|
||||||
const selectedRows = ref([]);
|
const selectedRows = ref([]);
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
name: 'roadmap',
|
align: 'left',
|
||||||
|
name: 'id',
|
||||||
|
label: 'Id',
|
||||||
|
isId: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'name',
|
||||||
label: t('Roadmap'),
|
label: t('Roadmap'),
|
||||||
field: (row) => row.name,
|
create: true,
|
||||||
sortable: true,
|
cardVisible: true,
|
||||||
align: 'left',
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ETD',
|
align: 'left',
|
||||||
|
name: 'etd',
|
||||||
label: t('ETD'),
|
label: t('ETD'),
|
||||||
field: (row) => toDateHourMin(row.etd),
|
component: 'date',
|
||||||
sortable: true,
|
columnFilter: {
|
||||||
align: 'left',
|
alias: 'c',
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
format: ({ date }) => toDate(date),
|
||||||
|
cardVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'carrier',
|
align: 'left',
|
||||||
|
name: 'supplierFk',
|
||||||
label: t('Carrier'),
|
label: t('Carrier'),
|
||||||
field: (row) => row.supplier?.nickname,
|
component: 'select',
|
||||||
sortable: true,
|
attrs: {
|
||||||
align: 'left',
|
url: 'suppliers',
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
optionLabel: 'name',
|
||||||
|
optionValue: 'id',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'plate',
|
name: 'tractorPlate',
|
||||||
label: t('Plate'),
|
label: t('Plate'),
|
||||||
field: (row) => row.tractorPlate,
|
field: (row) => row.tractorPlate,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
|
@ -80,30 +83,29 @@ const columns = computed(() => [
|
||||||
align: 'left',
|
align: 'left',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'actions',
|
|
||||||
label: '',
|
|
||||||
sortable: false,
|
|
||||||
align: 'right',
|
align: 'right',
|
||||||
|
name: 'tableActions',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
title: t('Ver cmr'),
|
||||||
|
icon: 'visibility',
|
||||||
|
isPrimary: true,
|
||||||
|
action: (row) => viewSummary(row?.id, RoadmapSummary),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const refreshKey = ref(0);
|
const tableRef = ref(0);
|
||||||
const isCloneDialogOpen = ref(false);
|
const isCloneDialogOpen = ref(false);
|
||||||
const etdDate = ref(null);
|
const etdDate = ref(null);
|
||||||
|
|
||||||
const filter = {
|
|
||||||
include: { relation: 'supplier', scope: { fields: ['nickname'] } },
|
|
||||||
where: {
|
|
||||||
and: [{ etd: { gte: from } }, { etd: { lte: to } }],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const cloneSelection = async () => {
|
const cloneSelection = async () => {
|
||||||
await axios.post('Roadmaps/clone', {
|
await axios.post('Roadmaps/clone', {
|
||||||
etd: etdDate.value,
|
etd: etdDate.value,
|
||||||
ids: selectedRows.value.map((row) => row?.id),
|
ids: selectedRows.value.map((row) => row?.id),
|
||||||
});
|
});
|
||||||
refreshKey.value++;
|
tableRef.value.reload();
|
||||||
etdDate.value = null;
|
etdDate.value = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,11 +127,7 @@ function confirmRemove() {
|
||||||
promise: removeSelection,
|
promise: removeSelection,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.onOk(() => refreshKey.value++);
|
.onOk(() => tableRef.value++);
|
||||||
}
|
|
||||||
|
|
||||||
function navigateToRoadmapSummary(_, { id }) {
|
|
||||||
router.push({ name: 'RoadmapSummary', params: { id } });
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -139,11 +137,6 @@ function navigateToRoadmapSummary(_, { id }) {
|
||||||
:label="t('Search roadmaps')"
|
:label="t('Search roadmaps')"
|
||||||
:info="t('You can search by roadmap reference')"
|
:info="t('You can search by roadmap reference')"
|
||||||
/>
|
/>
|
||||||
<RightMenu>
|
|
||||||
<template #right-panel>
|
|
||||||
<RoadmapFilter data-key="RoadmapList" />
|
|
||||||
</template>
|
|
||||||
</RightMenu>
|
|
||||||
<QDialog v-model="isCloneDialogOpen">
|
<QDialog v-model="isCloneDialogOpen">
|
||||||
<QCard style="min-width: 350px">
|
<QCard style="min-width: 350px">
|
||||||
<QCardSection>
|
<QCardSection>
|
||||||
|
@ -163,7 +156,6 @@ function navigateToRoadmapSummary(_, { id }) {
|
||||||
</QCardActions>
|
</QCardActions>
|
||||||
</QCard>
|
</QCard>
|
||||||
</QDialog>
|
</QDialog>
|
||||||
<QPage class="column items-center">
|
|
||||||
<VnSubToolbar class="justify-end">
|
<VnSubToolbar class="justify-end">
|
||||||
<template #st-actions>
|
<template #st-actions>
|
||||||
<QBtn
|
<QBtn
|
||||||
|
@ -186,72 +178,33 @@ function navigateToRoadmapSummary(_, { id }) {
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</template>
|
</template>
|
||||||
</VnSubToolbar>
|
</VnSubToolbar>
|
||||||
<div class="route-list">
|
<VnTable
|
||||||
<VnPaginate
|
ref="tableRef"
|
||||||
:key="refreshKey"
|
|
||||||
data-key="RoadmapList"
|
data-key="RoadmapList"
|
||||||
url="Roadmaps"
|
url="roadmaps"
|
||||||
:limit="20"
|
|
||||||
:filter="filter"
|
|
||||||
>
|
|
||||||
<template #body="{ rows }">
|
|
||||||
<div class="q-pa-md">
|
|
||||||
<QTable
|
|
||||||
v-model:selected="selectedRows"
|
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:rows="rows"
|
:right-search="true"
|
||||||
flat
|
:use-model="true"
|
||||||
row-key="id"
|
default-mode="table"
|
||||||
selection="multiple"
|
v-model:selected="selectedRows"
|
||||||
:rows-per-page-options="[0]"
|
table-height="85vh"
|
||||||
hide-pagination
|
:table="{
|
||||||
:pagination="{ sortBy: 'ID', descending: true }"
|
selection: 'multiple',
|
||||||
@row-click="navigateToRoadmapSummary"
|
}"
|
||||||
|
redirect="route/roadmap"
|
||||||
|
:create="{
|
||||||
|
urlCreate: 'Roadmaps',
|
||||||
|
title: t('Create routemap'),
|
||||||
|
onDataSaved: ({ id }) => tableRef.redirect(id),
|
||||||
|
formInitialData: {},
|
||||||
|
}"
|
||||||
|
:disable-option="{ card: true }"
|
||||||
>
|
>
|
||||||
<template #body-cell-carrier="props">
|
<template #more-create-dialog="{ data }">
|
||||||
<QTd :props="props">
|
<VnInputDate v-model="data.etd" />
|
||||||
<span v-if="props.value" class="link" @click.stop>
|
<VnInputTime v-model="data.etd" />
|
||||||
{{ props.value }}
|
|
||||||
<SupplierDescriptorProxy
|
|
||||||
:id="props.row?.supplier?.id"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-actions="props">
|
</VnTable>
|
||||||
<QTd :props="props">
|
|
||||||
<div class="flex items-center table-actions">
|
|
||||||
<QIcon
|
|
||||||
name="preview"
|
|
||||||
size="sm"
|
|
||||||
color="primary"
|
|
||||||
@click.stop="
|
|
||||||
viewSummary(
|
|
||||||
props?.row?.id,
|
|
||||||
RoadmapSummary
|
|
||||||
)
|
|
||||||
"
|
|
||||||
class="cursor-pointer"
|
|
||||||
>
|
|
||||||
<QTooltip>{{ t('Preview') }}</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</div>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
</QTable>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</VnPaginate>
|
|
||||||
</div>
|
|
||||||
<QPageSticky :offset="[20, 20]">
|
|
||||||
<RouterLink :to="{ name: 'RouteRoadmapCreate' }">
|
|
||||||
<QBtn fab icon="add" color="primary" />
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('Create roadmap') }}
|
|
||||||
</QTooltip>
|
|
||||||
</RouterLink>
|
|
||||||
</QPageSticky>
|
|
||||||
</QPage>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -264,6 +217,7 @@ function navigateToRoadmapSummary(_, { id }) {
|
||||||
</style>
|
</style>
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
|
Create routemap: Crear troncal
|
||||||
Search roadmaps: Buscar troncales
|
Search roadmaps: Buscar troncales
|
||||||
You can search by roadmap reference: Puedes buscar por referencia del troncal
|
You can search by roadmap reference: Puedes buscar por referencia del troncal
|
||||||
Delete roadmap(s): Eliminar troncal(es)
|
Delete roadmap(s): Eliminar troncal(es)
|
||||||
|
|
|
@ -57,15 +57,6 @@ export default {
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Route/RouteRoadmap.vue'),
|
component: () => import('src/pages/Route/RouteRoadmap.vue'),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'roadmap/create',
|
|
||||||
name: 'RouteRoadmapCreate',
|
|
||||||
meta: {
|
|
||||||
title: 'RouteRoadmapCreate',
|
|
||||||
icon: 'vn:troncales',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Route/Roadmap/RoadmapCreate.vue'),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'cmr',
|
path: 'cmr',
|
||||||
name: 'CmrList',
|
name: 'CmrList',
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
describe('Route', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.viewport(1920, 1080);
|
||||||
|
cy.login('developer');
|
||||||
|
cy.visit(`/#/route/roadmap`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Route list create route', () => {
|
||||||
|
cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
|
||||||
|
cy.get('input[name="name"]').eq(1).type('routeTestOne{enter}');
|
||||||
|
cy.get('.q-notification__message').should('have.text', 'Data created');
|
||||||
|
cy.url().should('include', '/summary');
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,15 @@
|
||||||
|
describe('Route', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.viewport(1920, 1080);
|
||||||
|
cy.login('developer');
|
||||||
|
cy.visit(`/#/route/list`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Route list create route', () => {
|
||||||
|
cy.visit(`/#/route/list`);
|
||||||
|
cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
|
||||||
|
cy.get('input[name="description"]').eq(1).type('routeTestOne{enter}');
|
||||||
|
cy.get('.q-notification__message').should('have.text', 'Data created');
|
||||||
|
cy.url().should('include', '/summary');
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue