diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index 63a3f088f..d4bbbc979 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -73,6 +73,10 @@ const $props = defineProps({ type: Boolean, default: true, }, + params: { + type: Object, + default: null, + }, }); const { t } = useI18n(); @@ -205,6 +209,7 @@ function nullishToTrue(value) { :limit="limit" :sort-by="sortBy" :fields="fields" + :params="params" /> <QSelect v-model="value" diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index 9059605ca..b3e002ebb 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -180,10 +180,10 @@ const tagsList = computed(() => { }); const tags = computed(() => { - return tagsList.value.filter((tag) => !($props.customTags || []).includes(tag.key)); + return tagsList.value.filter((tag) => !($props.customTags || []).includes(tag.label)); }); const customTags = computed(() => - tagsList.value.filter((tag) => ($props.customTags || []).includes(tag.key)) + tagsList.value.filter((tag) => ($props.customTags || []).includes(tag.label)) ); async function remove(key) { diff --git a/src/filters/dateRange.js b/src/filters/dateRange.js index 7aa2869e5..4c0cfe654 100644 --- a/src/filters/dateRange.js +++ b/src/filters/dateRange.js @@ -1,7 +1,7 @@ export default function dateRange(value) { const minHour = new Date(value); minHour.setHours(0, 0, 0, 0); - const maxHour = new Date(); + const maxHour = new Date(value); maxHour.setHours(23, 59, 59, 59); return [minHour, maxHour]; diff --git a/src/pages/Monitor/MonitorSaleClients.vue b/src/pages/Monitor/MonitorClients.vue similarity index 100% rename from src/pages/Monitor/MonitorSaleClients.vue rename to src/pages/Monitor/MonitorClients.vue diff --git a/src/pages/Monitor/MonitorClientsActions.vue b/src/pages/Monitor/MonitorClientsActions.vue index 87bcfe112..d6a72fbd9 100644 --- a/src/pages/Monitor/MonitorClientsActions.vue +++ b/src/pages/Monitor/MonitorClientsActions.vue @@ -1,6 +1,6 @@ <script setup> -import SalesClientTable from './MonitorSaleClients.vue'; -import SalesOrdersTable from './MonitorSaleOrders.vue'; +import SalesClientTable from './MonitorClients.vue'; +import SalesOrdersTable from './MonitorOrders.vue'; import VnRow from 'src/components/ui/VnRow.vue'; </script> <template> diff --git a/src/pages/Monitor/MonitorSaleOrders.vue b/src/pages/Monitor/MonitorOrders.vue similarity index 99% rename from src/pages/Monitor/MonitorSaleOrders.vue rename to src/pages/Monitor/MonitorOrders.vue index b10e50da6..9e8937c33 100644 --- a/src/pages/Monitor/MonitorSaleOrders.vue +++ b/src/pages/Monitor/MonitorOrders.vue @@ -191,7 +191,6 @@ const openTab = (id) => </template> <style lang="scss" scoped> .q-td { - color: gray; max-width: 140px; } </style> diff --git a/src/pages/Monitor/Ticket/MonitorTicketFilter.vue b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue new file mode 100644 index 000000000..ff9ea5e63 --- /dev/null +++ b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue @@ -0,0 +1,261 @@ +<script setup> +import { ref } from 'vue'; +import { useI18n } from 'vue-i18n'; + +import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; +import VnFilterPanelChip from 'src/components/ui/VnFilterPanelChip.vue'; +import VnSelect from 'src/components/common/VnSelect.vue'; +import VnInput from 'src/components/common/VnInput.vue'; +import VnInputNumber from 'src/components/common/VnInputNumber.vue'; +import FetchData from 'src/components/FetchData.vue'; + +defineProps({ dataKey: { type: String, required: true } }); +const { t } = useI18n(); +const warehouses = ref(); +const groupedStates = ref(); + +const handleScopeDays = (params, days, callback) => { + if (!days) { + Object.assign(params, { from: undefined, to: undefined, scopeDays: undefined }); + } else { + params.from = Date.vnNew(); + const to = Date.vnNew(); + to.setDate(to.getDate() + days); + to.setHours(23, 59, 59, 999); + params.to = to; + } + if (callback) callback(); +}; +</script> +<template> + <FetchData url="Warehouses" auto-load @on-fetch="(data) => (warehouses = data)" /> + <FetchData url="AlertLevels" auto-load @on-fetch="(data) => (groupedStates = data)" /> + <VnFilterPanel + :data-key="dataKey" + :search-button="true" + :hidden-tags="['from', 'to']" + :custom-tags="['scopeDays']" + > + <template #tags="{ tag, formatFn }"> + <div class="q-gutter-x-xs"> + <strong v-text="`${t(`params.${tag.label}`)}:`" /> + <span v-text="formatFn(tag.value)" /> + </div> + </template> + <template #customTags="{ params, searchFn, formatFn }"> + <VnFilterPanelChip + v-if="params.scopeDays" + removable + @remove="handleScopeDays(params, null, searchFn)" + > + <strong v-text="`${t(`params.scopeDays`)}:`" /> + <span v-text="formatFn(params.scopeDays)" /> + </VnFilterPanelChip> + </template> + <template #body="{ params }"> + <QItem> + <QItemSection> + <VnInput + :label="t('params.clientFk')" + v-model="params.clientFk" + is-outlined + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnInput + :label="t('params.orderFk')" + v-model="params.orderFk" + is-outlined + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <!-- Si se borran desde los tags no funciona--> + <VnInputNumber + :label="t('params.scopeDays')" + v-model="params.scopeDays" + is-outlined + @update:model-value="(val) => handleScopeDays(params, val)" + @remove="(val) => handleScopeDays(params, val)" + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnInput + :label="t('params.nickname')" + v-model="params.nickname" + is-outlined + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnSelect + outlined + dense + rounded + :label="t('params.salesPersonFk')" + v-model="params.salesPersonFk" + url="Workers/search" + :params="{ departmentCodes: ['VT'] }" + is-outlined + option-value="code" + option-label="nickname" + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnInput + :label="t('params.refFk')" + v-model="params.refFk" + is-outlined + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnSelect + outlined + dense + rounded + :label="t('params.agencyModeFk')" + v-model="params.agencyModeFk" + url="AgencyModes/isActive" + is-outlined + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnSelect + outlined + dense + rounded + :label="t('params.stateFk')" + v-model="params.stateFk" + url="States" + is-outlined + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnSelect + outlined + dense + rounded + :label="t('params.groupedStates')" + v-model="params.alertLevel" + :options="groupedStates" + option-label="code" + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnSelect + outlined + dense + rounded + :label="t('params.warehouseFk')" + v-model="params.warehouseFk" + :options="warehouses" + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnSelect + outlined + dense + rounded + :label="t('params.provinceFk')" + v-model="params.provinceFk" + url="Provinces" + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <QCheckbox + :label="t('params.myTeam')" + v-model="params.myTeam" + toggle-indeterminate + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <QCheckbox + :label="t('params.problems')" + v-model="params.problems" + toggle-indeterminate + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <QCheckbox + :label="t('params.pending')" + v-model="params.pending" + toggle-indeterminate + /> + </QItemSection> + </QItem> + </template> + </VnFilterPanel> +</template> +<i18n> +en: + params: + clientFk: Client id + orderFk: Order id + scopeDays: Days onward + nickname: Nickname + salesPersonFk: Sales person + refFk: Invoice + agencyModeFk: Agency + stateFk: State + groupedStates: Grouped State + warehouseFk: Warehouse + provinceFk: Province + myTeam: My team + problems: With problems + pending: Pending + from: From + to: To + FREE: Free + DELIVERED: Delivered + ON_PREPARATION: On preparation + ON_PREVIOUS: On previous + PACKED: Packed + +es: + params: + clientFk: Id cliente + orderFk: Id cesta + scopeDays: Días en adelante + nickname: Nombre mostrado + salesPersonFk: Comercial + refFk: Factura + agencyModeFk: Agencia + stateFk: Estado + groupedStates: Estado agrupado + warehouseFk: Almacén + provinceFk: Provincia + myTeam: Mi equipo + problems: Con problemas + pending: Pendiente + from: Desde + To: Hasta + FREE: Libre + DELIVERED: Servido + ON_PREPARATION: En preparación + ON_PREVIOUS: En previa + PACKED: Encajado +</i18n> diff --git a/src/pages/Monitor/Ticket/MonitorTicketSearchbar.vue b/src/pages/Monitor/Ticket/MonitorTicketSearchbar.vue new file mode 100644 index 000000000..4950ab381 --- /dev/null +++ b/src/pages/Monitor/Ticket/MonitorTicketSearchbar.vue @@ -0,0 +1,12 @@ +<script setup> +import VnSearchbar from 'components/ui/VnSearchbar.vue'; +</script> +<template> + <VnSearchbar + data-key="SalesMonitorTickets" + url="SalesMonitors/salesFilter" + :redirect="false" + :label="$t('searchBar.label')" + :info="$t('searchBar.info')" + /> +</template> diff --git a/src/pages/Monitor/MonitorTickets.vue b/src/pages/Monitor/Ticket/MonitorTickets.vue similarity index 96% rename from src/pages/Monitor/MonitorTickets.vue rename to src/pages/Monitor/Ticket/MonitorTickets.vue index a2ab65572..81e19be1e 100644 --- a/src/pages/Monitor/MonitorTickets.vue +++ b/src/pages/Monitor/Ticket/MonitorTickets.vue @@ -12,12 +12,12 @@ import VnTable from 'components/VnTable/VnTable.vue'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import { toDateFormat } from 'src/filters/date.js'; import { toCurrency, dateRange } from 'src/filters'; -import { useStateStore } from 'stores/useStateStore'; -import VnSearchbar from 'components/ui/VnSearchbar.vue'; +import RightMenu from 'src/components/common/RightMenu.vue'; +import MonitorTicketSearchbar from './MonitorTicketSearchbar.vue'; +import MonitorTicketFilter from './MonitorTicketFilter.vue'; const DEFAULT_AUTO_REFRESH = 2 * 60 * 1000; // 2min in ms const { t } = useI18n(); -const stateStore = useStateStore(); const autoRefresh = ref(false); const tableRef = ref(null); const provinceOpts = ref([]); @@ -325,23 +325,17 @@ const openTab = (id) => auto-load @on-fetch="(data) => (zoneOpts = data)" /> - <template v-if="stateStore.isHeaderMounted()"> - <Teleport to="#searchbar"> - <VnSearchbar - data-key="SalesMonitorTickets" - url="SalesMonitors/salesFilter" - :redirect="false" - :label="$t('searchBar.label')" - :info="$t('searchBar.info')" - /> - </Teleport> - </template> + <MonitorTicketSearchbar /> + <RightMenu> + <template #right-panel> + <MonitorTicketFilter data-key="saleMonitorTickets" /> + </template> + </RightMenu> <VnTable ref="tableRef" - data-key="SalesMonitorTickets" + data-key="saleMonitorTickets" url="SalesMonitors/salesFilter" - search-url="SalesMonitorTickets" - :limit="20" + search-url="saleMonitorTickets" :expr-builder="exprBuilder" :offset="50" :columns="columns" @@ -357,6 +351,7 @@ const openTab = (id) => icon="refresh" size="md" color="primary" + class="q-mr-sm" dense flat @click="$refs.tableRef.reload()" @@ -365,6 +360,7 @@ const openTab = (id) => v-model="autoRefresh" :label="$t('salesTicketsTable.autoRefresh')" @update:model-value="autoRefreshHandler" + dense > <QTooltip>{{ $t('refreshInfo') }}</QTooltip> </QCheckbox> diff --git a/src/router/modules/monitor.js b/src/router/modules/monitor.js index 904f2db74..9dc023c56 100644 --- a/src/router/modules/monitor.js +++ b/src/router/modules/monitor.js @@ -28,7 +28,8 @@ export default { title: 'ticketsMonitor', icon: 'grid_view', }, - component: () => import('src/pages/Monitor/MonitorTickets.vue'), + component: () => + import('src/pages/Monitor/Ticket/MonitorTickets.vue'), }, { path: 'clients-actions',