0
0
Fork 0

refs new sections

This commit is contained in:
Alexandre Riera 2023-03-21 10:46:51 +01:00
parent e9acc6b687
commit f4286b5d28
13 changed files with 807 additions and 649 deletions

Binary file not shown.

File diff suppressed because one or more lines are too long

Before

(image error) Size: 159 KiB

After

(image error) Size: 162 KiB

Binary file not shown.

Binary file not shown.

View File

@ -1,399 +1,403 @@
@font-face {
font-family: 'icomoon';
src: url('fonts/icomoon.eot?g6kvgn');
src: url('fonts/icomoon.eot?g6kvgn#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?g6kvgn') format('truetype'),
url('fonts/icomoon.woff?g6kvgn') format('woff'),
url('fonts/icomoon.svg?g6kvgn#icomoon') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
font-family: 'icomoon';
src: url('fonts/icomoon.eot?g6kvgn');
src: url('fonts/icomoon.eot?g6kvgn#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?g6kvgn') format('truetype'),
url('fonts/icomoon.woff?g6kvgn') format('woff'),
url('fonts/icomoon.svg?g6kvgn#icomoon') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
}
[class^="icon-"], [class*=" icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon' !important;
speak: never;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
[class^='icon-'],
[class*=' icon-'] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon' !important;
speak: never;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-pin:before {
content: "\e950";
content: '\e950';
}
.icon-pin_off:before {
content: "\e95b";
content: '\e95b';
}
.icon-frozen:before {
content: "\e900";
content: '\e900';
}
.icon-Person:before {
content: "\e901";
content: '\e901';
}
.icon-handmadeArtificial:before {
content: "\e902";
content: '\e902';
}
.icon-fruit:before {
content: "\e903";
content: '\e903';
}
.icon-funeral:before {
content: "\e904";
content: '\e904';
}
.icon-noPayMethod:before {
content: "\e905";
content: '\e905';
}
.icon-preserved:before {
content: "\e906";
content: '\e906';
}
.icon-greenery:before {
content: "\e907";
content: '\e907';
}
.icon-planta:before {
content: "\e908";
content: '\e908';
}
.icon-handmade:before {
content: "\e909";
content: '\e909';
}
.icon-accessory:before {
content: "\e90a";
content: '\e90a';
}
.icon-artificial:before {
content: "\e90b";
content: '\e90b';
}
.icon-flower:before {
content: "\e90c";
content: '\e90c';
}
.icon-fixedPrice:before {
content: "\e90d";
content: '\e90d';
}
.icon-addperson:before {
content: "\e90e";
content: '\e90e';
}
.icon-supplierfalse:before {
content: "\e90f";
content: '\e90f';
}
.icon-invoice-out:before {
content: "\e910";
content: '\e910';
}
.icon-invoice-in:before {
content: "\e911";
content: '\e911';
}
.icon-invoice-in-create:before {
content: "\e912";
content: '\e912';
}
.icon-basketadd:before {
content: "\e913";
content: '\e913';
}
.icon-basket:before {
content: "\e914";
content: '\e914';
}
.icon-uniE915:before {
content: "\e915";
content: '\e915';
}
.icon-uniE916:before {
content: "\e916";
content: '\e916';
}
.icon-uniE917:before {
content: "\e917";
content: '\e917';
}
.icon-uniE918:before {
content: "\e918";
content: '\e918';
}
.icon-uniE919:before {
content: "\e919";
content: '\e919';
}
.icon-uniE91A:before {
content: "\e91a";
content: '\e91a';
}
.icon-isTooLittle:before {
content: "\e91b";
content: '\e91b';
}
.icon-deliveryprices:before {
content: "\e91c";
content: '\e91c';
}
.icon-onlinepayment:before {
content: "\e91d";
content: '\e91d';
}
.icon-risk:before {
content: "\e91e";
content: '\e91e';
}
.icon-noweb:before {
content: "\e91f";
content: '\e91f';
}
.icon-no036:before {
content: "\e920";
content: '\e920';
}
.icon-disabled:before {
content: "\e921";
content: '\e921';
}
.icon-treatments:before {
content: "\e922";
content: '\e922';
}
.icon-invoice:before {
content: "\e923";
content: '\e923';
}
.icon-photo:before {
content: "\e924";
content: '\e924';
}
.icon-supplier:before {
content: "\e925";
content: '\e925';
}
.icon-languaje:before {
content: "\e926";
content: '\e926';
}
.icon-credit:before {
content: "\e927";
content: '\e927';
}
.icon-client:before {
content: "\e928";
content: '\e928';
}
.icon-shipment-01:before {
content: "\e929";
content: '\e929';
}
.icon-account:before {
content: "\e92a";
content: '\e92a';
}
.icon-inventory:before {
content: "\e92b";
content: '\e92b';
}
.icon-unavailable:before {
content: "\e92c";
content: '\e92c';
}
.icon-wiki:before {
content: "\e92d";
content: '\e92d';
}
.icon-attach:before {
content: "\e92e";
content: '\e92e';
}
.icon-exit:before {
content: "\e92f";
content: '\e92f';
}
.icon-anonymous:before {
content: "\e930";
content: '\e930';
}
.icon-net:before {
content: "\e931";
content: '\e931';
}
.icon-buyrequest:before {
content: "\e932";
content: '\e932';
}
.icon-thermometer:before {
content: "\e933";
content: '\e933';
}
.icon-entry:before {
content: "\e934";
content: '\e934';
}
.icon-deletedTicket:before {
content: "\e935";
content: '\e935';
}
.icon-logout:before {
content: "\e936";
content: '\e936';
}
.icon-catalog:before {
content: "\e937";
content: '\e937';
}
.icon-agency:before {
content: "\e938";
content: '\e938';
}
.icon-delivery:before {
content: "\e939";
content: '\e939';
}
.icon-wand:before {
content: "\e93a";
content: '\e93a';
}
.icon-buscaman:before {
content: "\e93b";
content: '\e93b';
}
.icon-pbx:before {
content: "\e93c";
content: '\e93c';
}
.icon-calendar:before {
content: "\e93d";
content: '\e93d';
}
.icon-splitline:before {
content: "\e93e";
content: '\e93e';
}
.icon-consignatarios:before {
content: "\e93f";
content: '\e93f';
}
.icon-tax:before {
content: "\e940";
content: '\e940';
}
.icon-notes:before {
content: "\e941";
content: '\e941';
}
.icon-lines:before {
content: "\e942";
content: '\e942';
}
.icon-zone:before {
content: "\e943";
content: '\e943';
}
.icon-greuge:before {
content: "\e944";
content: '\e944';
}
.icon-ticketAdd:before {
content: "\e945";
content: '\e945';
}
.icon-components:before {
content: "\e946";
content: '\e946';
}
.icon-pets:before {
content: "\e947";
content: '\e947';
}
.icon-linesprepaired:before {
content: "\e948";
content: '\e948';
}
.icon-control:before {
content: "\e949";
content: '\e949';
}
.icon-revision:before {
content: "\e94a";
content: '\e94a';
}
.icon-deaulter:before {
content: "\e94b";
content: '\e94b';
}
.icon-services:before {
content: "\e94c";
content: '\e94c';
}
.icon-albaran:before {
content: "\e94d";
content: '\e94d';
}
.icon-solunion:before {
content: "\e94e";
content: '\e94e';
}
.icon-stowaway:before {
content: "\e94f";
content: '\e94f';
}
.icon-apps:before {
content: "\e951";
content: '\e951';
}
.icon-info:before {
content: "\e952";
content: '\e952';
}
.icon-columndelete:before {
content: "\e953";
content: '\e953';
}
.icon-columnadd:before {
content: "\e954";
content: '\e954';
}
.icon-deleteline:before {
content: "\e955";
content: '\e955';
}
.icon-item:before {
content: "\e956";
content: '\e956';
}
.icon-worker:before {
content: "\e957";
content: '\e957';
}
.icon-headercol:before {
content: "\e958";
content: '\e958';
}
.icon-reserva:before {
content: "\e959";
content: '\e959';
}
.icon-100:before {
content: "\e95a";
content: '\e95a';
}
.icon-sign:before {
content: "\e95d";
content: '\e95d';
}
.icon-polizon:before {
content: "\e95e";
content: '\e95e';
}
.icon-solclaim:before {
content: "\e95f";
content: '\e95f';
}
.icon-actions:before {
content: "\e960";
content: '\e960';
}
.icon-details:before {
content: "\e961";
content: '\e961';
}
.icon-traceability:before {
content: "\e962";
content: '\e962';
}
.icon-claims:before {
content: "\e963";
content: '\e963';
}
.icon-regentry:before {
content: "\e964";
content: '\e964';
}
.icon-transaction:before {
content: "\e966";
content: '\e966';
}
.icon-History:before {
content: "\e968";
content: '\e968';
}
.icon-mana:before {
content: "\e96a";
content: '\e96a';
}
.icon-ticket:before {
content: "\e96b";
content: '\e96b';
}
.icon-niche:before {
content: "\e96c";
content: '\e96c';
}
.icon-tags:before {
content: "\e96d";
content: '\e96d';
}
.icon-volume:before {
content: "\e96e";
content: '\e96e';
}
.icon-bin:before {
content: "\e96f";
content: '\e96f';
}
.icon-splur:before {
content: "\e970";
content: '\e970';
}
.icon-barcode:before {
content: "\e971";
content: '\e971';
}
.icon-botanical:before {
content: "\e972";
content: '\e972';
}
.icon-clone:before {
content: "\e973";
content: '\e973';
}
.icon-sms:before {
content: "\e975";
content: '\e975';
}
.icon-eye:before {
content: "\e976";
content: '\e976';
}
.icon-doc:before {
content: "\e977";
content: '\e977';
}
.icon-package:before {
content: "\e978";
content: '\e978';
}
.icon-settings:before {
content: "\e979";
content: '\e979';
}
.icon-bucket:before {
content: "\e97a";
content: '\e97a';
}
.icon-mandatory:before {
content: "\e97b";
content: '\e97b';
}
.icon-recovery:before {
content: "\e97c";
content: '\e97c';
}
.icon-payment:before {
content: "\e97e";
content: '\e97e';
}
.icon-grid:before {
content: "\e980";
content: '\e980';
}
.icon-web:before {
content: "\e982";
content: '\e982';
}
.icon-dfiscales:before {
content: "\e984";
content: '\e984';
}
.icon-trolley:before {
content: '\e95c';
}

View File

@ -389,17 +389,42 @@ export default {
wagon: {
pageTitles: {
wagons: 'Wagons',
types: 'Types',
wagonsList: 'Wagons List',
wagonCreate: 'Create wagon',
wagonEdit: 'Edit wagon',
typesList: 'Types List',
typeCreate: 'Create type',
typeEdit: 'Edit type'
},
type: {
name: 'Name',
nameNotEmpty: 'Name can not be empty',
maxTrays: 'You have reached the max number of trays',
saveMessage: 'Wagon type successfully saved',
submit: 'Submit',
reset: 'Reset'
reset: 'Reset',
trayColor: 'Tray color',
},
list: {
plate: 'Plate',
volume: 'Volume',
type: 'Type',
remove: 'Remove'
},
create: {
plate: 'Plate',
volume: 'Volume',
type: 'Type',
label: 'Label'
},
warnings: {
nameNotEmpty: 'Name can not be empty',
labelNotEmpty: 'Label can not be empty',
plateNotEmpty: 'Plate can not be empty',
volumeNotEmpty: 'Volume can not be empty',
typeNotEmpty: 'Type can not be empty',
maxTrays: 'You have reached the max number of trays',
minHeightBetweenTrays: 'The minimum height between trays is ',
maxWagonHeight: 'The maximum height of the wagon is ',
uncompleteTrays: 'There are incomplete trays',
}
},
components: {

View File

@ -389,17 +389,41 @@ export default {
wagon: {
pageTitles: {
wagons: 'Vagones',
types: 'Tipos',
wagonsList: 'Listado vagones',
wagonCreate: 'Crear tipo',
wagonEdit: 'Editar tipo',
typesList: 'Listado tipos',
typeCreate: 'Crear tipo',
typeEdit: 'Editar tipo'
},
type: {
name: 'Nombre',
nameNotEmpty: 'El nombre no puede estar vacío',
maxTrays: 'Has alcanzado el número máximo de bandejas',
saveMessage: 'Tipo de vagón guardado correctamente',
submit: 'Guardar',
reset: 'Deshacer cambios'
reset: 'Deshacer cambios',
trayColor: 'Color de la bandeja',
},
list: {
plate: 'Matrícula',
volume: 'Volumen',
type: 'Tipo',
remove: 'Borrar'
},
create: {
plate: 'Matrícula',
volume: 'Volumen',
type: 'Tipo',
label: 'Etiqueta',
},
warnings: {
nameNotEmpty: 'El nombre no puede estar vacío',
labelNotEmpty: 'La etiqueta no puede estar vacía',
plateNotEmpty: 'La matrícula no puede estar vacía',
volumeNotEmpty: 'El volumen no puede estar vacío',
typeNotEmpty: 'El tipo no puede estar vacío',
maxTrays: 'Has alcanzado el número máximo de bandejas',
minHeightBetweenTrays: 'La distancia mínima entre bandejas es ',
maxWagonHeight: 'La altura máxima del vagón es ',
uncompleteTrays: 'Hay bandejas sin completar',
}
},
components: {

View File

@ -1,103 +0,0 @@
<script setup>
const props = defineProps({
position: {
type: Number,
required: true,
},
color: {
type: Object,
required: true,
},
action: {
type: String,
required: true,
},
divisible: {
type: Boolean,
required: true,
},
});
const emit = defineEmits(['add-tray', 'delete-tray']);
function doAction() {
if (props.action == 'add') {
emit('add-tray');
} else {
emit('delete-tray', props.position);
}
}
</script>
<template>
<div class="wagon-tray q-mx-xl">
<div class="position">{{ position }}</div>
<div class="shelving">
<div class="shelving-half">
<div class="shelving-up"></div>
<div
class="shelving-down"
:style="{ backgroundColor: props.color.rgb }"
></div>
</div>
<div
class="shelving-divisible"
:class="{ isDivisible: !props.divisible }"
></div>
<div class="shelving-half">
<div class="shelving-up"></div>
<div
class="shelving-down"
:style="{ backgroundColor: props.color.rgb }"
></div>
</div>
</div>
<div class="action-button">
<q-btn flat round color="primary" :icon="action" @click="doAction()" />
</div>
</div>
</template>
<style lang="scss" scoped>
.wagon-tray {
display: flex;
height: 6rem;
.position {
width: 10%;
border-right: 1rem solid gray;
display: flex;
align-items: flex-end;
justify-content: flex-end;
padding-right: 1rem;
}
.shelving {
display: flex;
width: 80%;
.shelving-half {
width: 50%;
height: 100%;
.shelving-up {
height: 80%;
width: 100%;
}
.shelving-down {
height: 20%;
width: 100%;
}
}
.shelving-divisible {
width: 1%;
height: 100%;
border-left: 0.5rem dashed grey;
border-right: 0.5rem dashed grey;
}
.isDivisible {
display: none;
}
}
.action-button {
width: 10%;
border-left: 1rem solid gray;
display: flex;
align-items: flex-end;
justify-content: flex-start;
padding-left: 1rem;
}
}
</style>

View File

@ -1,150 +1,304 @@
<!-- <script setup>
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import { useQuasar } from 'quasar';
import { useStateStore } from 'stores/useStateStore';
import Paginate from 'src/components/PaginateData.vue';
import WorkerSummaryDialog from 'src/pages/Worker/Card/WorkerSummaryDialog.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
import WorkerFilter from 'src/pages/Worker/WorkerFilter.vue';
const stateStore = useStateStore();
const router = useRouter();
const { t } = useI18n();
const quasar = useQuasar();
function navigate(id) {
router.push({ path: `/worker/${id}` });
}
function viewSummary(id) {
quasar.dialog({
component: WorkerSummaryDialog,
componentProps: {
id,
},
});
}
</script> -->
<script setup>
import axios from 'axios';
import FetchData from 'components/FetchData.vue';
import { useQuasar } from 'quasar';
import { ref } from 'vue';
import { computed, ref, onMounted, onUpdated } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import WagonTray from '../Type/WagonTray.vue';
import { useRoute, useRouter } from 'vue-router';
onMounted(() => fetch());
onUpdated(() => fetch());
const { t } = useI18n();
const route = useRoute();
const quasar = useQuasar();
const router = useRouter();
const wagonConfig = ref([]);
const wagonTypeColors = ref([]);
const $props = defineProps({
id: {
type: Number,
required: false,
default: null,
},
});
const entityId = computed(() => $props.id || route.params.id);
const wagon = ref([]);
const divisible = ref(false);
const name = ref('');
let currentPosition = 0;
const colorPickerActive = ref(false);
const originalData = { trays: [] };
let wagonConfig;
let wagonTypeColors;
let currentTrayColorPicked;
function addTray() {
if (wagon.value.length < wagonConfig.value.maxTrays - 1) {
currentPosition += wagonConfig.value.minTrayHeight;
if (
wagon.value.find((tray) => {
return tray.position == null;
})
) {
quasar.notify({
message: t('wagon.warnings.uncompleteTrays'),
type: 'warning',
});
return;
}
if (wagon.value.length < wagonConfig.maxTrays) {
wagon.value.unshift({
position: currentPosition,
color: {
id: 1,
rgb: 'blue',
},
id: wagon.value.length,
position: null,
color: { ...wagonTypeColors[0] },
action: 'delete',
});
} else {
quasar.notify({
message: t('wagon.type.maxTrays'),
message: t('wagon.warnings.maxTrays'),
type: 'warning',
});
}
}
function deleteTray(position) {
currentPosition = 0;
wagon.value = wagon.value.filter((tray) => tray.position !== position);
for (let i = wagon.value.length - 1; i >= 0; i--) {
currentPosition += wagonConfig.value.minTrayHeight;
wagon.value[i].position = currentPosition;
function deleteTray(trayToDelete) {
wagon.value = wagon.value.filter((tray) => tray.id !== trayToDelete.id);
reorderIds();
}
function reorderIds() {
for (let index = wagon.value.length - 1; index >= 0; index--) {
wagon.value[index].id = index;
}
}
async function onSubmit() {
try {
await axios
.post('WagonTypes', {
name: name.value,
})
.then(async (res) => {
const trays = [];
wagon.value.forEach((tray) => {
trays.push({
typeFk: res.data.id,
height: tray.position,
colorFk: tray.color.id,
});
});
await axios.post('WagonTypeTrays', trays).then(() => {
router.push({ path: `/wagon/type/list` });
quasar.notify({
message: t('wagon.type.saveMessage'),
type: 'positive',
});
});
});
const path = entityId.value
? 'WagonTypes/editWagonType'
: 'WagonTypes/createWagonType';
const params = {
id: entityId.value,
name: name.value,
divisible: divisible.value,
trays: wagon.value,
};
await axios.patch(path, params).then((res) => {
if (res.status == 204) router.push({ path: `/wagon/type/list` });
});
} catch (error) {
//
}
}
async function onReset() {
name.value = null;
divisible.value = false;
wagon.value = [];
currentPosition = 0;
name.value = entityId.value ? originalData.name : null;
divisible.value = entityId.value ? originalData.divisible : false;
wagon.value = entityId.value
? [...originalData.trays]
: [
{
id: 0,
position: 0,
color: { ...wagonTypeColors[0] },
action: 'add',
},
];
}
async function fetch() {
await axios.get(`WagonConfigs`).then(async (res) => {
if (res.data) {
wagonConfig = res.data[0];
}
});
await axios.get(`WagonTypeColors`).then(async (res) => {
if (res.data) {
wagonTypeColors = res.data;
if (!entityId.value)
wagon.value.push({
id: 0,
position: 0,
color: { ...wagonTypeColors[0] },
action: 'add',
});
else {
await axios
.get(`WagonTypeTrays`, {
params: { filter: { where: { typeFk: entityId.value } } },
})
.then(async (res) => {
if (res.data) {
for (let i = 0; i < res.data.length; i++) {
const tray = res.data[i];
wagon.value.push({
id: res.data.length - i - 1,
position: tray.height,
color: {
...wagonTypeColors.find((color) => {
return color.id === tray.colorFk;
}),
},
action: tray.height == 0 ? 'add' : 'delete',
});
}
wagon.value.forEach((value) => {
originalData.trays.push({ ...value });
});
}
});
}
}
});
if (entityId.value) {
await axios.get(`WagonTypes/${entityId.value}`).then((res) => {
if (res.data) {
originalData.name = name.value = res.data.name;
originalData.divisible = divisible.value = res.data.divisible;
}
});
}
}
function doAction(tray) {
if (tray.action == 'add') {
addTray();
} else {
deleteTray(tray);
}
}
function showColorPicker(tray) {
colorPickerActive.value = true;
currentTrayColorPicked = wagon.value.findIndex((val) => {
return val.id === tray.id;
});
}
function updateColor(newColor) {
wagon.value[currentTrayColorPicked].color = {
...wagonTypeColors.find((color) => {
return color.rgb === newColor;
}),
};
}
function onPositionBlur(tray) {
if (tray.position) {
if (tray.position == '' || tray.position < 0) {
tray.position = null;
return;
}
tray.position = parseInt(tray.position);
wagon.value.sort((a, b) => b.position - a.position);
reorderIds();
for (let index = wagon.value.length - 1; index > 0; index--) {
checkMaxHeight(index - 1);
if (
wagon.value[index - 1].position - wagon.value[index].position >=
wagonConfig.minHeightBetweenTrays
) {
continue;
} else {
wagon.value[index - 1].position +=
wagonConfig.minHeightBetweenTrays -
(wagon.value[index - 1].position - wagon.value[index].position);
quasar.notify({
message:
t('wagon.warnings.minHeightBetweenTrays') +
wagonConfig.minHeightBetweenTrays +
' cm',
type: 'warning',
});
checkMaxHeight(index - 1);
}
}
}
}
function checkMaxHeight(pos) {
if (wagon.value[pos].position > wagonConfig.maxWagonHeight) {
wagon.value.splice(pos, 1);
quasar.notify({
message:
t('wagon.warnings.maxWagonHeight') + wagonConfig.maxWagonHeight + ' cm',
type: 'warning',
});
}
}
</script>
<template>
<fetch-data
url="WagonConfigs"
@on-fetch="(data) => (wagonConfig = data[0])"
auto-load
/>
<fetch-data
url="WagonTypeColors"
@on-fetch="(data) => (wagonTypeColors = data)"
auto-load
/>
<q-page class="q-pa-sm q-mx-xl">
<q-card class="q-pa-sm">
<q-form @submit="onSubmit" @reset="onReset" class="q-pa-md">
<q-form @submit="onSubmit()" @reset="onReset()" class="q-pa-md">
<q-input
filled
v-model="name"
:label="t('wagon.type.name')"
:rules="[(val) => !!val || t('wagon.type.nameNotEmpty')]"
:rules="[(val) => !!val || t('wagon.warnings.nameNotEmpty')]"
/>
<q-checkbox class="q-mb-sm" v-model="divisible" label="Divisible" />
<div v-for="tray in wagon" :key="tray.position">
<WagonTray
action="delete"
@delete-tray="deleteTray"
:position="tray.position"
:color="{ rgb: 'blue' }"
:divisible="divisible"
></WagonTray>
<div class="wagon-tray q-mx-xl" v-for="tray in wagon" :key="tray.id">
<div class="position">
<q-input
autofocus
filled
type="number"
:class="{ isVisible: tray.action == 'add' }"
v-model="tray.position"
@blur="onPositionBlur(tray)"
>
<q-tooltip :delay="2000">
{{
t('wagon.warnings.minHeightBetweenTrays') +
wagonConfig.minHeightBetweenTrays +
' cm'
}}
<q-space />
{{
t('wagon.warnings.maxWagonHeight') +
wagonConfig.maxWagonHeight +
' cm'
}}
</q-tooltip>
</q-input>
</div>
<div class="shelving">
<div class="shelving-half">
<div class="shelving-up"></div>
<div
class="shelving-down"
:style="{ backgroundColor: tray.color.rgb }"
@click="showColorPicker(tray)"
></div>
</div>
<div
class="shelving-divisible"
:class="{ isVisible: !divisible }"
></div>
<div class="shelving-half">
<div class="shelving-up"></div>
<div
class="shelving-down"
:style="{ backgroundColor: tray.color.rgb }"
@click="showColorPicker(tray)"
></div>
</div>
</div>
<div class="action-button">
<q-btn
flat
round
color="primary"
:icon="tray.action"
@click="doAction(tray)"
/>
</div>
</div>
<WagonTray
v-if="wagonTypeColors.values"
action="add"
@add-tray="addTray"
:color="{ rgb: 'blue' }"
:divisible="divisible"
></WagonTray>
<div class="q-mb-sm wheels">
<q-icon color="grey-6" name="trip_origin" size="3rem" />
<q-icon color="grey-6" name="trip_origin" size="3rem" />
@ -162,19 +316,34 @@ async function onReset() {
flat
class="q-ml-sm"
/>
<!-- <q-color
flat
v-model="hex"
no-header
no-footer
default-view="palette"
:palette="
wagonTypeColors.map((color) => {
return color.rgb;
})
"
/> -->
</div>
<q-dialog
v-model="colorPickerActive"
position="right"
no-backdrop-dismiss="false"
>
<q-card>
<q-card-section>
<div class="text-h6">{{ t('wagon.type.trayColor') }}</div>
</q-card-section>
<q-card-section class="row items-center no-wrap">
<q-color
flat
v-model="wagon[currentTrayColorPicked].color.rgb"
no-header
no-footer
default-view="palette"
:palette="
wagonTypeColors.map((color) => {
return color.rgb;
})
"
@change="updateColor($event)"
/>
<q-btn flat round icon="close" v-close-popup />
</q-card-section>
</q-card>
</q-dialog>
</q-form>
</q-card>
</q-page>
@ -187,10 +356,62 @@ async function onReset() {
align-items: flex-start;
}
.q-card {
width: 50%;
width: 70%;
}
.q-dialog {
.q-card {
width: 100%;
}
}
.wheels {
margin-left: 5%;
display: flex;
justify-content: space-around;
}
.wagon-tray {
display: flex;
height: 6rem;
.position {
width: 15%;
border-right: 1rem solid gray;
display: flex;
align-items: flex-end;
justify-content: flex-end;
padding-right: 1rem;
}
.shelving {
display: flex;
width: 75%;
.shelving-half {
width: 50%;
height: 100%;
.shelving-up {
height: 80%;
width: 100%;
}
.shelving-down {
height: 20%;
width: 100%;
}
}
.shelving-divisible {
width: 1%;
height: 100%;
border-left: 0.5rem dashed grey;
border-right: 0.5rem dashed grey;
}
}
.action-button {
width: 10%;
border-left: 1rem solid gray;
display: flex;
align-items: flex-end;
justify-content: flex-start;
padding-left: 1rem;
}
.isVisible {
display: none;
}
}
</style>

View File

@ -1,223 +0,0 @@
<!-- <script setup>
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import { useQuasar } from 'quasar';
import { useStateStore } from 'stores/useStateStore';
import Paginate from 'src/components/PaginateData.vue';
import WorkerSummaryDialog from 'src/pages/Worker/Card/WorkerSummaryDialog.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
import WorkerFilter from 'src/pages/Worker/WorkerFilter.vue';
const stateStore = useStateStore();
const router = useRouter();
const { t } = useI18n();
const quasar = useQuasar();
function navigate(id) {
router.push({ path: `/worker/${id}` });
}
function viewSummary(id) {
quasar.dialog({
component: WorkerSummaryDialog,
componentProps: {
id,
},
});
}
</script> -->
<script setup>
import axios from 'axios';
import FetchData from 'components/FetchData.vue';
import { useQuasar } from 'quasar';
import { computed, onMounted, onUpdated, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import WagonTray from './WagonTray.vue';
const { t } = useI18n();
const quasar = useQuasar();
const route = useRoute();
const router = useRouter();
const wagonConfig = ref([]);
const wagonTypeColors = ref([]);
const wagon = ref([]);
const divisible = ref(false);
const name = ref('');
let currentPosition = 0;
const originalData = ref({});
onMounted(() => fetch());
onUpdated(() => fetch());
const $props = defineProps({
id: {
type: Number,
required: false,
default: null,
},
});
const entityId = computed(() => $props.id || route.params.id);
async function fetch() {
await axios.get(`WagonTypes/${entityId.value}`).then(async (type) => {
if (type) {
originalData.value.name = name.value = type.name;
await axios.get(`WagonTypeTrays`, {
params: { filter: { typeFk: entityId.value } },
});
}
});
}
function addTray() {
if (wagon.value.length < wagonConfig.value.maxTrays - 1) {
currentPosition += wagonConfig.value.trayStep;
wagon.value.unshift({
position: currentPosition,
color: {
id: 1,
rgb: 'blue',
},
});
} else {
quasar.notify({
message: t('wagon.type.maxTrays'),
type: 'warning',
});
}
}
function deleteTray(position) {
currentPosition = 0;
wagon.value = wagon.value.filter((tray) => tray.position !== position);
for (let i = wagon.value.length - 1; i >= 0; i--) {
currentPosition += wagonConfig.value.trayStep;
wagon.value[i].position = currentPosition;
}
}
async function onSubmit() {
try {
await axios
.post('WagonTypes', {
name: name.value,
})
.then(async (res) => {
const trays = [];
wagon.value.forEach((tray) => {
trays.push({
typeFk: res.data.id,
height: tray.position,
colorFk: tray.color.id,
});
});
await axios.post('WagonTypeTrays', trays).then(() => {
router.push({ path: `/wagon/type/list` });
quasar.notify({
message: t('wagon.type.saveMessage'),
type: 'positive',
});
});
});
} catch (error) {
//
}
}
async function onReset() {
name.value = originalData.value.name;
divisible.value = false;
wagon.value = [];
currentPosition = 0;
}
</script>
<template>
<fetch-data
url="WagonConfigs"
@on-fetch="(data) => (wagonConfig = data[0])"
auto-load
/>
<fetch-data
url="WagonTypeColors"
@on-fetch="(data) => (wagonTypeColors = data)"
auto-load
/>
<q-page class="q-pa-sm q-mx-xl">
<q-card class="q-pa-sm">
<q-form @submit="onSubmit" @reset="onReset" class="q-pa-md">
<q-input
filled
v-model="name"
:label="t('wagon.type.name')"
:rules="[(val) => !!val || t('wagon.type.nameNotEmpty')]"
/>
<q-checkbox class="q-mb-sm" v-model="divisible" label="Divisible" />
<div v-for="tray in wagon" :key="tray.position">
<WagonTray
action="delete"
@delete-tray="deleteTray"
:position="tray.position"
:color="{ rgb: 'blue' }"
:divisible="divisible"
></WagonTray>
</div>
<WagonTray
v-if="wagonTypeColors.values"
action="add"
@add-tray="addTray"
:color="{ rgb: 'blue' }"
:divisible="divisible"
></WagonTray>
<div class="q-mb-sm wheels">
<q-icon color="grey-6" name="trip_origin" size="3rem" />
<q-icon color="grey-6" name="trip_origin" size="3rem" />
</div>
<div>
<q-btn
:label="t('wagon.type.submit')"
type="submit"
color="primary"
/>
<q-btn
:label="t('wagon.type.reset')"
type="reset"
color="primary"
flat
class="q-ml-sm"
/>
<!-- <q-color
flat
v-model="hex"
no-header
no-footer
default-view="palette"
:palette="
wagonTypeColors.map((color) => {
return color.rgb;
})
"
/> -->
</div>
</q-form>
</q-card>
</q-page>
</template>
<style lang="scss" scoped>
.q-page {
display: flex;
justify-content: center;
align-items: flex-start;
}
.q-card {
width: 50%;
}
.wheels {
display: flex;
justify-content: space-around;
}
</style>

View File

@ -1,16 +1,10 @@
<script setup>
import axios from 'axios';
import Paginate from 'src/components/PaginateData.vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import { useQuasar } from 'quasar';
import { useStateStore } from 'stores/useStateStore';
import Paginate from 'src/components/PaginateData.vue';
// import CustomerSummaryDialog from './Card/CustomerSummaryDialog.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
// import CustomerFilter from './CustomerFilter.vue';
const stateStore = useStateStore();
const router = useRouter();
const quasar = useQuasar();
const { t } = useI18n();
function navigate(id) {
@ -20,36 +14,30 @@ function navigate(id) {
function create() {
router.push({ path: `/wagon/type/create` });
}
async function remove(id) {
try {
await axios
.delete(`WagonTypes/deleteWagonType`, { params: { id } })
.then(async () => {
// TODO: RELOAD PAGE
// router.push({ path: `/wagon/type/list` });
});
} catch (error) {
//
}
}
</script>
<template>
<template v-if="stateStore.isHeaderMounted()">
<Teleport to="#searchbar">
<VnSearchbar
data-key="CustomerList"
:label="t('Search wagon type')"
:info="t('You can search by wagon type id or name')"
/>
</Teleport>
<Teleport to="#actions-append">
<div class="row q-gutter-x-sm">
<q-btn
flat
@click="stateStore.toggleRightDrawer()"
round
dense
icon="menu"
>
<q-tooltip bottom anchor="bottom right">
{{ t('globals.collapseMenu') }}
</q-tooltip>
</q-btn>
</div>
</Teleport>
</template>
<q-page class="column items-center q-pa-md">
<div class="card-list">
<paginate data-key="CustomerList" url="/WagonTypes" order="id DESC" auto-load>
<paginate
data-key="WagonTypeList"
url="/WagonTypes"
order="id DESC"
auto-load
>
<template #body="{ rows }">
<q-card class="card q-mb-md" v-for="row of rows" :key="row.id">
<q-item
@ -74,6 +62,17 @@ function create() {
{{ t('components.smartCard.openCard') }}
</q-tooltip>
</q-btn>
<q-btn
flat
round
color="primary"
icon="delete"
@click="remove(row.id)"
>
<q-tooltip>
{{ t('wagon.list.remove') }}
</q-tooltip>
</q-btn>
</q-card-actions>
</q-item>
</q-card>
@ -92,9 +91,3 @@ function create() {
max-width: 60em;
}
</style>
<i18n>
es:
Search wagon type: Buscar tipo de vagón
You can search by wagon type id or name: Puedes buscar por id o nombre del tipo de vagón
</i18n>

View File

@ -0,0 +1,181 @@
<script setup>
import axios from 'axios';
import { computed, onMounted, onUpdated, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
onMounted(() => fetch());
onUpdated(() => fetch());
const { t } = useI18n();
const route = useRoute();
const router = useRouter();
const $props = defineProps({
id: {
type: Number,
required: false,
default: null,
},
});
const entityId = computed(() => $props.id || route.params.id);
let wagonTypes;
let originalData = {};
const wagon = ref({});
const filteredWagonTypes = ref(wagonTypes);
async function onSubmit() {
try {
const params = {
id: entityId.value,
label: wagon.value.label,
plate: wagon.value.plate,
volume: wagon.value.volume,
typeFk: wagon.value.typeFk,
};
await axios.patch('Wagons', params).then((res) => {
if (res.status == 200) router.push({ path: `/wagon/list` });
});
} catch (error) {
//
}
}
async function onReset() {
if (entityId.value) {
wagon.value = { ...originalData };
} else {
wagon.value = {};
}
}
async function fetch() {
await axios.get(`WagonTypes`).then(async (res) => {
if (res.data) {
filteredWagonTypes.value = wagonTypes = res.data;
}
});
if (entityId.value) {
await axios.get(`Wagons/${entityId.value}`).then(async (res) => {
const data = res.data;
if (data) {
wagon.value.label = data.label;
wagon.value.plate = data.plate;
wagon.value.volume = data.volume;
wagon.value.typeFk = data.typeFk;
originalData = { ...wagon.value };
}
});
}
}
function filterType(val, update) {
update(() => {
const needle = val.toLowerCase();
filteredWagonTypes.value = wagonTypes.filter(
(v) => v.name.toLowerCase().indexOf(needle) > -1
);
});
}
</script>
<template>
<q-page class="q-pa-sm q-mx-xl">
<q-card class="q-pa-sm">
<q-form @submit="onSubmit()" @reset="onReset()" class="q-pa-md">
<div class="row q-col-gutter-md q-mb-md">
<div class="col">
<q-input
filled
v-model="wagon.label"
:label="t('wagon.create.label')"
type="number"
min="0"
:rules="[(val) => !!val || t('wagon.warnings.labelNotEmpty')]"
/>
</div>
<div class="col">
<q-input
filled
v-model="wagon.plate"
:label="t('wagon.create.plate')"
:rules="[(val) => !!val || t('wagon.warnings.plateNotEmpty')]"
/>
</div>
</div>
<div class="row q-col-gutter-md q-mb-md">
<div class="col">
<q-input
filled
v-model="wagon.volume"
:label="t('wagon.create.volume')"
type="number"
min="0"
:rules="[
(val) => !!val || t('wagon.warnings.volumeNotEmpty'),
]"
/>
</div>
<div class="col">
<q-select
filled
v-model="wagon.typeFk"
use-input
fill-input
hide-selected
input-debounce="0"
option-label="name"
option-value="id"
emit-value
map-options
:label="t('wagon.create.type')"
:options="filteredWagonTypes"
:rules="[(val) => !!val || t('wagon.warnings.typeNotEmpty')]"
@filter="filterType"
>
<template v-if="wagon.typeFk" #append>
<q-icon
name="cancel"
@click.stop.prevent="wagon.typeFk = null"
class="cursor-pointer"
/>
</template>
<template #no-option>
<q-item>
<q-item-section class="text-grey">
{{ t('components.smartCard.noData') }}
</q-item-section>
</q-item>
</template>
</q-select>
</div>
</div>
<div>
<q-btn
:label="t('wagon.type.submit')"
type="submit"
color="primary"
/>
<q-btn
:label="t('wagon.type.reset')"
type="reset"
color="primary"
flat
class="q-ml-sm"
/>
</div>
</q-form>
</q-card>
</q-page>
</template>
<style lang="scss" scoped>
.q-page {
display: flex;
justify-content: center;
align-items: flex-start;
}
.q-card {
width: 70%;
}
</style>

View File

@ -5,26 +5,61 @@ export default {
name: 'Wagon',
meta: {
title: 'wagons',
icon: 'contact_support',
icon: 'vn:trolley',
},
component: RouterView,
redirect: { name: 'WagonMain' },
menus: {
main: ['WagonTypeList'],
main: ['WagonList', 'WagonTypeList'],
card: [],
},
children: [
{
path: '/wagon/type',
path: '/wagon',
name: 'WagonMain',
component: () => import('src/pages/Wagon/WagonMain.vue'),
redirect: { name: 'WagonList' },
children: [
{
path: 'list',
name: 'WagonList',
meta: {
title: 'wagonsList',
icon: 'vn:trolley',
},
component: () => import('src/pages/Wagon/WagonList.vue')
},
{
path: 'create',
name: 'WagonCreate',
meta: {
title: 'wagonCreate',
icon: 'create',
},
component: () => import('src/pages/Wagon/WagonCreate.vue')
},
{
path: ':id/edit',
name: 'WagonEdit',
meta: {
title: 'wagonEdit',
icon: 'edit',
},
component: () => import('src/pages/Wagon/WagonCreate.vue')
},
],
},
{
path: '/wagon/type',
name: 'WagonTypeMain',
component: () => import('src/pages/Wagon/WagonMain.vue'),
redirect: { name: 'WagonTypeList' },
children: [
{
path: 'list',
name: 'WagonTypeList',
meta: {
title: 'types',
title: 'typesList',
icon: 'view_list',
},
component: () => import('src/pages/Wagon/Type/WagonTypeList.vue')