0
0
Fork 0

refactor: refs #6896 end migration orders

This commit is contained in:
Jon Elias 2024-05-23 13:55:06 +02:00
parent 19bdd4fc36
commit 98159de257
5 changed files with 330 additions and 182 deletions

View File

@ -3,14 +3,15 @@ import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import axios from 'axios'; import axios from 'axios';
import VnInput from 'components/common/VnInput.vue'; import VnInput from 'components/common/VnInput.vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnSelect from 'components/common/VnSelect.vue'; import VnSelect from 'components/common/VnSelect.vue';
import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue'; import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
import { useValidator } from 'src/composables/useValidator';
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const props = defineProps({ const props = defineProps({
dataKey: { dataKey: {
@ -21,32 +22,34 @@ const props = defineProps({
type: Array, type: Array,
required: true, required: true,
}, },
tagValue: {
type: Array,
required: true,
},
}); });
const categoryList = ref(null); const categoryList = ref(null);
const selectedCategoryFk = ref(null); const selectedCategoryFk = ref(null);
const typeList = ref(null); const typeList = ref(null);
const selectedTypeFk = ref(null); const selectedTypeFk = ref(null);
const validationsStore = useValidator();
const selectedOrder = ref(null);
const selectedOrderField = ref(null);
const moreFields = ref([]);
const moreFieldsOrder = ref([]);
const createValue = (val, done) => {
if (val.length > 2) {
// if (!tagOptions.value.includes(val)) {
// done(tagOptions.value, 'add-unique');
// }
tagValues.value.push({ value: val });
}
};
const resetCategory = () => { const resetCategory = () => {
selectedCategoryFk.value = null; selectedCategoryFk.value = null;
typeList.value = null; typeList.value = null;
}; };
const selectedOrder = ref(null);
const orderList = [
{ way: 'ASC', name: 'Ascendant' },
{ way: 'DESC', name: 'Descendant' },
];
const selectedOrderField = ref(null);
const OrderFields = [
{ field: 'relevancy DESC, name', name: 'Relevancy', priority: 999 },
{ field: 'showOrder, price', name: 'Color and price', priority: 999 },
{ field: 'name', name: 'Name', priority: 999 },
{ field: 'price', name: 'Price', priority: 999 },
];
const clearFilter = (key) => { const clearFilter = (key) => {
if (key === 'categoryFk') { if (key === 'categoryFk') {
resetCategory(); resetCategory();
@ -72,21 +75,6 @@ const loadTypes = async (categoryFk) => {
typeList.value = data; typeList.value = data;
}; };
const onFilterInit = async ({ params }) => {
if (params.typeFk) {
selectedTypeFk.value = params.typeFk;
}
if (params.categoryFk) {
await loadTypes(params.categoryFk);
selectedCategoryFk.value = params.categoryFk;
}
if (params.orderBy) {
orderByParam.value = JSON.parse(params.orderBy);
selectedOrder.value = orderByParam.value?.way;
selectedOrderField.value = orderByParam.value?.field;
}
};
const selectedCategory = computed(() => const selectedCategory = computed(() =>
(categoryList.value || []).find( (categoryList.value || []).find(
(category) => category?.id === selectedCategoryFk.value (category) => category?.id === selectedCategoryFk.value
@ -109,12 +97,25 @@ function exprBuilder(param, value) {
const selectedTag = ref(null); const selectedTag = ref(null);
const tagValues = ref([{}]); const tagValues = ref([{}]);
const tagOptions = ref(null); const tagOptions = ref([]);
const isButtonDisabled = computed(
() => !selectedTag.value || tagValues.value.some((item) => !item.value)
);
const applyTagFilter = (params, search) => { const applyTagFilter = (params, search) => {
// console.log('params: ', params);
// if (!selectedTag.value) {
// console.log('values: ', selectedTag?.value?.name);
// params.tagGroups.push(
// JSON.stringify({
// values: selectedTag?.value?.name,
// // tagSelection: {
// // ...selectedTag.value,
// // orgShowField: selectedTag?.value?.name,
// // },
// })
// );
// search();
// return;
// }
if (!tagValues.value?.length) { if (!tagValues.value?.length) {
params.tagGroups = null; params.tagGroups = null;
search(); search();
@ -125,12 +126,12 @@ const applyTagFilter = (params, search) => {
} }
params.tagGroups.push( params.tagGroups.push(
JSON.stringify({ JSON.stringify({
values: tagValues.value, values: tagValues.value.filter((obj) => Object.keys(obj).length > 0),
tagSelection: { tagSelection: {
...selectedTag.value, ...selectedTag.value,
orgShowField: selectedTag.value.name, orgShowField: selectedTag?.value?.name,
}, },
tagFk: selectedTag.value.tagFk, tagFk: selectedTag?.value?.tagFk,
}) })
); );
search(); search();
@ -155,12 +156,6 @@ const onOrderFieldChange = (value, params, search) => {
search(); search();
}; };
const onOrderChange = (value, params, search) => {
const orderBy = Object.assign({}, orderByParam.value, { way: value.way });
params.orderBy = JSON.stringify(orderBy);
search();
};
const setCategoryList = (data) => { const setCategoryList = (data) => {
categoryList.value = (data || []) categoryList.value = (data || [])
.filter((category) => category.display) .filter((category) => category.display)
@ -168,6 +163,10 @@ const setCategoryList = (data) => {
...category, ...category,
icon: `vn:${(category.icon || '').split('-')[1]}`, icon: `vn:${(category.icon || '').split('-')[1]}`,
})); }));
const _moreFields = ['ASC', 'DESC'];
const _moreFieldsTypes = ['Relevancy', 'ColorAndPrice', 'Name', 'Price'];
moreFields.value = useLang(_moreFields);
moreFieldsOrder.value = useLang(_moreFieldsTypes);
}; };
const getCategoryClass = (category, params) => { const getCategoryClass = (category, params) => {
@ -175,6 +174,20 @@ const getCategoryClass = (category, params) => {
return 'active'; return 'active';
} }
}; };
const useLang = (values) => {
const { models } = validationsStore;
const properties = models.Item?.properties || {};
return values.map((name) => {
let prop = properties[name];
const label = t(`params.${name}`);
return {
name,
label,
type: prop ? prop.type : null,
};
});
};
</script> </script>
<template> <template>
@ -184,7 +197,6 @@ const getCategoryClass = (category, params) => {
:hidden-tags="['orderFk', 'orderBy']" :hidden-tags="['orderFk', 'orderBy']"
:expr-builder="exprBuilder" :expr-builder="exprBuilder"
:custom-tags="['tagGroups']" :custom-tags="['tagGroups']"
@init="onFilterInit"
@remove="clearFilter" @remove="clearFilter"
> >
<template #tags="{ tag, formatFn }"> <template #tags="{ tag, formatFn }">
@ -274,17 +286,13 @@ const getCategoryClass = (category, params) => {
<QItem class="q-my-md"> <QItem class="q-my-md">
<QItemSection> <QItemSection>
<VnSelect <VnSelect
:label="t('params.order')" :label="t('Order')"
v-model="selectedOrder" v-model="selectedOrder"
:options="orderList || []" :options="moreFields"
option-value="way" option-label="label"
option-label="name"
dense dense
outlined outlined
rounded rounded
:emit-value="false"
use-input
:is-clearable="false"
@update:model-value=" @update:model-value="
(value) => onOrderChange(value, params, searchFn) (value) => onOrderChange(value, params, searchFn)
" "
@ -294,17 +302,14 @@ const getCategoryClass = (category, params) => {
<QItem class="q-mb-md"> <QItem class="q-mb-md">
<QItemSection> <QItemSection>
<VnSelect <VnSelect
:label="t('params.order')" :label="t('Order by')"
v-model="selectedOrderField" v-model="selectedOrderField"
:options="OrderFields || []" :options="moreFieldsOrder"
option-value="field" option-label="label"
option-label="name" option-value="name"
dense dense
outlined outlined
rounded rounded
:emit-value="false"
use-input
:is-clearable="false"
@update:model-value=" @update:model-value="
(value) => onOrderFieldChange(value, params, searchFn) (value) => onOrderFieldChange(value, params, searchFn)
" "
@ -341,10 +346,9 @@ const getCategoryClass = (category, params) => {
class="filter-input" class="filter-input"
/> />
<VnSelect <VnSelect
v-else
:label="t('params.value')" :label="t('params.value')"
v-model="value.value" v-model="value.value"
:options="tagOptions || []" :options="tagValue || []"
option-value="value" option-value="value"
option-label="value" option-label="value"
dense dense
@ -352,17 +356,18 @@ const getCategoryClass = (category, params) => {
rounded rounded
emit-value emit-value
use-input use-input
:disable="!selectedTag"
class="filter-input" class="filter-input"
/> @new-value="createValue"
>
</VnSelect>
<FetchData <FetchData
v-if="selectedTag && !selectedTag.isFree" v-if="selectedTag"
:url="`Tags/${selectedTag?.id}/filterValue`" :url="`Tags/${selectedTag}/filterValue`"
limit="30" limit="30"
auto-load auto-load
@on-fetch="(data) => (tagOptions = data)" @on-fetch="(data) => (tagOptions = data)"
/> />
{{ console.log('selectedTag: ', selectedTag) }}
<QIcon <QIcon
name="delete" name="delete"
@ -388,7 +393,6 @@ const getCategoryClass = (category, params) => {
rounded rounded
type="button" type="button"
unelevated unelevated
:disable="isButtonDisabled"
@click.stop="applyTagFilter(params, searchFn)" @click.stop="applyTagFilter(params, searchFn)"
/> />
</QItemSection> </QItemSection>
@ -453,6 +457,12 @@ en:
tag: Tag tag: Tag
value: Value value: Value
order: Order order: Order
ASC: Ascendant
DESC: Descendant
Relevancy: Relevancy
ColorAndPrice: Color and price
Name: Name
Price: Price
es: es:
params: params:
type: Tipo type: Tipo
@ -460,6 +470,14 @@ es:
tag: Etiqueta tag: Etiqueta
value: Valor value: Valor
order: Orden order: Orden
ASC: Ascendiente
DESC: Descendiente
Relevancy: Relevancia
ColorAndPrice: Color y precio
Name: Nombre
Price: Precio
Order: Orden
Order by: Ordenar por
Plant: Planta Plant: Planta
Flower: Flor Flower: Flor
Handmade: Confección Handmade: Confección

View File

@ -59,7 +59,10 @@ const dialog = ref(null);
</template> </template>
<div class="footer"> <div class="footer">
<div class="price"> <div class="price">
<p>{{ item.available }} {{ t('to') }} {{ item.price }}</p> <p>
{{ item.available }} {{ t('to') }}
{{ toCurrency(item.price) }}
</p>
<QIcon name="add_circle" class="icon"> <QIcon name="add_circle" class="icon">
<QTooltip>{{ t('globals.add') }}</QTooltip> <QTooltip>{{ t('globals.add') }}</QTooltip>
<QPopupProxy ref="dialog"> <QPopupProxy ref="dialog">

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import { useRoute } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { reactive, ref, onMounted } from 'vue'; import { reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import axios from 'axios'; import axios from 'axios';
import { useState } from 'composables/useState'; import { useState } from 'composables/useState';
@ -16,6 +16,7 @@ const route = useRoute();
const state = useState(); const state = useState();
const ORDER_MODEL = 'order'; const ORDER_MODEL = 'order';
const router = useRouter();
const isNew = Boolean(!route.params.id); const isNew = Boolean(!route.params.id);
const initialFormState = reactive({ const initialFormState = reactive({
clientFk: null, clientFk: null,
@ -26,21 +27,20 @@ const initialFormState = reactive({
const clientList = ref([]); const clientList = ref([]);
const agencyList = ref([]); const agencyList = ref([]);
const addressList = ref([]); const addressList = ref([]);
const clientId = ref(null);
const onClientsFetched = async (data) => { const onClientsFetched = (data) => {
try { clientList.value = data;
clientList.value = data; initialFormState.clientFk = Number(route.query?.clientFk) || null;
initialFormState.clientFk = Number(route.query?.clientFk) || null; clientId.value = initialFormState.clientFk;
if (initialFormState.clientFk) { const client = clientList.value.find(
const { defaultAddressFk } = clientList.value.find( (client) => client.id === initialFormState.clientFk
(client) => client.id === initialFormState.clientFk );
); if (client && client.defaultAddressFk) {
fetchAddressList(client.defaultAddressFk);
if (defaultAddressFk) await fetchAddressList(defaultAddressFk); } else {
} throw new Error(t(`No default address found for the client`));
} catch (err) {
console.error('Error fetching clients', err);
} }
}; };
@ -55,7 +55,6 @@ const fetchAddressList = async (addressId) => {
}, },
}); });
addressList.value = data; addressList.value = data;
// Set address by default
if (addressList.value?.length === 1) { if (addressList.value?.length === 1) {
state.get(ORDER_MODEL).addressFk = addressList.value[0].id; state.get(ORDER_MODEL).addressFk = addressList.value[0].id;
} }
@ -121,6 +120,21 @@ const orderFilter = {
}, },
], ],
}; };
const onClientChange = async (clientId) => {
try {
const { data } = await axios.get(`Clients/${clientId}`);
console.log('info cliente: ', data);
await fetchAddressList(data.defaultAddressFk);
} catch (error) {
console.error('Error al cambiar el cliente:', error);
}
};
async function onDataSaved(data) {
await router.push({ path: `/order/${data}/catalog` });
}
</script> </script>
<template> <template>
@ -134,13 +148,15 @@ const orderFilter = {
<div class="q-pa-md"> <div class="q-pa-md">
<FormModel <FormModel
:url="!isNew ? `Orders/${route.params.id}` : null" :url="!isNew ? `Orders/${route.params.id}` : null"
:url-create="isNew ? 'Orders/new' : null" :url-create="'Orders/new'"
@on-data-saved="onDataSaved"
:model="ORDER_MODEL" :model="ORDER_MODEL"
:form-initial-data="isNew ? initialFormState : null" :form-initial-data="isNew ? initialFormState : null"
:observe-form-changes="!isNew" :observe-form-changes="!isNew"
:mapper="isNew ? orderMapper : null" :mapper="isNew ? orderMapper : null"
:filter="orderFilter" :filter="orderFilter"
@on-fetch="fetchOrderDetails" @on-fetch="fetchOrderDetails"
auto-load
> >
<template #form="{ data }"> <template #form="{ data }">
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">
@ -151,9 +167,7 @@ const orderFilter = {
option-value="id" option-value="id"
option-label="name" option-label="name"
hide-selected hide-selected
@update:model-value=" @update:model-value="onClientChange"
(client) => fetchAddressList(client.defaultAddressFk)
"
> >
<template #option="scope"> <template #option="scope">
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">
@ -170,12 +184,10 @@ const orderFilter = {
v-model="data.addressFk" v-model="data.addressFk"
:options="addressList" :options="addressList"
option-value="id" option-value="id"
option-label="nickname" option-label="street"
hide-selected hide-selected
:disable="!addressList?.length" :disable="!addressList?.length"
@update:model-value=" @update:model-value="onAddressChange"
() => fetchAgencyList(data.landed, data.addressFk)
"
> >
<template #option="scope"> <template #option="scope">
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">
@ -216,3 +228,8 @@ const orderFilter = {
</FormModel> </FormModel>
</div> </div>
</template> </template>
<i18n>
es:
No default address found for the client: No hay ninguna dirección asociada a este cliente.
</i18n>

View File

@ -35,6 +35,20 @@ function extractTags(items) {
}); });
}); });
tags.value = resultTags; tags.value = resultTags;
extractValueTags(items);
}
const tagValue = ref([]);
function extractValueTags(items) {
const resultValueTags = items.flatMap((x) =>
Object.keys(x)
.filter((k) => /^value\d+$/.test(k))
.map((v) => x[v])
.filter((v) => v)
.sort()
);
tagValue.value = resultValueTags;
} }
</script> </script>
@ -66,7 +80,11 @@ function extractTags(items) {
</Teleport> </Teleport>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
<QScrollArea class="fit text-grey-8"> <QScrollArea class="fit text-grey-8">
<OrderCatalogFilter data-key="OrderCatalogList" :tags="tags" /> <OrderCatalogFilter
data-key="OrderCatalogList"
:tag-value="tagValue"
:tags="tags"
/>
</QScrollArea> </QScrollArea>
</QDrawer> </QDrawer>
<QPage class="column items-center q-pa-md"> <QPage class="column items-center q-pa-md">

View File

@ -7,13 +7,13 @@ import { useQuasar } from 'quasar';
import VnPaginate from 'components/ui/VnPaginate.vue'; import VnPaginate from 'components/ui/VnPaginate.vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import VnLv from 'components/ui/VnLv.vue'; import VnLv from 'components/ui/VnLv.vue';
import CardList from 'components/ui/CardList.vue';
import FetchedTags from 'components/ui/FetchedTags.vue'; import FetchedTags from 'components/ui/FetchedTags.vue';
import VnConfirm from 'components/ui/VnConfirm.vue'; import VnConfirm from 'components/ui/VnConfirm.vue';
import { toCurrency, toDate } from 'src/filters'; import { toCurrency, toDate } from 'src/filters';
import { useSession } from 'composables/useSession'; import { useSession } from 'composables/useSession';
import axios from 'axios'; import axios from 'axios';
import ItemDescriptorProxy from '../Item/Card/ItemDescriptorProxy.vue';
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
@ -43,6 +43,7 @@ function confirmRemove(item) {
} }
async function remove(item) { async function remove(item) {
console.log('item: ', item);
await axios.post('OrderRows/removes', { await axios.post('OrderRows/removes', {
actualOrderId: route.params.id, actualOrderId: route.params.id,
rows: [item.id], rows: [item.id],
@ -61,6 +62,35 @@ async function confirmOrder() {
type: 'positive', type: 'positive',
}); });
} }
const detailsColumns = ref([
{
name: 'item',
label: t('order.summary.item'),
field: (row) => row?.item?.id,
sortable: true,
},
{
name: 'description',
label: t('globals.description'),
field: (row) => row?.item?.name,
},
{
name: 'quantity',
label: t('order.summary.quantity'),
field: (row) => row?.quantity,
},
{
name: 'price',
label: t('order.summary.price'),
field: (row) => toCurrency(row?.price),
},
{
name: 'amount',
label: t('order.summary.amount'),
field: (row) => toCurrency(row?.quantity * row?.price),
},
]);
</script> </script>
<template> <template>
@ -83,30 +113,33 @@ async function confirmOrder() {
auto-load auto-load
/> />
<QPage :key="componentKey" class="column items-center q-pa-md"> <QPage :key="componentKey" class="column items-center q-pa-md">
<div class="vn-card-list"> <div class="order-list">
<div v-if="!orderSummary.total" class="no-result"> <div v-if="!orderSummary.total" class="no-result">
{{ t('globals.noResults') }} {{ t('globals.noResults') }}
</div> </div>
<QCard v-else class="order-lines-summary q-pa-lg">
<p class="header text-right block"> <QDrawer side="right" :width="300" show-if-above>
{{ t('summary') }} <QCard class="order-lines-summary q-pa-lg">
</p> <p class="header text-right block">
<VnLv {{ t('summary') }}
v-if="orderSummary.vat && orderSummary.total" </p>
:label="t('subtotal')" <VnLv
:value="toCurrency(orderSummary.total - orderSummary.vat)" v-if="orderSummary.vat && orderSummary.total"
/> :label="t('subtotal')"
<VnLv :value="toCurrency(orderSummary.total - orderSummary.vat)"
v-if="orderSummary.vat" />
:label="t('VAT')" <VnLv
:value="toCurrency(orderSummary?.vat)" v-if="orderSummary.vat"
/> :label="t('VAT')"
<VnLv :value="toCurrency(orderSummary?.vat)"
v-if="orderSummary.total" />
:label="t('total')" <VnLv
:value="toCurrency(orderSummary?.total)" v-if="orderSummary.total"
/> :label="t('total')"
</QCard> :value="toCurrency(orderSummary?.total)"
/>
</QCard>
</QDrawer>
<VnPaginate <VnPaginate
data-key="OrderLines" data-key="OrderLines"
url="OrderRows" url="OrderRows"
@ -125,74 +158,108 @@ async function confirmOrder() {
}" }"
> >
<template #body="{ rows }"> <template #body="{ rows }">
<div class="catalog-list q-mt-xl"> <div class="q-pa-md">
<CardList <QTable
v-for="row in rows" :columns="detailsColumns"
:key="row.id" :rows="rows"
:id="row.id" flat
:title="row?.item?.name" style="text-align: center"
class="cursor-inherit"
> >
<template #title> <template #header="props">
<div class="flex items-center"> <QTr :props="props" class="tr-header">
<div class="image-wrapper q-mr-md"> <QTh></QTh>
<QTh auto-width>{{ t('item') }}</QTh>
<QTh>{{ t('globals.description') }}</QTh>
<QTh>{{ t('warehouse') }}</QTh>
<QTh>{{ t('shipped') }}</QTh>
<QTh auto-width>
{{ t('order.summary.quantity') }}
</QTh>
<QTh auto-width>{{ t('order.summary.price') }}</QTh>
<QTh auto-width>{{ t('amount') }}</QTh>
<QTh></QTh>
</QTr>
</template>
<template #body="props">
<QTr :props="props">
<QTd>
{{ console.log('props: ', props.row.item.id) }}
<QImg <QImg
:src="`/api/Images/catalog/50x50/${row?.item?.id}/download?access_token=${token}`" :src="`/api/Images/catalog/50x50/${props.row.item?.id}/download?access_token=${token}`"
spinner-color="primary" spinner-color="primary"
:ratio="1" :ratio="1"
height="50" height="50"
width="50" width="50"
class="image" class="image-wrapper"
style="cursor: pointer"
/> />
</div> </QTd>
<div <QTd key="item" :props="props" class="item">
class="title text-primary text-weight-bold text-h5" <span class="link">
<QBtn flat>
{{ props.row.item?.id }}
</QBtn>
<ItemDescriptorProxy
:id="props.row.item?.id"
/>
</span>
</QTd>
<QTd
key="description"
:props="props"
class="description-cell"
> >
{{ row?.item?.name }} <div class="row full-width justify-between">
</div> {{ props.row.item.name }}
<QChip class="q-chip-color" outline size="sm"> <div
{{ t('ID') }}: {{ row.id }} v-if="props.row.item.subName"
</QChip> class="subName"
</div> >
{{ props.row.item.subName.toUpperCase() }}
</div>
</div>
<FetchedTags
:item="props.row.item"
:max-length="6"
class="fetched-tags"
/>
</QTd>
<QTd>
{{ props.row.warehouse.name }}
</QTd>
<QTd>
{{ toDate(props.row.shipped) }}
</QTd>
<QTd key="quantity" :props="props">
{{ props.row.quantity }}
</QTd>
<QTd key="price" :props="props">
{{ toCurrency(props.row.price) }}
</QTd>
<QTd key="amount" :props="props">
{{
toCurrency(
props.row?.quantity * props.row?.price
)
}}
</QTd>
<QTd>
<QIcon
name="delete"
color="primary"
size="sm"
class="cursor-pointer"
@click.stop="confirmRemove(props.row)"
style="margin-left: 40%"
>
<QTooltip>{{
t('Remove thermograph')
}}</QTooltip>
</QIcon>
</QTd>
</QTr>
</template> </template>
<template #list-items> </QTable>
<div class="q-mb-sm">
<span class="text-uppercase subname">
{{ row.item.subName }}
</span>
<fetched-tags :item="row.item" :max-length="5" />
</div>
<VnLv :label="t('item')" :value="String(row.item.id)" />
<VnLv
:label="t('warehouse')"
:value="row.warehouse.name"
/>
<VnLv
:label="t('shipped')"
:value="toDate(row.shipped)"
/>
<VnLv
:label="t('quantity')"
:value="String(row.quantity)"
/>
<VnLv
:label="t('price')"
:value="toCurrency(row.price)"
/>
<VnLv
:label="t('amount')"
:value="toCurrency(row.price * row.quantity)"
/>
</template>
<template #actions v-if="!order?.isConfirmed">
<QBtn
:label="t('remove')"
@click.stop="confirmRemove(row)"
color="primary"
style="margin-top: 15px"
/>
</template>
</CardList>
</div> </div>
</template> </template>
</VnPaginate> </VnPaginate>
@ -239,14 +306,7 @@ async function confirmOrder() {
.image-wrapper { .image-wrapper {
height: 50px; height: 50px;
width: 50px; width: 50px;
border-radius: 50%;
.image {
border-radius: 50%;
}
}
.subname {
color: var(--vn-label-color);
} }
.no-result { .no-result {
@ -255,6 +315,38 @@ async function confirmOrder() {
color: var(--vn-label-color); color: var(--vn-label-color);
text-align: center; text-align: center;
} }
.description {
display: flex;
flex-direction: column;
justify-content: center;
text-align: left;
height: auto;
padding-top: 12px;
padding-bottom: 12px;
.name {
display: flex;
align-items: center;
padding-bottom: 8px;
& > * {
flex: 1;
}
}
}
.description-cell {
width: 25%;
}
.fetched-tags {
max-width: 90%;
}
.subName {
text-transform: uppercase;
color: var(--vn-label-color);
}
</style> </style>
<i18n> <i18n>
en: en: