Claim RMA section
gitea/salix-front/pipeline/head There was a failure building this commit Details

This commit is contained in:
Joan Sanchez 2022-10-25 14:23:59 +02:00
parent 2363ab4670
commit 125d86cb25
8 changed files with 206 additions and 83 deletions

View File

@ -67,7 +67,7 @@ function responseError(error) {
axios.interceptors.response.use((response) => { axios.interceptors.response.use((response) => {
const { method } = response.config; const { method } = response.config;
const isSaveRequest = method === 'post' || method === 'patch'; const isSaveRequest = method === 'patch';
if (isSaveRequest) { if (isSaveRequest) {
quasar.notify({ quasar.notify({
message: t('globals.dataSaved'), message: t('globals.dataSaved'),

View File

@ -43,10 +43,11 @@ const pagination = ref({
page: 1, page: 1,
}); });
const rows = ref([]); const rows = ref(null);
onMounted(() => { onMounted(() => {
if ($props.autoLoad) fetch(); if ($props.autoLoad) fetch();
else rows.value = [];
}); });
async function fetch() { async function fetch() {
@ -74,6 +75,7 @@ async function fetch() {
hasMoreData.value = data.length === rowsPerPage; hasMoreData.value = data.length === rowsPerPage;
if (!rows.value) rows.value = [];
for (const row of data) rows.value.push(row); for (const row of data) rows.value.push(row);
pagination.value.rowsNumber = rows.value.length; pagination.value.rowsNumber = rows.value.length;
@ -87,7 +89,7 @@ async function fetch() {
async function onLoad(...params) { async function onLoad(...params) {
const done = params[1]; const done = params[1];
if (rows.value.length === 0) return done(false); if (!rows.value || rows.value.length === 0) return done(false);
pagination.value.page = pagination.value.page + 1; pagination.value.page = pagination.value.page + 1;
@ -100,7 +102,7 @@ async function onLoad(...params) {
<template> <template>
<q-infinite-scroll @load="onLoad" :offset="offset" class="column items-center"> <q-infinite-scroll @load="onLoad" :offset="offset" class="column items-center">
<div class="card-list q-gutter-y-md"> <div v-if="rows" class="card-list q-gutter-y-md">
<q-card class="card" v-for="row of rows" :key="row.id"> <q-card class="card" v-for="row of rows" :key="row.id">
<q-item v-ripple class="q-pa-none items-start cursor-pointer q-hoverable"> <q-item v-ripple class="q-pa-none items-start cursor-pointer q-hoverable">
<q-item-section class="q-pa-md" @click="$emit('onNavigate', row.id)"> <q-item-section class="q-pa-md" @click="$emit('onNavigate', row.id)">
@ -138,6 +140,25 @@ async function onLoad(...params) {
<q-spinner color="orange" size="md" /> <q-spinner color="orange" size="md" />
</div> </div>
</div> </div>
<div v-if="!rows" class="card-list q-gutter-y-md">
<q-card class="card" v-for="$index in $props.rowsPerPage" :key="$index">
<q-item v-ripple class="q-pa-none items-start cursor-pointer q-hoverable">
<q-item-section class="q-pa-md">
<q-skeleton type="rect" class="q-mb-md" square />
<q-skeleton type="text" square />
<q-skeleton type="text" class="q-mb-md" square />
<q-skeleton type="text" square />
<q-skeleton type="text" square />
</q-item-section>
<q-separator vertical />
<q-card-actions vertical class="justify-between">
<q-skeleton type="QBtn" class="q-mb-md" size="40px" />
<q-skeleton type="QBtn" class="q-mb-md" size="40px" />
<q-skeleton type="QBtn" class="q-mb-md" size="40px" />
</q-card-actions>
</q-item>
</q-card>
</div>
</q-infinite-scroll> </q-infinite-scroll>
</template> </template>

View File

@ -63,7 +63,6 @@ async function saveDarkMode(value) {
} }
async function saveLanguage(value) { async function saveLanguage(value) {
console.log(value);
const query = `/Accounts/${user.value.id}`; const query = `/Accounts/${user.value.id}`;
await axios.patch(query, { await axios.patch(query, {
lang: value, lang: value,

View File

@ -1,10 +1,12 @@
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
export default function (value) { export default function (value, options = {}) {
if (!value) return; if (!value) return;
if (!options.dateStyle) options.dateStyle = 'short';
const { locale } = useI18n(); const { locale } = useI18n();
const date = new Date(value); const date = new Date(value);
return new Intl.DateTimeFormat(locale.value).format(date) return new Intl.DateTimeFormat(locale.value, options).format(date)
} }

View File

@ -12,9 +12,18 @@ export default {
theme: 'Theme', theme: 'Theme',
logOut: 'Log out', logOut: 'Log out',
dataSaved: 'Data saved', dataSaved: 'Data saved',
add: 'Add',
create: 'Create',
save: 'Save', save: 'Save',
remove: 'Remove',
reset: 'Reset', reset: 'Reset',
noChanges: 'No changes to save' cancel: 'Cancel',
yes: 'Yes',
no: 'No',
noChanges: 'No changes to save',
confirmRemove: 'You are about to delete this row. Are you sure?',
rowAdded: 'Row added',
rowRemoved: 'Row removed'
}, },
moduleIndex: { moduleIndex: {
allModules: 'All modules' allModules: 'All modules'
@ -177,6 +186,14 @@ export default {
created: 'Created', created: 'Created',
state: 'State' state: 'State'
}, },
rmaList: {
code: 'Code',
newRma: 'New RMA...'
},
rma: {
user: 'User',
created: 'Created'
},
card: { card: {
claimId: 'Claim ID', claimId: 'Claim ID',
assignedTo: 'Assigned', assignedTo: 'Assigned',

View File

@ -12,9 +12,18 @@ export default {
theme: 'Tema', theme: 'Tema',
logOut: 'Cerrar sesión', logOut: 'Cerrar sesión',
dataSaved: 'Datos guardados', dataSaved: 'Datos guardados',
add: 'Añadir',
create: 'Crear',
save: 'Guardar', save: 'Guardar',
remove: 'Eliminar',
reset: 'Restaurar', reset: 'Restaurar',
noChanges: 'Sin cambios que guardar' cancel: 'Cancelar',
yes: 'Si',
no: 'No',
noChanges: 'Sin cambios que guardar',
confirmRemove: 'Vas a eliminar este registro. ¿Continuar?',
rowAdded: 'Fila añadida',
rowRemoved: 'Fila eliminada'
}, },
moduleIndex: { moduleIndex: {
allModules: 'Todos los módulos' allModules: 'Todos los módulos'
@ -165,8 +174,10 @@ export default {
claims: 'Reclamaciones', claims: 'Reclamaciones',
list: 'Listado', list: 'Listado',
createClaim: 'Crear reclamación', createClaim: 'Crear reclamación',
rmaList: 'RMA',
summary: 'Resumen', summary: 'Resumen',
basicData: 'Datos básicos' basicData: 'Datos básicos',
rma: 'RMA'
}, },
list: { list: {
customer: 'Cliente', customer: 'Cliente',
@ -174,6 +185,14 @@ export default {
created: 'Creada', created: 'Creada',
state: 'Estado' state: 'Estado'
}, },
rmaList: {
code: 'Código',
newRma: 'Nuevo RMA...'
},
rma: {
user: 'Usuario',
created: 'Creado'
},
card: { card: {
claimId: 'ID reclamación', claimId: 'ID reclamación',
assignedTo: 'Asignada a', assignedTo: 'Asignada a',

View File

@ -1,9 +1,10 @@
<script setup> <script setup>
import { onMounted } from 'vue'; import { onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
// import { useQuasar } from 'quasar'; import { useQuasar } from 'quasar';
// import axios from 'axios'; import axios from 'axios';
import SmartCard from 'src/components/SmartCard.vue'; import SmartCard from 'src/components/SmartCard.vue';
import { toDate } from 'src/filters';
onMounted(() => fetch()); onMounted(() => fetch());
@ -14,7 +15,18 @@ const $props = defineProps({
}, },
}); });
const quasar = useQuasar();
const { t } = useI18n();
const filter = { const filter = {
include: {
relation: 'worker',
scope: {
include: {
relation: 'user',
},
},
},
where: { where: {
code: $props.claim.rma, code: $props.claim.rma,
}, },
@ -24,57 +36,101 @@ function fetch() {
//console.log($props.claim); //console.log($props.claim);
} }
// const route = useRoute(); function addRow() {
// const quasar = useQuasar(); const formData = {
const { t } = useI18n(); code: $props.claim.rma,
};
axios.post(`ClaimRmas`, formData).then(() => {
quasar.notify({
type: 'positive',
message: t('globals.rowAdded'),
icon: 'check',
});
});
}
const confirmShown = ref(false);
const rmaId = ref(null);
function confirmRemove(id) {
confirmShown.value = true;
rmaId.value = id;
}
function remove() {
const id = rmaId.value;
axios.delete(`ClaimRmas/${id}`).then(() => {
confirmShown.value = false;
quasar.notify({
type: 'positive',
message: t('globals.rowRemoved'),
icon: 'check',
});
});
}
function hide() {
rmaId.value = null;
}
</script> </script>
<template> <template>
<q-page class="q-pa-md column items-center" style="padding-top: 66px"> <q-page class="q-pa-md sticky">
<q-page-sticky expand position="top"> <q-page-sticky expand position="top">
<q-toolbar class="bg-primary z-top" style="text-align: right"> <q-toolbar class="bg-grey-9">
<q-btn icon="add" label="Add" color="dark" /> <q-space />
<div class="q-gutter-md">
<q-btn icon="add" :label="t('globals.add')" color="primary" @click="addRow()" />
</div>
</q-toolbar> </q-toolbar>
</q-page-sticky> </q-page-sticky>
<div class="card-list"> <smart-card ref="card" url="/ClaimRmas" :filter="filter" sort-by="id DESC" auto-load>
<!-- <q-card class="q-mb-md" style="position: sticky:top:0"> <template #header="{ row }">
<q-card-actions align="right"> <q-item-label caption>{{ t('claim.rma.user') }}</q-item-label>
<q-btn icon="add" label="Add" color="primary" /> <q-item-label>{{ row.worker.user.name }}</q-item-label>
</q-card-actions> </template>
</q-card> --> <template #labels="{ row }">
<q-list>
<smart-card ref="card" url="/ClaimRmas" :filter="filter" sort-by="id DESC" auto-load> <q-item class="q-pa-none">
<template #labels="{ row }"> <q-item-section>
<q-list> <q-item-label caption>{{ t('claim.rma.created') }}</q-item-label>
<q-item class="q-pa-none"> <q-item-label>{{ toDate(row.created, { timeStyle: 'medium' }) }}</q-item-label>
<q-item-section> </q-item-section>
<q-item-label caption>{{ t('claim.rma.code') }}</q-item-label> </q-item>
<q-item-label>{{ row.code }}</q-item-label> </q-list>
</q-item-section> </template>
</q-item> <template #actions="{ row }">
</q-list> <q-btn flat round color="orange" icon="vn:bin" @click="confirmRemove(row.id)">
<q-list> <q-tooltip>{{ t('globals.remove') }}</q-tooltip>
<q-item class="q-pa-none"> </q-btn>
<q-item-section> </template>
<q-item-label caption>{{ t('claim.rma.worker') }}</q-item-label> </smart-card>
<q-item-label>{{ row.workerFk }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</template>
<template #actions="{ row }">
<q-btn flat round color="orange" icon="vn:bin" @click="confirm(row.id)">
<q-tooltip>{{ t('claim.rma.remove') }}</q-tooltip>
</q-btn>
</template>
</smart-card>
</div>
</q-page> </q-page>
<q-dialog v-model="confirmShown" persistent @hide="hide">
<q-card>
<q-card-section class="row items-center">
<q-avatar icon="warning" color="primary" text-color="white" />
<span class="q-ml-sm">{{ t('globals.confirmRemove') }}</span>
</q-card-section>
<q-card-actions align="right">
<q-btn flat :label="t('globals.no')" color="primary" v-close-popup autofocus />
<q-btn flat :label="t('globals.yes')" color="primary" @click="remove()" />
</q-card-actions>
</q-card>
</q-dialog>
</template> </template>
<style lang="scss"> <style lang="scss" scoped>
.card-list { .q-toolbar {
width: 100%; background-color: $grey-9;
max-width: 60em; }
.sticky {
padding-top: 66px;
}
.q-page-sticky {
z-index: 2998;
} }
</style> </style>

View File

@ -55,52 +55,61 @@ function hide() {
</script> </script>
<template> <template>
<q-page class="q-pa-md column items-center"> <q-page class="q-pa-md sticky">
<div class="card-list"> <q-page-sticky expand position="top" :offset="[16, 16]">
<q-card class="q-pa-md q-mb-md"> <q-card class="card q-pa-md">
<q-form @submit="submit"> <q-form @submit="submit">
<q-input v-model="newRma.code" label="New RMA..."></q-input> <q-input v-model="newRma.code" :label="t('claim.rmaList.newRma')" class="q-mb-md" />
<div class="text-caption">$(0) entries</div>
</q-form> </q-form>
</q-card> </q-card>
</q-page-sticky>
<smart-card ref="card" url="/ClaimRmas" sort-by="id DESC" auto-load> <smart-card ref="card" url="/ClaimRmas" sort-by="id DESC" auto-load>
<template #labels="{ row }"> <template #labels="{ row }">
<q-list> <q-list>
<q-item class="q-pa-none"> <q-item class="q-pa-none">
<q-item-section> <q-item-section>
<q-item-label caption>{{ t('claim.rma.code') }}</q-item-label> <q-item-label caption>{{ t('claim.rmaList.code') }}</q-item-label>
<q-item-label>{{ row.code }}</q-item-label> <q-item-label>{{ row.code }}</q-item-label>
</q-item-section> </q-item-section>
</q-item> </q-item>
</q-list> </q-list>
</template> </template>
<template #actions="{ row }"> <template #actions="{ row }">
<q-btn flat round color="orange" icon="vn:bin" @click="confirm(row.id)"> <q-btn flat round color="primary" icon="vn:bin" @click="confirm(row.id)">
<q-tooltip>{{ t('claim.rma.remove') }}</q-tooltip> <q-tooltip>{{ t('globals.remove') }}</q-tooltip>
</q-btn> </q-btn>
</template> </template>
</smart-card> </smart-card>
</div>
</q-page> </q-page>
<q-dialog v-model="confirmShown" persistent @hide="hide"> <q-dialog v-model="confirmShown" persistent @hide="hide">
<q-card> <q-card>
<q-card-section class="row items-center"> <q-card-section class="row items-center">
<q-avatar icon="warning" color="primary" text-color="white" /> <q-avatar icon="warning" color="primary" text-color="white" />
<span class="q-ml-sm">You are about to delete this entry. Are you sure?</span> <span class="q-ml-sm">{{ t('globals.confirmRemove') }}</span>
</q-card-section> </q-card-section>
<q-card-actions align="right"> <q-card-actions align="right">
<q-btn flat label="Cancel" color="primary" v-close-popup /> <q-btn flat :label="t('globals.no')" color="primary" v-close-popup autofocus />
<q-btn flat label="Yes" color="primary" @click="remove()" autofocus /> <q-btn flat :label="t('globals.yes')" color="primary" @click="remove()" />
</q-card-actions> </q-card-actions>
</q-card> </q-card>
</q-dialog> </q-dialog>
</template> </template>
<style lang="scss"> <style lang="scss" scoped>
.card-list { .sticky {
padding-top: 156px;
}
.card {
width: 100%; width: 100%;
max-width: 60em; max-width: 60em;
} }
.q-page-sticky {
z-index: 2998;
}
</style> </style>