feat: #8217 implement onBeforeSave function for form data processing #1631
|
@ -1,6 +1,15 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { onMounted, onUnmounted, computed, ref, watch, nextTick, useAttrs } from 'vue';
|
import {
|
||||||
|
onMounted,
|
||||||
|
onUnmounted,
|
||||||
|
computed,
|
||||||
|
ref,
|
||||||
|
watch,
|
||||||
|
nextTick,
|
||||||
|
useAttrs,
|
||||||
|
toRef,
|
||||||
|
} from 'vue';
|
||||||
import { onBeforeRouteLeave, useRouter, useRoute } from 'vue-router';
|
import { onBeforeRouteLeave, useRouter, useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
|
@ -12,7 +21,7 @@ import SkeletonForm from 'components/ui/SkeletonForm.vue';
|
||||||
import VnConfirm from './ui/VnConfirm.vue';
|
import VnConfirm from './ui/VnConfirm.vue';
|
||||||
import { tMobile } from 'src/composables/tMobile';
|
import { tMobile } from 'src/composables/tMobile';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
import { getDifferences, getUpdatedValues } from 'src/filters';
|
import { onBeforeSave } from 'src/filters';
|
||||||
const { push } = useRouter();
|
const { push } = useRouter();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const state = useState();
|
const state = useState();
|
||||||
|
@ -67,7 +76,7 @@ const $props = defineProps({
|
||||||
},
|
},
|
||||||
mapper: {
|
mapper: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: null,
|
default: onBeforeSave,
|
||||||
},
|
},
|
||||||
clearStoreOnUnmount: {
|
clearStoreOnUnmount: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -140,6 +149,7 @@ const submitForm = async (evt) => {
|
||||||
await save(evt);
|
await save(evt);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const mapper = toRef($props, 'mapper');
|
||||||
|
|||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
nextTick(() => (componentIsRendered.value = true));
|
nextTick(() => (componentIsRendered.value = true));
|
||||||
|
@ -223,25 +233,8 @@ async function fetch() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function save() {
|
async function handleResponse(promise) {
|
||||||
if ($props.observeFormChanges && !hasChanges.value)
|
const response = await Promise.allSettled([promise]);
|
||||||
return notify('globals.noChanges', 'negative');
|
|
||||||
|
|
||||||
isLoading.value = true;
|
|
||||||
try {
|
|
||||||
formData.value = trimData(formData.value);
|
|
||||||
const body = $props.mapper
|
|
||||||
? $props.mapper(formData.value, originalData.value)
|
|
||||||
: formData.value;
|
|
||||||
const method = $props.urlCreate ? 'post' : 'patch';
|
|
||||||
const url =
|
|
||||||
$props.urlCreate || $props.urlUpdate || $props.url || arrayData.store.url;
|
|
||||||
const response = await Promise.resolve(
|
|
||||||
$props.saveFn ? $props.saveFn(body) : axios[method](url, body),
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($props.urlCreate) notify('globals.dataCreated', 'positive');
|
|
||||||
|
|
||||||
updateAndEmit('onDataSaved', {
|
updateAndEmit('onDataSaved', {
|
||||||
val: formData.value,
|
val: formData.value,
|
||||||
res: response?.data,
|
res: response?.data,
|
||||||
|
@ -249,6 +242,38 @@ async function save() {
|
||||||
});
|
});
|
||||||
if ($props.reload) await arrayData.fetch({});
|
if ($props.reload) await arrayData.fetch({});
|
||||||
hasChanges.value = false;
|
hasChanges.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function create() {
|
||||||
|
const promise = $props.saveFn
|
||||||
|
? $props.saveFn(formData.value)
|
||||||
|
: axios.post($props.urlCreate, formData.value);
|
||||||
|
|
||||||
|
await handleResponse(promise);
|
||||||
|
notify('globals.dataCreated', 'positive');
|
||||||
|
}
|
||||||
|
|
||||||
alexm
commented
La parte de la notificacion la pondria directamente aqui, y quitaria el if de La parte de la notificacion la pondria directamente aqui, y quitaria el if de `handleResponse`
jsegarra
commented
Hay una notificación que la he cambiado de sitio, no se si es la que tu dices Hay una notificación que la he cambiado de sitio, no se si es la que tu dices
|
|||||||
|
async function update() {
|
||||||
|
const body = mapper.value
|
||||||
|
? mapper.value(originalData.value, formData.value)
|
||||||
|
: formData.value;
|
||||||
|
const url = $props.urlUpdate || $props.url || arrayData.store.url;
|
||||||
|
const promise = $props.saveFn ? $props.saveFn(body) : axios.patch(url, body);
|
||||||
|
await handleResponse(promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function save() {
|
||||||
|
if ($props.observeFormChanges && !hasChanges.value)
|
||||||
|
return notify('globals.noChanges', 'negative');
|
||||||
|
|
||||||
|
isLoading.value = true;
|
||||||
|
try {
|
||||||
|
formData.value = trimData(formData.value);
|
||||||
|
if ($props.urlCreate) {
|
||||||
|
await create();
|
||||||
|
} else {
|
||||||
|
await update();
|
||||||
|
}
|
||||||
alexm
commented
`if ($props.urlCreate)` ?
|
|||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
|
@ -297,12 +322,7 @@ function trimData(data) {
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
function onBeforeSave(formData, originalData) {
|
|
||||||
return getUpdatedValues(
|
|
||||||
Object.keys(getDifferences(formData, originalData)),
|
|
||||||
formData,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
async function onKeyup(evt) {
|
async function onKeyup(evt) {
|
||||||
if (evt.key === 'Enter' && !$props.preventSubmit) {
|
if (evt.key === 'Enter' && !$props.preventSubmit) {
|
||||||
const input = evt.target;
|
const input = evt.target;
|
||||||
|
@ -333,16 +353,15 @@ defineExpose({
|
||||||
<template>
|
<template>
|
||||||
<div class="column items-center full-width">
|
<div class="column items-center full-width">
|
||||||
<QForm
|
<QForm
|
||||||
|
id="formModel"
|
||||||
v-on="$attrs"
|
v-on="$attrs"
|
||||||
ref="myForm"
|
ref="myForm"
|
||||||
v-if="formData"
|
v-if="formData"
|
||||||
@submit.prevent="save"
|
@submit.prevent="save"
|
||||||
@keyup.prevent="onKeyup"
|
@keyup.prevent="onKeyup"
|
||||||
@reset="reset"
|
@reset="reset"
|
||||||
class="q-pa-md"
|
class="full-width q-pa-md"
|
||||||
:style="maxWidth ? 'max-width: ' + maxWidth : ''"
|
:style="maxWidth ? 'max-width: ' + maxWidth : ''"
|
||||||
id="formModel"
|
|
||||||
:mapper="onBeforeSave"
|
|
||||||
>
|
>
|
||||||
<QCard>
|
<QCard>
|
||||||
<slot
|
<slot
|
||||||
|
@ -432,9 +451,6 @@ defineExpose({
|
||||||
.q-notifications {
|
.q-notifications {
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
#formModel {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.q-card {
|
.q-card {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
|
|
|
@ -115,6 +115,7 @@ describe('CrudModel', () => {
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
a: null,
|
a: null,
|
||||||
b: 4,
|
b: 4,
|
||||||
|
c: 3,
|
||||||
d: 5,
|
d: 5,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -241,7 +242,7 @@ describe('CrudModel', () => {
|
||||||
|
|
||||||
await vm.saveChanges(data);
|
await vm.saveChanges(data);
|
||||||
|
|
||||||
expect(postMock).toHaveBeenCalledWith(vm.url + '/crud', data);
|
expect(postMock).toHaveBeenCalledWith(`${vm.url}/crud`, data);
|
||||||
expect(vm.isLoading).toBe(false);
|
expect(vm.isLoading).toBe(false);
|
||||||
expect(vm.hasChanges).toBe(false);
|
expect(vm.hasChanges).toBe(false);
|
||||||
expect(vm.originalData).toEqual(JSON.parse(JSON.stringify(vm.formData)));
|
expect(vm.originalData).toEqual(JSON.parse(JSON.stringify(vm.formData)));
|
||||||
|
|
|
@ -3,11 +3,17 @@ import { createWrapper } from 'app/test/vitest/helper';
|
||||||
import { default as axios } from 'axios';
|
import { default as axios } from 'axios';
|
||||||
|
|
||||||
import FormModel from 'src/components/FormModel.vue';
|
import FormModel from 'src/components/FormModel.vue';
|
||||||
|
import { useState } from 'src/composables/useState';
|
||||||
|
|
||||||
describe('FormModel', () => {
|
describe('FormModel', () => {
|
||||||
const model = 'mockModel';
|
const model = 'mockModel';
|
||||||
const url = 'mockUrl';
|
const url = 'mockUrl';
|
||||||
const formInitialData = { mockKey: 'mockVal' };
|
const formInitialData = { mockKey: 'mockVal' };
|
||||||
|
let state;
|
||||||
|
beforeEach(() => {
|
||||||
|
state = useState();
|
||||||
|
state.set(model, formInitialData);
|
||||||
|
});
|
||||||
|
|
||||||
describe('modelValue', () => {
|
describe('modelValue', () => {
|
||||||
it('should use the provided model', () => {
|
it('should use the provided model', () => {
|
||||||
|
@ -94,30 +100,39 @@ describe('FormModel', () => {
|
||||||
expect(vm.hasChanges).toBe(false);
|
expect(vm.hasChanges).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call axios.patch with the right data', async () => {
|
it('should call axios.post with the right data', async () => {
|
||||||
const spy = vi.spyOn(axios, 'patch').mockResolvedValue({ data: {} });
|
const spy = vi.spyOn(axios, 'post').mockResolvedValue({ data: {} });
|
||||||
const { vm } = mount({ propsData: { url, model } });
|
const urlCreate = 'mockUrlCreate';
|
||||||
|
const { vm } = mount({ propsData: { url, urlCreate, model } });
|
||||||
|
|
||||||
vm.formData = {};
|
vm.formData = {};
|
||||||
await vm.$nextTick();
|
await vm.$nextTick();
|
||||||
vm.formData = { mockKey: 'newVal' };
|
const formData = { mockKey: 'newVal', mockKey2: 'newVal2' };
|
||||||
|
vm.formData = formData;
|
||||||
await vm.$nextTick();
|
await vm.$nextTick();
|
||||||
|
|
||||||
await vm.save();
|
await vm.save();
|
||||||
expect(spy).toHaveBeenCalled();
|
expect(spy).toHaveBeenCalled();
|
||||||
|
expect(spy).toHaveBeenCalledWith(urlCreate, formData);
|
||||||
vm.formData.mockKey = 'mockVal';
|
vm.formData.mockKey = 'mockVal';
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call axios.post with the right data', async () => {
|
it('should call axios.patch with the right data', async () => {
|
||||||
const spy = vi.spyOn(axios, 'post').mockResolvedValue({ data: {} });
|
const spy = vi.spyOn(axios, 'patch').mockResolvedValue({ data: {} });
|
||||||
|
|
||||||
const { vm } = mount({
|
const { vm } = mount({
|
||||||
propsData: { url, model, formInitialData, urlCreate: 'mockUrlCreate' },
|
propsData: {
|
||||||
|
url,
|
||||||
|
model,
|
||||||
|
formInitialData,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
await vm.$nextTick();
|
await vm.$nextTick();
|
||||||
vm.formData.mockKey = 'newVal';
|
vm.formData.mockKey = 'newVal';
|
||||||
await vm.$nextTick();
|
await vm.$nextTick();
|
||||||
await vm.save();
|
await vm.save();
|
||||||
expect(spy).toHaveBeenCalled();
|
expect(spy).toHaveBeenCalled();
|
||||||
|
expect(spy).toHaveBeenCalledWith(url, { mockKey: 'newVal' });
|
||||||
vm.formData.mockKey = 'mockVal';
|
vm.formData.mockKey = 'mockVal';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ watch(
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
if (!modelValue.value) return;
|
if (!modelValue.value) return;
|
||||||
modelValue.value = formatLocation(newValue) ?? null;
|
modelValue.value = formatLocation(newValue) ?? null;
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const mixinRules = [requiredFieldRule];
|
const mixinRules = [requiredFieldRule];
|
||||||
|
@ -45,7 +45,7 @@ const formatLocation = (obj, properties = locationProperties) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const filteredParts = parts.filter(
|
const filteredParts = parts.filter(
|
||||||
(part) => part !== null && part !== undefined && part !== ''
|
(part) => part !== null && part !== undefined && part !== '',
|
||||||
);
|
);
|
||||||
|
|
||||||
return filteredParts.join(', ');
|
return filteredParts.join(', ');
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import getDifferences from '../getDifferences';
|
||||||
|
|
||||||
|
describe('getDifferences', () => {
|
||||||
|
it('should handle empty initialData', () => {
|
||||||
|
const initialData = {};
|
||||||
|
const formData = { name: 'John' };
|
||||||
|
expect(getDifferences(initialData, formData)).toEqual({ name: 'John' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect when formData has a key not present in initialData', () => {
|
||||||
|
const initialData = { age: 30 };
|
||||||
|
const formData = { name: 'John' };
|
||||||
|
expect(getDifferences(initialData, formData)).toEqual({ age: 30, name: 'John' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect when formData has different value for existing key', () => {
|
||||||
|
const initialData = { name: 'John', age: 30 };
|
||||||
|
const formData = { name: 'Jane', age: 30 };
|
||||||
|
expect(getDifferences(initialData, formData)).toEqual({ name: 'Jane' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect when formData has null value for existing key', () => {
|
||||||
|
const initialData = { name: 'John' };
|
||||||
|
const formData = { name: null };
|
||||||
|
expect(getDifferences(initialData, formData)).toEqual({ name: null });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle missing keys in formData', () => {
|
||||||
|
const initialData = { name: 'John', age: 30 };
|
||||||
|
const formData = { name: 'John' };
|
||||||
|
expect(getDifferences(initialData, formData)).toEqual({ age: 30 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle complex objects', () => {
|
||||||
|
const initialData = { user: { name: 'John', age: 30 } };
|
||||||
|
const formData = { user: { name: 'John', age: 31 } };
|
||||||
|
expect(getDifferences(initialData, formData)).toEqual({
|
||||||
|
user: { name: 'John', age: 31 },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,19 +1,23 @@
|
||||||
export default function getDifferences(obj1, obj2) {
|
export default function getDifferences(initialData = {}, formData = {}) {
|
||||||
let diff = {};
|
const diff = {};
|
||||||
delete obj1.$index;
|
delete initialData?.$index;
|
||||||
delete obj2.$index;
|
delete formData?.$index;
|
||||||
|
|
||||||
for (let key in obj1) {
|
// Añadimos los valores que están en initialData
|
||||||
if (obj2[key] && JSON.stringify(obj1[key]) !== JSON.stringify(obj2[key])) {
|
for (const key in initialData) {
|
||||||
diff[key] = obj2[key];
|
if (!Object.prototype.hasOwnProperty.call(formData, key)) {
|
||||||
|
// Caso 1: initialData tiene una clave que no tiene formData
|
||||||
|
diff[key] = initialData[key];
|
||||||
|
} else if (JSON.stringify(initialData[key]) !== JSON.stringify(formData[key])) {
|
||||||
|
// Caso 2 y 3: valores diferentes o null en formData
|
||||||
|
diff[key] = formData[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let key in obj2) {
|
|
||||||
if (
|
// Añadimos las claves nuevas de formData
|
||||||
obj1[key] === undefined ||
|
for (const key in formData) {
|
||||||
JSON.stringify(obj1[key]) !== JSON.stringify(obj2[key])
|
if (!Object.prototype.hasOwnProperty.call(initialData, key)) {
|
||||||
) {
|
diff[key] = formData[key];
|
||||||
diff[key] = obj2[key];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import toDate from './toDate';
|
||||||
import toDateString from './toDateString';
|
import toDateString from './toDateString';
|
||||||
import toDateHourMin from './toDateHourMin';
|
import toDateHourMin from './toDateHourMin';
|
||||||
import toDateHourMinSec from './toDateHourMinSec';
|
import toDateHourMinSec from './toDateHourMinSec';
|
||||||
|
import onBeforeSave from './onBeforeSave';
|
||||||
import toRelativeDate from './toRelativeDate';
|
import toRelativeDate from './toRelativeDate';
|
||||||
import toCurrency from './toCurrency';
|
import toCurrency from './toCurrency';
|
||||||
import toPercentage from './toPercentage';
|
import toPercentage from './toPercentage';
|
||||||
|
@ -19,6 +20,7 @@ import isDialogOpened from './isDialogOpened';
|
||||||
import toCelsius from './toCelsius';
|
import toCelsius from './toCelsius';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
onBeforeSave,
|
||||||
getUpdatedValues,
|
getUpdatedValues,
|
||||||
getDifferences,
|
getDifferences,
|
||||||
isDialogOpened,
|
isDialogOpened,
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import getDifferences from './getDifferences';
|
||||||
|
import getUpdatedValues from './getUpdatedValues';
|
||||||
|
|
||||||
|
export default function onBeforeSave(originalData, formData) {
|
||||||
|
return getUpdatedValues(
|
||||||
|
Object.keys(getDifferences(originalData, formData)),
|
||||||
|
formData,
|
||||||
|
);
|
||||||
|
}
|
|
@ -15,13 +15,6 @@ import VnAvatar from 'src/components/ui/VnAvatar.vue';
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const workersOptions = ref([]);
|
const workersOptions = ref([]);
|
||||||
|
|
||||||
function onBeforeSave(formData, originalData) {
|
|
||||||
return getUpdatedValues(
|
|
||||||
Object.keys(getDifferences(formData, originalData)),
|
|
||||||
formData,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
<FetchData
|
||||||
|
@ -34,7 +27,6 @@ function onBeforeSave(formData, originalData) {
|
||||||
<FormModel
|
<FormModel
|
||||||
model="Claim"
|
model="Claim"
|
||||||
:url-update="`Claims/updateClaim/${route.params.id}`"
|
:url-update="`Claims/updateClaim/${route.params.id}`"
|
||||||
:mapper="onBeforeSave"
|
|
||||||
auto-load
|
auto-load
|
||||||
>
|
>
|
||||||
<template #form="{ data, validate }">
|
<template #form="{ data, validate }">
|
||||||
|
|
|
@ -8,37 +8,12 @@ import FormModel from 'components/FormModel.vue';
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import { getDifferences, getUpdatedValues } from 'src/filters';
|
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const businessTypes = ref([]);
|
const businessTypes = ref([]);
|
||||||
const contactChannels = ref([]);
|
const contactChannels = ref([]);
|
||||||
const handleSalesModelValue = (val) => {
|
|
||||||
if (!val) val = '';
|
|
||||||
return {
|
|
||||||
or: [
|
|
||||||
{ id: val },
|
|
||||||
{ name: val },
|
|
||||||
{ nickname: { like: '%' + val + '%' } },
|
|
||||||
{ code: { like: `${val}%` } },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const exprBuilder = (param, value) => {
|
|
||||||
return {
|
|
||||||
and: [{ active: { neq: false } }, handleSalesModelValue(value)],
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
function onBeforeSave(formData, originalData) {
|
|
||||||
return getUpdatedValues(
|
|
||||||
Object.keys(getDifferences(formData, originalData)),
|
|
||||||
formData,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
<FetchData
|
||||||
|
@ -52,12 +27,7 @@ function onBeforeSave(formData, originalData) {
|
||||||
@on-fetch="(data) => (businessTypes = data)"
|
@on-fetch="(data) => (businessTypes = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<FormModel
|
<FormModel :url-update="`Clients/${route.params.id}`" auto-load model="Customer">
|
||||||
:url-update="`Clients/${route.params.id}`"
|
|
||||||
auto-load
|
|
||||||
:mapper="onBeforeSave"
|
|
||||||
model="Customer"
|
|
||||||
>
|
|
||||||
<template #form="{ data, validate }">
|
<template #form="{ data, validate }">
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnInput
|
<VnInput
|
||||||
|
|
|
@ -13,7 +13,6 @@ import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import VnLocation from 'src/components/common/VnLocation.vue';
|
import VnLocation from 'src/components/common/VnLocation.vue';
|
||||||
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
|
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
|
||||||
import { getDifferences, getUpdatedValues } from 'src/filters';
|
|
||||||
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||||
|
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
|
@ -31,12 +30,6 @@ function handleLocation(data, location) {
|
||||||
data.provinceFk = provinceFk;
|
data.provinceFk = provinceFk;
|
||||||
data.countryFk = countryFk;
|
data.countryFk = countryFk;
|
||||||
}
|
}
|
||||||
function onBeforeSave(formData, originalData) {
|
|
||||||
return getUpdatedValues(
|
|
||||||
Object.keys(getDifferences(formData, originalData)),
|
|
||||||
formData,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function checkEtChanges(data, _, originalData) {
|
async function checkEtChanges(data, _, originalData) {
|
||||||
const equalizatedHasChanged = originalData.isEqualizated != data.isEqualizated;
|
const equalizatedHasChanged = originalData.isEqualizated != data.isEqualizated;
|
||||||
|
@ -75,7 +68,6 @@ async function acceptPropagate({ isEqualizated }) {
|
||||||
:url-update="`Clients/${route.params.id}/updateFiscalData`"
|
:url-update="`Clients/${route.params.id}/updateFiscalData`"
|
||||||
auto-load
|
auto-load
|
||||||
model="Customer"
|
model="Customer"
|
||||||
:mapper="onBeforeSave"
|
|
||||||
observe-form-changes
|
observe-form-changes
|
||||||
@on-data-saved="checkEtChanges"
|
@on-data-saved="checkEtChanges"
|
||||||
>
|
>
|
||||||
|
|
|
@ -39,6 +39,7 @@ const entityId = computed(() => {
|
||||||
where: { itemFk: entityId },
|
where: { itemFk: entityId },
|
||||||
}"
|
}"
|
||||||
@on-fetch="(data) => (itemBotanicalsForm = data)"
|
@on-fetch="(data) => (itemBotanicalsForm = data)"
|
||||||
|
:mapper="(_, data) => data"
|
||||||
>
|
>
|
||||||
<template #form="{ data }">
|
<template #form="{ data }">
|
||||||
<VnRow>
|
<VnRow>
|
||||||
|
|
Loading…
Reference in New Issue
Asi es reactivo??
Reactivo? porque, para que??