Merge branch 'dev' into 8612-shelvinge2e
gitea/salix-front/pipeline/pr-dev This commit is unstable
Details
gitea/salix-front/pipeline/pr-dev This commit is unstable
Details
This commit is contained in:
commit
8ed3441007
|
@ -184,8 +184,11 @@ async function saveChanges(data) {
|
||||||
if ($props.beforeSaveFn) {
|
if ($props.beforeSaveFn) {
|
||||||
changes = await $props.beforeSaveFn(changes, getChanges);
|
changes = await $props.beforeSaveFn(changes, getChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (changes?.creates?.length === 0 && changes?.updates?.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await axios.post($props.saveUrl || $props.url + '/crud', changes);
|
await axios.post($props.saveUrl || $props.url + '/crud', changes);
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
|
|
|
@ -30,8 +30,8 @@ describe('CrudModel', () => {
|
||||||
saveFn: '',
|
saveFn: '',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
wrapper=wrapper.wrapper;
|
wrapper = wrapper.wrapper;
|
||||||
vm=wrapper.vm;
|
vm = wrapper.vm;
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -143,14 +143,14 @@ describe('CrudModel', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true if object is empty', async () => {
|
it('should return true if object is empty', async () => {
|
||||||
dummyObj ={};
|
dummyObj = {};
|
||||||
result = vm.isEmpty(dummyObj);
|
result = vm.isEmpty(dummyObj);
|
||||||
|
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false if object is not empty', async () => {
|
it('should return false if object is not empty', async () => {
|
||||||
dummyObj = {a:1, b:2, c:3};
|
dummyObj = { a: 1, b: 2, c: 3 };
|
||||||
result = vm.isEmpty(dummyObj);
|
result = vm.isEmpty(dummyObj);
|
||||||
|
|
||||||
expect(result).toBe(false);
|
expect(result).toBe(false);
|
||||||
|
@ -158,29 +158,31 @@ describe('CrudModel', () => {
|
||||||
|
|
||||||
it('should return true if array is empty', async () => {
|
it('should return true if array is empty', async () => {
|
||||||
dummyArray = [];
|
dummyArray = [];
|
||||||
result = vm.isEmpty(dummyArray);
|
result = vm.isEmpty(dummyArray);
|
||||||
|
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false if array is not empty', async () => {
|
it('should return false if array is not empty', async () => {
|
||||||
dummyArray = [1,2,3];
|
dummyArray = [1, 2, 3];
|
||||||
result = vm.isEmpty(dummyArray);
|
result = vm.isEmpty(dummyArray);
|
||||||
|
|
||||||
expect(result).toBe(false);
|
expect(result).toBe(false);
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('resetData()', () => {
|
describe('resetData()', () => {
|
||||||
it('should add $index to elements in data[] and sets originalData and formData with data', async () => {
|
it('should add $index to elements in data[] and sets originalData and formData with data', async () => {
|
||||||
data = [{
|
data = [
|
||||||
name: 'Tony',
|
{
|
||||||
lastName: 'Stark',
|
name: 'Tony',
|
||||||
age: 42,
|
lastName: 'Stark',
|
||||||
}];
|
age: 42,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
vm.resetData(data);
|
vm.resetData(data);
|
||||||
|
|
||||||
expect(vm.originalData).toEqual(data);
|
expect(vm.originalData).toEqual(data);
|
||||||
expect(vm.originalData[0].$index).toEqual(0);
|
expect(vm.originalData[0].$index).toEqual(0);
|
||||||
expect(vm.formData).toEqual(data);
|
expect(vm.formData).toEqual(data);
|
||||||
|
@ -200,7 +202,7 @@ describe('CrudModel', () => {
|
||||||
lastName: 'Stark',
|
lastName: 'Stark',
|
||||||
age: 42,
|
age: 42,
|
||||||
};
|
};
|
||||||
|
|
||||||
vm.resetData(data);
|
vm.resetData(data);
|
||||||
|
|
||||||
expect(vm.originalData).toEqual(data);
|
expect(vm.originalData).toEqual(data);
|
||||||
|
@ -210,17 +212,19 @@ describe('CrudModel', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('saveChanges()', () => {
|
describe('saveChanges()', () => {
|
||||||
data = [{
|
data = [
|
||||||
name: 'Tony',
|
{
|
||||||
lastName: 'Stark',
|
name: 'Tony',
|
||||||
age: 42,
|
lastName: 'Stark',
|
||||||
}];
|
age: 42,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
it('should call saveFn if exists', async () => {
|
it('should call saveFn if exists', async () => {
|
||||||
await wrapper.setProps({ saveFn: vi.fn() });
|
await wrapper.setProps({ saveFn: vi.fn() });
|
||||||
|
|
||||||
vm.saveChanges(data);
|
vm.saveChanges(data);
|
||||||
|
|
||||||
expect(vm.saveFn).toHaveBeenCalledOnce();
|
expect(vm.saveFn).toHaveBeenCalledOnce();
|
||||||
expect(vm.isLoading).toBe(false);
|
expect(vm.isLoading).toBe(false);
|
||||||
expect(vm.hasChanges).toBe(false);
|
expect(vm.hasChanges).toBe(false);
|
||||||
|
@ -229,13 +233,15 @@ describe('CrudModel', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should use default url if there's not saveFn", async () => {
|
it("should use default url if there's not saveFn", async () => {
|
||||||
const postMock =vi.spyOn(axios, 'post');
|
const postMock = vi.spyOn(axios, 'post');
|
||||||
|
|
||||||
vm.formData = [{
|
vm.formData = [
|
||||||
name: 'Bruce',
|
{
|
||||||
lastName: 'Wayne',
|
name: 'Bruce',
|
||||||
age: 45,
|
lastName: 'Wayne',
|
||||||
}]
|
age: 45,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
await vm.saveChanges(data);
|
await vm.saveChanges(data);
|
||||||
|
|
||||||
|
|
|
@ -158,15 +158,10 @@ const getBadgeAttrs = (_date) => {
|
||||||
|
|
||||||
const scrollToToday = async () => {
|
const scrollToToday = async () => {
|
||||||
await nextTick();
|
await nextTick();
|
||||||
const todayCell = document.querySelector(`td[data-date="${today.toISOString()}"]`);
|
const todayCell = document.querySelector(
|
||||||
if (todayCell) {
|
`td[data-date="${date.formatDate(today, 'YYYY-MM-DD')}"]`,
|
||||||
todayCell.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
);
|
||||||
}
|
if (todayCell) todayCell.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||||
};
|
|
||||||
|
|
||||||
const formatDateForAttribute = (dateValue) => {
|
|
||||||
if (dateValue instanceof Date) return date.formatDate(dateValue, 'YYYY-MM-DD');
|
|
||||||
return dateValue;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
async function updateWarehouse(warehouseFk) {
|
async function updateWarehouse(warehouseFk) {
|
||||||
|
@ -242,7 +237,7 @@ async function updateWarehouse(warehouseFk) {
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-date="{ row }">
|
<template #body-cell-date="{ row }">
|
||||||
<QTd @click.stop :data-date="formatDateForAttribute(row.shipped)">
|
<QTd @click.stop :data-date="row?.shipped.substring(0, 10)">
|
||||||
<QBadge
|
<QBadge
|
||||||
v-bind="getBadgeAttrs(row.shipped)"
|
v-bind="getBadgeAttrs(row.shipped)"
|
||||||
class="q-ma-none"
|
class="q-ma-none"
|
||||||
|
|
|
@ -121,6 +121,50 @@ async function handleSave() {
|
||||||
isSaving.value = false;
|
isSaving.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function validateFields(item) {
|
||||||
|
// Only validate fields that are being updated
|
||||||
|
const shouldExist = (field) => !isUpdate || field in item;
|
||||||
|
|
||||||
|
if (!shouldExist('ticketServiceTypeFk') && !item.ticketServiceTypeFk) {
|
||||||
|
notify('Description is required', 'negative');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shouldExist('quantity') && (!item.quantity || item.quantity <= 0)) {
|
||||||
|
notify('Quantity must be greater than 0', 'negative');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shouldExist('price') && (!item.price || item.price < 0)) {
|
||||||
|
notify('Price must be valid', 'negative');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function beforeSave(data) {
|
||||||
|
const { creates = [], updates = [] } = data;
|
||||||
|
const validData = { creates: [], updates: [] };
|
||||||
|
|
||||||
|
// Validate creates
|
||||||
|
if (creates.length) {
|
||||||
|
for (const create of creates) {
|
||||||
|
create.ticketFk = route.params.id;
|
||||||
|
if (validateFields(create)) {
|
||||||
|
validData.creates.push(create);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate updates
|
||||||
|
if (updates.length) {
|
||||||
|
for (const update of updates) {
|
||||||
|
validData.updates.push(update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return validData;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -141,6 +185,7 @@ async function handleSave() {
|
||||||
v-model:selected="selected"
|
v-model:selected="selected"
|
||||||
:order="['description ASC']"
|
:order="['description ASC']"
|
||||||
:default-remove="false"
|
:default-remove="false"
|
||||||
|
:beforeSaveFn="beforeSave"
|
||||||
>
|
>
|
||||||
<template #moreBeforeActions>
|
<template #moreBeforeActions>
|
||||||
<QBtn
|
<QBtn
|
||||||
|
@ -170,6 +215,7 @@ async function handleSave() {
|
||||||
option-value="id"
|
option-value="id"
|
||||||
hide-selected
|
hide-selected
|
||||||
sort-by="name ASC"
|
sort-by="name ASC"
|
||||||
|
:required="true"
|
||||||
>
|
>
|
||||||
<template #form>
|
<template #form>
|
||||||
<TicketCreateServiceType
|
<TicketCreateServiceType
|
||||||
|
@ -185,6 +231,7 @@ async function handleSave() {
|
||||||
:label="col.label"
|
:label="col.label"
|
||||||
v-model.number="row.quantity"
|
v-model.number="row.quantity"
|
||||||
type="number"
|
type="number"
|
||||||
|
:required="true"
|
||||||
min="0"
|
min="0"
|
||||||
:info="t('service.quantityInfo')"
|
:info="t('service.quantityInfo')"
|
||||||
/>
|
/>
|
||||||
|
@ -196,6 +243,7 @@ async function handleSave() {
|
||||||
:label="col.label"
|
:label="col.label"
|
||||||
v-model.number="row.price"
|
v-model.number="row.price"
|
||||||
type="number"
|
type="number"
|
||||||
|
:required="true"
|
||||||
min="0"
|
min="0"
|
||||||
@keyup.enter="handleSave"
|
@keyup.enter="handleSave"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { ref, nextTick } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
|
Loading…
Reference in New Issue