#8944: New date filter and make section use salix's back #1750

Open
jon wants to merge 18 commits from 8944-FixedPriceChanges into dev
6 changed files with 101 additions and 42 deletions

View File

@ -102,6 +102,10 @@ const $props = defineProps({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
customMethod: {
type: String,
default: null,
},
}); });
const emit = defineEmits(['onFetch', 'onDataSaved', 'submit']); const emit = defineEmits(['onFetch', 'onDataSaved', 'submit']);
const modelValue = computed( const modelValue = computed(
@ -237,7 +241,9 @@ async function save() {
const url = const url =
$props.urlCreate || $props.urlUpdate || $props.url || arrayData.store.url; $props.urlCreate || $props.urlUpdate || $props.url || arrayData.store.url;
const response = await Promise.resolve( const response = await Promise.resolve(
$props.saveFn ? $props.saveFn(body) : axios[method](url, body), $props.saveFn
? $props.saveFn(body)
: axios[$props.customMethod ?? method](url, body),
); );
if ($props.urlCreate) notify('globals.dataCreated', 'positive'); if ($props.urlCreate) notify('globals.dataCreated', 'positive');

View File

@ -896,6 +896,7 @@ components:
rate3: Packing price rate3: Packing price
minPrice: Min. Price minPrice: Min. Price
itemFk: Item id itemFk: Item id
dated: Date
userPanel: userPanel:
copyToken: Token copied to clipboard copyToken: Token copied to clipboard
settings: Settings settings: Settings

View File

@ -980,6 +980,7 @@ components:
rate3: Precio packing rate3: Precio packing
minPrice: Precio mínimo minPrice: Precio mínimo
itemFk: Id item itemFk: Id item
dated: Fecha
userPanel: userPanel:
copyToken: Token copiado al portapapeles copyToken: Token copiado al portapapeles
settings: Configuración settings: Configuración

View File

@ -1,9 +1,11 @@
<script setup> <script setup>
import { onMounted, ref, onUnmounted, computed, watch } from 'vue'; import { onMounted, ref, onUnmounted, computed, watch } from 'vue';
import axios from 'axios';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
import { beforeSave } from 'src/composables/updateMinPriceBeforeSave'; import { beforeSave } from 'src/composables/updateMinPriceBeforeSave';
import FetchedTags from 'components/ui/FetchedTags.vue'; import FetchedTags from 'components/ui/FetchedTags.vue';
@ -14,13 +16,13 @@ import RightMenu from 'src/components/common/RightMenu.vue';
import VnTable from 'src/components/VnTable/VnTable.vue'; import VnTable from 'src/components/VnTable/VnTable.vue';
import VnColor from 'src/components/common/VnColor.vue'; import VnColor from 'src/components/common/VnColor.vue';
import { toDate } from 'src/filters'; import { toDate, toCurrency } from 'src/filters';
import { isLower, isBigger } from 'src/filters/date.js'; import { isLower, isBigger } from 'src/filters/date.js';
import ItemFixedPriceFilter from './ItemFixedPriceFilter.vue'; import ItemFixedPriceFilter from './ItemFixedPriceFilter.vue';
import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue'; import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue';
import { toCurrency } from 'src/filters';
const stateStore = useStateStore(); const stateStore = useStateStore();
const quasar = useQuasar();
const { t } = useI18n(); const { t } = useI18n();
const tableRef = ref(); const tableRef = ref();
const editFixedPriceForm = ref(null); const editFixedPriceForm = ref(null);
@ -218,11 +220,36 @@ const dateStyle = (date) =>
} }
: { color: dateColor, 'background-color': 'transparent' }; : { color: dateColor, 'background-color': 'transparent' };
const onDataSaved = () => { const onDataSaved = async (data) => {
tableRef.value.CrudModelRef.saveChanges(); for (const row of data) {
await axios.patch('FixedPrices/upsertFixedPrice', row);
}
selectedRows.value = []; selectedRows.value = [];
tableRef.value.reload();
tableRef.value.CrudModelRef.reset();
}; };
async function saveData(data, getChanges) {
const changes = getChanges();
if (changes?.updates?.length) {
for (const change of changes.updates) {
const row = data.find((row) => row.id === change.where.id);
await axios.patch('FixedPrices/upsertFixedPrice', row);
}
}
if (data?.deletes?.length) {
for (const deleteItem of data.deletes) {
await axios.delete(`FixedPrices/${deleteItem}`);
quasar.notify({
message: t('globals.dataDeleted'),
color: 'positive',
});
}
}
tableRef.value.reload();
}
onMounted(() => { onMounted(() => {
if (tableRef.value) { if (tableRef.value) {
tableRef.value.showForm = false; tableRef.value.showForm = false;
@ -273,7 +300,8 @@ watch(
data-key="ItemFixedPrices" data-key="ItemFixedPrices"
url="FixedPrices/filter" url="FixedPrices/filter"
:order="'name DESC'" :order="'name DESC'"
save-url="FixedPrices/crud" save-url="FixedPrices/upsertFixedPrice"
:saveFn="saveData"
:columns="columns" :columns="columns"
:is-editable="true" :is-editable="true"
:right-search="false" :right-search="false"
@ -283,7 +311,8 @@ watch(
}" }"
v-model:selected="selectedRows" v-model:selected="selectedRows"
:create="{ :create="{
urlCreate: 'FixedPrices', urlCreate: 'FixedPrices/upsertFixedPrice',
customMethod: 'patch',
title: t('Create fixed price'), title: t('Create fixed price'),
formInitialData: { warehouseFk: warehouse }, formInitialData: { warehouseFk: warehouse },
onDataSaved: () => tableRef.reload(), onDataSaved: () => tableRef.reload(),

View File

@ -3,6 +3,7 @@ import { useI18n } from 'vue-i18n';
import VnInputDate from 'src/components/common/VnInputDate.vue'; import VnInputDate from 'src/components/common/VnInputDate.vue';
import VnSelect from 'components/common/VnSelect.vue'; import VnSelect from 'components/common/VnSelect.vue';
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
import ItemsFilterPanel from 'src/components/ItemsFilterPanel.vue'; import ItemsFilterPanel from 'src/components/ItemsFilterPanel.vue';
const { t } = useI18n(); const { t } = useI18n();
@ -51,42 +52,41 @@ const props = defineProps({
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
<QSeparator />
<QItemSection>
<QIcon name="info" size="sm" class="info-icon cursor-pointer">
<QTooltip>{{ t('params.incompatibleFilters') }}</QTooltip>
</QIcon>
<QItem> <QItem>
<QItemSection> <QItemSection>
<VnInputDate <VnInputDate
v-model="params.started" v-model="params.dated"
:label="t('params.started')" :label="t('params.date')"
filled filled
@update:model-value="searchFn()"
/>
</QItemSection>
<QItemSection>
<VnInputDate
v-model="params.ended"
:label="t('params.ended')"
filled
@update:model-value="searchFn()"
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem> <QItem>
<QItemSection> <QItemSection>
jon marked this conversation as resolved
Review

VnCheckbox

VnCheckbox
<QCheckbox <VnCheckbox
v-model="params.showBadDates"
:label="t(`params.showBadDates`)"
toggle-indeterminate
@update:model-value="searchFn()"
/>
</QItemSection>
</QItem>
</QItemSection>
<QSeparator />
<QItem>
<QItemSection>
<VnCheckbox
:label="t('params.mine')" :label="t('params.mine')"
v-model="params.mine" v-model="params.mine"
toggle-indeterminate toggle-indeterminate
@update:model-value="searchFn()" @update:model-value="searchFn()"
/> />
<VnCheckbox
<QCheckbox
v-model="params.showBadDates"
:label="t(`params.showBadDates`)"
toggle-indeterminate
@update:model-value="searchFn()"
>
</QCheckbox>
<QCheckbox
:label="t('params.hasMinPrice')" :label="t('params.hasMinPrice')"
v-model="params.hasMinPrice" v-model="params.hasMinPrice"
toggle-indeterminate toggle-indeterminate
@ -97,6 +97,13 @@ const props = defineProps({
</template> </template>
</ItemsFilterPanel> </ItemsFilterPanel>
</template> </template>
<style lang="scss" scoped>
.info-icon {
position: relative;
top: 0;
left: 90%;
}
</style>
<i18n> <i18n>
en: en:
params: params:
@ -107,6 +114,8 @@ en:
mine: Mine mine: Mine
showBadDates: Show future items showBadDates: Show future items
hasMinPrice: Has Min Price hasMinPrice: Has Min Price
date: Date
incompatibleFilters: Cannot select "Date" and "Show future items" at the same time
es: es:
params: params:
buyerFk: Comprador buyerFk: Comprador
@ -116,4 +125,6 @@ es:
mine: Para mi mine: Para mi
showBadDates: Ver items a futuro showBadDates: Ver items a futuro
hasMinPrice: Precio mínimo hasMinPrice: Precio mínimo
date: Fecha
incompatibleFilters: No se puede seleccionar "Fecha" y "Ver items a futuro" a la vez
</i18n> </i18n>

View File

@ -26,7 +26,6 @@ const $props = defineProps({
default: () => {}, default: () => {},
}, },
}); });
const { t } = useI18n(); const { t } = useI18n();
const emit = defineEmits(['onDataSaved']); const emit = defineEmits(['onDataSaved']);
@ -38,7 +37,7 @@ const inputs = {
select: markRaw(VnSelect), select: markRaw(VnSelect),
}; };
const newValue = ref(null); const newFieldValue = ref(null);
const selectedField = ref(null); const selectedField = ref(null);
const closeButton = ref(null); const closeButton = ref(null);
const isLoading = ref(false); const isLoading = ref(false);
@ -46,7 +45,11 @@ const isLoading = ref(false);
const onSubmit = async () => { const onSubmit = async () => {
isLoading.value = true; isLoading.value = true;
$props.rows.forEach((row) => { $props.rows.forEach((row) => {
row[selectedField.value.name] = newValue.value; const newValue =
selectedField.value.component === 'number'
? parseInt(newFieldValue.value)
: newFieldValue.value;
row[selectedField.value.name] = newValue;
}); });
emit('onDataSaved', $props.rows); emit('onDataSaved', $props.rows);
closeForm(); closeForm();
@ -77,11 +80,19 @@ const closeForm = () => {
data-cy="EditFixedPriceSelectOption" data-cy="EditFixedPriceSelectOption"
@update:model-value="newValue = null" @update:model-value="newValue = null"
:class="{ 'is-select': selectedField?.component === 'select' }" :class="{ 'is-select': selectedField?.component === 'select' }"
/> >
<template #option="{ opt, itemProps }">
<QItem v-bind="itemProps" class="q-pa-xs row items-center">
<QItemSection class="col-9 justify-center">
<span>{{ opt?.label }}</span>
</QItemSection>
</QItem>
</template>
</VnSelect>
<component <component
:is="inputs[selectedField?.component || 'input']" :is="inputs[selectedField?.component || 'input']"
v-bind="selectedField?.attrs || {}" v-bind="selectedField?.attrs || {}"
v-model="newValue" v-model="newFieldValue"
:label="t('Value')" :label="t('Value')"
data-cy="EditFixedPriceValueOption" data-cy="EditFixedPriceValueOption"
style="width: 200px" style="width: 200px"