diff --git a/src/components/VnTable/VnChip.vue b/src/components/VnTable/VnChip.vue index 74207b943..f70ba7423 100644 --- a/src/components/VnTable/VnChip.vue +++ b/src/components/VnTable/VnChip.vue @@ -35,7 +35,9 @@ function stopEventPropagation(event) { dense square > - <span v-if="!col.chip.icon">{{ row[col.name] }}</span> + <span v-if="!col.chip.icon"> + {{ col.format ? col.format(row) : row[col.name] }} + </span> <QIcon v-else :name="col.chip.icon" color="primary-light" /> </QChip> </span> diff --git a/src/components/VnTable/VnColumn.vue b/src/components/VnTable/VnColumn.vue index 3af58226f..9f6c6d53d 100644 --- a/src/components/VnTable/VnColumn.vue +++ b/src/components/VnTable/VnColumn.vue @@ -147,7 +147,7 @@ const col = computed(() => { } if ( (newColumn.name.startsWith('is') || newColumn.name.startsWith('has')) && - !newColumn.component + newColumn.component == null ) newColumn.component = 'checkbox'; if ($props.default && !newColumn.component) newColumn.component = $props.default; diff --git a/src/components/VnTable/VnFilter.vue b/src/components/VnTable/VnFilter.vue index 285e2338e..e1faec0a0 100644 --- a/src/components/VnTable/VnFilter.vue +++ b/src/components/VnTable/VnFilter.vue @@ -75,6 +75,7 @@ const components = { attrs: { ...defaultAttrs, clearable: true, + type: 'number', }, forceAttrs, }, diff --git a/src/components/VnTable/VnOrder.vue b/src/components/VnTable/VnOrder.vue index 1e1dc9e01..98c7ab392 100644 --- a/src/components/VnTable/VnOrder.vue +++ b/src/components/VnTable/VnOrder.vue @@ -1,7 +1,7 @@ <script setup> import { ref } from 'vue'; import { useArrayData } from 'composables/useArrayData'; -const model = defineModel({ type: Object, required: true }); +const model = defineModel({ type: Object }); const $props = defineProps({ name: { type: String, @@ -56,7 +56,7 @@ defineExpose({ orderBy }); <span :title="label">{{ label }}</span> <QChip v-if="name" - :label="!vertical && model?.index" + :label="!vertical ? model?.index : ''" :icon=" (model?.index || hover) && !vertical ? model?.direction == 'DESC' diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index 686f56135..15cf39bd6 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -96,9 +96,9 @@ const route = useRoute(); const router = useRouter(); const quasar = useQuasar(); -const DEFAULT_MODE = 'card'; +const CARD_MODE = 'card'; const TABLE_MODE = 'table'; -const mode = ref(DEFAULT_MODE); +const mode = ref(CARD_MODE); const selected = ref([]); const hasParams = ref(false); const routeQuery = JSON.parse(route?.query[$props.searchUrl] ?? '{}'); @@ -118,7 +118,7 @@ const tableModes = [ { icon: 'grid_view', title: t('grid view'), - value: DEFAULT_MODE, + value: CARD_MODE, disable: $props.disableOption?.card, }, ]; @@ -128,7 +128,10 @@ onBeforeMount(() => { }); onMounted(() => { - mode.value = quasar.platform.is.mobile ? DEFAULT_MODE : $props.defaultMode; + mode.value = + quasar.platform.is.mobile && !$props.disableOption?.card + ? CARD_MODE + : $props.defaultMode; stateStore.rightDrawer = true; columnsVisibilitySkiped.value = [ ...splittedColumns.value.columns @@ -230,6 +233,7 @@ function stopEventPropagation(event) { } function reload(params) { + selected.value = []; CrudModelRef.value.reload(params); } @@ -383,7 +387,7 @@ defineExpose({ /> </template> <template #header-cell="{ col }"> - <QTh v-if="col.visible ?? true" auto-width> + <QTh v-if="col.visible ?? true"> <div class="column self-start q-ml-xs ellipsis" :class="`text-${col?.align ?? 'left'}`" @@ -408,6 +412,7 @@ defineExpose({ :data-key="$attrs['data-key']" v-model="params[columnName(col)]" :search-url="searchUrl" + class="full-width" /> </div> </QTh> @@ -432,7 +437,7 @@ defineExpose({ <QTd auto-width class="no-margin q-px-xs" - :class="[getColAlign(col), col.class, col.columnField?.class]" + :class="[getColAlign(col), col.columnClass]" v-if="col.visible ?? true" @click.ctrl=" ($event) => @@ -460,6 +465,7 @@ defineExpose({ > <QBtn v-for="(btn, index) of col.actions" + v-show="btn.show ? btn.show(row) : true" :key="index" :title="btn.title" :icon="btn.icon" diff --git a/src/components/common/VnComponent.vue b/src/components/common/VnComponent.vue index d7719034a..f512b846a 100644 --- a/src/components/common/VnComponent.vue +++ b/src/components/common/VnComponent.vue @@ -17,15 +17,17 @@ const $props = defineProps({ }, }); +let mixed; const componentArray = computed(() => { if (typeof $props.prop === 'object') return [$props.prop]; return $props.prop; }); function mix(toComponent) { + if (mixed) return mixed; const { component, attrs, event } = toComponent; const customComponent = $props.components[component]; - return { + mixed = { component: customComponent?.component ?? component, attrs: { ...toValueAttrs(attrs), @@ -35,6 +37,7 @@ function mix(toComponent) { }, event: event ?? customComponent?.event, }; + return mixed; } function toValueAttrs(attrs) { diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index 3cba466a3..fdc1e9f9e 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -27,7 +27,7 @@ const $props = defineProps({ }, url: { type: String, - default: '', + default: null, }, filterOptions: { type: [Array], @@ -113,7 +113,7 @@ function setOptions(data) { } function filter(val, options) { - const search = val.toString().toLowerCase(); + const search = val?.toString()?.toLowerCase(); if (!search) return options; diff --git a/src/components/ui/VnRow.vue b/src/components/ui/VnRow.vue index a2f89ff3f..642adedf1 100644 --- a/src/components/ui/VnRow.vue +++ b/src/components/ui/VnRow.vue @@ -1,18 +1,28 @@ +<script setup> +defineProps({ wrap: { type: Boolean, default: false } }); +</script> <template> - <div class="vn-row q-gutter-md q-mb-md"> - <slot></slot> + <div class="vn-row q-gutter-md q-mb-md" :class="{ wrap }"> + <slot /> </div> </template> -<style lang="scss" scopped> +<style lang="scss" scoped> .vn-row { display: flex; - > * { - flex: 1; + &.wrap { + flex-wrap: wrap; + } + &:not(.wrap) { + > :slotted(*) { + flex: 1; + } } } @media screen and (max-width: 800px) { .vn-row { - flex-direction: column; + &:not(.wrap) { + flex-direction: column; + } } } </style> diff --git a/src/css/app.scss b/src/css/app.scss index 504718ff5..69861a80c 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -233,27 +233,23 @@ input::-webkit-inner-spin-button { } .q-table { - thead, - tbody { - th { - .q-select { - max-width: 120px; - } - } - td { - padding: 1px 10px 1px 10px; - max-width: 100px; - div span { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } + th, + td { + padding: 1px 10px 1px 10px; + max-width: 100px; + div span { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } - .expand { - max-width: 400px; - } + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + .shrink { + max-width: 75px; + } + .expand { + max-width: 400px; } } diff --git a/src/pages/Claim/ClaimList.vue b/src/pages/Claim/ClaimList.vue index 05698debe..8c5c6a3d0 100644 --- a/src/pages/Claim/ClaimList.vue +++ b/src/pages/Claim/ClaimList.vue @@ -44,7 +44,7 @@ const columns = computed(() => [ fields: ['id', 'name'], }, }, - class: 'expand', + columnClass: 'expand', }, { align: 'left', diff --git a/src/pages/Customer/Card/CustomerConsumption.vue b/src/pages/Customer/Card/CustomerConsumption.vue index 1ee771bf8..98a3115da 100644 --- a/src/pages/Customer/Card/CustomerConsumption.vue +++ b/src/pages/Customer/Card/CustomerConsumption.vue @@ -1,13 +1,14 @@ <script setup> import { useI18n } from 'vue-i18n'; - +import CustomerConsumptionFilter from './CustomerConsumptionFilter.vue'; +import { useStateStore } from 'src/stores/useStateStore'; const { t } = useI18n(); </script> <template> - <h5 class="flex justify-center color-vn-label"> - {{ t('Enter a new search') }} - </h5> + <Teleport to="#right-panel" v-if="useStateStore().isHeaderMounted()"> + <CustomerConsumptionFilter data-key="CustomerConsumption" /> + </Teleport> </template> <i18n> diff --git a/src/pages/Customer/Card/CustomerConsumptionFilter.vue b/src/pages/Customer/Card/CustomerConsumptionFilter.vue new file mode 100644 index 000000000..4d2c5ff3c --- /dev/null +++ b/src/pages/Customer/Card/CustomerConsumptionFilter.vue @@ -0,0 +1,91 @@ +<script setup> +import { useI18n } from 'vue-i18n'; +import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; +import VnInput from 'src/components/common/VnInput.vue'; +import { QItem } from 'quasar'; +import VnSelect from 'src/components/common/VnSelect.vue'; +import { QItemSection } from 'quasar'; + +const { t } = useI18n(); +defineProps({ dataKey: { type: String, required: true } }); +</script> +<template> + <VnFilterPanel :data-key="dataKey" :search-button="true"> + <template #tags="{ tag, formatFn }"> + <div class="q-gutter-x-xs"> + <strong>{{ t(`params.${tag.label}`) }}: </strong> + <span>{{ formatFn(tag.value) }}</span> + </div> + </template> + <template #body="{ params }"> + <QItem> + <QItemSection> + <VnInput + :label="t('params.item')" + v-model="params.itemId" + is-outlined + lazy-rules + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnSelect + v-model="params.buyerId" + url="TicketRequests/getItemTypeWorker" + :label="t('params.buyer')" + option-value="id" + option-label="nickname" + dense + outlined + rounded + /> + </QItemSection> + </QItem> + <QItem> + <!--It's required to include the relation category !! There's 413 records in production--> + <QItemSection> + <VnSelect + v-model="params.typeId" + url="ItemTypes" + :label="t('params.type')" + option-label="name" + option-value="id" + dense + outlined + rounded + > + </VnSelect> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnSelect + url="ItemCategories" + :label="t('params.category')" + option-label="name" + option-value="id" + v-model="params.categoryId" + dense + outlined + rounded + /> + </QItemSection> + </QItem> + </template> + </VnFilterPanel> +</template> +<i18n> +en: + params: + item: Item id + buyer: Buyer + type: Type + category: Category +es: + params: + item: Id artículo + buyer: Comprador + type: Tipo + category: Categoría +</i18n> diff --git a/src/pages/Customer/Card/CustomerCredits.vue b/src/pages/Customer/Card/CustomerCredits.vue index 755ba3b9a..b93e1f340 100644 --- a/src/pages/Customer/Card/CustomerCredits.vue +++ b/src/pages/Customer/Card/CustomerCredits.vue @@ -1,20 +1,14 @@ <script setup> -import { computed, ref } from 'vue'; +import { computed } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRoute, useRouter } from 'vue-router'; - +import { useRoute } from 'vue-router'; import { QBtn } from 'quasar'; - import { toCurrency, toDateHourMin } from 'src/filters'; - -import FetchData from 'components/FetchData.vue'; -import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; +import VnTable from 'components/VnTable/VnTable.vue'; +import VnUserLink from 'src/components/ui/VnUserLink.vue'; const { t } = useI18n(); const route = useRoute(); -const router = useRouter(); - -const rows = ref([]); const filter = { include: [ @@ -26,113 +20,63 @@ const filter = { }, }, ], - where: { clientFk: route.params.id }, + where: { clientFk: +route.params.id }, order: ['created DESC'], limit: 20, }; -const tableColumnComponents = { - created: { - component: 'span', - props: () => {}, - event: () => {}, - }, - employee: { - component: QBtn, - props: () => ({ flat: true, color: 'blue', noCaps: true }), - event: () => {}, - }, - amount: { - component: 'span', - props: () => {}, - event: () => {}, - }, -}; - const columns = computed(() => [ { align: 'left', - field: 'created', - label: t('Since'), name: 'created', - format: (value) => toDateHourMin(value), + label: t('Since'), + format: ({ created }) => toDateHourMin(created), }, { align: 'left', - field: (value) => value.worker.user.name, label: t('Employee'), name: 'employee', }, { align: 'left', - field: 'amount', label: t('Credit'), name: 'amount', - format: (value) => toCurrency(value), + format: ({ amount }) => toCurrency(amount), }, ]); - -const toCustomerCreditCreate = () => { - router.push({ name: 'CustomerCreditCreate' }); -}; </script> - <template> - <FetchData - :filter="filter" - @on-fetch="(data) => (rows = data)" - auto-load + <!-- Column titles are missing --> + <VnTable + ref="tableRef" + data-key="ClientCredit" url="ClientCredits" - /> - - <div class="full-width flex justify-center"> - <QCard class="card-width q-pa-lg"> - <QTable - :columns="columns" - :pagination="{ rowsPerPage: 12 }" - :rows="rows" - class="full-width q-mt-md" - row-key="id" - v-if="rows?.length" - > - <template #body-cell="props"> - <QTd :props="props"> - <QTr :props="props" class="cursor-pointer"> - <component - :is="tableColumnComponents[props.col.name].component" - @click=" - tableColumnComponents[props.col.name].event(props) - " - class="rounded-borders q-pa-sm" - v-bind=" - tableColumnComponents[props.col.name].props(props) - " - > - {{ props.value }} - <WorkerDescriptorProxy - :id="props.row.workerFk" - v-if="props.col.name === 'employee'" - /> - </component> - </QTr> - </QTd> - </template> - </QTable> - - <h5 class="flex justify-center color-vn-label" v-else> - {{ t('globals.noResults') }} - </h5> - </QCard> - </div> - + :filter="filter" + :columns="columns" + default-mode="table" + auto-load + :right-search="false" + :is-editable="false" + :use-model="true" + :column-search="false" + :disable-option="{ card: true }" + > + <template #column-employee="{ row }"> + <VnUserLink :name="row?.worker?.user?.name" :worker-id="row.worker?.id" /> + </template> + </VnTable> <QPageSticky :offset="[18, 18]"> - <QBtn @click.stop="toCustomerCreditCreate()" color="primary" fab icon="add" /> + <QBtn + @click.stop="$router.push({ name: 'CustomerCreditCreate' })" + color="primary" + fab + icon="add" + /> <QTooltip> {{ t('New credit') }} </QTooltip> </QPageSticky> </template> - <i18n> es: Since: Desde diff --git a/src/pages/Customer/Card/CustomerSummary.vue b/src/pages/Customer/Card/CustomerSummary.vue index 86de5217e..15bf19b48 100644 --- a/src/pages/Customer/Card/CustomerSummary.vue +++ b/src/pages/Customer/Card/CustomerSummary.vue @@ -9,7 +9,7 @@ import VnLv from 'src/components/ui/VnLv.vue'; import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue'; import CustomerSummaryTable from 'src/pages/Customer/components/CustomerSummaryTable.vue'; import VnTitle from 'src/components/common/VnTitle.vue'; - +import VnRow from 'src/components/ui/VnRow.vue'; const route = useRoute(); const { t } = useI18n(); @@ -131,41 +131,33 @@ const creditWarning = computed(() => { :url="`#/customer/${entityId}/fiscal-data`" :text="t('customer.summary.fiscalData')" /> - <QCheckbox - :label="t('customer.summary.isEqualizated')" - v-model="entity.isEqualizated" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.isActive')" - v-model="entity.isActive" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.invoiceByAddress')" - v-model="entity.hasToInvoiceByAddress" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.verifiedData')" - v-model="entity.isTaxDataChecked" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.hasToInvoice')" - v-model="entity.hasToInvoice" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.notifyByEmail')" - v-model="entity.isToBeMailed" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.vies')" - v-model="entity.isVies" - :disable="true" - /> + <VnRow> + <VnLv + :label="t('customer.summary.isEqualizated')" + :value="entity.isEqualizated" + /> + <VnLv + :label="t('customer.summary.isActive')" + :value="entity.isActive" + /> + </VnRow> + <VnRow> + <VnLv + :label="t('customer.summary.verifiedData')" + :value="entity.isTaxDataChecked" + /> + <VnLv + :label="t('customer.summary.hasToInvoice')" + :value="entity.hasToInvoice" + /> + </VnRow> + <VnRow> + <VnLv + :label="t('customer.summary.notifyByEmail')" + :value="entity.isToBeMailed" + /> + <VnLv :label="t('customer.summary.vies')" :value="entity.isVies" /> + </VnRow> </QCard> <QCard class="vn-one"> <VnTitle @@ -178,23 +170,18 @@ const creditWarning = computed(() => { /> <VnLv :label="t('customer.summary.bankAccount')" :value="entity.iban" /> <VnLv :label="t('customer.summary.dueDay')" :value="entity.dueDay" /> - <QCheckbox - style="padding: 0" - :label="t('customer.summary.hasLcr')" - v-model="entity.hasLcr" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.hasCoreVnl')" - v-model="entity.hasCoreVnl" - :disable="true" - /> + <VnRow class="q-mt-sm" wrap> + <VnLv :label="t('customer.summary.hasLcr')" :value="entity.hasLcr" /> + <VnLv + :label="t('customer.summary.hasCoreVnl')" + :value="entity.hasCoreVnl" + /> - <QCheckbox - :label="t('customer.summary.hasB2BVnl')" - v-model="entity.hasSepaVnl" - :disable="true" - /> + <VnLv + :label="t('customer.summary.hasB2BVnl')" + :value="entity.hasSepaVnl" + /> + </VnRow> </QCard> <QCard class="vn-one" v-if="entity.defaultAddress"> <VnTitle diff --git a/src/pages/Customer/CustomerList.vue b/src/pages/Customer/CustomerList.vue index a9e4d978e..a82f1fc0e 100644 --- a/src/pages/Customer/CustomerList.vue +++ b/src/pages/Customer/CustomerList.vue @@ -42,9 +42,7 @@ const columns = computed(() => [ name: 'name', isTitle: true, create: true, - columnField: { - class: 'expand', - }, + columnClass: 'expand', }, { align: 'left', @@ -52,9 +50,7 @@ const columns = computed(() => [ label: t('customer.extendedList.tableVisibleColumns.socialName'), isTitle: true, create: true, - columnField: { - class: 'expand', - }, + columnClass: 'expand', }, { align: 'left', @@ -136,9 +132,7 @@ const columns = computed(() => [ columnFilter: { inWhere: true, }, - columnField: { - class: 'expand', - }, + columnClass: 'expand', }, { align: 'left', diff --git a/src/pages/Customer/Defaulter/CustomerDefaulter.vue b/src/pages/Customer/Defaulter/CustomerDefaulter.vue index 693b016fb..11f6362f8 100644 --- a/src/pages/Customer/Defaulter/CustomerDefaulter.vue +++ b/src/pages/Customer/Defaulter/CustomerDefaulter.vue @@ -1,9 +1,8 @@ <script setup> import { ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; -import { QBtn, QCheckbox, useQuasar } from 'quasar'; +import { useQuasar } from 'quasar'; import { toCurrency, toDate, dateRange } from 'filters/index'; -import VnPaginate from 'src/components/ui/VnPaginate.vue'; import CustomerNotificationsFilter from './CustomerDefaulterFilter.vue'; import CustomerBalanceDueTotal from './CustomerBalanceDueTotal.vue'; import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue'; @@ -11,8 +10,9 @@ import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.v import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnInput from 'src/components/common/VnInput.vue'; import CustomerDefaulterAddObservation from './CustomerDefaulterAddObservation.vue'; -import axios from 'axios'; +import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue'; import RightMenu from 'src/components/common/RightMenu.vue'; +import VnTable from 'src/components/VnTable/VnTable.vue'; const { t } = useI18n(); const quasar = useQuasar(); @@ -21,175 +21,139 @@ const dataRef = ref(null); const balanceDueTotal = ref(0); const selected = ref([]); -const tableColumnComponents = { - clientFk: { - component: QBtn, - props: () => ({ flat: true, class: 'link', noCaps: true }), - event: () => {}, - }, - isWorker: { - component: QCheckbox, - props: (prop) => ({ - disable: true, - 'model-value': Boolean(prop.value), - }), - event: () => {}, - }, - salesPerson: { - component: QBtn, - props: () => ({ flat: true, class: 'link', noCaps: true }), - event: () => {}, - }, - departmentName: { - component: 'span', - props: () => {}, - event: () => {}, - }, - country: { - component: 'span', - props: () => {}, - event: () => {}, - }, - payMethod: { - component: 'span', - props: () => {}, - event: () => {}, - }, - balance: { - component: 'span', - props: () => {}, - event: () => {}, - }, - author: { - component: QBtn, - props: () => ({ flat: true, class: 'link', noCaps: true }), - event: () => {}, - }, - lastObservation: { - component: 'span', - props: () => {}, - event: () => {}, - }, - date: { - component: 'span', - props: () => {}, - event: () => {}, - }, - credit: { - component: 'span', - props: () => {}, - event: () => {}, - }, - from: { - component: 'span', - props: () => {}, - event: () => {}, - }, - finished: { - component: QCheckbox, - - props: (prop) => ({ - disable: true, - 'model-value': prop.value, - }), - event: () => {}, - }, -}; - const columns = computed(() => [ { align: 'left', - field: 'clientName', - label: t('Client'), name: 'clientFk', - sortable: true, + label: t('Client'), + columnFilter: { + component: 'select', + attrs: { + url: 'Clients', + fields: ['id', 'name'], + }, + }, }, { align: 'left', - field: ({ isWorker }) => Boolean(isWorker), - label: t('Is worker'), name: 'isWorker', + label: t('Is worker'), }, { align: 'left', - field: 'salesPersonName', + name: 'salesPersonFk', label: t('Salesperson'), - name: 'salesPerson', - sortable: true, + columnFilter: { + component: 'select', + attrs: { + url: 'Workers/activeWithInheritedRole', + fields: ['id', 'name'], + where: { role: 'salesPerson' }, + useLike: false, + optionValue: 'id', + optionLabel: 'name', + optionFilter: 'firstName', + }, + }, }, { align: 'left', - field: 'departmentName', + name: 'departmentFk', label: t('Department'), - name: 'departmentName', - sortable: true, + columnFilter: { + component: 'select', + attrs: { + url: 'Departments', + fields: ['id', 'name'], + }, + }, }, { align: 'left', - field: 'country', + name: 'countryFk', label: t('Country'), - name: 'country', - sortable: true, + format: ({ country }) => country, + columnFilter: { + component: 'select', + attrs: { + url: 'Countries', + fields: ['id', 'name'], + }, + }, }, { align: 'left', - field: 'payMethod', - label: t('P. Method'), name: 'payMethod', - sortable: true, - tooltip: t('Pay method'), + label: t('P. Method'), + columnFilter: { + component: 'select', + attrs: { + url: 'Paymethods', + }, + }, }, { align: 'left', - field: ({ amount }) => toCurrency(amount), + name: 'amount', label: t('Balance D.'), - name: 'balance', - sortable: true, - tooltip: t('Balance due'), + format: ({ amount }) => toCurrency(amount), }, { align: 'left', - field: 'workerName', + name: 'workerFk', label: t('Author'), - name: 'author', - sortable: true, tooltip: t('Worker who made the last observation'), + columnFilter: { + component: 'select', + attrs: { + url: 'Workers/activeWithInheritedRole', + fields: ['id', 'name'], + useLike: false, + optionValue: 'id', + optionLabel: 'name', + optionFilter: 'firstName', + }, + }, }, { align: 'left', - field: 'observation', + name: 'observation', label: t('Last observation'), - name: 'lastObservation', - sortable: true, + columnClass: 'expand', }, { align: 'left', - field: ({ created }) => toDate(created), + name: 'created', label: t('L. O. Date'), - name: 'date', - sortable: true, + format: ({ created }) => toDate(created), tooltip: t('Last observation date'), + columnFilter: { + component: 'date', + }, }, { align: 'left', - field: ({ creditInsurance }) => toCurrency(creditInsurance), + name: 'creditInsurance', + format: ({ creditInsurance }) => toCurrency(creditInsurance), label: t('Credit I.'), - name: 'credit', - sortable: true, tooltip: t('Credit insurance'), + columnFilter: { + component: 'number', + }, }, { align: 'left', - field: ({ defaulterSinced }) => toDate(defaulterSinced), + name: 'defaulterSinced', + format: ({ defaulterSinced }) => toDate(defaulterSinced), label: t('From'), - name: 'from', - sortable: true, + columnFilter: { + component: 'date', + }, }, { align: 'left', - field: 'finished', - label: t('Has recover'), - name: 'finished', + label: t('Has recovery'), + name: 'hasRecovery', }, ]); @@ -198,22 +162,12 @@ const viewAddObservation = (rowsSelected) => { component: CustomerDefaulterAddObservation, componentProps: { clients: rowsSelected, - promise: async () => await dataRef.value.fetch(), + promise: async () => await dataRef.value.reload(), }, }); }; const onFetch = async (data) => { - const recoveryData = await axios.get('Recoveries'); - const recoveries = recoveryData.data.map(({ clientFk, finished }) => ({ - clientFk, - finished, - })); - - data.forEach((item) => { - const recovery = recoveries.find(({ clientFk }) => clientFk === item.clientFk); - item.finished = recovery?.finished === null; - }); balanceDueTotal.value = data.reduce((acc, { amount = 0 }) => acc + amount, 0); }; @@ -229,7 +183,7 @@ function exprBuilder(param, value) { case 'payMethod': case 'salesPersonFk': return { [`d.${param}`]: value }; - case 'date': + case 'created': return { 'd.created': { between: dateRange(value) } }; case 'defaulterSinced': return { 'd.defaulterSinced': { between: dateRange(value) } }; @@ -246,123 +200,64 @@ function exprBuilder(param, value) { <VnSubToolbar> <template #st-data> <CustomerBalanceDueTotal :amount="balanceDueTotal" /> - <div class="flex items-center q-ml-lg"> - <QBtn - color="primary" - icon="vn:notes" - :disabled="!selected.length" - @click.stop="viewAddObservation(selected)" - > - <QTooltip>{{ t('Add observation') }}</QTooltip> - </QBtn> - </div> + </template> + <template #st-actions> + <QBtn + color="primary" + icon="vn:notes" + :disabled="!selected.length" + @click.stop="viewAddObservation(selected)" + > + <QTooltip>{{ t('Add observation') }}</QTooltip> + </QBtn> </template> </VnSubToolbar> - <QPage class="column items-center q-pa-md"> - <VnPaginate - ref="dataRef" - @on-fetch="onFetch" - data-key="CustomerDefaulter" - :filter="filter" - :expr-builder="exprBuilder" - auto-load - url="Defaulters/filter" - > - <template #body="{ rows }"> - <div class="q-pa-md"> - <QTable - :columns="columns" - :rows="rows" - class="full-width" - row-key="clientFk" - selection="multiple" - v-model:selected="selected" - > - <template #header="props"> - <QTr :props="props" class="bg" style="min-height: 200px"> - <QTh> - <QCheckbox v-model="props.selected" /> - </QTh> - <QTh - v-for="col in props.cols" - :key="col.name" - :props="props" - > - {{ t(col.label) }} - <QTooltip v-if="col.tooltip">{{ - col.tooltip - }}</QTooltip> - </QTh> - </QTr> - </template> - - <template #body-cell="props"> - <QTd :props="props"> - <QTr :props="props" class="cursor-pointer"> - <component - :is=" - tableColumnComponents[props.col.name] - .component - " - class="col-content" - v-bind=" - tableColumnComponents[props.col.name].props( - props - ) - " - @click=" - tableColumnComponents[props.col.name].event( - props - ) - " - > - <template v-if="typeof props.value !== 'boolean'"> - <div - v-if=" - props.col.name === 'lastObservation' - " - > - <VnInput - type="textarea" - v-model="props.value" - readonly - dense - rows="2" - /> - </div> - <div v-else>{{ props.value }}</div> - </template> - - <WorkerDescriptorProxy - :id="props.row.salesPersonFk" - v-if="props.col.name === 'salesPerson'" - /> - <WorkerDescriptorProxy - :id="props.row.workerFk" - v-if="props.col.name === 'author'" - /> - <CustomerDescriptorProxy - :id="props.row.clientFk" - v-if="props.col.name === 'client'" - /> - </component> - </QTr> - </QTd> - </template> - </QTable> - </div> - </template> - </VnPaginate> - </QPage> + <VnTable + ref="dataRef" + data-key="CustomerDefaulter" + url="Defaulters/filter" + :expr-builder="exprBuilder" + :columns="columns" + @on-fetch="onFetch" + :use-model="true" + :table="{ + 'row-key': 'clientFk', + selection: 'multiple', + }" + v-model:selected="selected" + :disable-option="{ card: true }" + auto-load + :order="['amount DESC']" + > + <template #column-clientFk="{ row }"> + <span class="link" @click.stop> + {{ row.clientName }} + <CustomerDescriptorProxy :id="row.clientFk" /> + </span> + </template> + <template #column-observation="{ row }"> + <VnInput type="textarea" v-model="row.observation" readonly dense rows="2" /> + </template> + <template #column-salesPersonFk="{ row }"> + <span class="link" @click.stop> + {{ row.salesPersonName }} + <WorkerDescriptorProxy :id="row.salesPersonFk" /> + </span> + </template> + <template #column-departmentFk="{ row }"> + <span class="link" @click.stop> + {{ row.departmentName }} + <DepartmentDescriptorProxy :id="row.departmentFk" /> + </span> + </template> + <template #column-workerFk="{ row }"> + <span class="link" @click.stop> + {{ row.workerName }} + <WorkerDescriptorProxy :id="row.workerFk" /> + </span> + </template> + </VnTable> </template> - -<style lang="scss" scoped> -.col-content { - border-radius: 4px; - padding: 6px; -} -</style> - <i18n> es: Add observation: Añadir observación @@ -383,4 +278,5 @@ es: Credit I.: Crédito A. Credit insurance: Crédito asegurado From: Desde + Has recovery: Tiene recobro </i18n> diff --git a/src/pages/Customer/Notifications/CustomerNotifications.vue b/src/pages/Customer/Notifications/CustomerNotifications.vue index 2b816b5d0..ce18739b4 100644 --- a/src/pages/Customer/Notifications/CustomerNotifications.vue +++ b/src/pages/Customer/Notifications/CustomerNotifications.vue @@ -1,92 +1,92 @@ <script setup> import { ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; -import { QBtn } from 'quasar'; -import CustomerNotificationsFilter from './CustomerNotificationsFilter.vue'; import CustomerDescriptorProxy from '../Card/CustomerDescriptorProxy.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; -import VnPaginate from 'src/components/ui/VnPaginate.vue'; import CustomerNotificationsCampaignConsumption from './CustomerNotificationsCampaignConsumption.vue'; -import RightMenu from 'src/components/common/RightMenu.vue'; +import VnTable from 'src/components/VnTable/VnTable.vue'; const { t } = useI18n(); +const dataKey = 'CustomerNotifications'; const selected = ref([]); -const selectedCustomerId = ref(0); - -const tableColumnComponents = { - id: { - component: QBtn, - props: () => ({ flat: true, color: 'blue' }), - event: (prop) => selectCustomerId(prop.row.id), - }, - socialName: { - component: 'span', - props: () => {}, - event: () => {}, - }, - city: { - component: 'span', - props: () => {}, - event: () => {}, - }, - phone: { - component: 'span', - props: () => {}, - event: () => {}, - }, - email: { - component: 'span', - props: () => {}, - event: () => {}, - }, -}; - const columns = computed(() => [ { align: 'left', - field: 'id', label: t('Identifier'), name: 'id', + columnClass: 'shrink', }, { align: 'left', - field: 'socialName', label: t('Social name'), name: 'socialName', + columnFilter: { + component: 'select', + attrs: { + url: 'Clients', + fields: ['id', 'socialName'], + optionLabel: 'socialName', + }, + }, + columnClass: 'expand', + isTitle: true, }, { align: 'left', - field: 'city', label: t('City'), name: 'city', + columnFilter: { + component: 'select', + attrs: { + url: 'Towns', + }, + }, + cardVisible: true, }, { align: 'left', - field: 'phone', label: t('Phone'), name: 'phone', + cardVisible: true, }, { align: 'left', - field: 'email', label: t('Email'), name: 'email', + cardVisible: true, + }, + { + align: 'left', + name: 'fi', + label: t('Fi'), + visible: false, + }, + { + align: 'left', + name: 'postcode', + label: t('Postcode'), + visible: false, + }, + { + align: 'left', + label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'), + name: 'salesPersonFk', + component: 'select', + attrs: { + url: 'Workers/activeWithInheritedRole', + fields: ['id', 'name'], + where: { role: 'salesPerson' }, + optionFilter: 'firstName', + useLike: false, + }, + visible: false, }, ]); - -const selectCustomerId = (id) => { - selectedCustomerId.value = id; -}; </script> <template> - <RightMenu> - <template #right-panel> - <CustomerNotificationsFilter data-key="CustomerNotifications" /> - </template> - </RightMenu> <VnSubToolbar class="justify-end"> - <template #st-data> + <template #st-actions> <CustomerNotificationsCampaignConsumption :selected-rows="selected.length > 0" :clients="selected" @@ -94,51 +94,26 @@ const selectCustomerId = (id) => { /> </template> </VnSubToolbar> - <QPage class="column items-center q-pa-md"> - <VnPaginate data-key="CustomerNotifications" url="Clients" auto-load> - <template #body="{ rows }"> - <div class="q-pa-md"> - <QTable - :columns="columns" - :rows="rows" - class="full-width q-mt-md" - row-key="id" - selection="multiple" - v-model:selected="selected" - > - <template #body-cell="props"> - <QTd :props="props"> - <QTr :props="props" class="cursor-pointer"> - <component - :is=" - tableColumnComponents[props.col.name] - .component - " - class="col-content" - v-bind=" - tableColumnComponents[props.col.name].props( - props - ) - " - @click=" - tableColumnComponents[props.col.name].event( - props - ) - " - > - {{ props.value }} - <CustomerDescriptorProxy - :id="selectedCustomerId" - /> - </component> - </QTr> - </QTd> - </template> - </QTable> - </div> - </template> - </VnPaginate> - </QPage> + <VnTable + :data-key="dataKey" + url="Clients" + :table="{ + 'row-key': 'id', + selection: 'multiple', + }" + v-model:selected="selected" + :right-search="true" + :columns="columns" + :use-model="true" + auto-load + > + <template #column-id="{ row }"> + <span class="link"> + {{ row.id }} + <CustomerDescriptorProxy :id="row.id" /> + </span> + </template> + </VnTable> </template> <style lang="scss" scoped> diff --git a/src/pages/Customer/Notifications/CustomerNotificationsFilter.vue b/src/pages/Customer/Notifications/CustomerNotificationsFilter.vue deleted file mode 100644 index a7c8635e7..000000000 --- a/src/pages/Customer/Notifications/CustomerNotificationsFilter.vue +++ /dev/null @@ -1,145 +0,0 @@ -<script setup> -import { ref } from 'vue'; -import { useI18n } from 'vue-i18n'; - -import FetchData from 'components/FetchData.vue'; -import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; -import VnInput from 'src/components/common/VnInput.vue'; -import VnSelect from 'components/common/VnSelect.vue'; - -const { t } = useI18n(); -const props = defineProps({ - dataKey: { - type: String, - required: true, - }, -}); - -const cities = ref(); -const clients = ref(); -</script> - -<template> - <FetchData - :filter="{ where: { role: 'socialName' } }" - @on-fetch="(data) => (clients = data)" - auto-load - url="Clients" - /> - <FetchData @on-fetch="(data) => (cities = data)" auto-load url="Towns" /> - <VnFilterPanel :data-key="props.dataKey" :search-button="true"> - <template #tags="{ tag, formatFn }"> - <div class="q-gutter-x-xs"> - <strong>{{ t(`params.${tag.label}`) }}: </strong> - <span>{{ formatFn(tag.value) }}</span> - </div> - </template> - - <template #body="{ params, searchFn }"> - <QItem class="q-mb-sm q-mt-sm"> - <QItemSection> - <VnInput - :label="t('Identifier')" - clearable - is-outlined - v-model="params.identifier" - /> - </QItemSection> - </QItem> - - <QItem class="q-mb-sm"> - <QItemSection v-if="!clients"> - <QSkeleton type="QInput" class="full-width" /> - </QItemSection> - <QItemSection v-if="clients"> - <VnSelect - :input-debounce="0" - :label="t('Social name')" - :options="clients" - @update:model-value="searchFn()" - dense - emit-value - hide-selected - map-options - option-label="socialName" - option-value="socialName" - outlined - rounded - use-input - v-model="params.socialName" - /> - </QItemSection> - </QItem> - - <QItem class="q-mb-sm"> - <QItemSection v-if="!cities"> - <QSkeleton type="QInput" class="full-width" /> - </QItemSection> - <QItemSection v-if="cities"> - <VnSelect - :input-debounce="0" - :label="t('City')" - :options="cities" - @update:model-value="searchFn()" - dense - emit-value - hide-selected - map-options - option-label="name" - option-value="name" - outlined - rounded - use-input - v-model="params.city" - /> - </QItemSection> - </QItem> - - <QItem class="q-mb-sm"> - <QItemSection> - <VnInput - :label="t('Phone')" - clearable - is-outlined - v-model="params.phone" - /> - </QItemSection> - </QItem> - - <QItem class="q-mb-sm"> - <QItemSection> - <VnInput - :label="t('Email')" - clearable - is-outlined - type="email" - v-model="params.email" - /> - </QItemSection> - </QItem> - <QSeparator /> - </template> - </VnFilterPanel> -</template> - -<i18n> -en: - params: - identifier: Identifier - socialName: Social name - city: City - phone: Phone - email: Email -es: - params: - identifier: Identificador - socialName: Razón social - city: Población - phone: Teléfono - email: Email - Identifier: Identificador - Social name: Razón social - City: Población - Phone: Teléfono - Email: Email -</i18n> diff --git a/src/pages/Customer/Payments/CustomerPayments.vue b/src/pages/Customer/Payments/CustomerPayments.vue index cd2642c57..25dfcc58a 100644 --- a/src/pages/Customer/Payments/CustomerPayments.vue +++ b/src/pages/Customer/Payments/CustomerPayments.vue @@ -1,19 +1,18 @@ <script setup> import axios from 'axios'; -import { ref, computed } from 'vue'; +import { computed } from 'vue'; import { useI18n } from 'vue-i18n'; import { useQuasar } from 'quasar'; -import { useArrayData } from 'composables/useArrayData'; -import VnPaginate from 'components/ui/VnPaginate.vue'; +import { toDate, toCurrency } from 'filters/index'; + +import VnTable from 'src/components/VnTable/VnTable.vue'; import VnConfirm from 'components/ui/VnConfirm.vue'; import CustomerDescriptorProxy from '../Card/CustomerDescriptorProxy.vue'; -import { toDate, toCurrency } from 'filters/index'; import CustomerPaymentsFilter from './CustomerPaymentsFilter.vue'; import RightMenu from 'src/components/common/RightMenu.vue'; const quasar = useQuasar(); const { t } = useI18n(); -const arrayData = useArrayData('CustomerTransactions'); async function confirm(transaction) { quasar @@ -36,59 +35,73 @@ async function confirmTransaction({ id }) { }); } -const grid = ref(false); const columns = computed(() => [ { name: 'id', label: t('Transaction ID'), - field: (row) => row.id, - sortable: true, - }, - { - name: 'customerId', - label: t('Customer ID'), - field: (row) => row.clientFk, - align: 'right', - sortable: true, - }, - { - name: 'customer', - label: t('Customer Name'), - field: (row) => row.customerName, - }, - { - name: 'state', - label: t('State'), - field: (row) => row.isConfirmed, - format: (value) => (value ? t('Confirmed') : t('Unconfirmed')), + isTitle: true, align: 'left', - sortable: true, + columnFilter: { + inWhere: true, + alias: 't', + }, + columnClass: 'shrink', }, { - name: 'dated', + align: 'left', + name: 'clientFk', + label: t('Customer'), + columnFilter: { + component: 'select', + attrs: { + url: 'Clients', + fields: ['id', 'name'], + }, + }, + columnClass: 'expand', + cardVisible: true, + }, + { + name: 'isConfirmed', + label: t('State'), + align: 'left', + format: ({ isConfirmed }) => (isConfirmed ? t('Confirmed') : t('Unconfirmed')), + chip: { + condition: () => true, + color: ({ isConfirmed }) => (isConfirmed ? 'bg-positive' : 'bg-primary'), + }, + visible: false, + }, + { + name: 'created', label: t('Dated'), - field: (row) => toDate(row.created), - sortable: true, + format: ({ created }) => toDate(created), + columnFilter: false, + cardVisible: true, }, { name: 'amount', label: t('Amount'), - field: (row) => row.amount, - format: (value) => toCurrency(value), - sortable: true, + format: ({ amount }) => toCurrency(amount), + columnFilter: { + component: 'number', + }, + cardVisible: true, }, { - name: 'actions', - label: t('Actions'), - grid: false, + align: 'right', + name: 'tableActions', + actions: [ + { + title: t('Confirm transaction'), + icon: 'check', + action: (row) => confirm(row), + show: ({ isConfirmed }) => !isConfirmed, + isPrimary: true, + }, + ], }, ]); -const isLoading = computed(() => arrayData.isLoading.value); - -function stateColor(row) { - if (row.isConfirmed) return 'positive'; - return 'primary'; -} </script> <template> @@ -97,158 +110,22 @@ function stateColor(row) { <CustomerPaymentsFilter data-key="CustomerTransactions" /> </template> </RightMenu> - <QPage class="column items-center q-pa-md customer-payments"> - <div class="vn-card-list"> - <QToolbar class="q-pa-none justify-end"> - <QBtn - @click="arrayData.refresh()" - :loading="isLoading" - icon="refresh" - color="primary" - class="q-mr-sm" - round - dense - /> - <QBtn @click="grid = !grid" icon="list" color="primary" round dense> - <QTooltip>{{ t('Change view') }}</QTooltip> - </QBtn> - </QToolbar> - <VnPaginate - data-key="CustomerTransactions" - url="Clients/transactions" - order="created DESC" - :limit="20" - :offset="50" - :auto-load="!!$route?.query.params" - > - <template #body="{ rows }"> - <QTable - :dense="$q.screen.lt.md" - :columns="columns" - :rows="rows" - row-key="id" - :grid="grid || $q.screen.lt.sm" - class="q-mt-xs custom-table" - > - <template #body-cell-actions="{ row }"> - <QTd auto-width class="text-center"> - <QBtn - v-if="!row.isConfirmed" - icon="check" - @click="confirm(row)" - color="primary" - size="md" - round - flat - dense - > - <QTooltip>{{ t('Confirm transaction') }}</QTooltip> - </QBtn> - </QTd> - </template> - <template #body-cell-id="{ row }"> - <QTd auto-width align="right"> - <span> - {{ row.id }} - </span> - </QTd> - </template> - <template #body-cell-customerId="{ row }"> - <QTd align="right"> - <span class="link"> - {{ row.clientFk }} - <CustomerDescriptorProxy :id="row.clientFk" /> - </span> - </QTd> - </template> - <template #body-cell-customer="{ row }"> - <QTd auto-width align="left" :title="row.customerName"> - <span> - {{ row.customerName }} - </span> - </QTd> - </template> - <template #body-cell-state="{ row }"> - <QTd auto-width class="text-center"> - <QBadge text-color="black" :color="stateColor(row)"> - {{ - row.isConfirmed - ? t('Confirmed') - : t('Unconfirmed') - }} - </QBadge> - </QTd> - </template> - <template #item="{ cols, row }"> - <div class="q-mb-md col-12"> - <QCard class="q-pa-none"> - <QItem class="q-pa-none items-start"> - <QItemSection class="q-pa-none"> - <QList> - <template - v-for="col of cols" - :key="col.name" - > - <QItem - v-if="col.grid !== false" - class="q-pa-none" - > - <QItemSection> - <QItemLabel caption> - {{ col.label }} - </QItemLabel> - <QItemLabel - v-if="col.name == 'state'" - > - <QBadge - text-color="black" - :color=" - stateColor(row) - " - > - {{ col.value }} - </QBadge> - </QItemLabel> - <QItemLabel - v-if="col.name != 'state'" - > - {{ col.value }} - </QItemLabel> - </QItemSection> - </QItem> - </template> - </QList> - </QItemSection> - <template v-if="!row.isConfirmed"> - <QSeparator vertical /> - <QCardActions - vertical - class="justify-between" - > - <QBtn - icon="check" - @click="confirm(row)" - color="primary" - size="md" - round - flat - dense - > - <QTooltip> - {{ t('Confirm transaction') }} - </QTooltip> - </QBtn> - </QCardActions> - </template> - </QItem> - </QCard> - </div> - </template> - </QTable> - </template> - </VnPaginate> - </div> - </QPage> + <VnTable + data-key="CustomerTransactions" + url="Clients/transactions" + order="created DESC" + :columns="columns" + :right-search="false" + auto-load + > + <template #column-clientFk="{ row }"> + <span class="link"> + {{ row.clientFk }} - + {{ row.customerName }} + <CustomerDescriptorProxy :id="row.clientFk" /> + </span> + </template> + </VnTable> </template> <style lang="scss"> @@ -269,14 +146,11 @@ es: Web Payments: Pagos Web Confirm transaction: Confirmar transacción Transaction ID: ID transacción - Customer ID: ID cliente - Customer Name: Nombre cliente + Customer: cliente State: Estado Dated: Fecha Amount: Importe - Actions: Acciones Confirmed: Confirmada Unconfirmed: Sin confirmar - Change view: Cambiar vista Payment confirmed: Pago confirmado </i18n> diff --git a/src/pages/Customer/components/CustomerNewPayment.vue b/src/pages/Customer/components/CustomerNewPayment.vue index cc92d7907..9acb6af3a 100644 --- a/src/pages/Customer/components/CustomerNewPayment.vue +++ b/src/pages/Customer/components/CustomerNewPayment.vue @@ -11,10 +11,12 @@ import VnRow from 'components/ui/VnRow.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import VnInput from 'src/components/common/VnInput.vue'; - +import { useState } from 'src/composables/useState'; const { t } = useI18n(); const route = useRoute(); const { dialogRef } = useDialogPluginComponent(); +const state = useState(); +const user = state.getUser(); const $props = defineProps({ companyId: { @@ -55,12 +57,12 @@ const filterClientFindOne = { id: route.params.id, }, }; - const initialData = reactive({ amountPaid: $props.totalCredit, clientFk: route.params.id, companyFk: $props.companyId, email: clientFindOne.value.email, + bankFk: user.value.localBankFk, }); onBeforeMount(() => { diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue index d8bee4714..11c36c22d 100644 --- a/src/pages/Worker/Card/WorkerSummary.vue +++ b/src/pages/Worker/Card/WorkerSummary.vue @@ -10,6 +10,7 @@ import CardSummary from 'components/ui/CardSummary.vue'; import VnUserLink from 'src/components/ui/VnUserLink.vue'; import VnTitle from 'src/components/common/VnTitle.vue'; import RoleDescriptorProxy from 'src/pages/Account/Role/Card/RoleDescriptorProxy.vue'; +import VnRow from 'src/components/ui/VnRow.vue'; const route = useRoute(); const { t } = useI18n(); @@ -133,30 +134,24 @@ const filter = { /> <VnLv :label="t('worker.summary.fi')" :value="worker.fi" /> <VnLv :label="t('worker.summary.birth')" :value="toDate(worker.birth)" /> - <QCheckbox - class="padding-none" - :label="t('worker.summary.isFreelance')" - v-model="worker.isFreelance" - :disable="true" - /> - <QCheckbox - class="padding-none" - :label="t('worker.summary.isSsDiscounted')" - v-model="worker.isSsDiscounted" - :disable="true" - /> - <QCheckbox - class="padding-none" - :label="t('worker.summary.hasMachineryAuthorized')" - v-model="worker.hasMachineryAuthorized" - :disable="true" - /> - <QCheckbox - class="padding-none" - :label="t('worker.summary.isDisable')" - v-model="worker.isDisable" - :disable="true" - /> + <VnRow class="q-mt-sm" wrap> + <VnLv + :label="t('worker.summary.isFreelance')" + :value="worker.isFreelance" + /> + <VnLv + :label="t('worker.summary.isSsDiscounted')" + :value="worker.isSsDiscounted" + /> + <VnLv + :label="t('worker.summary.hasMachineryAuthorized')" + :value="worker.hasMachineryAuthorized" + /> + <VnLv + :label="t('worker.summary.isDisable')" + :value="worker.isDisable" + /> + </VnRow> </QCard> <QCard class="vn-one"> <VnTitle :text="t('worker.summary.userData')" /> diff --git a/test/vitest/__tests__/pages/Customer/CustomerPayments.spec.js b/test/vitest/__tests__/pages/Customer/CustomerPayments.spec.js index 13293f596..466a544b4 100644 --- a/test/vitest/__tests__/pages/Customer/CustomerPayments.spec.js +++ b/test/vitest/__tests__/pages/Customer/CustomerPayments.spec.js @@ -35,18 +35,4 @@ describe('CustomerPayments', () => { ); }); }); - - describe('stateColor()', () => { - it('should return "positive" when isConfirmed property is truthy', async () => { - const result = await vm.stateColor({ isConfirmed: true }); - - expect(result).toEqual('positive'); - }); - - it('should return "primary" when isConfirmed property is falsy', async () => { - const result = await vm.stateColor({ isConfirmed: false }); - - expect(result).toEqual('primary'); - }); - }); });