Import lines & responsive layout
gitea/salix-front/pipeline/head This commit looks good
Details
gitea/salix-front/pipeline/head This commit looks good
Details
This commit is contained in:
parent
fd4b2bf926
commit
e1cfe14121
|
@ -66,7 +66,7 @@ async function confirm() {
|
|||
<q-btn icon="close" :disable="isLoading" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
<q-card-section class="row items-center">
|
||||
{{ message }}
|
||||
<span v-html="message"></span>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn
|
||||
|
|
|
@ -107,10 +107,6 @@ const columns = computed(() => [
|
|||
format: (value) => toCurrency(value),
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
label: t('Actions'),
|
||||
},
|
||||
]);
|
||||
|
||||
const selected = ref([]);
|
||||
|
@ -145,22 +141,40 @@ function onUpdateDiscount(response) {
|
|||
});
|
||||
}
|
||||
|
||||
async function confirmRemove(id, index) {
|
||||
async function confirmRemove() {
|
||||
const rows = selected.value;
|
||||
const count = rows.length;
|
||||
|
||||
if (count === 0) {
|
||||
return quasar.notify({
|
||||
message: 'You must select at least one row',
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
|
||||
quasar
|
||||
.dialog({
|
||||
component: VnConfirm,
|
||||
componentProps: {
|
||||
title: t('Delete claimed sale'),
|
||||
data: { id },
|
||||
title: t('Delete claimed sales'),
|
||||
message: t('You are about to remove {count} rows', count, { count }),
|
||||
data: { rows },
|
||||
promise: remove,
|
||||
},
|
||||
})
|
||||
.onOk(() => store.data.splice(index, 1));
|
||||
.onOk(() => {
|
||||
for (const row of rows) {
|
||||
const orgData = store.data;
|
||||
const index = orgData.findIndex((item) => item.id === row.id);
|
||||
store.data.splice(index, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function remove({ id }) {
|
||||
if (!id) return;
|
||||
await axios.delete(`ClaimBeginnings/${id}`);
|
||||
async function remove({ rows }) {
|
||||
if (!rows.length) return;
|
||||
const body = { deletes: rows.map((row) => row.id) };
|
||||
await axios.post(`ClaimBeginnings/crud`, body);
|
||||
quasar.notify({
|
||||
type: 'positive',
|
||||
message: t('globals.rowRemoved'),
|
||||
|
@ -172,23 +186,29 @@ function showImportDialog() {
|
|||
.dialog({
|
||||
component: ClaimLinesImport,
|
||||
})
|
||||
.onOk(() => {});
|
||||
.onOk(() => arrayData.refresh());
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<q-page-sticky position="top" :offset="[0, 0]" expand>
|
||||
<q-toolbar class="bg-dark text-white">
|
||||
<q-toolbar-title class="row q-gutter-md">
|
||||
<q-toolbar-title> Lines </q-toolbar-title>
|
||||
<q-space />
|
||||
<div class="row q-gutter-md">
|
||||
<div>
|
||||
{{ t('Amount') }}
|
||||
<q-chip>{{ toCurrency(amount) }}</q-chip>
|
||||
<q-chip :dense="$q.screen.lt.sm">
|
||||
{{ toCurrency(amount) }}
|
||||
</q-chip>
|
||||
</div>
|
||||
<q-separator dark vertical />
|
||||
<div>
|
||||
{{ t('Amount Claimed') }}
|
||||
<q-chip color="positive">{{ toCurrency(amountClaimed) }}</q-chip>
|
||||
<q-chip color="positive" :dense="$q.screen.lt.sm">
|
||||
{{ toCurrency(amountClaimed) }}
|
||||
</q-chip>
|
||||
</div>
|
||||
</q-toolbar-title>
|
||||
</div>
|
||||
</q-toolbar>
|
||||
</q-page-sticky>
|
||||
|
||||
|
@ -217,6 +237,7 @@ function showImportDialog() {
|
|||
selection="multiple"
|
||||
v-model:selected="selected"
|
||||
hide-pagination
|
||||
:grid="$q.screen.lt.md"
|
||||
>
|
||||
<template #body-cell-claimed="{ row, value }">
|
||||
<q-td auto-width align="right" class="dimmed">
|
||||
|
@ -273,20 +294,6 @@ function showImportDialog() {
|
|||
/>
|
||||
</q-td>
|
||||
</template>
|
||||
<template #body-cell-actions="{ row, rowIndex }">
|
||||
<q-td auto-width class="text-center">
|
||||
<q-btn
|
||||
icon="vn:deleteline"
|
||||
color="primary"
|
||||
flat
|
||||
round
|
||||
dense
|
||||
@click="confirmRemove(row.id, rowIndex)"
|
||||
>
|
||||
<q-tooltip>Delete claimed sale</q-tooltip>
|
||||
</q-btn>
|
||||
</q-td>
|
||||
</template>
|
||||
</q-table>
|
||||
</template>
|
||||
</VnPaginate>
|
||||
|
@ -294,26 +301,46 @@ function showImportDialog() {
|
|||
</div>
|
||||
|
||||
<Teleport
|
||||
v-if="stateStore.isHeaderMounted() && !quasar.platform.is.mobile"
|
||||
v-if="stateStore.isHeaderMounted() && $q.screen.gt.sm"
|
||||
to="#actions-prepend"
|
||||
>
|
||||
<div class="row q-gutter-x-sm">
|
||||
<q-btn @click="showImportDialog" icon="add" color="primary" dense rounded>
|
||||
<q-btn
|
||||
v-if="selected.length > 0"
|
||||
@click="confirmRemove"
|
||||
icon="delete"
|
||||
color="primary"
|
||||
flat
|
||||
dense
|
||||
rounded
|
||||
>
|
||||
<q-tooltip bottom> {{ t('globals.remove') }} </q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
@click="showImportDialog"
|
||||
icon="add"
|
||||
color="primary"
|
||||
flat
|
||||
dense
|
||||
rounded
|
||||
>
|
||||
<q-tooltip bottom> {{ t('globals.add') }} </q-tooltip>
|
||||
</q-btn>
|
||||
<q-separator vertical />
|
||||
</div>
|
||||
</Teleport>
|
||||
|
||||
<q-page-sticky
|
||||
v-if="quasar.platform.is.mobile"
|
||||
position="bottom"
|
||||
:offset="[0, 0]"
|
||||
expand
|
||||
>
|
||||
<!-- v-if="quasar.platform.is.mobile" -->
|
||||
<q-page-sticky v-if="$q.screen.lt.sm" position="bottom" :offset="[0, 0]" expand>
|
||||
<q-toolbar class="bg-primary text-white q-pa-none">
|
||||
<q-tabs class="full-width" align="justify" inline-label narrow-indicator>
|
||||
<q-tab @click="addRow()" icon="add_circle" :label="t('globals.add')" />
|
||||
<q-tab @click="showImportDialog" icon="add" :label="t('globals.add')" />
|
||||
<q-separator vertical inset />
|
||||
<q-tab
|
||||
@click="confirmRemove"
|
||||
icon="delete"
|
||||
:label="t('globals.remove')"
|
||||
:disable="selected.length === 0"
|
||||
/>
|
||||
</q-tabs>
|
||||
</q-toolbar>
|
||||
</q-page-sticky>
|
||||
|
@ -322,11 +349,16 @@ function showImportDialog() {
|
|||
<style lang="scss" scoped>
|
||||
.list {
|
||||
padding-top: 50px;
|
||||
max-width: 900px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
en:
|
||||
You are about to remove {count} rows: '
|
||||
You are about to remove <strong>{count}</strong> row |
|
||||
You are about to remove <strong>{count}</strong> rows'
|
||||
es:
|
||||
Delivered: Entregado
|
||||
Quantity: Cantidad
|
||||
|
@ -337,7 +369,11 @@ es:
|
|||
Actions: Acciones
|
||||
Amount: Total
|
||||
Amount Claimed: Cantidad reclamada
|
||||
Delete claimed sale: Eliminar venta reclamada
|
||||
Delete claimed sales: Eliminar ventas reclamadas
|
||||
Discount updated: Descuento actualizado
|
||||
Claimed quantity: Cantidad reclamada
|
||||
row: 'línea | líneas'
|
||||
You are about to remove {count} rows: '
|
||||
Vas a eliminar <strong>{count}</strong> línea |
|
||||
Vas a eliminar <strong>{count}</strong> líneas'
|
||||
</i18n>
|
||||
|
|
|
@ -1,80 +1,139 @@
|
|||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useDialogPluginComponent } from 'quasar';
|
||||
import { useQuasar, useDialogPluginComponent } from 'quasar';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
||||
import { toDate } from 'filters';
|
||||
import { useRoute } from 'vue-router';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import { toDate, toCurrency, toPercentage } from 'filters';
|
||||
import axios from 'axios';
|
||||
|
||||
defineEmits([...useDialogPluginComponent.emits]);
|
||||
|
||||
const { dialogRef, onDialogOK } = useDialogPluginComponent();
|
||||
const { dialogRef, onDialogOK, onDialogCancel } = useDialogPluginComponent();
|
||||
const route = useRoute();
|
||||
const quasar = useQuasar();
|
||||
const { t } = useI18n();
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
name: 'delivered',
|
||||
label: 'Delivered',
|
||||
label: t('Delivered'),
|
||||
field: (row) => row.landed,
|
||||
format: (value) => toDate(value),
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'quantity',
|
||||
label: 'Quantity',
|
||||
label: t('Quantity'),
|
||||
field: (row) => row.quantity,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: 'Description',
|
||||
label: t('Description'),
|
||||
field: (row) => row.concept,
|
||||
},
|
||||
{
|
||||
name: 'price',
|
||||
label: 'Price',
|
||||
label: t('Price'),
|
||||
field: (row) => row.price,
|
||||
format: (value) => toCurrency(value),
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'discount',
|
||||
label: 'Discount',
|
||||
label: t('Discount'),
|
||||
field: (row) => row.discount,
|
||||
format: (value) => toPercentage(value),
|
||||
sortable: true,
|
||||
},
|
||||
]);
|
||||
|
||||
const selected = ref([]);
|
||||
const scrollable = ref();
|
||||
const claimableSales = ref([]);
|
||||
const isLoading = ref(false);
|
||||
let canceller;
|
||||
|
||||
async function importLines() {
|
||||
const sales = selected.value;
|
||||
|
||||
if (!sales.length) {
|
||||
return quasar.notify({
|
||||
message: 'You must select at least one',
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
|
||||
const body = sales.map((row) => ({
|
||||
claimFk: route.params.id,
|
||||
saleFk: row.saleFk,
|
||||
quantity: row.quantity,
|
||||
}));
|
||||
|
||||
canceller = new AbortController();
|
||||
isLoading.value = true;
|
||||
|
||||
const { data } = await axios.post('ClaimBeginnings', body, {
|
||||
signal: canceller.signal,
|
||||
});
|
||||
|
||||
quasar.notify({
|
||||
message: 'Lines added to claim',
|
||||
type: 'positive',
|
||||
});
|
||||
|
||||
onDialogOK(data);
|
||||
|
||||
canceller = null;
|
||||
isLoading.value = false;
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
if (canceller) {
|
||||
canceller.abort();
|
||||
canceller = null;
|
||||
}
|
||||
|
||||
onDialogCancel();
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<fetch-data
|
||||
url="Sales/getClaimableFromTicket?ticketFk=16"
|
||||
@on-fetch="(data) => (claimableSales = data)"
|
||||
auto-load
|
||||
/>
|
||||
<q-dialog ref="dialogRef" persistent>
|
||||
<q-card>
|
||||
<q-card-section class="row items-center">
|
||||
<span class="text-h6 text-grey">{{ t('Available Sales') }}</span>
|
||||
<span class="text-h6 text-grey">{{ t('Available sales lines') }}</span>
|
||||
<q-space />
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
<q-table
|
||||
class="my-sticky-header-table"
|
||||
:columns="columns"
|
||||
:rows="claimableSales"
|
||||
:pagination="{ rowsPerPage: 10 }"
|
||||
row-key="saleFk"
|
||||
selection="multiple"
|
||||
v-model:selected="selected"
|
||||
square
|
||||
flat
|
||||
></q-table>
|
||||
<q-separator />
|
||||
<VnPaginate data-key="ClaimableSales" url="Sales" :offset="50" auto-load>
|
||||
<template #body="{ rows }">
|
||||
<q-table
|
||||
ref="scrollable"
|
||||
class="my-sticky-header-table"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:pagination="{ rowsPerPage: 0 }"
|
||||
row-key="saleFk"
|
||||
selection="multiple"
|
||||
v-model:selected="selected"
|
||||
hide-pagination
|
||||
square
|
||||
flat
|
||||
></q-table>
|
||||
</template>
|
||||
</VnPaginate>
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn :label="t('globals.cancel')" color="primary" flat v-close-popup />
|
||||
<q-btn
|
||||
:label="t('globals.cancel')"
|
||||
color="primary"
|
||||
flat
|
||||
@click="cancel"
|
||||
/>
|
||||
<q-btn
|
||||
:label="t('globals.confirm')"
|
||||
color="primary"
|
||||
:loading="isLoading"
|
||||
@click="confirm"
|
||||
@click="importLines"
|
||||
unelevated
|
||||
/>
|
||||
</q-card-actions>
|
||||
|
@ -91,17 +150,12 @@ const scrollable = ref();
|
|||
<style lang="scss">
|
||||
.my-sticky-header-table {
|
||||
height: 400px;
|
||||
.q-table__top,
|
||||
.q-table__bottom,
|
||||
thead tr:first-child th {
|
||||
/* bg color is important for th; just specify one */
|
||||
background-color: $primary;
|
||||
}
|
||||
|
||||
thead tr th {
|
||||
position: sticky;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
thead tr:first-child th {
|
||||
/* this is when the loading indicator appears */
|
||||
top: 0;
|
||||
|
@ -119,3 +173,15 @@ const scrollable = ref();
|
|||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Available sales lines: Líneas de venta disponibles
|
||||
Delivered: Entrega
|
||||
Quantity: Cantidad
|
||||
Description: Descripción
|
||||
Price: Precio
|
||||
Discount: Descuento
|
||||
Lines added to claim: Lineas añadidas a la reclamación
|
||||
You must select at least one: Debes seleccionar al menos una
|
||||
</i18n>
|
||||
|
|
Loading…
Reference in New Issue