forked from verdnatura/salix-front
Merge branch '6825-vnTable' of https://gitea.verdnatura.es/verdnatura/salix-front into 6553-workerBusiness
This commit is contained in:
commit
b6836fc59e
97
CHANGELOG.md
97
CHANGELOG.md
|
@ -1,3 +1,100 @@
|
||||||
|
# Version 24.24 - 2024-06-11
|
||||||
|
|
||||||
|
### Added 🆕
|
||||||
|
|
||||||
|
- feat: 6942 hashtag in key : value summary by:jgallego
|
||||||
|
- feat: #6957: Rename FetchedTags instance tag by:Javier Segarra
|
||||||
|
- feat: refactor template by:Javier Segarra
|
||||||
|
- feat: refs #6600 Add option to add comment for photo motivation by:jorgep
|
||||||
|
- feat: refs #6942 test e2e tobook & toUnbook by:jorgep
|
||||||
|
- feat: refs #6942 to book summary button & reactive value by:jorgep
|
||||||
|
- feat: refs #6942 to unbook by:jorgep
|
||||||
|
- feat: refs #6942 url update by:jorgep
|
||||||
|
- feat: refs #6942 use correct currency in InvoiceIn components by:jorgep
|
||||||
|
- feat: refs #6942 vat rate total by:jorgep
|
||||||
|
- feat: refs #7494 new icons (7494-icons) by:alexm
|
||||||
|
- feat: refs #7494 new icons by:alexm
|
||||||
|
- feat: refs #7542 drop space by:jorgep
|
||||||
|
- feat: refs #7542 empty by:jorgep
|
||||||
|
- fix: refs #6942 changes and new features by:jorgep
|
||||||
|
- fix: style by:Javier Segarra
|
||||||
|
- style: color transparent when is fetive by:Javier Segarra
|
||||||
|
- style: fix color when is empty by:Javier Segarra
|
||||||
|
- style: reset poc style (6957_refactorFetechedTags) by:Javier Segarra
|
||||||
|
- style: reset poc style by:Javier Segarra
|
||||||
|
- style updates by:Javier Segarra
|
||||||
|
|
||||||
|
### Changed 📦
|
||||||
|
|
||||||
|
- feat: refactor template by:Javier Segarra
|
||||||
|
- perf: 6957 add color as new shared variable by:Javier Segarra
|
||||||
|
- perf: 6957 change fetchedTags color by:Javier Segarra
|
||||||
|
- perf: remove local tree variable by:Javier Segarra
|
||||||
|
- refactor: add flat by:alexm
|
||||||
|
- refactor: refs #6600 replace QInput to VnInput by:jorgep
|
||||||
|
- refactor: refs #6652 improved defaulter section by:Jon
|
||||||
|
- refactor: refs #6942 Fix getTotalAmount function to correctly calculate the total amount in InvoiceInDueDay.vue by:jorgep
|
||||||
|
- refactor: refs #6942 new summary layout by:jorgep
|
||||||
|
- refactor: refs #6942 store key & actions by:jorgep
|
||||||
|
- refactor: refs #6942 summary by:jorgep
|
||||||
|
- refactor: refs #6942 use router hook by:jorgep
|
||||||
|
- refactor: refs #6942 WIP summary layout by:jorgep
|
||||||
|
|
||||||
|
### Fixed 🛠️
|
||||||
|
|
||||||
|
- fix: 9-12 by:Javier Segarra
|
||||||
|
- fix: defaulter icon by:alexm
|
||||||
|
- fix: refs #5186 validation by:jorgep
|
||||||
|
- fix: refs #6095 add reFfk null on search by:pablone
|
||||||
|
- fix: refs #6942 cardDescriptor use store if its popup or different source data by:jorgep
|
||||||
|
- fix: refs #6942 changes and new features by:jorgep
|
||||||
|
- fix: refs #6942 drop comments by:jorgep
|
||||||
|
- fix: refs #6942 drop console by:jorgep
|
||||||
|
- fix: refs #6942 drop console.log by:jorgep
|
||||||
|
- fix: refs #6942 e2e test (origin/6942-warmfix-fixFormModel) by:jorgep
|
||||||
|
- fix: refs #6942 e2e tests by:jorgep
|
||||||
|
- fix: refs #6942 e2e tests by:jorgep
|
||||||
|
- fix: refs #6942 fix emit on data saved by:jorgep
|
||||||
|
- fix: refs #6942 fix emit on reset by:jorgep
|
||||||
|
- fix: refs #6942 fix vncard by:jorgep
|
||||||
|
- fix: refs #6942 formModel & CardDescriptor by:jorgep
|
||||||
|
- fix: refs #6942 formModel watch changes & invoiceInCreate by:jorgep
|
||||||
|
- fix: refs #6942 import by:jorgep
|
||||||
|
- fix: refs #6942 reloading by:jorgep
|
||||||
|
- fix: refs #6942 rollback by:jorgep
|
||||||
|
- fix: refs #6942 selectable expense by:jorgep
|
||||||
|
- fix: refs #6942 skip e2e tests by:jorgep
|
||||||
|
- fix: refs #6942 table bottom highlight & drop isBooked field by:jorgep
|
||||||
|
- fix: refs #6942 tests e2e by:jorgep
|
||||||
|
- fix: refs #6942 tests & summary table spacing by:jorgep
|
||||||
|
- fix: refs #6942 unit tests by:jorgep
|
||||||
|
- fix: refs #6942 vnLocation by:jorgep
|
||||||
|
- fix: refs #6942 wip: formModel by:jorgep
|
||||||
|
- fix: refs #7542 use right panel by:jorgep
|
||||||
|
- fix: searchbar redirect by:alexm
|
||||||
|
- fix: style by:Javier Segarra
|
||||||
|
- fix: WorkerCalendarItem by:Javier Segarra
|
||||||
|
- mini fix by:wbuezas
|
||||||
|
- refs #6111 clean code fix changes by:carlossa
|
||||||
|
- refs #6111 fix merge, fix column by:carlossa
|
||||||
|
- refs #6111 fix qtable, actions, scroll by:carlossa
|
||||||
|
- refs #6111 fix routeList by:carlossa
|
||||||
|
- refs #6111 fix sticky by:carlossa
|
||||||
|
- refs #6111 fix trad remove logs by:carlossa
|
||||||
|
- refs #6111 fix visibleColumns by:carlossa
|
||||||
|
- refs #6111 routeList fix by:carlossa
|
||||||
|
- refs #6332 fix calendar by:carlossa
|
||||||
|
- refs #6332 fix colors by:carlossa
|
||||||
|
- refs #6332 fix festive by:carlossa
|
||||||
|
- refs #6820 fix BasicData Tickets by:carlossa
|
||||||
|
- refs #6820 fix error front by:carlossa
|
||||||
|
- refs #6820 fix traduction by:carlossa
|
||||||
|
- refs #7391 fix textarea by:carlossa
|
||||||
|
- refs #7396 fix summary by:carlossa
|
||||||
|
- Search childs fix by:wbuezas
|
||||||
|
- small fix by:wbuezas
|
||||||
|
- style: fix color when is empty by:Javier Segarra
|
||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
|
@ -94,7 +94,7 @@ pipeline {
|
||||||
sh 'quasar build'
|
sh 'quasar build'
|
||||||
script {
|
script {
|
||||||
def packageJson = readJSON file: 'package.json'
|
def packageJson = readJSON file: 'package.json'
|
||||||
env.VERSION = packageJson.version
|
env.VERSION = "${packageJson.version}-build${env.BUILD_ID}"
|
||||||
}
|
}
|
||||||
dockerBuild()
|
dockerBuild()
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ pipeline {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
def packageJson = readJSON file: 'package.json'
|
def packageJson = readJSON file: 'package.json'
|
||||||
env.VERSION = packageJson.version
|
env.VERSION = "${packageJson.version}-build${env.BUILD_ID}"
|
||||||
}
|
}
|
||||||
withKubeConfig([
|
withKubeConfig([
|
||||||
serverUrl: "$KUBERNETES_API",
|
serverUrl: "$KUBERNETES_API",
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
features_types=(chore feat style)
|
||||||
|
changes_types=(refactor perf)
|
||||||
|
fix_types=(fix revert)
|
||||||
|
file="CHANGELOG.md"
|
||||||
|
file_tmp="temp_log.txt"
|
||||||
|
file_current_tmp="temp_current_log.txt"
|
||||||
|
|
||||||
|
setType(){
|
||||||
|
echo "### $1" >> $file_tmp
|
||||||
|
arr=("$@")
|
||||||
|
echo "" > $file_current_tmp
|
||||||
|
for i in "${arr[@]}"
|
||||||
|
do
|
||||||
|
git log --grep="$i" --oneline --no-merges --format="- %s %d by:%an" master..test >> $file_current_tmp
|
||||||
|
done
|
||||||
|
# remove duplicates
|
||||||
|
sort -o $file_current_tmp -u $file_current_tmp
|
||||||
|
cat $file_current_tmp >> $file_tmp
|
||||||
|
echo "" >> $file_tmp
|
||||||
|
# remove tmp current file
|
||||||
|
[ -e $file_current_tmp ] && rm $file_current_tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "# Version XX.XX - XXXX-XX-XX" >> $file_tmp
|
||||||
|
echo "" >> $file_tmp
|
||||||
|
|
||||||
|
setType "Added 🆕" "${features_types[@]}"
|
||||||
|
setType "Changed 📦" "${changes_types[@]}"
|
||||||
|
setType "Fixed 🛠️" "${fix_types[@]}"
|
||||||
|
|
||||||
|
cat $file >> $file_tmp
|
||||||
|
mv $file_tmp $file
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,10 @@ const $props = defineProps({
|
||||||
default: '',
|
default: '',
|
||||||
description: 'It is used for redirect on click "save and continue"',
|
description: 'It is used for redirect on click "save and continue"',
|
||||||
},
|
},
|
||||||
|
hasSubtoolbar: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
|
@ -310,7 +314,7 @@ watch(formUrl, async () => {
|
||||||
</template>
|
</template>
|
||||||
</VnPaginate>
|
</VnPaginate>
|
||||||
<SkeletonTable v-if="!formData" :columns="$attrs.columns?.length" />
|
<SkeletonTable v-if="!formData" :columns="$attrs.columns?.length" />
|
||||||
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
|
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown() && hasSubtoolbar">
|
||||||
<QBtnGroup push style="column-gap: 10px">
|
<QBtnGroup push style="column-gap: 10px">
|
||||||
<slot name="moreBeforeActions" />
|
<slot name="moreBeforeActions" />
|
||||||
<QBtn
|
<QBtn
|
||||||
|
|
|
@ -12,6 +12,7 @@ import SkeletonForm from 'components/ui/SkeletonForm.vue';
|
||||||
import VnConfirm from './ui/VnConfirm.vue';
|
import VnConfirm from './ui/VnConfirm.vue';
|
||||||
import { tMobile } from 'src/composables/tMobile';
|
import { tMobile } from 'src/composables/tMobile';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
const { push } = useRouter();
|
const { push } = useRouter();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
|
@ -20,6 +21,7 @@ const stateStore = useStateStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { validate } = useValidator();
|
const { validate } = useValidator();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
url: {
|
url: {
|
||||||
|
@ -28,7 +30,7 @@ const $props = defineProps({
|
||||||
},
|
},
|
||||||
model: {
|
model: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: null,
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -82,17 +84,18 @@ const $props = defineProps({
|
||||||
description: 'It is used for redirect on click "save and continue"',
|
description: 'It is used for redirect on click "save and continue"',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['onFetch', 'onDataSaved']);
|
const emit = defineEmits(['onFetch', 'onDataSaved']);
|
||||||
|
const modelValue = computed(
|
||||||
|
() => $props.model ?? `formModel_${route?.meta?.title ?? route.name}`
|
||||||
|
).value;
|
||||||
const componentIsRendered = ref(false);
|
const componentIsRendered = ref(false);
|
||||||
const arrayData = useArrayData($props.model);
|
const arrayData = useArrayData(modelValue);
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
// Si elegimos observar los cambios del form significa que inicialmente las actions estaran deshabilitadas
|
// Si elegimos observar los cambios del form significa que inicialmente las actions estaran deshabilitadas
|
||||||
const isResetting = ref(false);
|
const isResetting = ref(false);
|
||||||
const hasChanges = ref(!$props.observeFormChanges);
|
const hasChanges = ref(!$props.observeFormChanges);
|
||||||
const originalData = ref({});
|
const originalData = ref({});
|
||||||
const formData = computed(() => state.get($props.model));
|
const formData = computed(() => state.get(modelValue));
|
||||||
const formUrl = computed(() => $props.url);
|
const formUrl = computed(() => $props.url);
|
||||||
const defaultButtons = computed(() => ({
|
const defaultButtons = computed(() => ({
|
||||||
save: {
|
save: {
|
||||||
|
@ -114,11 +117,12 @@ onMounted(async () => {
|
||||||
nextTick(() => (componentIsRendered.value = true));
|
nextTick(() => (componentIsRendered.value = true));
|
||||||
|
|
||||||
// Podemos enviarle al form la estructura de data inicial sin necesidad de fetchearla
|
// Podemos enviarle al form la estructura de data inicial sin necesidad de fetchearla
|
||||||
state.set($props.model, $props.formInitialData);
|
state.set(modelValue, $props.formInitialData);
|
||||||
|
|
||||||
if ($props.autoLoad && !$props.formInitialData && $props.url) await fetch();
|
if (!$props.formInitialData) {
|
||||||
|
if ($props.autoLoad && $props.url) await fetch();
|
||||||
else if (arrayData.store.data) updateAndEmit('onFetch', arrayData.store.data);
|
else if (arrayData.store.data) updateAndEmit('onFetch', arrayData.store.data);
|
||||||
|
}
|
||||||
if ($props.observeFormChanges) {
|
if ($props.observeFormChanges) {
|
||||||
watch(
|
watch(
|
||||||
() => formData.value,
|
() => formData.value,
|
||||||
|
@ -161,8 +165,8 @@ onBeforeRouteLeave((to, from, next) => {
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
// Restauramos los datos originales en el store si se realizaron cambios en el formulario pero no se guardaron, evitando modificaciones erróneas.
|
// Restauramos los datos originales en el store si se realizaron cambios en el formulario pero no se guardaron, evitando modificaciones erróneas.
|
||||||
if (hasChanges.value) return state.set($props.model, originalData.value);
|
if (hasChanges.value) return state.set(modelValue, originalData.value);
|
||||||
if ($props.clearStoreOnUnmount) state.unset($props.model);
|
if ($props.clearStoreOnUnmount) state.unset(modelValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function fetch() {
|
async function fetch() {
|
||||||
|
@ -174,7 +178,7 @@ async function fetch() {
|
||||||
|
|
||||||
updateAndEmit('onFetch', data);
|
updateAndEmit('onFetch', data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
state.set($props.model, {});
|
state.set(modelValue, {});
|
||||||
originalData.value = {};
|
originalData.value = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,11 +239,11 @@ function filter(value, update, filterOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateAndEmit(evt, val, res) {
|
function updateAndEmit(evt, val, res) {
|
||||||
state.set($props.model, val);
|
state.set(modelValue, val);
|
||||||
originalData.value = val && JSON.parse(JSON.stringify(val));
|
originalData.value = val && JSON.parse(JSON.stringify(val));
|
||||||
if (!$props.url) arrayData.store.data = val;
|
if (!$props.url) arrayData.store.data = val;
|
||||||
|
|
||||||
emit(evt, state.get($props.model), res);
|
emit(evt, state.get(modelValue), res);
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ save, isLoading, hasChanges });
|
defineExpose({ save, isLoading, hasChanges });
|
||||||
|
|
|
@ -134,6 +134,7 @@ const col = computed(() => {
|
||||||
const components = computed(() => $props.components ?? defaultComponents);
|
const components = computed(() => $props.components ?? defaultComponents);
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
<div class="row no-wrap fit">
|
||||||
<VnComponent
|
<VnComponent
|
||||||
v-if="col.before"
|
v-if="col.before"
|
||||||
:prop="col.before"
|
:prop="col.before"
|
||||||
|
@ -156,4 +157,5 @@ const components = computed(() => $props.components ?? defaultComponents);
|
||||||
:value="model"
|
:value="model"
|
||||||
v-model="model"
|
v-model="model"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -53,7 +53,7 @@ const $props = defineProps({
|
||||||
},
|
},
|
||||||
isEditable: {
|
isEditable: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: null,
|
default: false,
|
||||||
},
|
},
|
||||||
useModel: {
|
useModel: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -83,7 +83,6 @@ const tableModes = [
|
||||||
icon: 'grid_view',
|
icon: 'grid_view',
|
||||||
title: t('grid view'),
|
title: t('grid view'),
|
||||||
value: 'card',
|
value: 'card',
|
||||||
disable: () => console.log('called'),
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -212,28 +211,29 @@ defineExpose({
|
||||||
</VnFilterPanel>
|
</VnFilterPanel>
|
||||||
</QScrollArea>
|
</QScrollArea>
|
||||||
</QDrawer>
|
</QDrawer>
|
||||||
|
<!-- class in div to fix warn-->
|
||||||
|
<div class="q-px-md">
|
||||||
<CrudModel
|
<CrudModel
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
class="q-px-md"
|
|
||||||
:limit="20"
|
:limit="20"
|
||||||
ref="CrudModelRef"
|
ref="CrudModelRef"
|
||||||
:search-url="searchUrl"
|
:search-url="searchUrl"
|
||||||
:disable-infinite-scroll="mode == 'table'"
|
:disable-infinite-scroll="mode == 'table'"
|
||||||
@save-changes="reload"
|
@save-changes="reload"
|
||||||
|
:has-subtoolbar="isEditable"
|
||||||
>
|
>
|
||||||
<template #body="{ rows }">
|
<template #body="{ rows }">
|
||||||
<QTable
|
<QTable
|
||||||
|
v-bind="$attrs['QTable']"
|
||||||
class="vnTable"
|
class="vnTable"
|
||||||
:columns="splittedColumns.columns"
|
:columns="splittedColumns.columns"
|
||||||
:rows="rows"
|
:rows="rows"
|
||||||
row-key="id"
|
|
||||||
selection="multiple"
|
|
||||||
v-model:selected="selected"
|
v-model:selected="selected"
|
||||||
:grid="mode != 'table'"
|
:grid="mode != 'table'"
|
||||||
table-header-class="bg-header"
|
table-header-class="bg-header"
|
||||||
card-container-class="grid-three"
|
card-container-class="grid-three"
|
||||||
flat
|
flat
|
||||||
:style="mode == 'table' && 'max-height: 92vh'"
|
:style="mode == 'table' && 'max-height: 90vh'"
|
||||||
virtual-scroll
|
virtual-scroll
|
||||||
@virtual-scroll="
|
@virtual-scroll="
|
||||||
(event) =>
|
(event) =>
|
||||||
|
@ -269,7 +269,11 @@ defineExpose({
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #header-cell="{ col }">
|
<template #header-cell="{ col }">
|
||||||
<QTh auto-width style="min-width: 100px" v-if="$props.columnSearch">
|
<QTh
|
||||||
|
auto-width
|
||||||
|
style="min-width: 100px"
|
||||||
|
v-if="$props.columnSearch"
|
||||||
|
>
|
||||||
<VnTableFilter
|
<VnTableFilter
|
||||||
:column="col"
|
:column="col"
|
||||||
:show-title="true"
|
:show-title="true"
|
||||||
|
@ -284,7 +288,10 @@ defineExpose({
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-tableStatus="{ col, row }">
|
<template #body-cell-tableStatus="{ col, row }">
|
||||||
<QTd auto-width :class="`text-${col.align ?? 'left'}`">
|
<QTd auto-width :class="`text-${col.align ?? 'left'}`">
|
||||||
<VnTableChip :columns="splittedColumns.columnChips" :row="row">
|
<VnTableChip
|
||||||
|
:columns="splittedColumns.columnChips"
|
||||||
|
:row="row"
|
||||||
|
>
|
||||||
<template #afterChip>
|
<template #afterChip>
|
||||||
<slot name="afterChip" :row="row"></slot>
|
<slot name="afterChip" :row="row"></slot>
|
||||||
</template>
|
</template>
|
||||||
|
@ -322,7 +329,9 @@ defineExpose({
|
||||||
class="q-px-sm"
|
class="q-px-sm"
|
||||||
flat
|
flat
|
||||||
:class="
|
:class="
|
||||||
btn.isPrimary ? 'text-primary-light' : 'color-vn-text '
|
btn.isPrimary
|
||||||
|
? 'text-primary-light'
|
||||||
|
: 'color-vn-text '
|
||||||
"
|
"
|
||||||
@click="btn.action(row)"
|
@click="btn.action(row)"
|
||||||
/>
|
/>
|
||||||
|
@ -394,7 +403,9 @@ defineExpose({
|
||||||
>
|
>
|
||||||
<template #value>
|
<template #value>
|
||||||
<span
|
<span
|
||||||
@click="stopEventPropagation($event)"
|
@click="
|
||||||
|
stopEventPropagation($event)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<VnTableColumn
|
<VnTableColumn
|
||||||
:column="col"
|
:column="col"
|
||||||
|
@ -438,6 +449,7 @@ defineExpose({
|
||||||
</QTable>
|
</QTable>
|
||||||
</template>
|
</template>
|
||||||
</CrudModel>
|
</CrudModel>
|
||||||
|
</div>
|
||||||
<QPageSticky v-if="create" :offset="[20, 20]" style="z-index: 2">
|
<QPageSticky v-if="create" :offset="[20, 20]" style="z-index: 2">
|
||||||
<QBtn @click="showForm = !showForm" color="primary" fab icon="add" />
|
<QBtn @click="showForm = !showForm" color="primary" fab icon="add" />
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
|
@ -446,7 +458,7 @@ defineExpose({
|
||||||
</QPageSticky>
|
</QPageSticky>
|
||||||
<QDialog v-model="showForm" transition-show="scale" transition-hide="scale">
|
<QDialog v-model="showForm" transition-show="scale" transition-hide="scale">
|
||||||
<FormModelPopup
|
<FormModelPopup
|
||||||
v-bind="{ ...$attrs, ...create }"
|
v-bind="create"
|
||||||
:model="$attrs['data-key'] + 'Create'"
|
:model="$attrs['data-key'] + 'Create'"
|
||||||
@on-data-saved="(_, res) => create.onDataSaved(res)"
|
@on-data-saved="(_, res) => create.onDataSaved(res)"
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,14 +1,3 @@
|
||||||
<template>
|
|
||||||
<span v-for="toComponent of componentArray" :key="toComponent.name">
|
|
||||||
<component
|
|
||||||
v-if="toComponent?.component"
|
|
||||||
:is="mix(toComponent).component"
|
|
||||||
v-bind="mix(toComponent).attrs"
|
|
||||||
v-on="mix(toComponent).event ?? {}"
|
|
||||||
v-model="model"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, defineModel } from 'vue';
|
import { computed, defineModel } from 'vue';
|
||||||
|
|
||||||
|
@ -53,3 +42,19 @@ function toValueAttrs(attrs) {
|
||||||
return typeof attrs == 'function' ? attrs($props.value) : attrs;
|
return typeof attrs == 'function' ? attrs($props.value) : attrs;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<template>
|
||||||
|
<span
|
||||||
|
v-for="toComponent of componentArray"
|
||||||
|
:key="toComponent.name"
|
||||||
|
class="column flex-center fit"
|
||||||
|
>
|
||||||
|
<component
|
||||||
|
v-if="toComponent?.component"
|
||||||
|
:is="mix(toComponent).component"
|
||||||
|
v-bind="mix(toComponent).attrs"
|
||||||
|
v-on="mix(toComponent).event ?? {}"
|
||||||
|
v-model="model"
|
||||||
|
class="fit"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
|
@ -115,13 +115,13 @@ const emit = defineEmits(['onFetch']);
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<QBtn
|
<QBtn
|
||||||
|
v-if="$slots.menu"
|
||||||
color="white"
|
color="white"
|
||||||
dense
|
dense
|
||||||
flat
|
flat
|
||||||
icon="more_vert"
|
icon="more_vert"
|
||||||
round
|
round
|
||||||
size="md"
|
size="md"
|
||||||
:class="{ invisible: !$slots.menu }"
|
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('components.cardDescriptor.moreOptions') }}
|
{{ t('components.cardDescriptor.moreOptions') }}
|
||||||
|
|
|
@ -147,7 +147,7 @@ const tagsList = computed(() => {
|
||||||
const tagList = [];
|
const tagList = [];
|
||||||
for (const key of Object.keys(params.value)) {
|
for (const key of Object.keys(params.value)) {
|
||||||
const value = params.value[key];
|
const value = params.value[key];
|
||||||
if (!value || ($props.hiddenTags || []).includes(key)) continue;
|
if (value == null || ($props.hiddenTags || []).includes(key)) continue;
|
||||||
tagList.push({ label: key, value });
|
tagList.push({ label: key, value });
|
||||||
}
|
}
|
||||||
return tagList;
|
return tagList;
|
||||||
|
@ -161,21 +161,14 @@ const customTags = computed(() =>
|
||||||
);
|
);
|
||||||
|
|
||||||
async function remove(key) {
|
async function remove(key) {
|
||||||
delete params.value[key];
|
|
||||||
delete params.value.filter?.where?.[key];
|
|
||||||
params.value[key] = undefined;
|
params.value[key] = undefined;
|
||||||
await arrayData.applyFilter({ params: params.value });
|
search();
|
||||||
emit('remove', key);
|
emit('remove', key);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatValue(value) {
|
function formatValue(value) {
|
||||||
if (typeof value === 'boolean') {
|
if (typeof value === 'boolean') return value ? t('Yes') : t('No');
|
||||||
return value ? t('Yes') : t('No');
|
if (isNaN(value) && !isNaN(Date.parse(value))) return toDate(value);
|
||||||
}
|
|
||||||
|
|
||||||
if (isNaN(value) && !isNaN(Date.parse(value))) {
|
|
||||||
return toDate(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return `"${value}"`;
|
return `"${value}"`;
|
||||||
}
|
}
|
||||||
|
@ -236,7 +229,7 @@ function formatValue(value) {
|
||||||
<slot name="tags" :tag="chip" :format-fn="formatValue">
|
<slot name="tags" :tag="chip" :format-fn="formatValue">
|
||||||
<div class="q-gutter-x-xs">
|
<div class="q-gutter-x-xs">
|
||||||
<strong>{{ chip.label }}:</strong>
|
<strong>{{ chip.label }}:</strong>
|
||||||
<span>"{{ chip.value }}"</span>
|
<span>"{{ formatValue(chip.value) }}"</span>
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
</VnFilterPanelChip>
|
</VnFilterPanelChip>
|
||||||
|
|
|
@ -70,6 +70,7 @@ const props = defineProps({
|
||||||
|
|
||||||
const emit = defineEmits(['onFetch', 'onPaginate', 'onChange']);
|
const emit = defineEmits(['onFetch', 'onPaginate', 'onChange']);
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
|
const mounted = ref(false);
|
||||||
const pagination = ref({
|
const pagination = ref({
|
||||||
sortBy: props.order,
|
sortBy: props.order,
|
||||||
rowsPerPage: props.limit,
|
rowsPerPage: props.limit,
|
||||||
|
@ -89,8 +90,9 @@ const arrayData = useArrayData(props.dataKey, {
|
||||||
});
|
});
|
||||||
const store = arrayData.store;
|
const store = arrayData.store;
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
if (props.autoLoad) fetch();
|
if (props.autoLoad) await fetch();
|
||||||
|
mounted.value = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
@ -155,7 +157,7 @@ function endPagination() {
|
||||||
emit('onPaginate');
|
emit('onPaginate');
|
||||||
}
|
}
|
||||||
async function onLoad(index, done) {
|
async function onLoad(index, done) {
|
||||||
if (!store.data) return done();
|
if (!store.data || !mounted.value) return done();
|
||||||
|
|
||||||
if (store.data.length === 0 || !props.url) return done(false);
|
if (store.data.length === 0 || !props.url) return done(false);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { onMounted, ref, computed, onUnmounted } from 'vue';
|
import { onMounted, ref, computed } from 'vue';
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
import { useRouter, useRoute } from 'vue-router';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useArrayDataStore } from 'stores/useArrayDataStore';
|
import { useArrayDataStore } from 'stores/useArrayDataStore';
|
||||||
|
@ -221,6 +221,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
const pushUrl = { path: to };
|
const pushUrl = { path: to };
|
||||||
if (to.endsWith('/list') || to.endsWith('/'))
|
if (to.endsWith('/list') || to.endsWith('/'))
|
||||||
pushUrl.query = newUrl.query;
|
pushUrl.query = newUrl.query;
|
||||||
|
destroy();
|
||||||
return router.push(pushUrl);
|
return router.push(pushUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -396,6 +396,7 @@ entry:
|
||||||
type: Type
|
type: Type
|
||||||
color: Color
|
color: Color
|
||||||
id: ID
|
id: ID
|
||||||
|
printedStickers: Printed stickers
|
||||||
notes:
|
notes:
|
||||||
observationType: Observation type
|
observationType: Observation type
|
||||||
descriptor:
|
descriptor:
|
||||||
|
@ -420,6 +421,7 @@ entry:
|
||||||
buyingValue: Buying value
|
buyingValue: Buying value
|
||||||
freightValue: Freight value
|
freightValue: Freight value
|
||||||
comissionValue: Commission value
|
comissionValue: Commission value
|
||||||
|
description: Description
|
||||||
packageValue: Package value
|
packageValue: Package value
|
||||||
isIgnored: Is ignored
|
isIgnored: Is ignored
|
||||||
price2: Grouping
|
price2: Grouping
|
||||||
|
@ -582,6 +584,9 @@ claim:
|
||||||
created: Created
|
created: Created
|
||||||
state: State
|
state: State
|
||||||
pickup: Pick up
|
pickup: Pick up
|
||||||
|
null: No
|
||||||
|
agency: Agency
|
||||||
|
delivery: Delivery
|
||||||
photo:
|
photo:
|
||||||
fileDescription: 'Claim id {claimId} from client {clientName} id {clientId}'
|
fileDescription: 'Claim id {claimId} from client {clientName} id {clientId}'
|
||||||
noData: 'There are no images/videos, click here or drag and drop the file'
|
noData: 'There are no images/videos, click here or drag and drop the file'
|
||||||
|
|
|
@ -394,6 +394,7 @@ entry:
|
||||||
type: Tipo
|
type: Tipo
|
||||||
color: Color
|
color: Color
|
||||||
id: ID
|
id: ID
|
||||||
|
printedStickers: Etiquetas impresas
|
||||||
notes:
|
notes:
|
||||||
observationType: Tipo de observación
|
observationType: Tipo de observación
|
||||||
descriptor:
|
descriptor:
|
||||||
|
@ -418,6 +419,7 @@ entry:
|
||||||
buyingValue: Coste
|
buyingValue: Coste
|
||||||
freightValue: Porte
|
freightValue: Porte
|
||||||
comissionValue: Comisión
|
comissionValue: Comisión
|
||||||
|
description: Descripción
|
||||||
packageValue: Embalaje
|
packageValue: Embalaje
|
||||||
isIgnored: Ignorado
|
isIgnored: Ignorado
|
||||||
price2: Grouping
|
price2: Grouping
|
||||||
|
|
|
@ -1,94 +1,433 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { ref, computed, markRaw } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
import VnLocation from 'src/components/common/VnLocation.vue';
|
||||||
import CustomerFilter from './CustomerFilter.vue';
|
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
|
||||||
import CardList from 'src/components/ui/CardList.vue';
|
|
||||||
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
|
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
|
||||||
import CustomerSummary from './Card/CustomerSummary.vue';
|
import CustomerSummary from './Card/CustomerSummary.vue';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
|
|
||||||
|
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
|
||||||
|
|
||||||
|
import { toDate } from 'src/filters';
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { viewSummary } = useSummaryDialog();
|
const router = useRouter();
|
||||||
|
|
||||||
function navigate(id) {
|
const postcodesOptions = ref([]);
|
||||||
router.push({ path: `/customer/${id}` });
|
const tableRef = ref();
|
||||||
}
|
|
||||||
|
|
||||||
const redirectToCreateView = () => {
|
const columns = computed(() => [
|
||||||
router.push({ name: 'CustomerCreate' });
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'id',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.id'),
|
||||||
|
chip: {
|
||||||
|
condition: () => true,
|
||||||
|
},
|
||||||
|
isId: true,
|
||||||
|
columnFilter: {
|
||||||
|
component: 'select',
|
||||||
|
name: 'search',
|
||||||
|
attrs: {
|
||||||
|
url: 'Clients',
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.name'),
|
||||||
|
name: 'name',
|
||||||
|
isTitle: true,
|
||||||
|
create: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'socialName',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.socialName'),
|
||||||
|
isTitle: true,
|
||||||
|
create: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.fi'),
|
||||||
|
name: 'fi',
|
||||||
|
create: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'),
|
||||||
|
name: 'salesPersonFk',
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'Workers/activeWithInheritedRole',
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
where: { role: 'salesPerson' },
|
||||||
|
},
|
||||||
|
create: true,
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.salesPerson),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.credit'),
|
||||||
|
name: 'credit',
|
||||||
|
component: 'number',
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.creditInsurance'),
|
||||||
|
name: 'creditInsurance',
|
||||||
|
component: 'number',
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.phone'),
|
||||||
|
name: 'phone',
|
||||||
|
cardVisible: true,
|
||||||
|
columnFilter: {
|
||||||
|
component: 'number',
|
||||||
|
},
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
after: {
|
||||||
|
component: markRaw(VnLinkPhone),
|
||||||
|
attrs: (prop) => {
|
||||||
|
return {
|
||||||
|
'phone-number': prop,
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.mobile'),
|
||||||
|
name: 'mobile',
|
||||||
|
cardVisible: true,
|
||||||
|
columnFilter: {
|
||||||
|
component: 'number',
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.street'),
|
||||||
|
name: 'street',
|
||||||
|
create: true,
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.countryFk'),
|
||||||
|
name: 'countryFk',
|
||||||
|
columnFilter: {
|
||||||
|
component: 'select',
|
||||||
|
inWhere: true,
|
||||||
|
alias: 'c',
|
||||||
|
attrs: {
|
||||||
|
url: 'Countries',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.country),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.provinceFk'),
|
||||||
|
name: 'provinceFk',
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'Provinces',
|
||||||
|
},
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.province),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.city'),
|
||||||
|
name: 'city',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.postcode'),
|
||||||
|
name: 'postcode',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.email'),
|
||||||
|
name: 'email',
|
||||||
|
cardVisible: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.created'),
|
||||||
|
name: 'created',
|
||||||
|
format: ({ created }) => toDate(created),
|
||||||
|
component: 'date',
|
||||||
|
columnFilter: {
|
||||||
|
alias: 'c',
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.businessTypeFk'),
|
||||||
|
name: 'businessTypeFk',
|
||||||
|
create: true,
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'BusinessTypes',
|
||||||
|
optionLabel: 'description',
|
||||||
|
optionValue: 'code',
|
||||||
|
},
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.businessType),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.payMethodFk'),
|
||||||
|
name: 'payMethodFk',
|
||||||
|
columnFilter: {
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'PayMethods',
|
||||||
|
},
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.payMethod),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.sageTaxTypeFk'),
|
||||||
|
name: 'sageTaxTypeFk',
|
||||||
|
columnFilter: {
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
optionLabel: 'vat',
|
||||||
|
url: 'SageTaxTypes',
|
||||||
|
},
|
||||||
|
alias: 'sti',
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.sageTaxType),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.sageTransactionTypeFk'),
|
||||||
|
name: 'sageTransactionTypeFk',
|
||||||
|
columnFilter: {
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
optionLabel: 'transaction',
|
||||||
|
url: 'SageTransactionTypes',
|
||||||
|
},
|
||||||
|
alias: 'stt',
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.sageTransactionType),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.isActive'),
|
||||||
|
name: 'isActive',
|
||||||
|
chip: {
|
||||||
|
color: null,
|
||||||
|
condition: (value) => !value,
|
||||||
|
icon: 'vn:disabled',
|
||||||
|
},
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.isVies'),
|
||||||
|
name: 'isVies',
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.isTaxDataChecked'),
|
||||||
|
name: 'isTaxDataChecked',
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.isEqualizated'),
|
||||||
|
name: 'isEqualizated',
|
||||||
|
create: true,
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.isFreezed'),
|
||||||
|
name: 'isFreezed',
|
||||||
|
chip: {
|
||||||
|
color: null,
|
||||||
|
condition: (value) => value,
|
||||||
|
icon: 'vn:frozen',
|
||||||
|
},
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.hasToInvoice'),
|
||||||
|
name: 'hasToInvoice',
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.hasToInvoiceByAddress'),
|
||||||
|
name: 'hasToInvoiceByAddress',
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.isToBeMailed'),
|
||||||
|
name: 'isToBeMailed',
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.hasLcr'),
|
||||||
|
name: 'hasLcr',
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.hasCoreVnl'),
|
||||||
|
name: 'hasCoreVnl',
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('customer.extendedList.tableVisibleColumns.hasSepaVnl'),
|
||||||
|
name: 'hasSepaVnl',
|
||||||
|
columnFilter: {
|
||||||
|
inWhere: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
label: '',
|
||||||
|
name: 'tableActions',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
title: t('Client ticket list'),
|
||||||
|
icon: 'vn:ticket',
|
||||||
|
action: redirectToCreateView,
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('Client ticket list'),
|
||||||
|
icon: 'preview',
|
||||||
|
action: (row) => viewSummary(row.id, CustomerSummary),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const { viewSummary } = useSummaryDialog();
|
||||||
|
const redirectToCreateView = (row) => {
|
||||||
|
router.push({
|
||||||
|
name: 'TicketList',
|
||||||
|
query: {
|
||||||
|
params: JSON.stringify({
|
||||||
|
clientFk: row.id,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleLocation(data, location) {
|
||||||
|
const { town, code, provinceFk, countryFk } = location ?? {};
|
||||||
|
data.postcode = code;
|
||||||
|
data.city = town;
|
||||||
|
data.provinceFk = provinceFk;
|
||||||
|
data.countryFk = countryFk;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnSearchbar
|
<VnTable
|
||||||
:info="t('You can search by customer id or name')"
|
ref="tableRef"
|
||||||
:label="t('Search customer')"
|
data-key="CustomerExtendedList"
|
||||||
data-key="CustomerList"
|
url="Clients/extendedListFilter"
|
||||||
/>
|
:create="{
|
||||||
<RightMenu>
|
urlCreate: 'Clients/createWithUser',
|
||||||
<template #right-panel>
|
title: 'Create client',
|
||||||
<CustomerFilter data-key="CustomerList" />
|
onDataSaved: ({ id }) => tableRef.redirect(id),
|
||||||
</template>
|
formInitialData: {
|
||||||
</RightMenu>
|
active: true,
|
||||||
<QPage class="column items-center q-pa-md">
|
isEqualizated: false,
|
||||||
<div class="vn-card-list">
|
},
|
||||||
<VnPaginate
|
}"
|
||||||
auto-load
|
|
||||||
data-key="CustomerList"
|
|
||||||
order="id DESC"
|
order="id DESC"
|
||||||
url="/Clients/filter"
|
:columns="columns"
|
||||||
|
default-mode="table"
|
||||||
|
redirect="customer"
|
||||||
|
auto-load
|
||||||
>
|
>
|
||||||
<template #body="{ rows }">
|
<template #more-create-dialog="{ data }">
|
||||||
<CardList
|
<VnLocation
|
||||||
:id="row.id"
|
:roles-allowed-to-create="['deliveryAssistant']"
|
||||||
:key="row.id"
|
:options="postcodesOptions"
|
||||||
:title="row.name"
|
v-model="data.location"
|
||||||
@click="navigate(row.id)"
|
@update:model-value="(location) => handleLocation(data, location)"
|
||||||
v-for="row of rows"
|
|
||||||
>
|
|
||||||
<template #list-items>
|
|
||||||
<VnLv :label="t('customer.list.email')" :value="row.email" />
|
|
||||||
<VnLv :value="row.phone">
|
|
||||||
<template #label>
|
|
||||||
{{ t('customer.list.phone') }}
|
|
||||||
<VnLinkPhone :phone-number="row.phone" />
|
|
||||||
</template>
|
|
||||||
</VnLv>
|
|
||||||
</template>
|
|
||||||
<template #actions>
|
|
||||||
<QBtn
|
|
||||||
:label="t('components.smartCard.openCard')"
|
|
||||||
@click.stop="navigate(row.id)"
|
|
||||||
outline
|
|
||||||
/>
|
|
||||||
<QBtn
|
|
||||||
:label="t('components.smartCard.openSummary')"
|
|
||||||
@click.stop="viewSummary(row.id, CustomerSummary)"
|
|
||||||
color="primary"
|
|
||||||
style="margin-top: 15px"
|
|
||||||
/>
|
/>
|
||||||
|
<QInput v-model="data.userName" :label="t('Web user')" />
|
||||||
|
<QInput :label="t('Email')" clearable type="email" v-model="data.email">
|
||||||
|
<template #append>
|
||||||
|
<QIcon name="info" class="cursor-info">
|
||||||
|
<QTooltip max-width="400px">{{
|
||||||
|
t('customer.basicData.youCanSaveMultipleEmails')
|
||||||
|
}}</QTooltip>
|
||||||
|
</QIcon>
|
||||||
</template>
|
</template>
|
||||||
</CardList>
|
</QInput>
|
||||||
</template>
|
</template>
|
||||||
</VnPaginate>
|
</VnTable>
|
||||||
</div>
|
|
||||||
<QPageSticky :offset="[20, 20]">
|
|
||||||
<QBtn @click="redirectToCreateView()" color="primary" fab icon="add" />
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('New client') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QPageSticky>
|
|
||||||
</QPage>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Search customer: Buscar cliente
|
Web user: Usuario Web
|
||||||
You can search by customer id or name: Puedes buscar por id o nombre del cliente
|
|
||||||
New client: Nuevo cliente
|
|
||||||
</i18n>
|
</i18n>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.col-content {
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,428 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { ref, computed, markRaw } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
import VnTable from 'components/VnTable/VnTable.vue';
|
|
||||||
import VnLocation from 'src/components/common/VnLocation.vue';
|
|
||||||
import CustomerSummary from '../Card/CustomerSummary.vue';
|
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
|
||||||
|
|
||||||
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
|
|
||||||
|
|
||||||
import { toDate } from 'src/filters';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const postcodesOptions = ref([]);
|
|
||||||
const tableRef = ref();
|
|
||||||
|
|
||||||
const columns = computed(() => [
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
name: 'id',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.id'),
|
|
||||||
chip: {
|
|
||||||
condition: () => true,
|
|
||||||
},
|
|
||||||
isId: true,
|
|
||||||
columnFilter: {
|
|
||||||
component: 'select',
|
|
||||||
name: 'search',
|
|
||||||
attrs: {
|
|
||||||
url: 'Clients',
|
|
||||||
fields: ['id', 'name'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.name'),
|
|
||||||
name: 'name',
|
|
||||||
isTitle: true,
|
|
||||||
create: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
name: 'socialName',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.socialName'),
|
|
||||||
isTitle: true,
|
|
||||||
create: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.fi'),
|
|
||||||
name: 'fi',
|
|
||||||
create: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'),
|
|
||||||
name: 'salesPersonFk',
|
|
||||||
component: 'select',
|
|
||||||
attrs: {
|
|
||||||
url: 'Workers/activeWithInheritedRole',
|
|
||||||
fields: ['id', 'name'],
|
|
||||||
where: { role: 'salesPerson' },
|
|
||||||
},
|
|
||||||
create: true,
|
|
||||||
columnField: {
|
|
||||||
component: null,
|
|
||||||
},
|
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.salesPerson),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.credit'),
|
|
||||||
name: 'credit',
|
|
||||||
component: 'number',
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.creditInsurance'),
|
|
||||||
name: 'creditInsurance',
|
|
||||||
component: 'number',
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.phone'),
|
|
||||||
name: 'phone',
|
|
||||||
cardVisible: true,
|
|
||||||
after: {
|
|
||||||
component: markRaw(VnLinkPhone),
|
|
||||||
props: (prop) => ({
|
|
||||||
'phone-number': prop.phone,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
component: 'number',
|
|
||||||
columnField: {
|
|
||||||
component: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.mobile'),
|
|
||||||
name: 'mobile',
|
|
||||||
cardVisible: true,
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.street'),
|
|
||||||
name: 'street',
|
|
||||||
create: true,
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.countryFk'),
|
|
||||||
name: 'countryFk',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'select',
|
|
||||||
inWhere: true,
|
|
||||||
alias: 'c',
|
|
||||||
attrs: {
|
|
||||||
url: 'Countries',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.country),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.provinceFk'),
|
|
||||||
name: 'provinceFk',
|
|
||||||
component: 'select',
|
|
||||||
attrs: {
|
|
||||||
url: 'Provinces',
|
|
||||||
},
|
|
||||||
columnField: {
|
|
||||||
component: null,
|
|
||||||
},
|
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.province),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.city'),
|
|
||||||
name: 'city',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.postcode'),
|
|
||||||
name: 'postcode',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.email'),
|
|
||||||
name: 'email',
|
|
||||||
cardVisible: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.created'),
|
|
||||||
name: 'created',
|
|
||||||
format: ({ created }) => toDate(created),
|
|
||||||
component: 'date',
|
|
||||||
columnFilter: {
|
|
||||||
alias: 'c',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.businessTypeFk'),
|
|
||||||
name: 'businessTypeFk',
|
|
||||||
create: true,
|
|
||||||
component: 'select',
|
|
||||||
attrs: {
|
|
||||||
url: 'BusinessTypes',
|
|
||||||
optionLabel: 'description',
|
|
||||||
optionValue: 'code',
|
|
||||||
},
|
|
||||||
columnField: {
|
|
||||||
component: null,
|
|
||||||
},
|
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.businessType),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.payMethodFk'),
|
|
||||||
name: 'payMethodFk',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'select',
|
|
||||||
attrs: {
|
|
||||||
url: 'PayMethods',
|
|
||||||
},
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.payMethod),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.sageTaxTypeFk'),
|
|
||||||
name: 'sageTaxTypeFk',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'select',
|
|
||||||
attrs: {
|
|
||||||
optionLabel: 'vat',
|
|
||||||
url: 'SageTaxTypes',
|
|
||||||
},
|
|
||||||
alias: 'sti',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.sageTaxType),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.sageTransactionTypeFk'),
|
|
||||||
name: 'sageTransactionTypeFk',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'select',
|
|
||||||
attrs: {
|
|
||||||
optionLabel: 'transaction',
|
|
||||||
url: 'SageTransactionTypes',
|
|
||||||
},
|
|
||||||
alias: 'stt',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.sageTransactionType),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.isActive'),
|
|
||||||
name: 'isActive',
|
|
||||||
chip: {
|
|
||||||
color: null,
|
|
||||||
condition: (value) => !value,
|
|
||||||
icon: 'vn:disabled',
|
|
||||||
},
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.isVies'),
|
|
||||||
name: 'isVies',
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.isTaxDataChecked'),
|
|
||||||
name: 'isTaxDataChecked',
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.isEqualizated'),
|
|
||||||
name: 'isEqualizated',
|
|
||||||
created: true,
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.isFreezed'),
|
|
||||||
name: 'isFreezed',
|
|
||||||
chip: {
|
|
||||||
color: null,
|
|
||||||
condition: (value) => value,
|
|
||||||
icon: 'vn:frozen',
|
|
||||||
},
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.hasToInvoice'),
|
|
||||||
name: 'hasToInvoice',
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.hasToInvoiceByAddress'),
|
|
||||||
name: 'hasToInvoiceByAddress',
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.isToBeMailed'),
|
|
||||||
name: 'isToBeMailed',
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.hasLcr'),
|
|
||||||
name: 'hasLcr',
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.hasCoreVnl'),
|
|
||||||
name: 'hasCoreVnl',
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('customer.extendedList.tableVisibleColumns.hasSepaVnl'),
|
|
||||||
name: 'hasSepaVnl',
|
|
||||||
columnFilter: {
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'right',
|
|
||||||
label: '',
|
|
||||||
name: 'tableActions',
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
title: t('Client ticket list'),
|
|
||||||
icon: 'vn:ticket',
|
|
||||||
action: redirectToCreateView,
|
|
||||||
isPrimary: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('Client ticket list'),
|
|
||||||
icon: 'preview',
|
|
||||||
action: (row) => viewSummary(row.id, CustomerSummary),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const { viewSummary } = useSummaryDialog();
|
|
||||||
const redirectToCreateView = (row) => {
|
|
||||||
router.push({
|
|
||||||
name: 'TicketList',
|
|
||||||
query: {
|
|
||||||
params: JSON.stringify({
|
|
||||||
clientFk: row.id,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function handleLocation(data, location) {
|
|
||||||
const { town, code, provinceFk, countryFk } = location ?? {};
|
|
||||||
data.postcode = code;
|
|
||||||
data.city = town;
|
|
||||||
data.provinceFk = provinceFk;
|
|
||||||
data.countryFk = countryFk;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<VnTable
|
|
||||||
ref="tableRef"
|
|
||||||
data-key="CustomerExtendedList"
|
|
||||||
url="Clients/extendedListFilter"
|
|
||||||
url-create="Clients/createWithUser"
|
|
||||||
:create="{
|
|
||||||
urlCreate: 'Clients/createWithUser',
|
|
||||||
title: 'Create client',
|
|
||||||
onDataSaved: ({ id }) => tableRef.redirect(id),
|
|
||||||
formInitialData: {
|
|
||||||
active: true,
|
|
||||||
isEqualizated: false,
|
|
||||||
},
|
|
||||||
}"
|
|
||||||
order="id DESC"
|
|
||||||
:columns="columns"
|
|
||||||
default-mode="table"
|
|
||||||
redirect="customer"
|
|
||||||
auto-load
|
|
||||||
>
|
|
||||||
<template #more-create-dialog="{ data }">
|
|
||||||
<QInput :label="t('Email')" clearable type="email" v-model="data.email">
|
|
||||||
<template #append>
|
|
||||||
<QIcon name="info" class="cursor-info">
|
|
||||||
<QTooltip max-width="400px">{{
|
|
||||||
t('customer.basicData.youCanSaveMultipleEmails')
|
|
||||||
}}</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</template>
|
|
||||||
</QInput>
|
|
||||||
<QInput v-model="data.userName" :label="t('Web user')" />
|
|
||||||
<VnLocation
|
|
||||||
:roles-allowed-to-create="['deliveryAssistant']"
|
|
||||||
:options="postcodesOptions"
|
|
||||||
v-model="data.location"
|
|
||||||
@update:model-value="(location) => handleLocation(data, location)"
|
|
||||||
>
|
|
||||||
</VnLocation>
|
|
||||||
</template>
|
|
||||||
</VnTable>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.col-content {
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 6px;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -82,6 +82,16 @@ const tableColumnComponents = computed(() => ({
|
||||||
},
|
},
|
||||||
event: getInputEvents,
|
event: getInputEvents,
|
||||||
},
|
},
|
||||||
|
printedStickers: {
|
||||||
|
component: VnInput,
|
||||||
|
props: {
|
||||||
|
type: 'number',
|
||||||
|
min: 0,
|
||||||
|
class: 'input-number',
|
||||||
|
dense: true,
|
||||||
|
},
|
||||||
|
event: getInputEvents,
|
||||||
|
},
|
||||||
weight: {
|
weight: {
|
||||||
component: VnInput,
|
component: VnInput,
|
||||||
props: {
|
props: {
|
||||||
|
@ -147,7 +157,7 @@ const entriesTableColumns = computed(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: t('entry.summary.item'),
|
label: t('entry.summary.item'),
|
||||||
field: 'id',
|
field: 'itemFk',
|
||||||
name: 'item',
|
name: 'item',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
},
|
},
|
||||||
|
@ -169,6 +179,12 @@ const entriesTableColumns = computed(() => {
|
||||||
name: 'stickers',
|
name: 'stickers',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: t('entry.buys.printedStickers'),
|
||||||
|
field: 'printedStickers',
|
||||||
|
name: 'printedStickers',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: t('entry.summary.weight'),
|
label: t('entry.summary.weight'),
|
||||||
field: 'weight',
|
field: 'weight',
|
||||||
|
@ -216,7 +232,6 @@ const entriesTableColumns = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const copyOriginalRowsData = (rows) => {
|
const copyOriginalRowsData = (rows) => {
|
||||||
// el objetivo de esto es guardar los valores iniciales de todas las rows para evitar guardar cambios si la data no cambió al disparar los eventos
|
|
||||||
originalRowDataCopy.value = JSON.parse(JSON.stringify(rows));
|
originalRowDataCopy.value = JSON.parse(JSON.stringify(rows));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -386,19 +401,16 @@ const lockIconType = (groupingMode, mode) => {
|
||||||
</template>
|
</template>
|
||||||
<ItemDescriptorProxy
|
<ItemDescriptorProxy
|
||||||
v-if="col.name === 'item'"
|
v-if="col.name === 'item'"
|
||||||
:id="props.row.id"
|
:id="props.row.item.id"
|
||||||
/>
|
/>
|
||||||
</component>
|
</component>
|
||||||
</QTd>
|
</QTd>
|
||||||
</QTr>
|
</QTr>
|
||||||
<QTr no-hover>
|
<QTr no-hover class="full-width infoRow" style="column-span: all">
|
||||||
<QTd />
|
<QTd />
|
||||||
<QTd>
|
<QTd cols>
|
||||||
<span>{{ props.row.item.itemType.code }}</span>
|
<span>{{ props.row.item.itemType.code }}</span>
|
||||||
</QTd>
|
</QTd>
|
||||||
<QTd>
|
|
||||||
<span>{{ props.row.item.id }}</span>
|
|
||||||
</QTd>
|
|
||||||
<QTd>
|
<QTd>
|
||||||
<span>{{ props.row.item.size }}</span>
|
<span>{{ props.row.item.size }}</span>
|
||||||
</QTd>
|
</QTd>
|
||||||
|
@ -413,10 +425,6 @@ const lockIconType = (groupingMode, mode) => {
|
||||||
<FetchedTags :item="props.row.item" :max-length="5" />
|
<FetchedTags :item="props.row.item" :max-length="5" />
|
||||||
</QTd>
|
</QTd>
|
||||||
</QTr>
|
</QTr>
|
||||||
<!-- Esta última row es utilizada para agregar un espaciado y así marcar una diferencia visual entre los diferentes buys -->
|
|
||||||
<QTr v-if="props.rowIndex !== rows.length - 1" class="separation-row">
|
|
||||||
<QTd colspan="12" class="vn-table-separation-row" />
|
|
||||||
</QTr>
|
|
||||||
</template>
|
</template>
|
||||||
<template #item="props">
|
<template #item="props">
|
||||||
<div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
|
<div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
|
||||||
|
@ -466,11 +474,13 @@ const lockIconType = (groupingMode, mode) => {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.separation-row {
|
.q-table--horizontal-separator tbody tr:nth-child(odd) > td {
|
||||||
background-color: var(--vn-section-color) !important;
|
border-bottom-width: 0px;
|
||||||
|
border-top-width: 2px;
|
||||||
|
border-color: var(--vn-text-color);
|
||||||
}
|
}
|
||||||
.grid-style-transition {
|
.infoRow > td {
|
||||||
transition: transform 0.28s, background-color 0.28s;
|
color: var(--vn-label-color);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
@ -135,14 +135,19 @@ watch;
|
||||||
<template #icons>
|
<template #icons>
|
||||||
<QCardActions class="q-gutter-x-md">
|
<QCardActions class="q-gutter-x-md">
|
||||||
<QIcon
|
<QIcon
|
||||||
v-if="currentEntry.isExcludedFromAvailable"
|
v-if="currentEntry?.isExcludedFromAvailable"
|
||||||
name="vn:inventory"
|
name="vn:inventory"
|
||||||
color="primary"
|
color="primary"
|
||||||
size="xs"
|
size="xs"
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('Inventory entry') }}</QTooltip>
|
<QTooltip>{{ t('Inventory entry') }}</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
<QIcon v-if="currentEntry.isRaid" name="vn:net" color="primary" size="xs">
|
<QIcon
|
||||||
|
v-if="currentEntry?.isRaid"
|
||||||
|
name="vn:net"
|
||||||
|
color="primary"
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
<QTooltip>{{ t('Virtual entry') }}</QTooltip>
|
<QTooltip>{{ t('Virtual entry') }}</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
</QCardActions>
|
</QCardActions>
|
||||||
|
|
|
@ -167,7 +167,7 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('globals.description'),
|
label: t('entry.latestBuys.description'),
|
||||||
field: 'description',
|
field: 'description',
|
||||||
name: 'description',
|
name: 'description',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -653,6 +653,15 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
<EntryLatestBuysFilter data-key="EntryLatestBuys" />
|
<EntryLatestBuysFilter data-key="EntryLatestBuys" />
|
||||||
</template>
|
</template>
|
||||||
</RightMenu>
|
</RightMenu>
|
||||||
|
<Teleport to="#actions-append">
|
||||||
|
<div class="row q-gutter-x-sm">
|
||||||
|
<QBtn flat @click="stateStore.toggleRightDrawer()" round dense icon="menu">
|
||||||
|
<QTooltip bottom anchor="bottom right">
|
||||||
|
{{ t('globals.collapseMenu') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QBtn>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
<QPage class="column items-center q-pa-md">
|
<QPage class="column items-center q-pa-md">
|
||||||
<QTable
|
<QTable
|
||||||
:rows="rows"
|
:rows="rows"
|
||||||
|
|
|
@ -184,13 +184,6 @@ const suppliersOptions = ref([]);
|
||||||
@click="removeTag(index, params, searchFn)"
|
@click="removeTag(index, params, searchFn)"
|
||||||
/>
|
/>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem class="q-mt-lg">
|
|
||||||
<QIcon
|
|
||||||
name="add_circle"
|
|
||||||
class="filter-icon"
|
|
||||||
@click="tagValues.push({})"
|
|
||||||
/>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
</template>
|
||||||
</ItemsFilterPanel>
|
</ItemsFilterPanel>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref } from 'vue';
|
import { onBeforeMount, computed, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { Notify } from 'quasar';
|
import { Notify } from 'quasar';
|
||||||
|
import axios from 'axios';
|
||||||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
import VnPaginate from 'components/ui/VnPaginate.vue';
|
||||||
import { useSession } from 'src/composables/useSession';
|
import { useSession } from 'src/composables/useSession';
|
||||||
import { toDate } from 'filters/index';
|
import { toDate } from 'filters/index';
|
||||||
|
@ -29,7 +30,6 @@ const columns = computed(() => [
|
||||||
field: (row) => row.hasCmrDms,
|
field: (row) => row.hasCmrDms,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
headerStyle: 'padding-left: 35px',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ticketFk',
|
name: 'ticketFk',
|
||||||
|
@ -62,7 +62,6 @@ const columns = computed(() => [
|
||||||
field: (row) => toDate(row.shipped),
|
field: (row) => toDate(row.shipped),
|
||||||
align: 'center',
|
align: 'center',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
headerStyle: 'padding-left: 33px',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'warehouseFk',
|
name: 'warehouseFk',
|
||||||
|
@ -77,6 +76,11 @@ const columns = computed(() => [
|
||||||
field: (row) => row.cmrFk,
|
field: (row) => row.cmrFk,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
onBeforeMount(async () => {
|
||||||
|
const { data } = await axios.get('Warehouses');
|
||||||
|
warehouses.value = data;
|
||||||
|
});
|
||||||
function getApiUrl() {
|
function getApiUrl() {
|
||||||
return new URL(window.location).origin;
|
return new URL(window.location).origin;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +191,6 @@ function downloadPdfs() {
|
||||||
</QPageSticky>
|
</QPageSticky>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.list {
|
.list {
|
||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
|
@ -204,4 +207,10 @@ function downloadPdfs() {
|
||||||
#false {
|
#false {
|
||||||
background-color: $negative;
|
background-color: $negative;
|
||||||
}
|
}
|
||||||
|
:deep(.q-table th) {
|
||||||
|
max-width: 80px;
|
||||||
|
}
|
||||||
|
:deep(.q-table th:nth-child(3)) {
|
||||||
|
max-width: 100px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -17,6 +17,10 @@ const $props = defineProps({
|
||||||
required: false,
|
required: false,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
summary: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -106,6 +110,7 @@ const getEntryQueryParams = (supplier) => {
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
@on-fetch="setData"
|
@on-fetch="setData"
|
||||||
data-key="supplier"
|
data-key="supplier"
|
||||||
|
:summary="$props.summary"
|
||||||
>
|
>
|
||||||
<template #header-extra-action>
|
<template #header-extra-action>
|
||||||
<QBtn
|
<QBtn
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import SupplierDescriptor from './SupplierDescriptor.vue';
|
import SupplierDescriptor from './SupplierDescriptor.vue';
|
||||||
|
import SupplierSummary from './SupplierSummary.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -11,6 +12,6 @@ const $props = defineProps({
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QPopupProxy>
|
<QPopupProxy>
|
||||||
<SupplierDescriptor v-if="$props.id" :id="$props.id" />
|
<SupplierDescriptor v-if="$props.id" :id="$props.id" :summary="SupplierSummary" />
|
||||||
</QPopupProxy>
|
</QPopupProxy>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -24,7 +24,7 @@ const agenciesOptions = ref([]);
|
||||||
<FormModel
|
<FormModel
|
||||||
:url="`Travels/${route.params.id}`"
|
:url="`Travels/${route.params.id}`"
|
||||||
:url-update="`Travels/${route.params.id}`"
|
:url-update="`Travels/${route.params.id}`"
|
||||||
model="travel"
|
model="Travel"
|
||||||
auto-load
|
auto-load
|
||||||
>
|
>
|
||||||
<template #form="{ data }">
|
<template #form="{ data }">
|
||||||
|
|
|
@ -1,7 +1,40 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnCard from 'components/common/VnCard.vue';
|
import VnCard from 'components/common/VnCard.vue';
|
||||||
import TravelDescriptor from './TravelDescriptor.vue';
|
import TravelDescriptor from './TravelDescriptor.vue';
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
fields: [
|
||||||
|
'id',
|
||||||
|
'ref',
|
||||||
|
'shipped',
|
||||||
|
'landed',
|
||||||
|
'totalEntries',
|
||||||
|
'warehouseInFk',
|
||||||
|
'warehouseOutFk',
|
||||||
|
'cargoSupplierFk',
|
||||||
|
'agencyModeFk',
|
||||||
|
],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'warehouseIn',
|
||||||
|
scope: {
|
||||||
|
fields: ['name'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relation: 'warehouseOut',
|
||||||
|
scope: {
|
||||||
|
fields: ['name'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnCard data-key="Travel" base-url="Travels" :descriptor="TravelDescriptor" />
|
<VnCard
|
||||||
|
data-key="Travel"
|
||||||
|
:filter="filter"
|
||||||
|
base-url="Travels"
|
||||||
|
:descriptor="TravelDescriptor"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
|
import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
|
||||||
|
|
||||||
import useCardDescription from 'src/composables/useCardDescription';
|
|
||||||
import { toDate } from 'src/filters';
|
import { toDate } from 'src/filters';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
|
@ -52,23 +51,15 @@ const filter = {
|
||||||
const entityId = computed(() => {
|
const entityId = computed(() => {
|
||||||
return $props.id || route.params.id;
|
return $props.id || route.params.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = ref(useCardDescription());
|
|
||||||
|
|
||||||
const setData = (entity) => {
|
|
||||||
data.value = useCardDescription(entity.ref, entity.id);
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<CardDescriptor
|
<CardDescriptor
|
||||||
module="Travel"
|
module="Travel"
|
||||||
:url="`Travels/${entityId}`"
|
:url="`Travels/${entityId}`"
|
||||||
:title="data.title"
|
title="ref"
|
||||||
:subtitle="data.subtitle"
|
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
@on-fetch="setData"
|
data-key="Travel"
|
||||||
data-key="travelData"
|
|
||||||
>
|
>
|
||||||
<template #header-extra-action>
|
<template #header-extra-action>
|
||||||
<QBtn
|
<QBtn
|
||||||
|
|
|
@ -32,10 +32,11 @@ const cloneTravel = () => {
|
||||||
redirectToCreateView(stringifiedTravelData);
|
redirectToCreateView(stringifiedTravelData);
|
||||||
};
|
};
|
||||||
|
|
||||||
const cloneTravelWithEntries = () => {
|
const cloneTravelWithEntries = async () => {
|
||||||
try {
|
try {
|
||||||
axios.post(`Travels/${$props.travel.id}/cloneWithEntries`);
|
const { data } = await axios.post(`Travels/${$props.travel.id}/cloneWithEntries`);
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
|
router.push({ name: 'TravelBasicData', params: { id: data.id } });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.err('Error cloning travel with entries');
|
console.err('Error cloning travel with entries');
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import VnTitle from 'src/components/common/VnTitle.vue';
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue';
|
import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue';
|
||||||
import FetchData from 'src/components/FetchData.vue';
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
|
|
||||||
|
|
||||||
import { toDate, toCurrency } from 'src/filters';
|
import { toDate, toCurrency } from 'src/filters';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
@ -222,6 +221,8 @@ async function setTravelData(travelData) {
|
||||||
console.error(`Error setting travel data`, err);
|
console.error(`Error setting travel data`, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getLink = (param) => `#/travel/${entityId.value}/${param}`;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -240,21 +241,15 @@ async function setTravelData(travelData) {
|
||||||
<template #header>
|
<template #header>
|
||||||
<span>{{ travel.ref }} - {{ travel.id }}</span>
|
<span>{{ travel.ref }} - {{ travel.id }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #header-right>
|
|
||||||
<QBtn color="white" dense flat icon="more_vert" round size="md">
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('components.cardDescriptor.moreOptions') }}
|
|
||||||
</QTooltip>
|
|
||||||
<QMenu>
|
|
||||||
<QList>
|
|
||||||
<TravelDescriptorMenuItems :travel="travel" />
|
|
||||||
</QList>
|
|
||||||
</QMenu>
|
|
||||||
</QBtn>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #body>
|
<template #body>
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
|
<QCardSection class="q-pa-none">
|
||||||
|
<VnTitle
|
||||||
|
:url="getLink('basic-data')"
|
||||||
|
:text="t('travel.pageTitles.basicData')"
|
||||||
|
/>
|
||||||
|
</QCardSection>
|
||||||
<VnLv :label="t('globals.shipped')" :value="toDate(travel.shipped)" />
|
<VnLv :label="t('globals.shipped')" :value="toDate(travel.shipped)" />
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('globals.wareHouseOut')"
|
:label="t('globals.wareHouseOut')"
|
||||||
|
@ -267,6 +262,12 @@ async function setTravelData(travelData) {
|
||||||
/>
|
/>
|
||||||
</QCard>
|
</QCard>
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
|
<QCardSection class="q-pa-none">
|
||||||
|
<VnTitle
|
||||||
|
:url="getLink('basic-data')"
|
||||||
|
:text="t('travel.pageTitles.basicData')"
|
||||||
|
/>
|
||||||
|
</QCardSection>
|
||||||
<VnLv :label="t('globals.landed')" :value="toDate(travel.landed)" />
|
<VnLv :label="t('globals.landed')" :value="toDate(travel.landed)" />
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('globals.wareHouseIn')"
|
:label="t('globals.wareHouseIn')"
|
||||||
|
@ -279,12 +280,18 @@ async function setTravelData(travelData) {
|
||||||
/>
|
/>
|
||||||
</QCard>
|
</QCard>
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
|
<QCardSection class="q-pa-none">
|
||||||
|
<VnTitle
|
||||||
|
:url="getLink('basic-data')"
|
||||||
|
:text="t('travel.pageTitles.basicData')"
|
||||||
|
/>
|
||||||
|
</QCardSection>
|
||||||
<VnLv :label="t('globals.agency')" :value="travel.agency?.name" />
|
<VnLv :label="t('globals.agency')" :value="travel.agency?.name" />
|
||||||
<VnLv :label="t('globals.reference')" :value="travel.ref" />
|
<VnLv :label="t('globals.reference')" :value="travel.ref" />
|
||||||
<VnLv label="m³" :value="travel.m3" />
|
<VnLv label="m³" :value="travel.m3" />
|
||||||
<VnLv :label="t('globals.totalEntries')" :value="travel.totalEntries" />
|
<VnLv :label="t('globals.totalEntries')" :value="travel.totalEntries" />
|
||||||
</QCard>
|
</QCard>
|
||||||
<QCard class="full-width" v-if="entriesTableRows.length > 0">
|
<QCard class="full-width">
|
||||||
<VnTitle :text="t('travel.summary.entries')" />
|
<VnTitle :text="t('travel.summary.entries')" />
|
||||||
<QTable
|
<QTable
|
||||||
:rows="entriesTableRows"
|
:rows="entriesTableRows"
|
||||||
|
@ -299,13 +306,15 @@ async function setTravelData(travelData) {
|
||||||
</QTh>
|
</QTh>
|
||||||
</QTr>
|
</QTr>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-isConfirmed="{ col, value }">
|
<template #body-cell-isConfirmed="{ col, row }">
|
||||||
<QTd>
|
<QTd>
|
||||||
<QIcon
|
<QCheckbox
|
||||||
v-if="col.name === 'isConfirmed'"
|
v-if="col.name === 'isConfirmed'"
|
||||||
:name="value ? 'check' : 'close'"
|
:label="t('travel.summary.received')"
|
||||||
:color="value ? 'positive' : 'negative'"
|
:true-value="1"
|
||||||
size="sm"
|
:false-value="0"
|
||||||
|
v-model="row[col.name]"
|
||||||
|
:disable="true"
|
||||||
/>
|
/>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -53,6 +53,7 @@ const draggedRowIndex = ref(null);
|
||||||
const targetRowIndex = ref(null);
|
const targetRowIndex = ref(null);
|
||||||
const entryRowIndex = ref(null);
|
const entryRowIndex = ref(null);
|
||||||
const draggedEntry = ref(null);
|
const draggedEntry = ref(null);
|
||||||
|
const travelKgPercentages = ref([]);
|
||||||
|
|
||||||
const tableColumnComponents = {
|
const tableColumnComponents = {
|
||||||
id: {
|
id: {
|
||||||
|
@ -88,6 +89,10 @@ const tableColumnComponents = {
|
||||||
component: 'span',
|
component: 'span',
|
||||||
attrs: {},
|
attrs: {},
|
||||||
},
|
},
|
||||||
|
percentage: {
|
||||||
|
component: 'span',
|
||||||
|
attrs: {},
|
||||||
|
},
|
||||||
kg: {
|
kg: {
|
||||||
component: VnInput,
|
component: VnInput,
|
||||||
attrs: { dense: true, type: 'number', min: 0, class: 'input-number' },
|
attrs: { dense: true, type: 'number', min: 0, class: 'input-number' },
|
||||||
|
@ -179,6 +184,14 @@ const columns = computed(() => [
|
||||||
showValue: true,
|
showValue: true,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '%',
|
||||||
|
field: '',
|
||||||
|
name: 'percentage',
|
||||||
|
align: 'center',
|
||||||
|
showValue: false,
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: t('kg'),
|
label: t('kg'),
|
||||||
field: 'kg',
|
field: 'kg',
|
||||||
|
@ -278,6 +291,8 @@ const saveFieldValue = async (val, field, index) => {
|
||||||
await axios.patch(`Travels/${id}`, params);
|
await axios.patch(`Travels/${id}`, params);
|
||||||
// Actualizar la copia de los datos originales con el nuevo valor
|
// Actualizar la copia de los datos originales con el nuevo valor
|
||||||
originalRowDataCopy.value[index][field] = val;
|
originalRowDataCopy.value[index][field] = val;
|
||||||
|
|
||||||
|
await arrayData.fetch({ append: false });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error updating travel');
|
console.error('Error updating travel');
|
||||||
}
|
}
|
||||||
|
@ -302,6 +317,11 @@ onMounted(async () => {
|
||||||
|
|
||||||
landedTo.value.setDate(landedTo.value.getDate() + 7);
|
landedTo.value.setDate(landedTo.value.getDate() + 7);
|
||||||
landedTo.value.setHours(23, 59, 59, 59);
|
landedTo.value.setHours(23, 59, 59, 59);
|
||||||
|
const { data } = await axios.get('TravelKgPercentages', {
|
||||||
|
params: { filter: JSON.stringify({ order: 'value DESC' }) },
|
||||||
|
});
|
||||||
|
|
||||||
|
travelKgPercentages.value = data;
|
||||||
await getData();
|
await getData();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -419,6 +439,11 @@ const handleDragScroll = (event) => {
|
||||||
stopScroll();
|
stopScroll();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getColor = (percentage) => {
|
||||||
|
for (const { value, className } of travelKgPercentages.value)
|
||||||
|
if (percentage > value) return className;
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -460,7 +485,7 @@ const handleDragScroll = (event) => {
|
||||||
<template #body="props">
|
<template #body="props">
|
||||||
<QTr
|
<QTr
|
||||||
:props="props"
|
:props="props"
|
||||||
class="cursor-pointer bg-vn-primary-row"
|
class="cursor-pointer bg-travel"
|
||||||
@click="navigateToTravelId(props.row.id)"
|
@click="navigateToTravelId(props.row.id)"
|
||||||
@dragenter="handleDragEnter($event, props.rowIndex)"
|
@dragenter="handleDragEnter($event, props.rowIndex)"
|
||||||
@dragover.prevent
|
@dragover.prevent
|
||||||
|
@ -494,18 +519,32 @@ const handleDragScroll = (event) => {
|
||||||
: {}
|
: {}
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<template v-if="col.showValue">
|
<QChip
|
||||||
|
v-if="col.name === 'percentage'"
|
||||||
|
:label="
|
||||||
|
props.row.percentageKg
|
||||||
|
? `${props.row.percentageKg}%`
|
||||||
|
: '-'
|
||||||
|
"
|
||||||
|
class="text-left q-py-xs q-px-sm"
|
||||||
|
:color="getColor(props.row.percentageKg)"
|
||||||
|
/>
|
||||||
<span
|
<span
|
||||||
|
v-else-if="col.showValue"
|
||||||
:class="[
|
:class="[
|
||||||
'text-left',
|
'text-left',
|
||||||
{
|
{
|
||||||
'supplier-name':
|
'supplier-name':
|
||||||
col.name === 'cargoSupplierNickname',
|
col.name === 'cargoSupplierNickname',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
link: ['id', 'cargoSupplierNickname'].includes(
|
||||||
|
col.name
|
||||||
|
),
|
||||||
|
},
|
||||||
]"
|
]"
|
||||||
>{{ col.value }}</span
|
v-text="col.value"
|
||||||
>
|
/>
|
||||||
</template>
|
|
||||||
<!-- Main Row Descriptors -->
|
<!-- Main Row Descriptors -->
|
||||||
<TravelDescriptorProxy
|
<TravelDescriptorProxy
|
||||||
v-if="col.name === 'id'"
|
v-if="col.name === 'id'"
|
||||||
|
@ -539,11 +578,11 @@ const handleDragScroll = (event) => {
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<QTd>
|
<QTd>
|
||||||
<QBtn flat color="primary">{{ entry.id }} </QBtn>
|
<QBtn flat class="link">{{ entry.id }} </QBtn>
|
||||||
<EntryDescriptorProxy :id="entry.id" />
|
<EntryDescriptorProxy :id="entry.id" />
|
||||||
</QTd>
|
</QTd>
|
||||||
<QTd>
|
<QTd>
|
||||||
<QBtn flat color="primary" dense>{{ entry.supplierName }}</QBtn>
|
<QBtn flat class="link" dense>{{ entry.supplierName }}</QBtn>
|
||||||
<SupplierDescriptorProxy :id="entry.supplierFk" />
|
<SupplierDescriptorProxy :id="entry.supplierFk" />
|
||||||
</QTd>
|
</QTd>
|
||||||
<QTd />
|
<QTd />
|
||||||
|
@ -556,6 +595,7 @@ const handleDragScroll = (event) => {
|
||||||
<QTd>
|
<QTd>
|
||||||
<span>{{ entry.stickers }}</span>
|
<span>{{ entry.stickers }}</span>
|
||||||
</QTd>
|
</QTd>
|
||||||
|
<QTd />
|
||||||
<QTd></QTd>
|
<QTd></QTd>
|
||||||
<QTd>
|
<QTd>
|
||||||
<span>{{ entry.loadedkg }}</span>
|
<span>{{ entry.loadedkg }}</span>
|
||||||
|
@ -574,10 +614,23 @@ const handleDragScroll = (event) => {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.q-chip {
|
||||||
|
color: var(--vn-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.q-table) {
|
:deep(.q-table) {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.q-td :deep(input) {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-travel {
|
||||||
|
background-color: var(--vn-page-color);
|
||||||
|
border-bottom: 2px solid $primary;
|
||||||
|
}
|
||||||
|
|
||||||
.dashed-border {
|
.dashed-border {
|
||||||
&.--left {
|
&.--left {
|
||||||
border-left: 1px dashed #ccc;
|
border-left: 1px dashed #ccc;
|
||||||
|
|
|
@ -15,29 +15,19 @@ const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const newTravelForm = reactive({
|
|
||||||
ref: null,
|
|
||||||
agencyModeFk: null,
|
|
||||||
shipped: null,
|
|
||||||
landed: null,
|
|
||||||
warehouseOutFk: null,
|
|
||||||
warehouseInFk: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
const agenciesOptions = ref([]);
|
const agenciesOptions = ref([]);
|
||||||
const warehousesOptions = ref([]);
|
const warehousesOptions = ref([]);
|
||||||
const viewAction = ref();
|
const viewAction = ref();
|
||||||
|
|
||||||
|
const newTravelForm = ref({});
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
// Esto nos permite decirle a FormModel si queremos observar los cambios o no
|
|
||||||
// Ya que si queremos clonar queremos que nos permita guardar inmediatamente sin realizar cambios en el form
|
|
||||||
viewAction.value = route.query.travelData ? 'clone' : 'create';
|
viewAction.value = route.query.travelData ? 'clone' : 'create';
|
||||||
|
|
||||||
if (route.query.travelData) {
|
if (route.query.travelData) {
|
||||||
const travelData = JSON.parse(route.query.travelData);
|
const travelData = JSON.parse(route.query.travelData);
|
||||||
for (let key in newTravelForm) {
|
|
||||||
newTravelForm[key] = travelData[key];
|
newTravelForm.value = { ...newTravelForm.value, ...travelData };
|
||||||
}
|
delete newTravelForm.value.id;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -60,8 +50,8 @@ const redirectToTravelBasicData = (_, { id }) => {
|
||||||
<QPage>
|
<QPage>
|
||||||
<VnSubToolbar />
|
<VnSubToolbar />
|
||||||
<FormModel
|
<FormModel
|
||||||
url-update="Travels"
|
url-create="Travels"
|
||||||
model="travel"
|
model="travelCreate"
|
||||||
:form-initial-data="newTravelForm"
|
:form-initial-data="newTravelForm"
|
||||||
:observe-form-changes="viewAction === 'create'"
|
:observe-form-changes="viewAction === 'create'"
|
||||||
@on-data-saved="redirectToTravelBasicData"
|
@on-data-saved="redirectToTravelBasicData"
|
||||||
|
|
|
@ -40,6 +40,7 @@ onMounted(() => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FormModel
|
<FormModel
|
||||||
|
model="createDepartmentChild"
|
||||||
:form-initial-data="departmentChildData"
|
:form-initial-data="departmentChildData"
|
||||||
:observe-form-changes="false"
|
:observe-form-changes="false"
|
||||||
:default-actions="false"
|
:default-actions="false"
|
||||||
|
|
|
@ -6,12 +6,11 @@ import { useQuasar } from 'quasar';
|
||||||
import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
|
import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
|
||||||
import CreateDepartmentChild from './CreateDepartmentChild.vue';
|
import CreateDepartmentChild from './CreateDepartmentChild.vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||||
|
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { notify } = useNotify();
|
|
||||||
const state = useState();
|
const state = useState();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
@ -62,24 +61,27 @@ const removeNode = (node) => {
|
||||||
const { id, parentFk } = node;
|
const { id, parentFk } = node;
|
||||||
quasar
|
quasar
|
||||||
.dialog({
|
.dialog({
|
||||||
|
component: VnConfirm,
|
||||||
|
componentProps: {
|
||||||
title: t('Are you sure you want to delete it?'),
|
title: t('Are you sure you want to delete it?'),
|
||||||
message: t('Delete department'),
|
message: t('Delete department'),
|
||||||
ok: {
|
promise: () => remove(id),
|
||||||
push: true,
|
|
||||||
color: 'primary',
|
|
||||||
},
|
},
|
||||||
cancel: true,
|
|
||||||
})
|
})
|
||||||
.onOk(async () => {
|
.onOk(async () => await fetchNodeLeaves(parentFk));
|
||||||
|
};
|
||||||
|
|
||||||
|
async function remove(id) {
|
||||||
try {
|
try {
|
||||||
await axios.post(`/Departments/${id}/removeChild`, id);
|
await axios.post(`/Departments/${id}/removeChild`, { id });
|
||||||
notify(t('department.departmentRemoved'), 'positive');
|
quasar.notify({
|
||||||
await fetchNodeLeaves(parentFk);
|
message: t('department.departmentRemoved'),
|
||||||
|
type: 'positive',
|
||||||
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error removing department');
|
console.error('Error removing department');
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const showCreateNodeForm = (nodeId) => {
|
const showCreateNodeForm = (nodeId) => {
|
||||||
showCreateNodeFormVal.value = true;
|
showCreateNodeFormVal.value = true;
|
||||||
|
|
|
@ -14,7 +14,6 @@ export default {
|
||||||
main: [
|
main: [
|
||||||
'CustomerList',
|
'CustomerList',
|
||||||
'CustomerPayments',
|
'CustomerPayments',
|
||||||
'CustomerExtendedList',
|
|
||||||
'CustomerNotifications',
|
'CustomerNotifications',
|
||||||
'CustomerDefaulter',
|
'CustomerDefaulter',
|
||||||
],
|
],
|
||||||
|
@ -70,18 +69,6 @@ export default {
|
||||||
component: () =>
|
component: () =>
|
||||||
import('src/pages/Customer/Payments/CustomerPayments.vue'),
|
import('src/pages/Customer/Payments/CustomerPayments.vue'),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'extendedList',
|
|
||||||
name: 'CustomerExtendedList',
|
|
||||||
meta: {
|
|
||||||
title: 'extendedList',
|
|
||||||
icon: 'vn:client',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import(
|
|
||||||
'src/pages/Customer/ExtendedList/CustomerExtendedList.vue'
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'notifications',
|
path: 'notifications',
|
||||||
name: 'CustomerNotifications',
|
name: 'CustomerNotifications',
|
||||||
|
|
|
@ -2,8 +2,7 @@ const locationOptions = '[role="listbox"] > div.q-virtual-scroll__content > .q-i
|
||||||
describe('VnLocation', () => {
|
describe('VnLocation', () => {
|
||||||
const dialogInputs = '.q-dialog label input';
|
const dialogInputs = '.q-dialog label input';
|
||||||
describe('Worker Create', () => {
|
describe('Worker Create', () => {
|
||||||
const inputLocation =
|
const inputLocation = '.q-form input[aria-label="Location"]';
|
||||||
'.q-form .q-card > :nth-child(3) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container';
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
|
@ -25,9 +24,6 @@ describe('VnLocation', () => {
|
||||||
cy.get(inputLocation).clear();
|
cy.get(inputLocation).clear();
|
||||||
cy.get(inputLocation).type('ecuador');
|
cy.get(inputLocation).type('ecuador');
|
||||||
cy.get(locationOptions).should('have.length.at.least', 1);
|
cy.get(locationOptions).should('have.length.at.least', 1);
|
||||||
cy.get(
|
|
||||||
'.q-form .q-card > :nth-child(3) > .q-field > .q-field__inner > .q-field__control > :nth-child(3) > .q-icon'
|
|
||||||
).click();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('Fiscal-data', () => {
|
describe('Fiscal-data', () => {
|
||||||
|
@ -38,9 +34,7 @@ describe('VnLocation', () => {
|
||||||
cy.waitForElement('.q-form');
|
cy.waitForElement('.q-form');
|
||||||
});
|
});
|
||||||
it('Create postCode', function () {
|
it('Create postCode', function () {
|
||||||
cy.get(
|
cy.get('.q-form > .q-card > .vn-row:nth-child(6) .--add-icon').click();
|
||||||
':nth-child(6) > .q-field > .q-field__inner > .q-field__control > :nth-child(2) > .q-icon'
|
|
||||||
).click();
|
|
||||||
cy.get('.q-card > h1').should('have.text', 'New postcode');
|
cy.get('.q-card > h1').should('have.text', 'New postcode');
|
||||||
cy.get(dialogInputs).eq(0).clear('12');
|
cy.get(dialogInputs).eq(0).clear('12');
|
||||||
cy.get(dialogInputs).eq(0).type('1234453');
|
cy.get(dialogInputs).eq(0).type('1234453');
|
||||||
|
|
|
@ -1,31 +1,81 @@
|
||||||
import { describe, expect, it, beforeAll } from 'vitest';
|
import { describe, expect, it, beforeAll, afterEach, vi } from 'vitest';
|
||||||
import { axios } from 'app/test/vitest/helper';
|
import { axios, flushPromises } from 'app/test/vitest/helper';
|
||||||
import { useArrayData } from 'composables/useArrayData';
|
import { useArrayData } from 'composables/useArrayData';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
describe('useArrayData', () => {
|
describe('useArrayData', () => {
|
||||||
let arrayData;
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
axios.get.mockResolvedValue({ data: [] });
|
vi.spyOn(useRouter(), 'replace');
|
||||||
arrayData = useArrayData('InvoiceIn', { url: 'invoice-in/list' });
|
vi.spyOn(useRouter(), 'push');
|
||||||
Object.defineProperty(window.location, 'href', {
|
|
||||||
writable: true,
|
|
||||||
value: 'localhost:9000/invoice-in/list',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mock the window.history.pushState method within useArrayData
|
afterEach(() => {
|
||||||
window.history.pushState = (data, title, url) => (window.location.href = url);
|
vi.clearAllMocks();
|
||||||
|
|
||||||
// Mock the URL constructor within useArrayData
|
|
||||||
global.URL = class URL {
|
|
||||||
constructor(url) {
|
|
||||||
this.hash = url.split('localhost:9000/')[1];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add the params to the url', async () => {
|
it('should fetch and repalce url with new params', async () => {
|
||||||
arrayData.store.userParams = { supplierFk: 2 };
|
vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [] });
|
||||||
arrayData.updateStateParams();
|
|
||||||
expect(window.location.href).contain('params=%7B%22supplierFk%22%3A2%7D');
|
const arrayData = useArrayData('ArrayData', { url: 'mockUrl' });
|
||||||
|
|
||||||
|
const filter = '{"order":"","limit":10,"skip":0}';
|
||||||
|
const params = { supplierFk: 2 };
|
||||||
|
arrayData.store.userParams = params;
|
||||||
|
arrayData.fetch({});
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
const routerReplace = useRouter().replace.mock.calls[0][0];
|
||||||
|
|
||||||
|
expect(axios.get.mock.calls[0][1].params).toEqual({
|
||||||
|
filter,
|
||||||
|
supplierFk: 2,
|
||||||
});
|
});
|
||||||
|
expect(routerReplace.path).toEqual('mockSection/list');
|
||||||
|
expect(JSON.parse(routerReplace.query.params)).toEqual(
|
||||||
|
expect.objectContaining(params)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should get data and send new URL without keeping parameters, if there is only one record', async () => {
|
||||||
|
vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [{ id: 1 }] });
|
||||||
|
|
||||||
|
const arrayData = useArrayData('ArrayData', { url: 'mockUrl', navigate: {} });
|
||||||
|
|
||||||
|
const filter = '{"order":"","limit":10,"skip":0}';
|
||||||
|
const params = { supplierFk: 2 };
|
||||||
|
arrayData.store.userParams = params;
|
||||||
|
arrayData.fetch({});
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
const routerPush = useRouter().push.mock.calls[0][0];
|
||||||
|
|
||||||
|
expect(axios.get.mock.calls[0][1].params).toEqual({
|
||||||
|
filter,
|
||||||
|
supplierFk: 2,
|
||||||
|
});
|
||||||
|
expect(routerPush.path).toEqual('mockName/1');
|
||||||
|
expect(routerPush.query).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
// it('Should get data and send new URL keeping parameters, if you have more than one record', async () => {
|
||||||
|
// vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [{ id: 1 }, { id: 2 }] });
|
||||||
|
|
||||||
|
// const arrayData = useArrayData('ArrayData', { url: 'mockUrl', navigate: {} });
|
||||||
|
|
||||||
|
// const filter = '{"order":"","limit":10,"skip":0}';
|
||||||
|
// const params = { supplierFk: 2 };
|
||||||
|
// arrayData.store.userParams = params;
|
||||||
|
// arrayData.fetch({});
|
||||||
|
|
||||||
|
// await flushPromises();
|
||||||
|
// const routerPush = useRouter().push.mock.calls[0][0];
|
||||||
|
// console.log('routerPush: ', routerPush);
|
||||||
|
|
||||||
|
// expect(axios.get.mock.calls[0][1].params).toEqual({
|
||||||
|
// filter,
|
||||||
|
// supplierFk: 2,
|
||||||
|
// });
|
||||||
|
// expect(routerPush.path).toEqual('mockName/1');
|
||||||
|
// expect(routerPush.query).toBeUndefined();
|
||||||
|
// });
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,16 +15,19 @@ installQuasarPlugin({
|
||||||
});
|
});
|
||||||
const pinia = createTestingPinia({ createSpy: vi.fn, stubActions: false });
|
const pinia = createTestingPinia({ createSpy: vi.fn, stubActions: false });
|
||||||
const mockPush = vi.fn();
|
const mockPush = vi.fn();
|
||||||
|
const mockReplace = vi.fn();
|
||||||
|
|
||||||
vi.mock('vue-router', () => ({
|
vi.mock('vue-router', () => ({
|
||||||
useRouter: () => ({
|
useRouter: () => ({
|
||||||
push: mockPush,
|
push: mockPush,
|
||||||
|
replace: mockReplace,
|
||||||
currentRoute: {
|
currentRoute: {
|
||||||
value: {
|
value: {
|
||||||
params: {
|
params: {
|
||||||
id: 1,
|
id: 1,
|
||||||
},
|
},
|
||||||
meta: { moduleName: 'mockName' },
|
meta: { moduleName: 'mockName' },
|
||||||
|
matched: [{ path: 'mockName/list' }],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
@ -33,6 +36,7 @@ vi.mock('vue-router', () => ({
|
||||||
query: {},
|
query: {},
|
||||||
params: {},
|
params: {},
|
||||||
meta: { moduleName: 'mockName' },
|
meta: { moduleName: 'mockName' },
|
||||||
|
path: 'mockSection/list',
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue