0
0
Fork 0

feat: #6321 Modals change qty and state

This commit is contained in:
Javier Segarra 2024-05-08 15:35:04 +02:00
parent 881e059121
commit 0eab0a9a98
6 changed files with 280 additions and 19 deletions

View File

@ -0,0 +1,98 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios';
import { useDialogPluginComponent } from 'quasar';
import VnInput from 'src/components/common/VnInput.vue';
const { t } = useI18n();
const showChangeQuantityDialog = ref(false);
const newQuantity = ref(null);
const { dialogRef, onDialogHide } = useDialogPluginComponent();
const $props = defineProps({
selectedRows: {
type: Array,
default: () => [],
},
});
const updateQuantity = async () => {
showChangeQuantityDialog.value = true;
const rowsToUpdate = $props.selectedRows.map(({ ticketFk }) =>
axios.post(`Tickets/state`, {
ticketFk,
quantity: newQuantity.value,
})
);
try {
await Promise.all(rowsToUpdate);
dialogRef.value.hide();
} catch (err) {
return err;
}
};
</script>
<template>
<QDialog ref="dialogRef" @hide="onDialogHide" v-model="showChangeQuantityDialog">
<QCard class="q-pa-sm">
<QCardSection class="row items-center q-pb-none">
<QAvatar
:icon="icon"
color="primary"
text-color="white"
size="xl"
v-if="icon"
/>
<span class="text-h6 text-grey">{{
t('negative.detail.modal.changeQuantity.title')
}}</span>
<QSpace />
<QBtn icon="close" flat round dense v-close-popup />
</QCardSection>
<QCardSection class="row items-center justify-center column items-stretch">
<span>{{ t('negative.detail.modal.changeQuantity.title') }}</span>
<VnInput
type="number"
:min="0"
:label="t('negative.detail.modal.changeQuantity.placeholder')"
v-model="newQuantity"
/>
</QCardSection>
<QCardActions align="right">
<QBtn :label="t('globals.cancel')" color="primary" flat v-close-popup />
<QBtn
:label="t('globals.confirm')"
color="primary"
:disable="!newQuantity || newQuantity < 0"
@click="updateQuantity()"
unelevated
autofocus
/> </QCardActions
></QCard>
</QDialog>
</template>
<style lang="scss" scoped>
.list {
max-height: 100%;
padding: 15px;
width: 100%;
}
.grid-style-transition {
transition: transform 0.28s, background-color 0.28s;
}
#true {
background-color: $positive;
}
#false {
background-color: $negative;
}
div.q-dialog__inner > div {
max-width: fit-content !important;
}
</style>

View File

@ -0,0 +1,106 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios';
import { useDialogPluginComponent } from 'quasar';
import VnSelect from 'src/components/common/VnSelect.vue';
import FetchData from 'components/FetchData.vue';
const editableStates = ref([]);
const { t } = useI18n();
const showChangeStateDialog = ref(false);
const newState = ref(null);
const { dialogRef, onDialogHide } = useDialogPluginComponent();
const $props = defineProps({
selectedRows: {
type: Array,
default: () => [],
},
});
const updateState = async () => {
showChangeStateDialog.value = true;
const rowsToUpdate = $props.selectedRows.map(({ ticketFk }) =>
axios.post(`Tickets/state`, {
ticketFk,
code: newState.value,
})
);
try {
await Promise.all(rowsToUpdate);
dialogRef.value.hide();
} catch (err) {
return err;
}
};
</script>
<template>
<QDialog ref="dialogRef" @hide="onDialogHide" v-model="showChangeStateDialog">
<FetchData
url="States/editableStates"
@on-fetch="(data) => (editableStates = data)"
auto-load
/>
<QCard class="q-pa-sm">
<QCardSection class="row items-center q-pb-none">
<QAvatar
:icon="icon"
color="primary"
text-color="white"
size="xl"
v-if="icon"
/>
<span class="text-h6 text-grey">{{
t('negative.detail.modal.changeState.title')
}}</span>
<QSpace />
<QBtn icon="close" flat round dense v-close-popup />
</QCardSection>
<QCardSection class="row items-center justify-center column items-stretch">
<span>{{ t('negative.detail.modal.changeState.title') }}</span>
<VnSelect
:label="t('negative.detail.modal.changeState.placeholder')"
v-model="newState"
:options="editableStates"
option-label="name"
option-value="id"
/>
</QCardSection>
<QCardActions align="right">
<QBtn :label="t('globals.cancel')" color="primary" flat v-close-popup />
<QBtn
:label="t('globals.confirm')"
color="primary"
:disable="!newState"
@click="updateState()"
unelevated
autofocus
/> </QCardActions
></QCard>
</QDialog>
</template>
<style lang="scss" scoped>
.list {
max-height: 100%;
padding: 15px;
width: 100%;
}
.grid-style-transition {
transition: transform 0.28s, background-color 0.28s;
}
#true {
background-color: $positive;
}
#false {
background-color: $negative;
}
div.q-dialog__inner > div {
max-width: fit-content !important;
}
</style>

View File

@ -6,7 +6,7 @@ import { useDialogPluginComponent } from 'quasar';
const { t } = useI18n(); const { t } = useI18n();
const showNegativeOriginDialog = ref(false); const showNegativeOriginDialog = ref(false);
const reasonegativeOriginDialog = ref(null); const reason = ref(null);
const { dialogRef, onDialogHide } = useDialogPluginComponent(); const { dialogRef, onDialogHide } = useDialogPluginComponent();
const $props = defineProps({ const $props = defineProps({
selectedRows: { selectedRows: {
@ -14,11 +14,11 @@ const $props = defineProps({
default: () => [], default: () => [],
}, },
}); });
const updateNegativeOrigin = async () => { const update = async () => {
showNegativeOriginDialog.value = true; showNegativeOriginDialog.value = true;
const negativeOrigins = $props.selectedRows.map(({ itemFk, lack }) => ({ const negativeOrigins = $props.selectedRows.map(({ itemFk, lack }) => ({
itemFk, itemFk,
negativeType: reasonegativeOriginDialog.value, negativeType: reason.value,
lack, lack,
})); }));
@ -52,7 +52,7 @@ const updateNegativeOrigin = async () => {
<span>{{ t('negative.modalOrigin.question') }}</span> <span>{{ t('negative.modalOrigin.question') }}</span>
<QSelect <QSelect
:label="t('globals.reason')" :label="t('globals.reason')"
v-model="reasonegativeOriginDialog" v-model="reason"
:options="['FALTAS', 'CONTENEDOR', 'ENTRADAS', 'OVERBOOKING']" :options="['FALTAS', 'CONTENEDOR', 'ENTRADAS', 'OVERBOOKING']"
/> />
</QCardSection> </QCardSection>
@ -61,8 +61,8 @@ const updateNegativeOrigin = async () => {
<QBtn <QBtn
:label="t('globals.confirm')" :label="t('globals.confirm')"
color="primary" color="primary"
:disable="!reasonegativeOriginDialog" :disable="!reason"
@click="updateNegativeOrigin()" @click="update()"
unelevated unelevated
autofocus autofocus
/> </QCardActions /> </QCardActions

View File

@ -106,6 +106,7 @@ const tableColumnComponents = computed(() => ({
event: () => ({}), event: () => ({}),
}, },
state: { state: {
style: 'width: 160px',
component: VnSelect, component: VnSelect,
type: 'select', type: 'select',
filterValue: null, filterValue: null,
@ -140,6 +141,7 @@ const tableColumnComponents = computed(() => ({
class: 'input-number', class: 'input-number',
}, },
event: getInputEvents, event: getInputEvents,
style: 'width: 100px',
}, },
alertLevelCode: { alertLevelCode: {
@ -205,6 +207,7 @@ const columns = computed(() => [
field: 'quantity', field: 'quantity',
align: 'left', align: 'left',
sortable: true, sortable: true,
style: 'width: 100px',
}, },
{ {
name: 'alertLevelCode', name: 'alertLevelCode',
@ -326,6 +329,7 @@ const handleRows = (rows) => {
props props
) )
" "
:style="tableColumnComponents[col.name].style"
> >
<template v-if="isComponentVn(col)">{{ <template v-if="isComponentVn(col)">{{
col.value col.value

View File

@ -5,6 +5,8 @@ import { useStateStore } from 'stores/useStateStore';
import VnPaginate from 'components/ui/VnPaginate.vue'; import VnPaginate from 'components/ui/VnPaginate.vue';
import TicketLackFilter from 'pages/Ticket/Negative/TicketLackFilter.vue'; import TicketLackFilter from 'pages/Ticket/Negative/TicketLackFilter.vue';
import TicketLackDetail from 'pages/Ticket/Negative/TicketLackDetail.vue'; import TicketLackDetail from 'pages/Ticket/Negative/TicketLackDetail.vue';
import ChangeQuantityDialog from 'pages/Ticket/Negative/ChangeQuantityDialog.vue';
import ChangeStateDialog from 'pages/Ticket/Negative/ChangeStateDialog.vue';
import ItemProposal from 'src/pages/Item/components/ItemProposal.vue'; import ItemProposal from 'src/pages/Item/components/ItemProposal.vue';
import NegativeOriginDialog from 'pages/Ticket/Negative/NegativeOriginDialog.vue'; import NegativeOriginDialog from 'pages/Ticket/Negative/NegativeOriginDialog.vue';
@ -15,9 +17,12 @@ import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
const stateStore = useStateStore(); const stateStore = useStateStore();
const { t } = useI18n(); const { t } = useI18n();
const selectedRows = ref([]); const selectedRows = ref([]);
const selectedRowsDetail = ref([]);
const showNegativeOriginDialog = ref(false); const showNegativeOriginDialog = ref(false);
const showTotalNegativeOriginDialog = ref(false); const showTotalNegativeOriginDialog = ref(false);
const showProposalDialog = ref(false); const showProposalDialog = ref(false);
const showChangeQuantityDialog = ref(false);
const showChangeStateDialog = ref(false);
const showFree = ref(true); const showFree = ref(true);
const currentRow = ref(null); const currentRow = ref(null);
@ -27,6 +32,8 @@ const viewSummary = (row) => {
const originDialogRef = ref(); const originDialogRef = ref();
const totalNegativeDialogRef = ref(); const totalNegativeDialogRef = ref();
const proposalDialogRef = ref(); const proposalDialogRef = ref();
const changeStateDialogRef = ref();
const changeQuantityDialogRef = ref();
const columns = computed(() => [ const columns = computed(() => [
{ {
name: 'minTimed', name: 'minTimed',
@ -46,7 +53,7 @@ const columns = computed(() => [
field: ({ longName }) => longName, field: ({ longName }) => longName,
align: 'center', align: 'center',
sortable: true, sortable: true,
headerStyle: 'padding-left: 35px', headerStyle: 'width: 350px',
}, },
{ {
name: 'producer', name: 'producer',
@ -141,18 +148,43 @@ const columns = computed(() => [
</QBtnGroup> </QBtnGroup>
</template> </template>
<template #st-data> <template #st-data>
<QBtnGroup v-if="currentRow" push style="column-gap: 1px"> <template v-if="currentRow">
<QBtn <QBtnGroup push style="column-gap: 1px">
color="primary" <QBtn
@click="showProposalDialog = true" color="primary"
icon="vn:splitline" :label="t('Change state')"
> :disable="selectedRowsDetail.length < 2"
<QTooltip bottom anchor="bottom right"> @click="showChangeStateDialog = true"
{{ t('Item proposal') }} >
</QTooltip> <QTooltip bottom anchor="bottom right">
</QBtn></QBtnGroup {{ t('Change state') }}
> </QTooltip>
<QCheckbox v-model="showFree" :label="t('negative.detail.showFree')" /> </QBtn>
<QBtn
color="primary"
:label="t('Change quantity')"
@click="showChangeQuantityDialog = true"
:disable="selectedRowsDetail.length < 2"
>
<QTooltip bottom anchor="bottom right">
{{ t('Change quantity') }}
</QTooltip>
</QBtn>
<QBtn
color="primary"
@click="showProposalDialog = true"
icon="vn:splitline"
>
<QTooltip bottom anchor="bottom right">
{{ t('Item proposal') }}
</QTooltip>
</QBtn>
</QBtnGroup>
<QCheckbox
v-model="showFree"
:label="t('negative.detail.showFree')"
/>
</template>
</template> </template>
</VnSubToolbar> </VnSubToolbar>
<div v-show="!currentRow" class="list"> <div v-show="!currentRow" class="list">
@ -233,8 +265,22 @@ const columns = computed(() => [
<TicketLackDetail <TicketLackDetail
:id="currentRow?.itemFk" :id="currentRow?.itemFk"
:filter="{ showFree }" :filter="{ showFree }"
@selection="(values) => (selectedRowsDetail = values)"
></TicketLackDetail> ></TicketLackDetail>
</div> </div>
<ChangeStateDialog
ref="changeStateDialogRef"
@hide="onDialogHide"
v-model="showChangeStateDialog"
:selected-rows="selectedRowsDetail"
></ChangeStateDialog>
<ChangeQuantityDialog
ref="changeQuantityDialogRef"
@hide="onDialogHide"
v-model="showChangeQuantityDialog"
:selected-rows="selectedRowsDetail"
>
</ChangeQuantityDialog>
<ItemProposal <ItemProposal
ref="proposalDialogRef" ref="proposalDialogRef"
@hide="onDialogHide" @hide="onDialogHide"

View File

@ -42,3 +42,10 @@ negative:
isRookie: 'Cliente nuevo' isRookie: 'Cliente nuevo'
turno: 'Linea turno' turno: 'Linea turno'
showFree: Mostrar las lineas Free showFree: Mostrar las lineas Free
modal:
changeState:
title: Actualizar estado de los tickets
placeholder: Nuevo estado
changeQuantity:
title: Actualizar cantidad de los tickets
placeholder: Nueva cantidad