4043-form_data #25
|
@ -61,7 +61,7 @@ function responseError(error) {
|
|||
router.push({ path: '/login' });
|
||||
}
|
||||
|
||||
return Promise.resolve(error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
axios.interceptors.response.use((response) => {
|
||||
|
|
|
@ -15,13 +15,10 @@ const $props = defineProps({
|
|||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
limit: {
|
||||
type: String,
|
||||
default: '20',
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['fetch-data']);
|
||||
defineExpose({ fetch });
|
||||
const emit = defineEmits(['onFetch']);
|
||||
|
||||
onMounted(async () => {
|
||||
if ($props.autoLoad) {
|
||||
|
@ -34,7 +31,7 @@ async function fetch() {
|
|||
params: { filter: $props.filter },
|
||||
});
|
||||
|
||||
return emit('fetch-data', data);
|
||||
emit('onFetch', data);
|
||||
}
|
||||
|
||||
const render = () => {
|
||||
|
|
|
@ -5,11 +5,13 @@ import { useQuasar } from 'quasar';
|
|||
import axios from 'axios';
|
||||
|
||||
import { useState } from 'src/composables/useState';
|
||||
import { useValidator } from 'src/composables/useValidator';
|
||||
import SkeletonForm from 'src/components/SkeletonForm.vue';
|
||||
|
||||
const quasar = useQuasar();
|
||||
const { t } = useI18n();
|
||||
const state = useState();
|
||||
const { validate } = useValidator();
|
||||
|
||||
const $props = defineProps({
|
||||
url: {
|
||||
|
@ -26,7 +28,7 @@ const $props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['fetch-data']);
|
||||
const emit = defineEmits(['onFetch']);
|
||||
|
||||
defineExpose({
|
||||
save,
|
||||
|
@ -53,7 +55,7 @@ async function fetch() {
|
|||
|
||||
watch(formData.value, () => (hasChanges.value = true));
|
||||
|
||||
return emit('fetch-data', state.get($props.model));
|
||||
emit('onFetch', state.get($props.model));
|
||||
}
|
||||
|
||||
async function save() {
|
||||
|
@ -64,10 +66,10 @@ async function save() {
|
|||
});
|
||||
}
|
||||
isLoading.value = true;
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 5000);
|
||||
});
|
||||
await axios.patch($props.url, formData.value);
|
||||
|
||||
originalData.value = formData.value;
|
||||
hasChanges.value = false;
|
||||
isLoading.value = false;
|
||||
}
|
||||
|
||||
|
@ -75,22 +77,41 @@ function reset() {
|
|||
state.set($props.model, originalData.value);
|
||||
hasChanges.value = false;
|
||||
}
|
||||
|
||||
function filter(value, update, filterOptions) {
|
||||
update(
|
||||
() => {
|
||||
const { options, filterFn } = filterOptions;
|
||||
|
||||
options.value = filterFn(options, value);
|
||||
},
|
||||
(ref) => {
|
||||
ref.setOptionIndex(-1);
|
||||
ref.moveOptionSelection(1, true);
|
||||
}
|
||||
);
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<q-banner v-if="hasChanges" inline-actions class="text-white bg-red"> You have changes pending to save </q-banner>
|
||||
<q-banner v-if="hasChanges" class="text-white bg-warning">
|
||||
<q-icon name="warning" size="md" class="q-mr-md" />
|
||||
<span>{{ t('globals.changesToSave') }}</span>
|
||||
</q-banner>
|
||||
<q-form v-if="formData" @submit="save" @reset="reset" class="q-pa-md">
|
||||
<slot name="form" :data="formData"></slot>
|
||||
<slot name="actions">
|
||||
<q-btn :label="t('globals.save')" type="submit" color="primary" />
|
||||
<q-btn
|
||||
:label="t('globals.reset')"
|
||||
type="reset"
|
||||
class="q-ml-sm"
|
||||
color="primary"
|
||||
flat
|
||||
:disable="!hasChanges"
|
||||
/>
|
||||
</slot>
|
||||
<slot name="form" :data="formData" :validate="validate" :filter="filter"></slot>
|
||||
<div class="q-mt-lg">
|
||||
<slot name="actions">
|
||||
<q-btn :label="t('globals.save')" type="submit" color="primary" />
|
||||
<q-btn
|
||||
:label="t('globals.reset')"
|
||||
type="reset"
|
||||
class="q-ml-sm"
|
||||
color="primary"
|
||||
flat
|
||||
:disable="!hasChanges"
|
||||
/>
|
||||
</slot>
|
||||
</div>
|
||||
</q-form>
|
||||
<skeleton-form v-if="!formData" />
|
||||
<q-inner-loading :showing="isLoading" :label="t('globals.pleaseWait')" color="primary" />
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import axios from 'axios';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
@ -10,6 +10,10 @@ const $props = defineProps({
|
|||
type: String,
|
||||
default: '',
|
||||
},
|
||||
data: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
filter: {
|
||||
type: Object,
|
||||
default: null,
|
||||
|
@ -35,6 +39,17 @@ const $props = defineProps({
|
|||
defineEmits(['onNavigate']);
|
||||
defineExpose({ fetch });
|
||||
|
||||
onMounted(() => {
|
||||
if ($props.autoLoad) fetch();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => $props.data,
|
||||
() => {
|
||||
rows.value = $props.data;
|
||||
}
|
||||
);
|
||||
|
||||
const isLoading = ref(false);
|
||||
const hasMoreData = ref(false);
|
||||
const pagination = ref({
|
||||
|
@ -42,17 +57,13 @@ const pagination = ref({
|
|||
rowsPerPage: $props.rowsPerPage,
|
||||
page: 1,
|
||||
});
|
||||
|
||||
const rows = ref(null);
|
||||
|
||||
onMounted(() => {
|
||||
if ($props.autoLoad) fetch();
|
||||
else rows.value = [];
|
||||
});
|
||||
|
||||
async function fetch() {
|
||||
const { page, rowsPerPage, sortBy, descending } = pagination.value;
|
||||
|
||||
if (!$props.url) return;
|
||||
|
||||
isLoading.value = true;
|
||||
|
||||
const filter = {
|
||||
|
@ -89,7 +100,7 @@ async function fetch() {
|
|||
|
||||
async function onLoad(...params) {
|
||||
const done = params[1];
|
||||
if (!rows.value || rows.value.length === 0) return done(false);
|
||||
if (!rows.value || rows.value.length === 0 || !$props.url) return done(false);
|
||||
|
||||
pagination.value.page = pagination.value.page + 1;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ export default {
|
|||
yes: 'Yes',
|
||||
no: 'No',
|
||||
noChanges: 'No changes to save',
|
||||
changesToSave: 'You have changes pending to save',
|
||||
confirmRemove: 'You are about to delete this row. Are you sure?',
|
||||
rowAdded: 'Row added',
|
||||
rowRemoved: 'Row removed',
|
||||
|
|
|
@ -21,6 +21,7 @@ export default {
|
|||
yes: 'Si',
|
||||
no: 'No',
|
||||
noChanges: 'Sin cambios que guardar',
|
||||
changesToSave: 'Tienes cambios pendientes de guardar',
|
||||
confirmRemove: 'Vas a eliminar este registro. ¿Continuar?',
|
||||
rowAdded: 'Fila añadida',
|
||||
rowRemoved: 'Fila eliminada',
|
||||
|
|
|
@ -1,231 +1,242 @@
|
|||
<script setup>
|
||||
import { ref, onMounted, watch } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useQuasar } from 'quasar';
|
||||
import axios from 'axios';
|
||||
import { useSession } from 'src/composables/useSession';
|
||||
import { useValidator } from 'src/composables/useValidator';
|
||||
import SkeletonForm from 'src/components/SkeletonForm.vue';
|
||||
|
||||
onMounted(() => {
|
||||
fetch();
|
||||
fetchWorkers();
|
||||
fetchClaimStates();
|
||||
});
|
||||
import { useSession } from 'src/composables/useSession';
|
||||
import FetchData from 'src/components/FetchData.vue';
|
||||
import FormModel from 'src/components/FormModel.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const quasar = useQuasar();
|
||||
const { t } = useI18n();
|
||||
const { validate } = useValidator();
|
||||
const session = useSession();
|
||||
const token = session.getToken();
|
||||
|
||||
const claim = ref(null);
|
||||
const claimCopy = ref(null);
|
||||
const hasChanges = ref(false);
|
||||
// const claim = ref(null);
|
||||
// const claimCopy = ref(null);
|
||||
// const hasChanges = ref(false);
|
||||
|
||||
function fetch() {
|
||||
const id = route.params.id;
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
},
|
||||
// function fetch() {
|
||||
// const id = route.params.id;
|
||||
// const filter = {
|
||||
// include: [
|
||||
// {
|
||||
// relation: 'client',
|
||||
// scope: {
|
||||
// fields: ['name'],
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// };
|
||||
// const options = { params: { filter } };
|
||||
// axios.get(`Claims/${id}`, options).then(({ data }) => {
|
||||
// claim.value = data;
|
||||
// claimCopy.value = Object.assign({}, data);
|
||||
|
||||
// watch(claim.value, () => (hasChanges.value = true));
|
||||
// });
|
||||
// }
|
||||
|
||||
const claimFilter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
},
|
||||
],
|
||||
};
|
||||
const options = { params: { filter } };
|
||||
axios.get(`Claims/${id}`, options).then(({ data }) => {
|
||||
claim.value = data;
|
||||
claimCopy.value = Object.assign({}, data);
|
||||
|
||||
watch(claim.value, () => (hasChanges.value = true));
|
||||
});
|
||||
}
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const workers = ref([]);
|
||||
const workersCopy = ref([]);
|
||||
function fetchWorkers() {
|
||||
const filter = {
|
||||
where: {
|
||||
role: 'salesPerson',
|
||||
},
|
||||
};
|
||||
const options = { params: { filter } };
|
||||
axios.get(`Workers/activeWithRole`, options).then(({ data }) => {
|
||||
workers.value = data;
|
||||
workersCopy.value = data;
|
||||
});
|
||||
}
|
||||
|
||||
const claimStates = ref([]);
|
||||
const claimStatesCopy = ref([]);
|
||||
function fetchClaimStates() {
|
||||
axios.get(`ClaimStates`).then(({ data }) => {
|
||||
claimStates.value = data;
|
||||
claimStatesCopy.value = data;
|
||||
});
|
||||
|
||||
// function filter(value, update, options, originalOptions, filter) {
|
||||
// update(
|
||||
// () => {
|
||||
// if (value === '') {
|
||||
// options.value = originalOptions.value;
|
||||
|
||||
// return;
|
||||
// }
|
||||
|
||||
// options.value = options.value.filter(filter);
|
||||
// },
|
||||
// (ref) => {
|
||||
// ref.setOptionIndex(-1);
|
||||
// ref.moveOptionSelection(1, true);
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
|
||||
// function filterWorkers(value, update) {
|
||||
// const search = value.toLowerCase();
|
||||
|
||||
// filter(value, update, workers, workersCopy, (row) => {
|
||||
// const id = row.id;
|
||||
// const name = row.name.toLowerCase();
|
||||
|
||||
// const idMatch = id == search;
|
||||
// const nameMatch = name.indexOf(search) > -1;
|
||||
|
||||
// return idMatch || nameMatch;
|
||||
// });
|
||||
// }
|
||||
|
||||
// function filterStates(value, update) {
|
||||
// const search = value.toLowerCase();
|
||||
|
||||
// filter(value, update, claimStates, claimStatesCopy, (row) => {
|
||||
// const description = row.description.toLowerCase();
|
||||
|
||||
// return description.indexOf(search) > -1;
|
||||
// });
|
||||
// }
|
||||
function setWorkers(data) {
|
||||
workers.value = data;
|
||||
workersCopy.value = data;
|
||||
}
|
||||
|
||||
function filter(value, update, options, originalOptions, filter) {
|
||||
update(
|
||||
() => {
|
||||
if (value === '') {
|
||||
options.value = originalOptions.value;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
options.value = options.value.filter(filter);
|
||||
},
|
||||
(ref) => {
|
||||
ref.setOptionIndex(-1);
|
||||
ref.moveOptionSelection(1, true);
|
||||
}
|
||||
);
|
||||
function setClaimStates(data) {
|
||||
claimStates.value = data;
|
||||
claimStatesCopy.value = data;
|
||||
}
|
||||
|
||||
function filterWorkers(value, update) {
|
||||
const search = value.toLowerCase();
|
||||
const workerFilter = {
|
||||
options: workers,
|
||||
filterFn: (options, value) => {
|
||||
const search = value.toLowerCase();
|
||||
|
||||
filter(value, update, workers, workersCopy, (row) => {
|
||||
const id = row.id;
|
||||
const name = row.name.toLowerCase();
|
||||
if (value === '') return workersCopy.value;
|
||||
|
||||
const idMatch = id == search;
|
||||
const nameMatch = name.indexOf(search) > -1;
|
||||
return options.value.filter((row) => {
|
||||
const id = row.id;
|
||||
const name = row.name.toLowerCase();
|
||||
|
||||
return idMatch || nameMatch;
|
||||
});
|
||||
}
|
||||
const idMatches = id == search;
|
||||
const nameMatches = name.indexOf(search) > -1;
|
||||
|
||||
function filterStates(value, update) {
|
||||
const search = value.toLowerCase();
|
||||
|
||||
filter(value, update, claimStates, claimStatesCopy, (row) => {
|
||||
const description = row.description.toLowerCase();
|
||||
|
||||
return description.indexOf(search) > -1;
|
||||
});
|
||||
}
|
||||
|
||||
function save() {
|
||||
const id = route.params.id;
|
||||
const formData = claim.value;
|
||||
|
||||
if (!hasChanges.value) {
|
||||
return quasar.notify({
|
||||
type: 'negative',
|
||||
message: t('globals.noChanges'),
|
||||
return idMatches || nameMatches;
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
axios.patch(`Claims/${id}`, formData).then((hasChanges.value = false));
|
||||
}
|
||||
const statesFilter = {
|
||||
options: claimStates,
|
||||
filterFn: (options, value) => {
|
||||
const search = value.toLowerCase();
|
||||
|
||||
function onReset() {
|
||||
claim.value = claimCopy.value;
|
||||
hasChanges.value = false;
|
||||
}
|
||||
if (value === '') return claimStatesCopy.value;
|
||||
|
||||
return options.value.filter((row) => {
|
||||
const description = row.description.toLowerCase();
|
||||
|
||||
return description.indexOf(search) > -1;
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<fetch-data
|
||||
url="Workers/activeWithInheritedRole"
|
||||
:filter="{ where: { role: 'salesPerson' } }"
|
||||
@on-fetch="setWorkers"
|
||||
auto-load
|
||||
/>
|
||||
<fetch-data url="ClaimStates" @on-fetch="setClaimStates" auto-load />
|
||||
<q-page class="q-pa-md">
|
||||
<div class="container">
|
||||
<q-card class="q-pa-md">
|
||||
<skeleton-form v-if="!claim" />
|
||||
<q-form v-if="claim" @submit="save" @reset="onReset" greedy>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-input v-model="claim.client.name" :label="t('claim.basicData.customer')" disable />
|
||||
<q-card>
|
||||
<form-model :url="`Claims/${route.params.id}`" :filter="claimFilter" model="claim">
|
||||
<template #form="{ data, validate, filter }">
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-input v-model="data.client.name" :label="t('claim.basicData.customer')" disable />
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-input v-model="data.created" mask="####-##-##" fill-mask="_" autofocus>
|
||||
<template #append>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||
<q-date v-model="data.created" mask="YYYY-MM-DD">
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn v-close-popup label="Close" color="primary" flat />
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-input v-model="claim.created" mask="####-##-##" fill-mask="_" autofocus>
|
||||
<template #append>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||
<q-date v-model="claim.created" mask="YYYY-MM-DD">
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn v-close-popup label="Close" color="primary" flat />
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-select
|
||||
v-model="data.workerFk"
|
||||
:options="workers"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
emit-value
|
||||
:label="t('claim.basicData.assignedTo')"
|
||||
map-options
|
||||
use-input
|
||||
@filter="(value, update) => filter(value, update, workerFilter)"
|
||||
:rules="validate('claim.claimStateFk')"
|
||||
:input-debounce="0"
|
||||
>
|
||||
<template #before>
|
||||
<q-avatar color="orange">
|
||||
<q-img
|
||||
v-if="data.workerFk"
|
||||
:src="`/api/Images/user/160x160/${data.workerFk}/download?access_token=${token}`"
|
||||
spinner-color="white"
|
||||
/>
|
||||
</q-avatar>
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-select
|
||||
v-model="data.claimStateFk"
|
||||
:options="claimStates"
|
||||
option-value="id"
|
||||
option-label="description"
|
||||
emit-value
|
||||
:label="t('claim.basicData.state')"
|
||||
map-options
|
||||
use-input
|
||||
@filter="(value, update) => filter(value, update, statesFilter)"
|
||||
:rules="validate('claim.claimStateFk')"
|
||||
:input-debounce="0"
|
||||
>
|
||||
</q-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-select
|
||||
v-model="claim.workerFk"
|
||||
:options="workers"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
emit-value
|
||||
:label="t('claim.basicData.assignedTo')"
|
||||
map-options
|
||||
use-input
|
||||
@filter="filterWorkers"
|
||||
:rules="validate('claim.claimStateFk')"
|
||||
:input-debounce="0"
|
||||
>
|
||||
<template #before>
|
||||
<q-avatar color="orange">
|
||||
<q-img
|
||||
v-if="claim.workerFk"
|
||||
:src="`/api/Images/user/160x160/${claim.workerFk}/download?access_token=${token}`"
|
||||
spinner-color="white"
|
||||
/>
|
||||
</q-avatar>
|
||||
</template>
|
||||
</q-select>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-input
|
||||
v-model="data.packages"
|
||||
:label="t('claim.basicData.packages')"
|
||||
:rules="validate('claim.packages')"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-input
|
||||
v-model="data.rma"
|
||||
:label="t('claim.basicData.returnOfMaterial')"
|
||||
:rules="validate('claim.rma')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-select
|
||||
v-model="claim.claimStateFk"
|
||||
:options="claimStates"
|
||||
option-value="id"
|
||||
option-label="description"
|
||||
emit-value
|
||||
:label="t('claim.basicData.state')"
|
||||
map-options
|
||||
use-input
|
||||
@filter="filterStates"
|
||||
:rules="validate('claim.claimStateFk')"
|
||||
:input-debounce="0"
|
||||
>
|
||||
</q-select>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-checkbox v-model="data.hasToPickUp" :label="t('claim.basicData.picked')" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-input
|
||||
v-model="claim.packages"
|
||||
:label="t('claim.basicData.packages')"
|
||||
:rules="validate('claim.packages')"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-input
|
||||
v-model="claim.rma"
|
||||
:label="t('claim.basicData.returnOfMaterial')"
|
||||
:rules="validate('claim.rma')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-checkbox v-model="claim.hasToPickUp" :label="t('claim.basicData.picked')" />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<q-btn :label="t('globals.save')" type="submit" color="primary" />
|
||||
<q-btn :label="t('globals.reset')" type="reset" class="q-ml-sm" color="primary" flat />
|
||||
</div>
|
||||
</q-form>
|
||||
</template>
|
||||
</form-model>
|
||||
</q-card>
|
||||
</div>
|
||||
</q-page>
|
||||
|
|
|
@ -163,7 +163,7 @@ function stateColor(code) {
|
|||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page-container>
|
||||
<router-view v-if="claim.id" :claim="claim"></router-view>
|
||||
<router-view></router-view>
|
||||
</q-page-container>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,52 +1,51 @@
|
|||
<script setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useRoute } from 'vue-router';
|
||||
import axios from 'axios';
|
||||
import SmartCard from 'src/components/SmartCard.vue';
|
||||
import FetchData from 'src/components/FetchData.vue';
|
||||
import { toDate } from 'src/filters';
|
||||
|
||||
onMounted(() => fetch());
|
||||
|
||||
const $props = defineProps({
|
||||
claim: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const quasar = useQuasar();
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
|
||||
// const card = ref();
|
||||
const claim = ref([]);
|
||||
const fetcher = ref();
|
||||
|
||||
// const rma = computed(() => claim.value.rma);
|
||||
|
||||
const filter = {
|
||||
include: {
|
||||
relation: 'worker',
|
||||
relation: 'rmas',
|
||||
scope: {
|
||||
include: {
|
||||
relation: 'user',
|
||||
relation: 'worker',
|
||||
scope: {
|
||||
include: {
|
||||
relation: 'user',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
where: {
|
||||
code: $props.claim.rma,
|
||||
},
|
||||
};
|
||||
|
||||
function fetch() {
|
||||
//console.log($props.claim);
|
||||
}
|
||||
|
||||
function addRow() {
|
||||
async function addRow() {
|
||||
const formData = {
|
||||
code: $props.claim.rma,
|
||||
code: claim.value.rma,
|
||||
};
|
||||
|
||||
axios.post(`ClaimRmas`, formData).then(() => {
|
||||
quasar.notify({
|
||||
type: 'positive',
|
||||
message: t('globals.rowAdded'),
|
||||
icon: 'check',
|
||||
});
|
||||
await axios.post(`ClaimRmas`, formData);
|
||||
await fetcher.value.fetch();
|
||||
|
||||
quasar.notify({
|
||||
type: 'positive',
|
||||
message: t('globals.rowAdded'),
|
||||
icon: 'check',
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -57,16 +56,17 @@ function confirmRemove(id) {
|
|||
rmaId.value = id;
|
||||
}
|
||||
|
||||
function remove() {
|
||||
async function remove() {
|
||||
const id = rmaId.value;
|
||||
axios.delete(`ClaimRmas/${id}`).then(() => {
|
||||
confirmShown.value = false;
|
||||
|
||||
quasar.notify({
|
||||
type: 'positive',
|
||||
message: t('globals.rowRemoved'),
|
||||
icon: 'check',
|
||||
});
|
||||
await axios.delete(`ClaimRmas/${id}`);
|
||||
await fetcher.value.fetch();
|
||||
confirmShown.value = false;
|
||||
|
||||
quasar.notify({
|
||||
type: 'positive',
|
||||
message: t('globals.rowRemoved'),
|
||||
icon: 'check',
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,13 @@ function hide() {
|
|||
}
|
||||
</script>
|
||||
<template>
|
||||
<fetch-data
|
||||
ref="fetcher"
|
||||
:url="`Claims/${route.params.id}`"
|
||||
:filter="filter"
|
||||
@on-fetch="($data) => (claim = $data)"
|
||||
auto-load
|
||||
/>
|
||||
<q-page class="q-pa-md sticky">
|
||||
<q-page-sticky expand position="top">
|
||||
<q-toolbar class="bg-grey-9">
|
||||
|
@ -85,7 +92,7 @@ function hide() {
|
|||
</q-toolbar>
|
||||
</q-page-sticky>
|
||||
|
||||
<smart-card ref="card" url="/ClaimRmas" :filter="filter" sort-by="id DESC" auto-load>
|
||||
<smart-card :data="claim.rmas">
|
||||
<template #header="{ row }">
|
||||
<q-item-label caption>{{ t('claim.rma.user') }}</q-item-label>
|
||||
<q-item-label>{{ row.worker.user.name }}</q-item-label>
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
<script setup>
|
||||
import { reactive, watch } from 'vue'
|
||||
|
||||
const customer = reactive({
|
||||
name: '',
|
||||
});
|
||||
|
||||
watch(() => customer.name, () => {
|
||||
console.log('customer.name changed');
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-page class="q-pa-md">
|
||||
<q-card class="q-pa-md">
|
||||
<q-form @submit="onSubmit" @reset="onReset" class="q-gutter-md">
|
||||
<q-input
|
||||
filled
|
||||
v-model="customer.name"
|
||||
label="Your name *"
|
||||
hint="Name and surname"
|
||||
lazy-rules
|
||||
:rules="[val => val && val.length > 0 || 'Please type something']"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
filled
|
||||
type="number"
|
||||
v-model="age"
|
||||
label="Your age *"
|
||||
lazy-rules
|
||||
:rules="[
|
||||
val => val !== null && val !== '' || 'Please type your age',
|
||||
val => val > 0 && val < 100 || 'Please type a real age'
|
||||
]"
|
||||
/>
|
||||
|
||||
<div>
|
||||
<q-btn label="Submit" type="submit" color="primary" />
|
||||
<q-btn label="Reset" type="reset" color="primary" flat class="q-ml-sm" />
|
||||
</div>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-page>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card {
|
||||
width: 100%;
|
||||
max-width: 60em;
|
||||
}
|
||||
</style>
|
|
@ -1,86 +1,60 @@
|
|||
<script setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
// import { useQuasar } from 'quasar';
|
||||
// import axios from 'axios';
|
||||
|
||||
import { useSession } from 'src/composables/useSession';
|
||||
import { useValidator } from 'src/composables/useValidator';
|
||||
import { useState } from 'src/composables/useState';
|
||||
import FetchData from 'src/components/FetchData.vue';
|
||||
import FormModel from 'src/components/FormModel.vue';
|
||||
|
||||
onMounted(() => {
|
||||
// fetch();
|
||||
// fetchWorkers();
|
||||
// fetchBusinessTypes();
|
||||
// fetchContactChannels();
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
// const quasar = useQuasar();
|
||||
const { t } = useI18n();
|
||||
const { validate } = useValidator();
|
||||
const state = useState();
|
||||
const session = useSession();
|
||||
const token = session.getToken();
|
||||
const data2 = state.get('customer');
|
||||
console.log(data2);
|
||||
|
||||
const workers = ref([]);
|
||||
const contactChannels = ref([]);
|
||||
const workersCopy = ref([]);
|
||||
const businessTypes = ref([]);
|
||||
const contactChannels = ref([]);
|
||||
|
||||
// const customer = ref(null);
|
||||
// const customerCopy = ref(null);
|
||||
// const hasChanges = ref(false);
|
||||
function setWorkers(data) {
|
||||
workers.value = data;
|
||||
workersCopy.value = data;
|
||||
}
|
||||
|
||||
// function filter(value, update, options, originalOptions, filter) {
|
||||
// update(
|
||||
// () => {
|
||||
// if (value === '') {
|
||||
// options.value = originalOptions.value;
|
||||
const filterOptions = {
|
||||
options: workers,
|
||||
filterFn: (options, value) => {
|
||||
const search = value.toLowerCase();
|
||||
|
||||
// return;
|
||||
// }
|
||||
if (value === '') return workersCopy.value;
|
||||
|
||||
// options.value = options.value.filter(filter);
|
||||
// },
|
||||
// (ref) => {
|
||||
// ref.setOptionIndex(-1);
|
||||
// ref.moveOptionSelection(1, true);
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
return options.value.filter((row) => {
|
||||
const id = row.id;
|
||||
const name = row.name.toLowerCase();
|
||||
|
||||
// function filterWorkers(value, update) {
|
||||
// const search = value.toLowerCase();
|
||||
const idMatches = id == search;
|
||||
const nameMatches = name.indexOf(search) > -1;
|
||||
|
||||
// filter(value, update, workers, workersCopy, (row) => {
|
||||
// const id = row.id;
|
||||
// const name = row.name.toLowerCase();
|
||||
|
||||
// const idMatch = id == search;
|
||||
// const nameMatch = name.indexOf(search) > -1;
|
||||
|
||||
// return idMatch || nameMatch;
|
||||
// });
|
||||
// }
|
||||
return idMatches || nameMatches;
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<fetch-data
|
||||
url="Workers/activeWithRole"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
:filter="{ where: { role: 'salesPerson' } }"
|
||||
@fetch-data="($data) => (workers = $data)"
|
||||
@on-fetch="setWorkers"
|
||||
auto-load
|
||||
/>
|
||||
<fetch-data url="ContactChannels" @fetch-data="($data) => (contactChannels = $data)" auto-load />
|
||||
<fetch-data url="BusinessTypes" @fetch-data="($data) => (businessTypes = $data)" auto-load />
|
||||
<fetch-data url="ContactChannels" @on-fetch="($data) => (contactChannels = $data)" auto-load />
|
||||
<fetch-data url="BusinessTypes" @on-fetch="($data) => (businessTypes = $data)" auto-load />
|
||||
<q-page class="q-pa-md">
|
||||
<div class="container">
|
||||
<q-card>
|
||||
<form-model :url="`Clients/${route.params.id}`" model="customer">
|
||||
<template #form="{ data }">
|
||||
<template #form="{ data, validate, filter }">
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-input
|
||||
|
@ -152,7 +126,7 @@ const businessTypes = ref([]);
|
|||
:label="t('customer.basicData.salesPerson')"
|
||||
map-options
|
||||
use-input
|
||||
@filter="filterWorkers"
|
||||
@filter="(value, update) => filter(value, update, filterOptions)"
|
||||
:rules="validate('client.salesPersonFk')"
|
||||
:input-debounce="0"
|
||||
>
|
||||
|
|
|
@ -34,15 +34,6 @@ export default {
|
|||
roles: ['claimManager']
|
||||
},
|
||||
component: () => import('src/pages/Claim/ClaimRmaList.vue'),
|
||||
},
|
||||
{
|
||||
name: 'ClaimCreate',
|
||||
path: 'create',
|
||||
meta: {
|
||||
title: 'createClaim',
|
||||
icon: 'vn:addperson',
|
||||
},
|
||||
component: () => import('src/pages/Claim/ClaimCreate.vue'),
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -76,8 +67,7 @@ export default {
|
|||
title: 'rma',
|
||||
roles: ['claimManager']
|
||||
},
|
||||
component: () => import('src/pages/Claim/Card/ClaimRma.vue'),
|
||||
props: { claim: true }
|
||||
component: () => import('src/pages/Claim/Card/ClaimRma.vue')
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue