refactor: refs #8684 improve input handling and rendering in VnTable enhance item request logic in ItemRequest
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:
parent
cb1fa3c7f5
commit
d64788732e
|
@ -110,7 +110,6 @@ const components = {
|
||||||
component: markRaw(VnCheckbox),
|
component: markRaw(VnCheckbox),
|
||||||
event: updateEvent,
|
event: updateEvent,
|
||||||
attrs: {
|
attrs: {
|
||||||
class: $props.showTitle ? 'q-py-sm' : 'q-px-md q-py-xs fit',
|
|
||||||
'toggle-indeterminate': true,
|
'toggle-indeterminate': true,
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
},
|
},
|
||||||
|
|
|
@ -398,8 +398,7 @@ const clickHandler = async (event) => {
|
||||||
if (isDateElement || isTimeElement || isQSelectDropDown) return;
|
if (isDateElement || isTimeElement || isQSelectDropDown) return;
|
||||||
|
|
||||||
if (clickedElement === null) {
|
if (clickedElement === null) {
|
||||||
console.log('destroyInput 1');
|
destroyInput(editingRow.value, editingField.value);
|
||||||
await destroyInput(editingRow.value, editingField.value);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const rowIndex = clickedElement.getAttribute('data-row-index');
|
const rowIndex = clickedElement.getAttribute('data-row-index');
|
||||||
|
@ -409,8 +408,7 @@ const clickHandler = async (event) => {
|
||||||
if (editingRow.value !== null && editingField.value !== null) {
|
if (editingRow.value !== null && editingField.value !== null) {
|
||||||
if (editingRow.value == rowIndex && editingField.value == colField) return;
|
if (editingRow.value == rowIndex && editingField.value == colField) return;
|
||||||
|
|
||||||
console.log('destroyInput 2');
|
destroyInput(editingRow.value, editingField.value);
|
||||||
await destroyInput(editingRow.value, editingField.value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -419,18 +417,16 @@ const clickHandler = async (event) => {
|
||||||
CrudModelRef.value.formData[rowIndex ?? editingRow.value],
|
CrudModelRef.value.formData[rowIndex ?? editingRow.value],
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
await renderInput(Number(rowIndex), colField, clickedElement);
|
renderInput(Number(rowIndex), colField, clickedElement);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
async function handleTabKey(event, rowIndex, colField) {
|
function handleTabKey(event, rowIndex, colField) {
|
||||||
if (editingRow.value == rowIndex && editingField.value == colField) {
|
if (editingRow.value == rowIndex && editingField.value == colField)
|
||||||
console.log('destroyInput 3');
|
destroyInput(editingRow.value, editingField.value);
|
||||||
await destroyInput(editingRow.value, editingField.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
const direction = event.shiftKey ? -1 : 1;
|
const direction = event.shiftKey ? -1 : 1;
|
||||||
const { nextRowIndex, nextColumnName } = await handleTabNavigation(
|
const { nextRowIndex, nextColumnName } = handleTabNavigation(
|
||||||
rowIndex,
|
rowIndex,
|
||||||
colField,
|
colField,
|
||||||
direction,
|
direction,
|
||||||
|
@ -439,11 +435,10 @@ async function handleTabKey(event, rowIndex, colField) {
|
||||||
if (nextRowIndex < 0 || nextRowIndex >= arrayData.store.data.length) return;
|
if (nextRowIndex < 0 || nextRowIndex >= arrayData.store.data.length) return;
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
console.log('nextColumnName: ', nextColumnName);
|
renderInput(nextRowIndex, nextColumnName, null);
|
||||||
await renderInput(nextRowIndex, nextColumnName, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function renderInput(rowId, field, clickedElement) {
|
function renderInput(rowId, field, clickedElement) {
|
||||||
editingField.value = field;
|
editingField.value = field;
|
||||||
editingRow.value = rowId;
|
editingRow.value = rowId;
|
||||||
|
|
||||||
|
@ -480,28 +475,20 @@ async function renderInput(rowId, field, clickedElement) {
|
||||||
} else row[column.name] = value;
|
} else row[column.name] = value;
|
||||||
await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
|
await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
|
||||||
},
|
},
|
||||||
keyup: async (event) => {
|
keyup: (event) => {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
console.log('destroyInput 4');
|
destroyInput(rowId, field, clickedElement);
|
||||||
await destroyInput(rowId, field, clickedElement);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
keydown: async (event) => {
|
keydown: (event) => {
|
||||||
switch (event.key) {
|
switch (event.key) {
|
||||||
case 'Tab':
|
case 'Tab':
|
||||||
console.log('field: ', field);
|
handleTabKey(event, rowId, field);
|
||||||
console.log('target: ', event.target);
|
|
||||||
await handleTabKey(event, rowId, field);
|
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const column = $props.columns.find((col) => col.name === field);
|
|
||||||
if (typeof column?.beforeDestroy === 'function')
|
|
||||||
await column.beforeDestroy(
|
|
||||||
CrudModelRef.value.formData[editingRow.value],
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
console.log('destroyInput 5');
|
destroyInput(rowId, field, clickedElement);
|
||||||
await destroyInput(rowId, field, clickedElement);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -534,18 +521,24 @@ async function updateSelectValue(value, column, row, oldValue) {
|
||||||
await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
|
await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function destroyInput(rowIndex, field, clickedElement) {
|
function destroyInput(rowIndex, field, clickedElement) {
|
||||||
if (!clickedElement)
|
if (!clickedElement)
|
||||||
clickedElement = document.querySelector(
|
clickedElement = document.querySelector(
|
||||||
`[data-row-index="${rowIndex}"][data-col-field="${field}"]`,
|
`[data-row-index="${rowIndex}"][data-col-field="${field}"]`,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (clickedElement) {
|
if (clickedElement) {
|
||||||
await nextTick();
|
const column = $props.columns.find((col) => col.name === field);
|
||||||
|
if (typeof column?.beforeDestroy === 'function')
|
||||||
|
column.beforeDestroy(CrudModelRef.value.formData[rowIndex]);
|
||||||
|
|
||||||
|
nextTick().then(() => {
|
||||||
render(null, clickedElement);
|
render(null, clickedElement);
|
||||||
Array.from(clickedElement.childNodes).forEach((child) => {
|
Array.from(clickedElement.childNodes).forEach((child) => {
|
||||||
child.style.visibility = 'visible';
|
child.style.visibility = 'visible';
|
||||||
child.style.position = '';
|
child.style.position = '';
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (editingRow.value !== rowIndex || editingField.value !== field) return;
|
if (editingRow.value !== rowIndex || editingField.value !== field) return;
|
||||||
|
@ -553,7 +546,7 @@ async function destroyInput(rowIndex, field, clickedElement) {
|
||||||
editingField.value = null;
|
editingField.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleTabNavigation(rowIndex, colName, direction) {
|
function handleTabNavigation(rowIndex, colName, direction) {
|
||||||
const columns = $props.columns;
|
const columns = $props.columns;
|
||||||
const totalColumns = columns.length;
|
const totalColumns = columns.length;
|
||||||
let currentColumnIndex = columns.findIndex((col) => col.name === colName);
|
let currentColumnIndex = columns.findIndex((col) => col.name === colName);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from 'vue';
|
import { ref, computed, onMounted, nextTick } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import { toCurrency } from 'filters/index';
|
import { toCurrency } from 'filters/index';
|
||||||
|
@ -23,7 +23,6 @@ const stateStore = useStateStore();
|
||||||
const denyFormRef = ref(null);
|
const denyFormRef = ref(null);
|
||||||
const denyRequestId = ref(null);
|
const denyRequestId = ref(null);
|
||||||
const userParams = {
|
const userParams = {
|
||||||
state: 'pending',
|
|
||||||
daysOnward: 7,
|
daysOnward: 7,
|
||||||
};
|
};
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
|
@ -136,6 +135,7 @@ const columns = computed(() => [
|
||||||
align: 'left',
|
align: 'left',
|
||||||
component: 'input',
|
component: 'input',
|
||||||
columnClass: 'expand',
|
columnClass: 'expand',
|
||||||
|
isEditable: ({ isOk }) => isOk === null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('item.buyRequest.achieved'),
|
label: t('item.buyRequest.achieved'),
|
||||||
|
@ -143,22 +143,35 @@ const columns = computed(() => [
|
||||||
align: 'left',
|
align: 'left',
|
||||||
component: 'input',
|
component: 'input',
|
||||||
columnClass: 'shrink',
|
columnClass: 'shrink',
|
||||||
isEditable: (row) => row?.itemFk,
|
isEditable: ({ itemFk, isOk }) => {
|
||||||
beforeDestroy: async ({ id, itemFk, saleQuantity, state }) => {
|
if (itemFk && isOk === null) return true;
|
||||||
if (!saleQuantity) {
|
},
|
||||||
await tableRef.value.reload();
|
beforeDestroy: (row) => {
|
||||||
return;
|
console.log('row: ', row);
|
||||||
|
if (!row.saleQuantity) {
|
||||||
|
return tableRef.value.reload();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await axios.post(`TicketRequests/${id}/confirm`, {
|
axios
|
||||||
id,
|
.post(`TicketRequests/${row.id}/confirm`, {
|
||||||
itemFk: parseInt(itemFk),
|
id: row.id,
|
||||||
quantity: parseInt(saleQuantity),
|
itemFk: parseInt(row.itemFk),
|
||||||
|
quantity: parseInt(row.saleQuantity),
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
axios
|
||||||
|
.get(`Items/findOne`, { where: { id: row.itemFk } })
|
||||||
|
.then((response) => {
|
||||||
|
console.log('response: ', response);
|
||||||
|
row.itemDescription = response.data.name;
|
||||||
|
row.state = 1;
|
||||||
|
});
|
||||||
|
notify(t('globals.dataSaved'), 'positive');
|
||||||
|
return tableRef.value.reload();
|
||||||
});
|
});
|
||||||
await tableRef.value.reload();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notify(error.response.data.error.message, 'negative');
|
notify(error.response.data.error.message, 'negative');
|
||||||
await tableRef.value.reload();
|
return tableRef.value.reload();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -174,7 +187,7 @@ const columns = computed(() => [
|
||||||
{
|
{
|
||||||
label: t('globals.state'),
|
label: t('globals.state'),
|
||||||
name: 'state',
|
name: 'state',
|
||||||
format: (row) => getState(row.isOk),
|
format: ({ isOk }) => getState(isOk),
|
||||||
align: 'left',
|
align: 'left',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -202,6 +215,7 @@ const columns = computed(() => [
|
||||||
icon: 'thumb_down',
|
icon: 'thumb_down',
|
||||||
fill: true,
|
fill: true,
|
||||||
isPrimary: true,
|
isPrimary: true,
|
||||||
|
show: ({ isOk }) => isOk === null,
|
||||||
action: (row) => showDenyRequestForm(row.id),
|
action: (row) => showDenyRequestForm(row.id),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -309,7 +323,8 @@ const showDenyRequestForm = (requestId) => {
|
||||||
v-model="data.observation"
|
v-model="data.observation"
|
||||||
fill-input
|
fill-input
|
||||||
:required="true"
|
:required="true"
|
||||||
autogrow
|
auto-grow
|
||||||
|
data-cy="discardTextArea"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</FormModelPopup>
|
</FormModelPopup>
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
describe('Item Request', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.login('buyer');
|
||||||
|
cy.visit(`/#/item/request`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fill the id and quantity then check the concept was updated', async () => {
|
||||||
|
cy.get('td[data-row-index="0"][data-col-field="itemFk"]')
|
||||||
|
.should('exist')
|
||||||
|
.type('4');
|
||||||
|
cy.get('td[data-row-index="0"][data-col-field="saleQuantity"]')
|
||||||
|
.should('exist')
|
||||||
|
.type('10{esc}');
|
||||||
|
cy.checkNotification('Data saved');
|
||||||
|
});
|
||||||
|
it('should now click on the second declain request icon then type the reason', async () => {
|
||||||
|
cy.selectOption('[data-cy="State_select"]', 'Pending');
|
||||||
|
cy.get('button[title="Discard"]').eq(0).click();
|
||||||
|
cy.dataCy('discardTextArea').should('exist').type('test(enter)');
|
||||||
|
cy.checkNotification('Data saved');
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue