feat: refs #6897 enhance VnTable input handling and improve WorkerMedical component filters
gitea/salix-front/pipeline/pr-test This commit looks good Details

This commit is contained in:
Pablo Natek 2025-02-19 22:03:48 +01:00
parent 74c40c7808
commit 380965fbea
3 changed files with 36 additions and 23 deletions

View File

@ -18,7 +18,6 @@ import { useQuasar, date } from 'quasar';
import { useStateStore } from 'stores/useStateStore';
import { useFilterParams } from 'src/composables/useFilterParams';
import { dashIfEmpty, toDate } from 'src/filters';
import { toTimeFormat } from 'src/filters/date';
import CrudModel from 'src/components/CrudModel.vue';
import FormModelPopup from 'components/FormModelPopup.vue';
@ -346,7 +345,7 @@ const clickHandler = async (event) => {
if (isDateElement || isTimeElement || isQselectDropDown) return;
if (clickedElement === null) {
destroyInput(editingRow.value, editingField.value);
await destroyInput(editingRow.value, editingField.value);
return;
}
const rowIndex = clickedElement.getAttribute('data-row-index');
@ -356,7 +355,7 @@ const clickHandler = async (event) => {
if (editingRow.value !== null && editingField.value !== null) {
if (editingRow.value == rowIndex && editingField.value == colField) return;
destroyInput(editingRow.value, editingField.value);
await destroyInput(editingRow.value, editingField.value);
}
if (isEditableColumn(column)) {
@ -366,7 +365,7 @@ const clickHandler = async (event) => {
async function handleTabKey(event, rowIndex, colField) {
if (editingRow.value == rowIndex && editingField.value == colField)
destroyInput(editingRow.value, editingField.value);
await destroyInput(editingRow.value, editingField.value);
const direction = event.shiftKey ? -1 : 1;
const { nextRowIndex, nextColumnName } = await handleTabNavigation(
@ -426,7 +425,8 @@ async function renderInput(rowId, field, clickedElement) {
await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
},
keyup: async (event) => {
if (event.key === 'Enter') handleBlur(rowId, field, clickedElement);
if (event.key === 'Enter')
await destroyInput(rowIndex, field, clickedElement);
},
keydown: async (event) => {
switch (event.key) {
@ -435,7 +435,7 @@ async function renderInput(rowId, field, clickedElement) {
event.stopPropagation();
break;
case 'Escape':
destroyInput(rowId, field, clickedElement);
await destroyInput(rowId, field, clickedElement);
break;
default:
break;
@ -457,12 +457,13 @@ async function renderInput(rowId, field, clickedElement) {
node.el?.querySelector('span > div > div').focus();
}
function destroyInput(rowIndex, field, clickedElement) {
async function destroyInput(rowIndex, field, clickedElement) {
if (!clickedElement)
clickedElement = document.querySelector(
`[data-row-index="${rowIndex}"][data-col-field="${field}"]`,
);
if (clickedElement) {
await nextTick();
render(null, clickedElement);
Array.from(clickedElement.childNodes).forEach((child) => {
child.style.visibility = 'visible';
@ -474,10 +475,6 @@ function destroyInput(rowIndex, field, clickedElement) {
editingField.value = null;
}
function handleBlur(rowIndex, field, clickedElement) {
destroyInput(rowIndex, field, clickedElement);
}
async function handleTabNavigation(rowIndex, colName, direction) {
const columns = $props.columns;
const totalColumns = columns.length;
@ -538,18 +535,22 @@ function formatColumnValue(col, row, dashIfEmpty) {
: row[col?.name];
if (selectRegex.test(col?.component) && $props.isEditable) {
const findBy = find ?? url?.charAt(0)?.toLocaleLowerCase() + url?.slice(1, -1);
const { find, url } = col.attrs;
const urlRelation = url?.charAt(0)?.toLocaleLowerCase() + url?.slice(1, -1);
if (col?.attrs.options)
return dashIfEmpty(
col?.attrs.options.find((option) => option.id === row[col.name])?.name,
);
if (typeof row[findBy] == 'object') {
return dashIfEmpty(row[findBy][col?.attrs.optionLabel ?? 'name']);
if (col?.attrs.options) {
const find = col?.attrs.options.find((option) => option.id === row[col.name]);
if (!col.attrs?.optionLabel || !find) return dashIfEmpty(row[col?.name]);
return dashIfEmpty(find[col.attrs?.optionLabel ?? 'name']);
}
if (row[findBy]) return dashIfEmpty(row[findBy]);
if (!findBy || !row) return;
if (typeof row[urlRelation] == 'object') {
if (typeof find == 'object')
return dashIfEmpty(row[urlRelation][find?.label ?? 'name']);
return dashIfEmpty(row[urlRelation][col?.attrs.optionLabel ?? 'name']);
}
if (typeof row[urlRelation] == 'string') return dashIfEmpty(row[urlRelation]);
} else {
return dashIfEmpty(row[col?.name]);
}

View File

@ -119,7 +119,7 @@ const columns = computed(() => [
:url="`Workers/${entityId}/trainingCourse`"
:url-create="`Workers/${entityId}/trainingCourse`"
save-url="TrainingCourses/crud"
:filter="courseFilter"
:user-filter="courseFilter"
:create="{
urlCreate: 'trainingCourses',
title: t('Create training course'),

View File

@ -8,6 +8,17 @@ const { t } = useI18n();
const route = useRoute();
const entityId = computed(() => route.params.id);
const centerFilter = {
include: [
{
relation: 'center',
scope: {
fields: ['id', 'name'],
},
},
],
};
const columns = [
{
align: 'left',
@ -33,7 +44,7 @@ const columns = [
create: true,
component: 'select',
attrs: {
url: 'medicalCenters',
url: 'centers',
fields: ['id', 'name'],
},
},
@ -84,6 +95,7 @@ const columns = [
ref="tableRef"
data-key="WorkerMedical"
:url="`Workers/${entityId}/medicalReview`"
:user-filter="centerFilter"
save-url="MedicalReviews/crud"
:create="{
urlCreate: 'medicalReviews',