WIP: refs #6416 - refactor-InvoiceIn #196

Closed
jsegarra wants to merge 17 commits from 6416-refactor-InvoiceIn into dev
27 changed files with 941 additions and 355 deletions

View File

@ -4,14 +4,15 @@ import { computed, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import { useValidator } from 'src/composables/useValidator';
import { useStateStore } from 'stores/useStateStore';
// import { useStateStore } from 'stores/useStateStore';
import VnPaginate from 'components/ui/VnPaginate.vue';
import VnConfirm from 'components/ui/VnConfirm.vue';
import SkeletonTable from 'components/ui/SkeletonTable.vue';
import { tMobile } from 'src/composables/tMobile';
import VnTeleport from 'components/ui/VnTeleport.vue';
const quasar = useQuasar();
const stateStore = useStateStore();
// const stateStore = useStateStore();
const { t } = useI18n();
const { validate } = useValidator();
@ -275,7 +276,8 @@ watch(formUrl, async () => {
</template>
</VnPaginate>
<SkeletonTable v-if="!formData" />
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
<VnTeleport>
<template #st-actions>
<QBtnGroup push style="column-gap: 10px">
<slot name="moreBeforeActions" />
<QBtn
@ -310,7 +312,8 @@ watch(formUrl, async () => {
/>
<slot name="moreAfterActions" />
</QBtnGroup>
</Teleport>
</template>
</VnTeleport>
<QInnerLoading
:showing="isLoading"
:label="t && t('globals.pleaseWait')"

View File

@ -0,0 +1,33 @@
<script setup>
import { useI18n } from 'vue-i18n';
const $props = defineProps({
class: { type: String, require: true, default: null },
padding: { type: String, require: true, default: null },
color: { type: String, require: true, default: null },
icon: { type: String, require: true, default: null },
promise: { type: Function, require: true, default: null },
});
const { t } = useI18n();
async function onClick() {
if ($props.promise) return await $props.promise();
}
</script>
<template>
<QBtn
:class="$props.class"
:padding="$props.padding"
:icon="$props.icon"
flat
:color="$props.color"
round
@click="onClick()"
>
<QTooltip>
<slot name="tooltip">
{{ t('components.smartCard.downloadFile') }}
</slot></QTooltip
>
</QBtn>
</template>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,18 @@
<script setup>
import { useI18n } from 'vue-i18n';
const $props = defineProps({
columns: { type: Object, require: true, default: null },
rows: { type: Object, require: true, default: null },
});
const { t } = useI18n();
</script>
<template>
<QCard>
<slot name="header"></slot>
<slot name="body"></slot>
<slot name="footer"></slot>
</QCard>
</template>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,19 @@
<script setup>
import { useI18n } from 'vue-i18n';
const $props = defineProps({
title: { type: String, require: true, default: 'twoFactor.validate' },
href: { type: String, require: true, default: null },
});
const { t } = useI18n();
</script>
<template>
<QCardSection class="q-pa-none">
<a class="header" :href="$props.href">
{{ t($props.title) }}
<slot name="icon"></slot>
</a>
<slot name="btn"></slot>
</QCardSection>
</template>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,16 @@
<script setup>
import { useI18n } from 'vue-i18n';
const $props = defineProps({
class: { type: String, require: true, default: null },
color: { type: String, require: true, default: null },
title: { type: String, require: true, default: null },
});
const { t } = useI18n();
</script>
<template>
<QChip dense :class="$props.class" :color="$props.color" :title="$props.title">
<slot name="body"> </slot
></QChip>
</template>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,13 @@
<script setup>
import { useI18n } from 'vue-i18n';
const $props = defineProps({
name: { type: String, require: true, default: null },
color: { type: String, require: true, default: null },
});
const { t } = useI18n();
</script>
<template>
<QIcon :name="$props.name" :color="$props.color" />
</template>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,34 @@
<script setup>
import { useI18n } from 'vue-i18n';
const $props = defineProps({
columns: { type: Object, require: true, default: null },
rows: { type: Object, require: true, default: null },
hasSummary: { type: Boolean, require: true, default: false },
summary: { type: Object, require: true, default: null },
});
const { t } = useI18n();
</script>
<template>
<QTable :columns="$props.columns" :rows="$props.rows" flat hide-pagination>
<template #header="props">
<QTr :props="props" class="bg">
<QTh v-for="col in props.cols" :key="col.name" :props="props">
{{ t(col.label) }}
</QTh>
</QTr>
</template>
<template #bottom-row v-if="hasSummary">
<QTr class="bg">
<QTd v-for="col in $props.columns" :key="col.name" :props="props">{{
$props.summary[col.name]
}}</QTd>
</QTr>
</template>
</QTable>
</template>
<style lang="scss" scoped>
.bg {
background-color: var(--vn-light-gray);
}
</style>

View File

@ -0,0 +1,14 @@
<script setup>
import { useStateStore } from 'stores/useStateStore';
const stateStore = useStateStore();
</script>
<template>
<Teleport to="#st-data" v-if="stateStore.isSubToolbarShown()">
<slot name="st-data"></slot>
</Teleport>
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
<slot name="st-actions"></slot>
</Teleport>
</template>

View File

@ -13,6 +13,7 @@ import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import VnConfirm from 'src/components/ui/VnConfirm.vue';
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
import { useArrayData } from 'composables/useArrayData';
import VnTeleport from 'components/ui/VnTeleport.vue';
const { t } = useI18n();
const quasar = useQuasar();
@ -267,7 +268,8 @@ async function importToNewRefundTicket() {
/>
</QCard>
</QDrawer>
<Teleport to="#st-data" v-if="stateStore.isSubToolbarShown()"> </Teleport>
<VnTeleport></VnTeleport>
<!-- <Teleport to="#st-data" v-if="stateStore.isSubToolbarShown()"> </Teleport> -->
<CrudModel
v-if="claim"
data-key="ClaimEnds"

View File

@ -4,11 +4,12 @@ import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import { useRoute } from 'vue-router';
import { useStateStore } from 'stores/useStateStore';
// import { useStateStore } from 'stores/useStateStore';
import { useArrayData } from 'composables/useArrayData';
import { toDate, toCurrency, toPercentage } from 'filters/index';
import CrudModel from 'components/CrudModel.vue';
import FetchData from 'components/FetchData.vue';
import VnTeleport from 'components/ui/VnTeleport.vue';
import VnDiscount from 'components/common/vnDiscount.vue';
import ClaimLinesImport from './ClaimLinesImport.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
@ -17,7 +18,7 @@ const quasar = useQuasar();
const route = useRoute();
const { t } = useI18n();
const stateStore = useStateStore();
// const stateStore = useStateStore();
const arrayData = useArrayData('ClaimLines');
const store = arrayData.store;
@ -157,7 +158,8 @@ function showImportDialog() {
}
</script>
<template>
<Teleport to="#st-data" v-if="stateStore.isSubToolbarShown()">
<VnTeleport>
<template #st-data>
<div class="row q-gutter-md">
<div>
{{ t('Amount') }}
@ -173,7 +175,8 @@ function showImportDialog() {
</QChip>
</div>
</div>
</Teleport>
</template>
</VnTeleport>
<FetchData
:url="`Claims/${route.params.id}`"

View File

@ -11,9 +11,10 @@ import VnInput from 'src/components/common/VnInput.vue';
import FetchedTags from 'components/ui/FetchedTags.vue';
import VnConfirm from 'components/ui/VnConfirm.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import VnTeleport from 'components/ui/VnTeleport.vue';
import { useQuasar } from 'quasar';
import { useStateStore } from 'stores/useStateStore';
// import { useStateStore } from 'stores/useStateStore';
import { toCurrency } from 'src/filters';
import axios from 'axios';
import useNotify from 'src/composables/useNotify.js';
@ -22,7 +23,7 @@ const quasar = useQuasar();
const route = useRoute();
const router = useRouter();
const { t } = useI18n();
const stateStore = useStateStore();
// const stateStore = useStateStore();
const { notify } = useNotify();
const rowsSelected = ref([]);
@ -293,7 +294,8 @@ const showLockIcon = (groupingMode, mode) => {
auto-load
@on-fetch="(data) => (packagingsOptions = data)"
/>
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
<VnTeleport>
<template #st-actions>
<QBtnGroup push style="column-gap: 10px">
<slot name="moreBeforeActions" />
<QBtn
@ -304,9 +306,9 @@ const showLockIcon = (groupingMode, mode) => {
@click="openRemoveDialog()"
:disable="!rowsSelected?.length"
:title="t('globals.remove')"
/>
</QBtnGroup>
</Teleport>
/> </QBtnGroup
></template>
</VnTeleport>
<VnPaginate
ref="entryBuysPaginateRef"
data-key="EntryBuys"

View File

@ -9,13 +9,14 @@ import FetchData from 'components/FetchData.vue';
import VnSelectFilter from 'components/common/VnSelectFilter.vue';
import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
import FilterItemForm from 'src/components/FilterItemForm.vue';
import VnTeleport from 'components/ui/VnTeleport.vue';
import { useStateStore } from 'stores/useStateStore';
// import { useStateStore } from 'stores/useStateStore';
import axios from 'axios';
import useNotify from 'src/composables/useNotify.js';
import { toCurrency } from 'filters/index';
const stateStore = useStateStore();
// const stateStore = useStateStore();
const route = useRoute();
const router = useRouter();
const { t } = useI18n();
@ -175,7 +176,8 @@ const redirectToBuysView = () => {
auto-load
/>
<QForm>
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
<VnTeleport>
<template #st-actions>
<div>
<QBtnGroup push class="q-gutter-x-sm">
<QBtn
@ -195,7 +197,8 @@ const redirectToBuysView = () => {
/>
</QBtnGroup>
</div>
</Teleport>
</template>
</VnTeleport>
<QCard class="q-pa-lg">
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">

View File

@ -8,9 +8,9 @@ import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import { useArrayData } from 'src/composables/useArrayData';
import { onMounted, watch } from 'vue';
import { useRoute } from 'vue-router';
const stateStore = useStateStore();
const { t } = useI18n();
import in18n from '../in18n';
const { t } = useI18n(in18n);
const route = useRoute();
const filter = {
@ -60,7 +60,7 @@ watch(
<VnSearchbar
data-key="InvoiceInList"
url="InvoiceIns/filter"
:label="t('Search invoice')"
:label="t('searchInvoice')"
:info="t('You can search by invoice reference')"
/>
</Teleport>

View File

@ -6,6 +6,13 @@ import { toCurrency, toDate } from 'src/filters';
import { getUrl } from 'src/composables/getUrl';
import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import VnTable from 'src/components/ui/VnTable.vue';
import VnCardSection from 'src/components/ui/VnCardSection.vue';
import VnCard from 'src/components/ui/VnCard.vue';
import VnIcon from 'src/components/ui/VnIcon.vue';
import VnBtn from 'src/components/ui/VnBtn.vue';
import in18n from '../in18n';
import VnChip from 'src/components/ui/VnChip.vue';
onMounted(async () => {
salixUrl.value = await getUrl('');
@ -13,7 +20,7 @@ onMounted(async () => {
});
const route = useRoute();
const { t } = useI18n();
const { t } = useI18n(in18n);
const $props = defineProps({
id: {
@ -207,16 +214,38 @@ function getLink(param) {
</template>
<template #body="{ entity: invoiceIn }">
<!--Basic Data-->
<QCard class="vn-one">
<QCardSection class="q-pa-none">
<a class="header" :href="getLink('basic-data')">
{{ t('invoiceIn.pageTitles.basicData') }}
<QIcon name="open_in_new" color="primary" />
</a>
</QCardSection>
<VnCard class="vn-max">
<template #header>
<VnCardSection
:title="'invoiceIn.pageTitles.basicData'"
:href="`#/invoice-in/${entityId}/basic-data`"
>
<template #icon>
<VnIcon name="open_in_new" color="primary" />
</template>
<template #btn>
<VnBtn
class="q-ml-sm"
padding="xs"
flat
color="primary"
round
icon="cloud_download"
:promise="() => downloadFile(invoiceIn.dmsFk)"
>
<template #tooltip>
{{ t('components.smartCard.downloadFile') }}
</template>
</VnBtn>
</template>
</VnCardSection>
</template>
<template #body>
<div class="card-section">
<div class="vn-one card">
<VnLv
:label="t('invoiceIn.summary.supplier')"
:value="invoiceIn.supplier?.name"
:value="invoiceIn.supplier.name"
/>
<VnLv
:label="t('invoiceIn.summary.supplierRef')"
@ -224,22 +253,15 @@ function getLink(param) {
/>
<VnLv
:label="t('invoiceIn.summary.currency')"
:value="invoiceIn.currency?.code"
:value="invoiceIn.currency.code"
/>
<VnLv
:label="t('invoiceIn.summary.docNumber')"
:value="`${invoiceIn.serial}/${invoiceIn.serialNumber}`"
/>
</QCard>
<QCard class="vn-one">
<QCardSection class="q-pa-none">
<a class="header" :href="getLink('basic-data')">
{{ t('invoiceIn.pageTitles.basicData') }}
<QIcon name="open_in_new" color="primary" />
</a>
</QCardSection>
</div>
<div class="card vn-two">
<VnLv
:ellipsis-value="false"
:label="t('invoiceIn.summary.issued')"
:value="toDate(invoiceIn.issued)"
/>
@ -255,40 +277,9 @@ function getLink(param) {
:label="t('invoiceIn.summary.bookedDate')"
:value="toDate(invoiceIn.booked)"
/>
</QCard>
<QCard class="vn-one">
<QCardSection class="q-pa-none">
<a class="header" :href="getLink('basic-data')">
{{ t('invoiceIn.pageTitles.basicData') }}
<QIcon name="open_in_new" color="primary" />
</a>
</QCardSection>
<VnLv
:label="t('invoiceIn.summary.sage')"
:value="invoiceIn.sageWithholding?.withholding"
/>
<VnLv
:label="t('invoiceIn.summary.vat')"
:value="invoiceIn.expenseDeductible?.name"
/>
<VnLv
:label="t('invoiceIn.summary.company')"
:value="invoiceIn.company?.code"
/>
<VnLv
:label="t('invoiceIn.summary.booked')"
:value="invoiceIn.isBooked"
/>
</QCard>
<QCard class="vn-one">
<QCardSection class="q-pa-none">
<a class="header" :href="getLink('basic-data')">
{{ t('invoiceIn.pageTitles.basicData') }}
<QIcon name="open_in_new" color="primary" />
</a>
</QCardSection>
<QCardSection class="q-pa-none">
<div class="bordered q-px-sm q-mx-auto">
</div>
<div class="card vn-three">
<div class="q-px-sm">
<VnLv
:label="t('invoiceIn.summary.taxableBase')"
:value="toCurrency(invoiceIn.totals.totalTaxableBase)"
@ -299,123 +290,129 @@ function getLink(param) {
/>
<VnLv :label="t('invoiceIn.summary.dueTotal')">
<template #value>
<QChip
<VnChip
dense
class="q-pa-xs"
:color="amountsNotMatch ? 'negative' : 'transparent'"
:color="
amountsNotMatch
? 'negative'
: 'transparent'
"
:title="
amountsNotMatch
? t('invoiceIn.summary.noMatch')
: t('invoiceIn.summary.dueTotal')
"
>
{{ toCurrency(invoiceIn.totals.totalDueDay) }}
</QChip>
<template #body>
{{
toCurrency(
invoiceIn.totals.totalDueDay
)
}}
</template>
</VnChip>
</template>
</VnLv>
</div>
</QCardSection>
</QCard>
</div>
<div class="card vn-four q-mb-md">
<VnLv
:label="t('invoiceIn.summary.sage')"
:value="invoiceIn.sageWithholding.withholding"
/>
<VnLv
:label="t('invoiceIn.summary.vat')"
:value="invoiceIn.expenseDeductible?.name"
/>
<VnLv
:label="t('invoiceIn.summary.company')"
:value="invoiceIn.company.code"
/>
<VnLv
:label="t('invoiceIn.summary.booked')"
:value="invoiceIn.isBooked"
/>
</div>
</div>
</template>
</VnCard>
<!--Vat-->
<QCard v-if="invoiceIn.invoiceInTax.length">
<a class="header" :href="getLink('vat')">
{{ t('invoiceIn.card.vat') }}
<QIcon name="open_in_new" color="primary" />
</a>
<QTable
<VnCard v-if="invoiceIn.invoiceInTax.length" class="vn-three">
<template #header>
<VnCardSection :title="'invoiceIn.card.vat'"> </VnCardSection>
</template>
<template #body>
<VnTable
:columns="vatColumns"
:rows="invoiceIn.invoiceInTax"
flat
hide-pagination
:has-summary="true"
:summary="{
landed: toCurrency(invoiceIn.totals.totalTaxableBase),
}"
>
<template #header="props">
<QTr :props="props" class="bg">
<QTh v-for="col in props.cols" :key="col.name" :props="props">
{{ t(col.label) }}
</QTh>
</QTr>
</VnTable>
</template>
<template #bottom-row>
<QTr class="bg">
<QTd></QTd>
<QTd>{{ toCurrency(invoiceIn.totals.totalTaxableBase) }}</QTd>
<QTd></QTd>
<QTd></QTd>
<QTd>{{
toCurrency(getTaxTotal(invoiceIn.invoiceInTax))
}}</QTd>
<QTd></QTd>
</QTr>
</template>
</QTable>
</QCard>
</VnCard>
<!--Due Day-->
<QCard v-if="invoiceIn.invoiceInDueDay.length">
<a class="header" :href="getLink('due-day')">
{{ t('invoiceIn.card.dueDay') }}
<QIcon name="open_in_new" color="primary" />
</a>
<QTable
class="full-width"
<VnCard v-if="invoiceIn.invoiceInDueDay.length" class="vn-two">
<template #header>
<VnCardSection :title="'invoiceIn.card.dueDay'"> </VnCardSection>
</template>
<template #body
><VnTable
:columns="dueDayColumns"
:rows="invoiceIn.invoiceInDueDay"
flat
hide-pagination
:has-summary="true"
:summary="{ amount: toCurrency(invoiceIn.totals.totalDueDay) }"
>
<template #header="props">
<QTr :props="props" class="bg">
<QTh v-for="col in props.cols" :key="col.name" :props="props">
{{ t(col.label) }}
</QTh>
</QTr>
</VnTable>
</template>
<template #bottom-row>
<QTr class="bg">
<QTd></QTd>
<QTd></QTd>
<QTd>{{ toCurrency(invoiceIn.totals.totalDueDay) }}</QTd>
<QTd></QTd>
</QTr>
</template>
</QTable>
</QCard>
</VnCard>
<!--Intrastat-->
<QCard v-if="invoiceIn.invoiceInIntrastat.length">
<a class="header" :href="getUrl('intrastat')">
{{ t('invoiceIn.card.intrastat') }}
<QIcon name="open_in_new" color="primary" />
</a>
<QTable
<VnCard v-if="invoiceIn.invoiceInIntrastat.length">
<template #header>
<VnCardSection :title="'invoiceIn.card.intrastat'"> </VnCardSection>
</template>
<template #body
><VnTable
:columns="intrastatColumns"
:rows="invoiceIn.invoiceInIntrastat"
flat
hide-pagination
:has-summary="true"
:summary="{
amount: toCurrency(intrastatTotals.amount),
net: intrastatTotals.net,
stems: intrastatTotals.stems,
}"
>
<template #header="props">
<QTr :props="props" class="bg">
<QTh v-for="col in props.cols" :key="col.name" :props="props">
{{ t(col.label) }}
</QTh>
</QTr>
</VnTable>
</template>
<template #bottom-row>
<QTr class="bg">
<QTd></QTd>
<QTd>{{ toCurrency(intrastatTotals.amount) }}</QTd>
<QTd>{{ intrastatTotals.net }}</QTd>
<QTd>{{ intrastatTotals.stems }}</QTd>
<QTd></QTd>
</QTr>
</template>
</QTable>
</QCard>
</VnCard>
</template>
</CardSummary>
</template>
<style lang="scss" scoped>
.bg {
background-color: var(--vn-light-gray);
.q-card {
.vn-max {
background-color: unset;
}
.card-section {
display: flex;
flex-wrap: wrap;
row-gap: 10px;
column-gap: 10px;
.card {
flex: 1 1 30%;
width: 100%;
background-color: var(--vn-gray);
padding: 15px;
font-size: 16px;
min-width: 275px;
border-radius: 4px;
}
}
}
.bordered {
border: 1px solid var(--vn-text);
max-width: 18em;

View File

@ -11,6 +11,7 @@ import VnLv from 'src/components/ui/VnLv.vue';
import CardList from 'src/components/ui/CardList.vue';
import InvoiceInFilter from './InvoiceInFilter.vue';
import { getUrl } from 'src/composables/getUrl';
import in18n from './in18n';
import InvoiceInSummary from './Card/InvoiceInSummary.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
@ -18,7 +19,7 @@ const stateStore = useStateStore();
const router = useRouter();
const { viewSummary } = useSummaryDialog();
let url = ref();
const { t } = useI18n();
const { t } = useI18n(in18n);
onMounted(async () => {
stateStore.rightDrawer = true;
@ -36,7 +37,7 @@ function navigate(id) {
<Teleport to="#searchbar">
<VnSearchbar
data-key="InvoiceInList"
:label="t('Search invoice')"
:label="t('searchInvoice')"
:info="t('You can search by invoice reference')"
/>
</Teleport>
@ -148,6 +149,13 @@ function navigate(id) {
</QPageSticky>
</template>
<style lang="scss" scoped>
.card-list {
width: 100%;
max-width: 60em;
}
</style>
<i18n>
es:
Search invoice: Buscar factura recibida

View File

@ -0,0 +1,8 @@
{
"es": {
"searchInvoice": "Buscar factura emitida"
},
"en": {
"searchInvoice": "Seaasdrch invoice"
}
}

View File

@ -0,0 +1,3 @@
{
"searchInvoice": "Seaasdrch invoice"
}

View File

@ -0,0 +1,3 @@
{
"searchInvoice": "Buasdscar factura emitida"
}

View File

@ -0,0 +1,19 @@
// OPTION 1
import en from './i18n/en.json';
import es from './i18n/es.json';
// OPTION 2
import _messages from './i18n.json';
// OPTION 3
const messages = {
en: {
searchInvoice: 'Search invoice',
},
es: {
searchInvoice: 'Buscar factura emitida',
},
};
export default {
messages: _messages,
};

View File

@ -6,6 +6,7 @@ import { QCheckbox, QBtn } from 'quasar';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
import InvoiceOutNegativeFilter from './InvoiceOutNegativeBasesFilter.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import VnTeleport from 'components/ui/VnTeleport.vue';
import { toCurrency } from 'src/filters';
import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js';
@ -217,9 +218,16 @@ const selectWorkerId = (id) => {
<template>
<template v-if="stateStore.isHeaderMounted()">
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
<QBtn color="primary" icon-right="archive" no-caps @click="downloadCSV()" />
</Teleport>
<VnTeleport>
<template #st-actions>
<QBtn
color="primary"
icon-right="archive"
no-caps
@click="downloadCSV()"
/>
</template>
</VnTeleport>
</template>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
<QScrollArea class="fit text-grey-8">

View File

@ -8,16 +8,17 @@ import FetchedTags from 'components/ui/FetchedTags.vue';
import SendEmailDialog from 'components/common/SendEmailDialog.vue';
import SupplierConsumptionFilter from './SupplierConsumptionFilter.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import VnTeleport from 'components/ui/VnTeleport.vue';
import { toDate } from 'src/filters';
import { dashIfEmpty } from 'src/filters';
import { usePrintService } from 'composables/usePrintService';
import useNotify from 'src/composables/useNotify.js';
import axios from 'axios';
import { useStateStore } from 'stores/useStateStore';
// import { useStateStore } from 'stores/useStateStore';
import { useArrayData } from 'composables/useArrayData';
const stateStore = useStateStore();
// const stateStore = useStateStore();
const { t } = useI18n();
const route = useRoute();
const { openReport, sendEmail } = usePrintService();
@ -115,7 +116,8 @@ onMounted(async () => {
</script>
<template>
<Teleport to="#st-actions" v-if="stateStore.isSubToolbarShown()">
<VnTeleport>
<template #st-actions>
<QBtn
:disabled="!dateRanges.from && !dateRanges.to"
color="primary"
@ -139,7 +141,8 @@ onMounted(async () => {
{{ t('Send to email') }}
</QTooltip>
</QBtn>
</Teleport>
</template>
</VnTeleport>
<QPage class="column items-center q-pa-md">
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>

View File

@ -2,7 +2,7 @@
import { useI18n } from 'vue-i18n';
import { reactive, ref, onBeforeMount } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import VnTeleport from 'components/ui/VnTeleport.vue';
import FetchData from 'components/FetchData.vue';
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import VnSelectDialog from 'components/common/VnSelectDialog.vue';
@ -11,7 +11,7 @@ import VnInput from 'src/components/common/VnInput.vue';
import CreateThermographForm from 'src/components/CreateThermographForm.vue';
import { useState } from 'src/composables/useState';
import { useStateStore } from 'stores/useStateStore';
// import { useStateStore } from 'stores/useStateStore';
import axios from 'axios';
import useNotify from 'src/composables/useNotify.js';
@ -22,7 +22,7 @@ const props = defineProps({
},
});
const stateStore = useStateStore();
// const stateStore = useStateStore();
const { t } = useI18n();
const route = useRoute();
const router = useRouter();
@ -214,7 +214,8 @@ const onThermographCreated = async (data) => {
class="full-width"
style="max-width: 800px"
>
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
<VnTeleport>
<template #st-actions>
<div>
<QBtnGroup push class="q-gutter-x-sm">
<slot name="moreActions" />
@ -233,7 +234,8 @@ const onThermographCreated = async (data) => {
/>
</QBtnGroup>
</div>
</Teleport>
</template>
</VnTeleport>
<QCard class="q-pa-lg">
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">

View File

@ -0,0 +1,75 @@
import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
import { createWrapper } from 'app/test/vitest/helper';
import VnBtn from 'src/components/common/VnBtn.vue';
describe('VnBtn', () => {
let vm;
beforeAll(() => {
vm = createWrapper(VnBtn, {
global: {
stubs: ['FetchData', 'VnPaginate'],
mocks: {
fetch: vi.fn(),
},
},
propsData: {
model: 'Claim',
},
}).vm;
});
afterEach(() => {
vi.clearAllMocks();
});
describe('formatValue()', () => {
it('should return Yes if has a true boolean', async () => {
const result = vm.formatValue(true);
expect(result).toEqual('Yes');
});
it('should return No if has a true boolean', async () => {
const result = vm.formatValue(false);
expect(result).toEqual('No');
});
it('should return Nothing if has no params', async () => {
const result = vm.formatValue();
expect(result).toEqual('Nothing');
});
it('should return a string from a string value', async () => {
const result = vm.formatValue('Something');
expect(result).toEqual(`"Something"`);
});
it('should call to format a date', async () => {
vi.mock('src/filters', () => ({
toDate: () => {
return 'Date formatted';
},
}));
const result = vm.formatValue('01-01-1970');
expect(result).toEqual('Date formatted');
});
});
describe('actionColor()', () => {
it('should return positive if insert', async () => {
const result = vm.actionColor('insert');
expect(result).toEqual('positive');
});
it('should return positive if update', async () => {
const result = vm.actionColor('update');
expect(result).toEqual('positive');
});
it('should return negative if delete', async () => {
const result = vm.actionColor('delete');
expect(result).toEqual('negative');
});
});
});

View File

@ -0,0 +1,75 @@
import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
import { createWrapper } from 'app/test/vitest/helper';
import VnCard from 'src/components/common/VnCard.vue';
describe('VnCard', () => {
let vm;
beforeAll(() => {
vm = createWrapper(VnCard, {
global: {
stubs: ['FetchData', 'VnPaginate'],
mocks: {
fetch: vi.fn(),
},
},
propsData: {
model: 'Claim',
},
}).vm;
});
afterEach(() => {
vi.clearAllMocks();
});
describe('formatValue()', () => {
it('should return Yes if has a true boolean', async () => {
const result = vm.formatValue(true);
expect(result).toEqual('Yes');
});
it('should return No if has a true boolean', async () => {
const result = vm.formatValue(false);
expect(result).toEqual('No');
});
it('should return Nothing if has no params', async () => {
const result = vm.formatValue();
expect(result).toEqual('Nothing');
});
it('should return a string from a string value', async () => {
const result = vm.formatValue('Something');
expect(result).toEqual(`"Something"`);
});
it('should call to format a date', async () => {
vi.mock('src/filters', () => ({
toDate: () => {
return 'Date formatted';
},
}));
const result = vm.formatValue('01-01-1970');
expect(result).toEqual('Date formatted');
});
});
describe('actionColor()', () => {
it('should return positive if insert', async () => {
const result = vm.actionColor('insert');
expect(result).toEqual('positive');
});
it('should return positive if update', async () => {
const result = vm.actionColor('update');
expect(result).toEqual('positive');
});
it('should return negative if delete', async () => {
const result = vm.actionColor('delete');
expect(result).toEqual('negative');
});
});
});

View File

@ -0,0 +1,75 @@
import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
import { createWrapper } from 'app/test/vitest/helper';
import VnCardSection from 'src/components/common/VnCardSection.vue';
describe('VnCardSection', () => {
let vm;
beforeAll(() => {
vm = createWrapper(VnCardSection, {
global: {
stubs: ['FetchData', 'VnPaginate'],
mocks: {
fetch: vi.fn(),
},
},
propsData: {
model: 'Claim',
},
}).vm;
});
afterEach(() => {
vi.clearAllMocks();
});
describe('formatValue()', () => {
it('should return Yes if has a true boolean', async () => {
const result = vm.formatValue(true);
expect(result).toEqual('Yes');
});
it('should return No if has a true boolean', async () => {
const result = vm.formatValue(false);
expect(result).toEqual('No');
});
it('should return Nothing if has no params', async () => {
const result = vm.formatValue();
expect(result).toEqual('Nothing');
});
it('should return a string from a string value', async () => {
const result = vm.formatValue('Something');
expect(result).toEqual(`"Something"`);
});
it('should call to format a date', async () => {
vi.mock('src/filters', () => ({
toDate: () => {
return 'Date formatted';
},
}));
const result = vm.formatValue('01-01-1970');
expect(result).toEqual('Date formatted');
});
});
describe('actionColor()', () => {
it('should return positive if insert', async () => {
const result = vm.actionColor('insert');
expect(result).toEqual('positive');
});
it('should return positive if update', async () => {
const result = vm.actionColor('update');
expect(result).toEqual('positive');
});
it('should return negative if delete', async () => {
const result = vm.actionColor('delete');
expect(result).toEqual('negative');
});
});
});

View File

@ -0,0 +1,75 @@
import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
import { createWrapper } from 'app/test/vitest/helper';
import VnChip from 'src/components/common/VnChip.vue';
describe('VnChip', () => {
let vm;
beforeAll(() => {
vm = createWrapper(VnChip, {
global: {
stubs: ['FetchData', 'VnPaginate'],
mocks: {
fetch: vi.fn(),
},
},
propsData: {
model: 'Claim',
},
}).vm;
});
afterEach(() => {
vi.clearAllMocks();
});
describe('formatValue()', () => {
it('should return Yes if has a true boolean', async () => {
const result = vm.formatValue(true);
expect(result).toEqual('Yes');
});
it('should return No if has a true boolean', async () => {
const result = vm.formatValue(false);
expect(result).toEqual('No');
});
it('should return Nothing if has no params', async () => {
const result = vm.formatValue();
expect(result).toEqual('Nothing');
});
it('should return a string from a string value', async () => {
const result = vm.formatValue('Something');
expect(result).toEqual(`"Something"`);
});
it('should call to format a date', async () => {
vi.mock('src/filters', () => ({
toDate: () => {
return 'Date formatted';
},
}));
const result = vm.formatValue('01-01-1970');
expect(result).toEqual('Date formatted');
});
});
describe('actionColor()', () => {
it('should return positive if insert', async () => {
const result = vm.actionColor('insert');
expect(result).toEqual('positive');
});
it('should return positive if update', async () => {
const result = vm.actionColor('update');
expect(result).toEqual('positive');
});
it('should return negative if delete', async () => {
const result = vm.actionColor('delete');
expect(result).toEqual('negative');
});
});
});

View File

@ -0,0 +1,75 @@
import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
import { createWrapper } from 'app/test/vitest/helper';
import VnTable from 'src/components/common/VnTable.vue';
describe('VnTable', () => {
let vm;
beforeAll(() => {
vm = createWrapper(VnTable, {
global: {
stubs: ['FetchData', 'VnPaginate'],
mocks: {
fetch: vi.fn(),
},
},
propsData: {
model: 'Claim',
},
}).vm;
});
afterEach(() => {
vi.clearAllMocks();
});
describe('formatValue()', () => {
it('should return Yes if has a true boolean', async () => {
const result = vm.formatValue(true);
expect(result).toEqual('Yes');
});
it('should return No if has a true boolean', async () => {
const result = vm.formatValue(false);
expect(result).toEqual('No');
});
it('should return Nothing if has no params', async () => {
const result = vm.formatValue();
expect(result).toEqual('Nothing');
});
it('should return a string from a string value', async () => {
const result = vm.formatValue('Something');
expect(result).toEqual(`"Something"`);
});
it('should call to format a date', async () => {
vi.mock('src/filters', () => ({
toDate: () => {
return 'Date formatted';
},
}));
const result = vm.formatValue('01-01-1970');
expect(result).toEqual('Date formatted');
});
});
describe('actionColor()', () => {
it('should return positive if insert', async () => {
const result = vm.actionColor('insert');
expect(result).toEqual('positive');
});
it('should return positive if update', async () => {
const result = vm.actionColor('update');
expect(result).toEqual('positive');
});
it('should return negative if delete', async () => {
const result = vm.actionColor('delete');
expect(result).toEqual('negative');
});
});
});