refs #5673 fix crudModel, claimDevelopment and VnSelect
gitea/salix-front/pipeline/head This commit looks good
Details
gitea/salix-front/pipeline/head This commit looks good
Details
This commit is contained in:
parent
8ba25314aa
commit
ff347db37a
|
@ -9,7 +9,7 @@
|
|||
"lint": "eslint --ext .js,.vue ./",
|
||||
"format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
|
||||
"test:e2e": "cypress open",
|
||||
"test:e2e:ci": "cypress run --browser chromium",
|
||||
"test:e2e:ci": "cd ../salix && gulp docker && cd ../salix-front && cypress run --browser chromium",
|
||||
"test": "echo \"See package.json => scripts for available tests.\" && exit 0",
|
||||
"test:unit": "vitest",
|
||||
"test:unit:ci": "vitest run"
|
||||
|
|
|
@ -46,7 +46,7 @@ const onResponseError = (error) => {
|
|||
message = responseError.message;
|
||||
}
|
||||
|
||||
switch (response.status) {
|
||||
switch (response?.status) {
|
||||
case 500:
|
||||
message = 'errors.statusInternalServerError';
|
||||
break;
|
||||
|
@ -58,7 +58,7 @@ const onResponseError = (error) => {
|
|||
break;
|
||||
}
|
||||
|
||||
if (session.isLoggedIn() && response.status === 401) {
|
||||
if (session.isLoggedIn() && response?.status === 401) {
|
||||
session.destroy();
|
||||
const hash = window.location.hash;
|
||||
const url = hash.slice(1);
|
||||
|
|
|
@ -8,6 +8,7 @@ import { useStateStore } from 'stores/useStateStore';
|
|||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
||||
import VnConfirm from 'components/ui/VnConfirm.vue';
|
||||
import SkeletonTable from 'components/ui/SkeletonTable.vue';
|
||||
import { tMobile } from 'src/composables/tMobile';
|
||||
|
||||
const quasar = useQuasar();
|
||||
const stateStore = useStateStore();
|
||||
|
@ -62,9 +63,10 @@ const hasChanges = ref(false);
|
|||
const originalData = ref();
|
||||
const vnPaginateRef = ref();
|
||||
const formData = ref();
|
||||
const saveButtonRef = ref(null);
|
||||
const formUrl = computed(() => $props.url);
|
||||
|
||||
const emit = defineEmits(['onFetch', 'update:selected']);
|
||||
const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
|
||||
|
||||
defineExpose({
|
||||
reload,
|
||||
|
@ -73,12 +75,9 @@ defineExpose({
|
|||
onSubmit,
|
||||
reset,
|
||||
hasChanges,
|
||||
saveChanges,
|
||||
});
|
||||
|
||||
function tMobile(...args) {
|
||||
if (!quasar.platform.is.mobile) return t(...args);
|
||||
}
|
||||
|
||||
async function fetch(data) {
|
||||
if (data && Array.isArray(data)) {
|
||||
let $index = 0;
|
||||
|
@ -135,6 +134,7 @@ async function saveChanges(data) {
|
|||
|
||||
hasChanges.value = false;
|
||||
isLoading.value = false;
|
||||
emit('saveChanges', data);
|
||||
}
|
||||
|
||||
async function insert() {
|
||||
|
@ -269,7 +269,7 @@ watch(formUrl, async () => {
|
|||
<SkeletonTable v-if="!formData" />
|
||||
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
|
||||
<QBtnGroup push class="q-gutter-x-sm">
|
||||
<slot name="moreActions" />
|
||||
<slot name="moreBeforeActions" />
|
||||
<QBtn
|
||||
:label="tMobile('globals.remove')"
|
||||
color="primary"
|
||||
|
@ -292,6 +292,7 @@ watch(formUrl, async () => {
|
|||
/>
|
||||
<QBtn
|
||||
:label="tMobile('globals.save')"
|
||||
ref="saveButtonRef"
|
||||
color="primary"
|
||||
icon="save"
|
||||
@click="onSubmit"
|
||||
|
@ -299,6 +300,7 @@ watch(formUrl, async () => {
|
|||
:title="t('globals.save')"
|
||||
v-if="$props.defaultSave"
|
||||
/>
|
||||
<slot name="moreAfterActions" />
|
||||
</QBtnGroup>
|
||||
</Teleport>
|
||||
<QInnerLoading
|
||||
|
|
|
@ -19,6 +19,8 @@ const $props = defineProps({
|
|||
const { optionLabel, options } = toRefs($props);
|
||||
const myOptions = ref([]);
|
||||
const myOptionsOriginal = ref([]);
|
||||
const vnSelectRef = ref(null);
|
||||
|
||||
function setOptions(data) {
|
||||
myOptions.value = JSON.parse(JSON.stringify(data));
|
||||
myOptionsOriginal.value = JSON.parse(JSON.stringify(data));
|
||||
|
@ -29,6 +31,7 @@ const filter = (val, options) => {
|
|||
const search = val.toLowerCase();
|
||||
|
||||
if (val === '') return options;
|
||||
|
||||
return options.filter((row) => {
|
||||
const id = row.id;
|
||||
const name = row[$props.optionLabel].toLowerCase();
|
||||
|
@ -41,9 +44,17 @@ const filter = (val, options) => {
|
|||
};
|
||||
|
||||
const filterHandler = (val, update) => {
|
||||
update(() => {
|
||||
myOptions.value = filter(val, myOptionsOriginal.value);
|
||||
});
|
||||
update(
|
||||
() => {
|
||||
myOptions.value = filter(val, myOptionsOriginal.value);
|
||||
},
|
||||
(ref) => {
|
||||
if (val !== '' && ref.options.length > 0) {
|
||||
ref.setOptionIndex(-1);
|
||||
ref.moveOptionSelection(1, true);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
watch(options, (newValue) => {
|
||||
|
@ -70,7 +81,15 @@ const value = computed({
|
|||
map-options
|
||||
use-input
|
||||
@filter="filterHandler"
|
||||
clearable
|
||||
clear-icon="close"
|
||||
/>
|
||||
hide-selected
|
||||
fill-input
|
||||
ref="vnSelectRef"
|
||||
>
|
||||
<template #append>
|
||||
<QIcon name="close" @click.stop="value = null" class="cursor-pointer" />
|
||||
</template>
|
||||
<template v-for="(_, slotName) in $slots" #[slotName]="slotData">
|
||||
<slot :name="slotName" v-bind="slotData" />
|
||||
</template>
|
||||
</QSelect>
|
||||
</template>
|
||||
|
|
|
@ -140,14 +140,6 @@ async function onLoad(...params) {
|
|||
{{ t('No data to display') }}
|
||||
</h5>
|
||||
</div>
|
||||
<div
|
||||
v-if="store.data && store.data.length === 0 && !isLoading"
|
||||
class="info-row q-pa-md text-center"
|
||||
>
|
||||
<h5>
|
||||
{{ t('No results found') }}
|
||||
</h5>
|
||||
</div>
|
||||
<div
|
||||
v-if="props.skeleton && props.autoLoad && !store.data"
|
||||
class="card-list q-gutter-y-md"
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import { useQuasar } from 'quasar';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
export function tMobile(...args) {
|
||||
const quasar = useQuasar();
|
||||
const { t } = useI18n();
|
||||
if (!quasar.platform.is.mobile) return t(...args);
|
||||
}
|
|
@ -1,12 +1,15 @@
|
|||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
import CrudModel from 'components/CrudModel.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import VnSelectFilter from 'components/common/VnSelectFilter.vue';
|
||||
import { getUrl } from 'composables/getUrl';
|
||||
import { tMobile } from 'composables/tMobile';
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const claimDevelopmentForm = ref();
|
||||
|
@ -16,6 +19,12 @@ const claimResponsibles = ref([]);
|
|||
const claimRedeliveries = ref([]);
|
||||
const workers = ref([]);
|
||||
const selected = ref([]);
|
||||
const insertButtonRef = ref();
|
||||
let salixUrl;
|
||||
|
||||
onMounted(async () => {
|
||||
salixUrl = await getUrl(`claim/${route.params.id}`);
|
||||
});
|
||||
|
||||
const developmentsFilter = {
|
||||
fields: [
|
||||
|
@ -43,6 +52,7 @@ const columns = computed(() => [
|
|||
model: 'claimReasonFk',
|
||||
optionValue: 'id',
|
||||
optionLabel: 'description',
|
||||
tabIndex: 1,
|
||||
},
|
||||
{
|
||||
name: 'claimResult',
|
||||
|
@ -54,6 +64,7 @@ const columns = computed(() => [
|
|||
model: 'claimResultFk',
|
||||
optionValue: 'id',
|
||||
optionLabel: 'description',
|
||||
tabIndex: 2,
|
||||
},
|
||||
{
|
||||
name: 'claimResponsible',
|
||||
|
@ -65,6 +76,7 @@ const columns = computed(() => [
|
|||
model: 'claimResponsibleFk',
|
||||
optionValue: 'id',
|
||||
optionLabel: 'description',
|
||||
tabIndex: 3,
|
||||
},
|
||||
{
|
||||
name: 'worker',
|
||||
|
@ -75,6 +87,7 @@ const columns = computed(() => [
|
|||
model: 'workerFk',
|
||||
optionValue: 'id',
|
||||
optionLabel: 'nickname',
|
||||
tabIndex: 4,
|
||||
},
|
||||
{
|
||||
name: 'claimRedelivery',
|
||||
|
@ -86,8 +99,13 @@ const columns = computed(() => [
|
|||
model: 'claimRedeliveryFk',
|
||||
optionValue: 'id',
|
||||
optionLabel: 'description',
|
||||
tabIndex: 5,
|
||||
},
|
||||
]);
|
||||
|
||||
function goToAction() {
|
||||
location.href = `${salixUrl}/action`;
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<FetchData
|
||||
|
@ -115,8 +133,9 @@ const columns = computed(() => [
|
|||
auto-load
|
||||
/>
|
||||
<FetchData
|
||||
url="Workers/activeWithInheritedRole"
|
||||
:where="{ role: 'employee' }"
|
||||
url="Workers/search"
|
||||
:where="{ active: 1 }"
|
||||
order="name ASC"
|
||||
@on-fetch="(data) => (workers = data)"
|
||||
auto-load
|
||||
/>
|
||||
|
@ -129,6 +148,8 @@ const columns = computed(() => [
|
|||
:data-required="{ claimFk: route.params.id }"
|
||||
v-model:selected="selected"
|
||||
auto-load
|
||||
@save-changes="goToAction"
|
||||
:default-save="false"
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<QTable
|
||||
|
@ -142,19 +163,40 @@ const columns = computed(() => [
|
|||
:grid="$q.screen.lt.md"
|
||||
>
|
||||
<template #body-cell="{ row, col }">
|
||||
<QTd auto-width>
|
||||
<QTd
|
||||
auto-width
|
||||
@keyup.ctrl.enter.stop="claimDevelopmentForm.saveChanges()"
|
||||
>
|
||||
<VnSelectFilter
|
||||
:label="col.label"
|
||||
v-model="row[col.model]"
|
||||
:options="col.options"
|
||||
:option-value="col.optionValue"
|
||||
:option-label="col.optionLabel"
|
||||
/>
|
||||
:autofocus="col.tabIndex == 1"
|
||||
input-debounce="0"
|
||||
>
|
||||
<template #option="scope" v-if="col.name == 'worker'">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ scope.opt?.nickname }}
|
||||
{{ scope.opt?.code }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelectFilter>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #item="props">
|
||||
<div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
|
||||
<QCard bordered flat>
|
||||
<QCard
|
||||
bordered
|
||||
flat
|
||||
@keyup.ctrl.enter.stop="claimDevelopmentForm?.saveChanges()"
|
||||
>
|
||||
<QCardSection>
|
||||
<QCheckbox v-model="props.selected" dense />
|
||||
</QCardSection>
|
||||
|
@ -169,6 +211,8 @@ const columns = computed(() => [
|
|||
:option-value="col.optionValue"
|
||||
:option-label="col.optionLabel"
|
||||
dense
|
||||
input-debounce="0"
|
||||
:autofocus="col.tabIndex == 1"
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
|
@ -178,9 +222,28 @@ const columns = computed(() => [
|
|||
</template>
|
||||
</QTable>
|
||||
</template>
|
||||
<template #moreAfterActions>
|
||||
<QBtn
|
||||
:label="tMobile('globals.save')"
|
||||
ref="saveButtonRef"
|
||||
color="primary"
|
||||
icon="save"
|
||||
:disable="!claimDevelopmentForm?.hasChanges"
|
||||
@click="claimDevelopmentForm?.onSubmit"
|
||||
:title="t('globals.save')"
|
||||
/>
|
||||
</template>
|
||||
</CrudModel>
|
||||
<QPageSticky position="bottom-right" :offset="[25, 25]">
|
||||
<QBtn fab color="primary" icon="add" @click="claimDevelopmentForm.insert()" />
|
||||
<QBtn
|
||||
ref="insertButtonRef"
|
||||
fab
|
||||
color="primary"
|
||||
icon="add"
|
||||
@click="claimDevelopmentForm.insert()"
|
||||
@keydown.ctrl.enter.stop="claimDevelopmentForm.saveChanges()"
|
||||
@keydown.enter.stop
|
||||
/>
|
||||
</QPageSticky>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ const claimLinesForm = ref();
|
|||
const claim = ref(null);
|
||||
async function onFetchClaim(data) {
|
||||
claim.value = data;
|
||||
|
||||
fetchMana();
|
||||
}
|
||||
|
||||
|
@ -147,8 +146,11 @@ function showImportDialog() {
|
|||
quasar
|
||||
.dialog({
|
||||
component: ClaimLinesImport,
|
||||
componentProps: {
|
||||
ticketId: claim.value.ticketFk,
|
||||
},
|
||||
})
|
||||
.onOk(() => arrayData.refresh());
|
||||
.onOk(() => claimLinesForm.value.reload());
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
|
|
|
@ -14,6 +14,13 @@ const route = useRoute();
|
|||
const quasar = useQuasar();
|
||||
const { t } = useI18n();
|
||||
|
||||
const $props = defineProps({
|
||||
ticketId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
name: 'delivered',
|
||||
|
@ -99,7 +106,7 @@ function cancel() {
|
|||
</script>
|
||||
<template>
|
||||
<FetchData
|
||||
url="Sales/getClaimableFromTicket?ticketFk=16"
|
||||
:url="`Sales/getClaimableFromTicket?ticketFk=${$props.ticketId}`"
|
||||
@on-fetch="(data) => (claimableSales = data)"
|
||||
auto-load
|
||||
/>
|
||||
|
|
|
@ -20,7 +20,8 @@ describe('ClaimDevelopment', () => {
|
|||
cy.selectOption(firstLineReason, 'Novato');
|
||||
cy.saveCard();
|
||||
|
||||
cy.reload();
|
||||
cy.login('developer');
|
||||
cy.visit(`/#/claim/${claimId}/development`);
|
||||
cy.getValue(firstLineReason).should('have.text', 'Novato');
|
||||
|
||||
//Restart data
|
||||
|
@ -29,13 +30,16 @@ describe('ClaimDevelopment', () => {
|
|||
});
|
||||
|
||||
it('should add and remove new line', () => {
|
||||
cy.login('developer');
|
||||
cy.visit(`/#/claim/${claimId}/development`);
|
||||
//add row
|
||||
cy.addCard();
|
||||
cy.get(thirdRow).should('exist');
|
||||
|
||||
const rowData = [false, 'Novato', 'Roces', 'Compradores', 'employeeNick', 'Tour'];
|
||||
cy.fillRow(thirdRow, rowData);
|
||||
cy.saveCard();
|
||||
cy.login('developer');
|
||||
cy.visit(`/#/claim/${claimId}/development`);
|
||||
cy.validateRow(thirdRow, rowData);
|
||||
|
||||
cy.reload();
|
||||
|
|
|
@ -52,6 +52,13 @@ Cypress.Commands.add('getValue', (selector) => {
|
|||
}
|
||||
// Si es un QSelect
|
||||
else if ($el.find('.q-select__dropdown-icon').length) {
|
||||
cy.log(
|
||||
selector,
|
||||
cy.get(
|
||||
selector +
|
||||
'> .q-field > .q-field__inner > .q-field__control > .q-field__control-container > .q-field__native'
|
||||
)
|
||||
);
|
||||
return cy.get(
|
||||
selector +
|
||||
'> .q-field > .q-field__inner > .q-field__control > .q-field__control-container > .q-field__native > span'
|
||||
|
|
Loading…
Reference in New Issue