Merge pull request '#7283 finish item card sections' (!588) from 7283-itemSectionsMigration into dev
Reviewed-on: #588 Reviewed-by: Alex Moreno <alexm@verdnatura.es> Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
This commit is contained in:
commit
59262019f8
|
@ -7,7 +7,7 @@ import { useQuasar } from 'quasar';
|
|||
import PinnedModules from './PinnedModules.vue';
|
||||
import UserPanel from 'components/UserPanel.vue';
|
||||
import VnBreadcrumbs from './common/VnBreadcrumbs.vue';
|
||||
import VnImg from 'src/components/ui/VnImg.vue';
|
||||
import VnAvatar from './ui/VnAvatar.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const stateStore = useStateStore();
|
||||
|
@ -72,22 +72,13 @@ const pinnedModulesRef = ref();
|
|||
</QTooltip>
|
||||
<PinnedModules ref="pinnedModulesRef" />
|
||||
</QBtn>
|
||||
<QBtn
|
||||
:class="{ 'q-pa-none': quasar.platform.is.mobile }"
|
||||
rounded
|
||||
dense
|
||||
flat
|
||||
no-wrap
|
||||
id="user"
|
||||
>
|
||||
<QAvatar size="lg">
|
||||
<VnImg
|
||||
:id="user.id"
|
||||
collection="user"
|
||||
size="160x160"
|
||||
:zoom-size="null"
|
||||
/>
|
||||
</QAvatar>
|
||||
<QBtn class="q-pa-none" rounded dense flat no-wrap id="user">
|
||||
<VnAvatar
|
||||
:worker-id="user.id"
|
||||
:title="user.name"
|
||||
size="lg"
|
||||
color="transparent"
|
||||
/>
|
||||
<QTooltip bottom>
|
||||
{{ t('globals.userPanel') }}
|
||||
</QTooltip>
|
||||
|
|
|
@ -11,8 +11,8 @@ import VnSelect from 'src/components/common/VnSelect.vue';
|
|||
import VnRow from 'components/ui/VnRow.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import { useClipboard } from 'src/composables/useClipboard';
|
||||
import VnImg from 'src/components/ui/VnImg.vue';
|
||||
import { useRole } from 'src/composables/useRole';
|
||||
import VnAvatar from './ui/VnAvatar.vue';
|
||||
|
||||
const state = useState();
|
||||
const session = useSession();
|
||||
|
@ -136,7 +136,7 @@ const isEmployee = computed(() => useRole().isEmployee());
|
|||
@update:model-value="saveLanguage"
|
||||
:label="t(`globals.lang['${userLocale}']`)"
|
||||
icon="public"
|
||||
color="orange"
|
||||
color="primary"
|
||||
false-value="es"
|
||||
true-value="en"
|
||||
/>
|
||||
|
@ -145,7 +145,7 @@ const isEmployee = computed(() => useRole().isEmployee());
|
|||
@update:model-value="saveDarkMode"
|
||||
:label="t(`globals.darkMode`)"
|
||||
checked-icon="dark_mode"
|
||||
color="orange"
|
||||
color="primary"
|
||||
unchecked-icon="light_mode"
|
||||
/>
|
||||
</div>
|
||||
|
@ -153,10 +153,12 @@ const isEmployee = computed(() => useRole().isEmployee());
|
|||
<QSeparator vertical inset class="q-mx-lg" />
|
||||
|
||||
<div class="col column items-center q-mb-sm">
|
||||
<QAvatar size="80px">
|
||||
<VnImg :id="user.id" collection="user" size="160x160" />
|
||||
</QAvatar>
|
||||
|
||||
<VnAvatar
|
||||
:worker-id="user.id"
|
||||
:title="user.name"
|
||||
size="xxl"
|
||||
color="transparent"
|
||||
/>
|
||||
<div class="text-subtitle1 q-mt-md">
|
||||
<strong>{{ user.nickname }}</strong>
|
||||
</div>
|
||||
|
@ -168,7 +170,7 @@ const isEmployee = computed(() => useRole().isEmployee());
|
|||
</div>
|
||||
<QBtn
|
||||
id="logout"
|
||||
color="orange"
|
||||
color="primary"
|
||||
flat
|
||||
:label="t('globals.logOut')"
|
||||
size="sm"
|
||||
|
|
|
@ -31,7 +31,7 @@ const dialog = ref(null);
|
|||
<div class="container order-catalog-item overflow-hidden">
|
||||
<QCard class="card shadow-6">
|
||||
<div class="img-wrapper">
|
||||
<VnImg :id="item.id" zoom-size="lg" class="image" />
|
||||
<VnImg :id="item.id" class="image" />
|
||||
<div v-if="item.hex && isCatalog" class="item-color-container">
|
||||
<div
|
||||
class="item-color"
|
||||
|
|
|
@ -1,45 +1,62 @@
|
|||
<script setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useSession } from 'src/composables/useSession';
|
||||
import { useColor } from 'src/composables/useColor';
|
||||
import { getCssVar } from 'quasar';
|
||||
|
||||
const $props = defineProps({
|
||||
workerId: { type: Number, required: true },
|
||||
description: { type: String, default: null },
|
||||
size: { type: String, default: null },
|
||||
title: { type: String, default: null },
|
||||
color: { type: String, default: null },
|
||||
});
|
||||
|
||||
const { getTokenMultimedia } = useSession();
|
||||
const token = getTokenMultimedia();
|
||||
const { t } = useI18n();
|
||||
|
||||
const title = computed(() => $props.title ?? t('globals.system'));
|
||||
const src = computed(
|
||||
() => `/api/Images/user/160x160/${$props.workerId}/download?access_token=${token}`
|
||||
);
|
||||
const title = computed(() => $props.title?.toUpperCase() || t('globals.system'));
|
||||
const showLetter = ref(false);
|
||||
const backgroundColor = computed(() => {
|
||||
const color = $props.color || useColor(title.value);
|
||||
return getCssVar(color) || color;
|
||||
});
|
||||
|
||||
watch(src, () => (showLetter.value = false));
|
||||
</script>
|
||||
<template>
|
||||
<div class="avatar-picture column items-center">
|
||||
<div class="column items-center">
|
||||
<QAvatar
|
||||
:style="{
|
||||
backgroundColor: useColor(title),
|
||||
}"
|
||||
:size="$props.size"
|
||||
:title="title"
|
||||
:style="{ backgroundColor }"
|
||||
v-bind="$attrs"
|
||||
:title="title || t('globals.system')"
|
||||
>
|
||||
<template v-if="showLetter">{{ title.charAt(0) }}</template>
|
||||
<QImg
|
||||
v-else
|
||||
:src="`/api/Images/user/160x160/${$props.workerId}/download?access_token=${token}`"
|
||||
spinner-color="white"
|
||||
@error="showLetter = true"
|
||||
/>
|
||||
<template v-if="showLetter">
|
||||
{{ title.charAt(0) }}
|
||||
</template>
|
||||
<QImg v-else :src="src" spinner-color="white" @error="showLetter = true" />
|
||||
</QAvatar>
|
||||
<div class="description">
|
||||
<slot name="description" v-if="$props.description">
|
||||
<p>
|
||||
{{ $props.description }}
|
||||
</p>
|
||||
<slot name="description" v-if="description">
|
||||
<p v-text="description" />
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
[size='xxl'] {
|
||||
.q-avatar,
|
||||
.q-img {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.q-img {
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { useSession } from 'src/composables/useSession';
|
||||
import noImage from '/no-user.png';
|
||||
import { useRole } from 'src/composables/useRole';
|
||||
|
||||
const $props = defineProps({
|
||||
storage: {
|
||||
|
@ -11,14 +13,17 @@ const $props = defineProps({
|
|||
type: String,
|
||||
default: 'catalog',
|
||||
},
|
||||
size: {
|
||||
resolution: {
|
||||
type: String,
|
||||
default: '200x200',
|
||||
},
|
||||
zoomSize: {
|
||||
zoomResolution: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'lg',
|
||||
default: null,
|
||||
},
|
||||
zoom: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
id: {
|
||||
type: Number,
|
||||
|
@ -28,14 +33,16 @@ const $props = defineProps({
|
|||
const show = ref(false);
|
||||
const token = useSession().getTokenMultimedia();
|
||||
const timeStamp = ref(`timestamp=${Date.now()}`);
|
||||
import noImage from '/no-user.png';
|
||||
import { useRole } from 'src/composables/useRole';
|
||||
const url = computed(() => {
|
||||
const isEmployee = useRole().isEmployee();
|
||||
const isEmployee = useRole().isEmployee();
|
||||
|
||||
const getUrl = (zoom = false) => {
|
||||
const curResolution = zoom
|
||||
? $props.zoomResolution || $props.resolution
|
||||
: $props.resolution;
|
||||
return isEmployee
|
||||
? `/api/${$props.storage}/${$props.collection}/${$props.size}/${$props.id}/download?access_token=${token}&${timeStamp.value}`
|
||||
? `/api/${$props.storage}/${$props.collection}/${curResolution}/${$props.id}/download?access_token=${token}&${timeStamp.value}`
|
||||
: noImage;
|
||||
});
|
||||
};
|
||||
const reload = () => {
|
||||
timeStamp.value = `timestamp=${Date.now()}`;
|
||||
};
|
||||
|
@ -45,23 +52,21 @@ defineExpose({
|
|||
</script>
|
||||
<template>
|
||||
<QImg
|
||||
:class="{ zoomIn: $props.zoomSize }"
|
||||
:src="url"
|
||||
:class="{ zoomIn: zoom }"
|
||||
:src="getUrl()"
|
||||
v-bind="$attrs"
|
||||
@click="show = !show"
|
||||
@click.stop="show = $props.zoom ? true : false"
|
||||
spinner-color="primary"
|
||||
/>
|
||||
<QDialog v-model="show" v-if="$props.zoomSize">
|
||||
<QDialog v-if="$props.zoom" v-model="show">
|
||||
<QImg
|
||||
:src="url"
|
||||
size="full"
|
||||
class="img_zoom"
|
||||
:src="getUrl(true)"
|
||||
v-bind="$attrs"
|
||||
spinner-color="primary"
|
||||
class="img_zoom"
|
||||
/>
|
||||
</QDialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.q-img {
|
||||
&.zoomIn {
|
||||
|
|
|
@ -221,7 +221,7 @@ defineExpose({ fetch, addFilter, paginate });
|
|||
>
|
||||
<slot name="body" :rows="store.data"></slot>
|
||||
<div v-if="isLoading" class="info-row q-pa-md text-center">
|
||||
<QSpinner color="orange" size="md" />
|
||||
<QSpinner color="primary" size="md" />
|
||||
</div>
|
||||
</QInfiniteScroll>
|
||||
</template>
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
<script setup>
|
||||
defineProps({ wrap: { type: Boolean, default: false } });
|
||||
</script>
|
||||
<template>
|
||||
<div class="vn-row q-gutter-md q-mb-md" :class="{ wrap }">
|
||||
<slot></slot>
|
||||
<div class="vn-row q-gutter-md q-mb-md">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scopped>
|
||||
<style lang="scss" scoped>
|
||||
.vn-row {
|
||||
display: flex;
|
||||
> * {
|
||||
> :deep(*) {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ const hasAccount = ref(false);
|
|||
</template>
|
||||
<template #before>
|
||||
<!-- falla id :id="entityId.value" collection="user" size="160x160" -->
|
||||
<VnImg :id="entityId" collection="user" size="160x160" class="photo">
|
||||
<VnImg :id="entityId" collection="user" resolution="160x160" class="photo">
|
||||
<template #error>
|
||||
<div
|
||||
class="absolute-full picture text-center q-pa-md flex flex-center"
|
||||
|
|
|
@ -10,13 +10,10 @@ import VnInput from 'src/components/common/VnInput.vue';
|
|||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
|
||||
import axios from 'axios';
|
||||
// import { useSession } from 'src/composables/useSession';
|
||||
import VnImg from 'src/components/ui/VnImg.vue';
|
||||
import VnAvatar from 'src/components/ui/VnAvatar.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
// const { getTokenMultimedia } = useSession();
|
||||
// const token = getTokenMultimedia();
|
||||
|
||||
const claimStates = ref([]);
|
||||
const claimStatesCopy = ref([]);
|
||||
|
@ -94,15 +91,14 @@ const statesFilter = {
|
|||
:rules="validate('claim.claimStateFk')"
|
||||
>
|
||||
<template #before>
|
||||
<QAvatar color="orange">
|
||||
<VnImg
|
||||
v-if="data.workerFk"
|
||||
:size="'160x160'"
|
||||
:id="data.workerFk"
|
||||
collection="user"
|
||||
spinner-color="white"
|
||||
/>
|
||||
</QAvatar>
|
||||
<VnAvatar
|
||||
:worker-id="data.workerFk"
|
||||
size="md"
|
||||
:title="
|
||||
workersOptions.find(({ id }) => id == data.workerFk)?.name
|
||||
"
|
||||
color="primary"
|
||||
/>
|
||||
</template>
|
||||
</VnSelect>
|
||||
<QSelect
|
||||
|
|
|
@ -7,14 +7,15 @@ import FetchData from 'components/FetchData.vue';
|
|||
import FormModel from 'components/FormModel.vue';
|
||||
import VnRow from 'components/ui/VnRow.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnImg from 'src/components/ui/VnImg.vue';
|
||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||
import VnAvatar from 'src/components/ui/VnAvatar.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
|
||||
const businessTypes = ref([]);
|
||||
const contactChannels = ref([]);
|
||||
const title = ref();
|
||||
</script>
|
||||
<template>
|
||||
<FetchData
|
||||
|
@ -95,16 +96,15 @@ const contactChannels = ref([]);
|
|||
:label="t('customer.basicData.salesPerson')"
|
||||
:rules="validate('client.salesPersonFk')"
|
||||
:use-like="false"
|
||||
:emit-value="false"
|
||||
@update:model-value="(val) => (title = val?.nickname)"
|
||||
>
|
||||
<template #prepend>
|
||||
<QAvatar color="orange">
|
||||
<VnImg
|
||||
v-if="data.salesPersonFk"
|
||||
:id="data.salesPersonFk"
|
||||
collection="user"
|
||||
spinner-color="white"
|
||||
/>
|
||||
</QAvatar>
|
||||
<VnAvatar
|
||||
:worker-id="data.salesPersonFk"
|
||||
color="primary"
|
||||
:title="title"
|
||||
/>
|
||||
</template>
|
||||
</VnSelect>
|
||||
<QSelect
|
||||
|
|
|
@ -10,7 +10,6 @@ import FetchData from 'src/components/FetchData.vue';
|
|||
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||
import { toCurrency } from 'src/filters';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||
|
||||
|
|
|
@ -36,15 +36,6 @@ const onIntrastatCreated = (response, formData) => {
|
|||
@on-fetch="(data) => (itemTypesOptions = data)"
|
||||
auto-load
|
||||
/>
|
||||
<FetchData
|
||||
url="Items/withName"
|
||||
:filter="{
|
||||
fields: ['id', 'name'],
|
||||
order: 'id DESC',
|
||||
}"
|
||||
@on-fetch="(data) => (itemsWithNameOptions = data)"
|
||||
auto-load
|
||||
/>
|
||||
<FetchData
|
||||
url="Intrastats"
|
||||
:filter="{
|
||||
|
@ -73,7 +64,7 @@ const onIntrastatCreated = (response, formData) => {
|
|||
<template #form="{ data }">
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
:label="t('basicData.type')"
|
||||
:label="t('itemBasicData.type')"
|
||||
v-model="data.typeFk"
|
||||
:options="itemTypesOptions"
|
||||
option-value="id"
|
||||
|
@ -92,19 +83,21 @@ const onIntrastatCreated = (response, formData) => {
|
|||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
<VnInput :label="t('basicData.reference')" v-model="data.comment" />
|
||||
<VnInput :label="t('basicData.relevancy')" v-model="data.relevancy" />
|
||||
<VnInput :label="t('itemBasicData.reference')" v-model="data.comment" />
|
||||
<VnInput :label="t('itemBasicData.relevancy')" v-model="data.relevancy" />
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnInput :label="t('basicData.stems')" v-model="data.stems" />
|
||||
<VnInput :label="t('itemBasicData.stems')" v-model="data.stems" />
|
||||
<VnInput
|
||||
:label="t('basicData.multiplier')"
|
||||
:label="t('itemBasicData.multiplier')"
|
||||
v-model="data.stemMultiplier"
|
||||
/>
|
||||
<VnSelectDialog
|
||||
:label="t('basicData.generic')"
|
||||
:label="t('itemBasicData.generic')"
|
||||
v-model="data.genericFk"
|
||||
:options="itemsWithNameOptions"
|
||||
url="Items/withName"
|
||||
:fields="['id', 'name']"
|
||||
sort-by="id DESC"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
map-options
|
||||
|
@ -129,7 +122,7 @@ const onIntrastatCreated = (response, formData) => {
|
|||
</VnRow>
|
||||
<VnRow>
|
||||
<VnSelectDialog
|
||||
:label="t('basicData.intrastat')"
|
||||
:label="t('itemBasicData.intrastat')"
|
||||
v-model="data.intrastatFk"
|
||||
:options="intrastatsOptions"
|
||||
option-value="id"
|
||||
|
@ -156,7 +149,7 @@ const onIntrastatCreated = (response, formData) => {
|
|||
</VnSelectDialog>
|
||||
<div class="col">
|
||||
<VnSelect
|
||||
:label="t('basicData.expense')"
|
||||
:label="t('itemBasicData.expense')"
|
||||
v-model="data.expenseFk"
|
||||
:options="expensesOptions"
|
||||
option-value="id"
|
||||
|
@ -168,61 +161,64 @@ const onIntrastatCreated = (response, formData) => {
|
|||
</VnRow>
|
||||
<VnRow>
|
||||
<VnInput
|
||||
:label="t('basicData.weightByPiece')"
|
||||
:label="t('itemBasicData.weightByPiece')"
|
||||
v-model.number="data.weightByPiece"
|
||||
:min="0"
|
||||
type="number"
|
||||
/>
|
||||
<VnInput
|
||||
:label="t('basicData.boxUnits')"
|
||||
:label="t('itemBasicData.boxUnits')"
|
||||
v-model.number="data.packingOut"
|
||||
:min="0"
|
||||
type="number"
|
||||
/>
|
||||
<VnInput
|
||||
:label="t('basicData.recycledPlastic')"
|
||||
:label="t('itemBasicData.recycledPlastic')"
|
||||
v-model.number="data.recycledPlastic"
|
||||
:min="0"
|
||||
type="number"
|
||||
/>
|
||||
<VnInput
|
||||
:label="t('basicData.nonRecycledPlastic')"
|
||||
:label="t('itemBasicData.nonRecycledPlastic')"
|
||||
v-model.number="data.nonRecycledPlastic"
|
||||
:min="0"
|
||||
type="number"
|
||||
/>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<QCheckbox v-model="data.isActive" :label="t('basicData.isActive')" />
|
||||
<QCheckbox v-model="data.hasKgPrice" :label="t('basicData.hasKgPrice')" />
|
||||
<QCheckbox v-model="data.isActive" :label="t('itemBasicData.isActive')" />
|
||||
<QCheckbox
|
||||
v-model="data.hasKgPrice"
|
||||
:label="t('itemBasicData.hasKgPrice')"
|
||||
/>
|
||||
<div>
|
||||
<QCheckbox
|
||||
v-model="data.isFragile"
|
||||
:label="t('basicData.isFragile')"
|
||||
:label="t('itemBasicData.isFragile')"
|
||||
class="q-mr-sm"
|
||||
/>
|
||||
<QIcon name="info" class="cursor-pointer" size="xs">
|
||||
<QTooltip max-width="300px">
|
||||
{{ t('basicData.isFragileTooltip') }}
|
||||
{{ t('itemBasicData.isFragileTooltip') }}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</div>
|
||||
<div>
|
||||
<QCheckbox
|
||||
v-model="data.isPhotoRequested"
|
||||
:label="t('basicData.isPhotoRequested')"
|
||||
:label="t('itemBasicData.isPhotoRequested')"
|
||||
class="q-mr-sm"
|
||||
/>
|
||||
<QIcon name="info" class="cursor-pointer" size="xs">
|
||||
<QTooltip>
|
||||
{{ t('basicData.isPhotoRequestedTooltip') }}
|
||||
{{ t('itemBasicData.isPhotoRequestedTooltip') }}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</div>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnInput
|
||||
:label="t('basicData.description')"
|
||||
:label="t('itemBasicData.description')"
|
||||
type="textarea"
|
||||
v-model="data.description"
|
||||
fill-input
|
||||
|
|
|
@ -112,7 +112,7 @@ const openCloneDialog = async () => {
|
|||
.dialog({
|
||||
component: VnConfirm,
|
||||
componentProps: {
|
||||
title: t("All it's properties will be copied"),
|
||||
title: t('All its properties will be copied'),
|
||||
message: t('Do you want to clone this item?'),
|
||||
},
|
||||
})
|
||||
|
@ -215,7 +215,7 @@ const openCloneDialog = async () => {
|
|||
<i18n>
|
||||
es:
|
||||
Regularize stock: Regularizar stock
|
||||
All it's properties will be copied: Todas sus propiedades serán copiadas
|
||||
All its properties will be copied: Todas sus propiedades serán copiadas
|
||||
Do you want to clone this item?: ¿Desea clonar este artículo?
|
||||
</i18n>
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ const handlePhotoUpdated = (evt = false) => {
|
|||
|
||||
<template>
|
||||
<div class="relative-position">
|
||||
<VnImg ref="image" :id="$props.entityId" @refresh="handlePhotoUpdated(true)">
|
||||
<VnImg ref="image" :id="$props.entityId" zoom-resolution="1600x900">
|
||||
<template #error>
|
||||
<div class="absolute-full picture text-center q-pa-md flex flex-center">
|
||||
<div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { onMounted, computed, onUnmounted, reactive, ref } from 'vue';
|
||||
import { onMounted, computed, onUnmounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { dateRange } from 'src/filters';
|
||||
|
@ -11,6 +11,7 @@ import { toDateTimeFormat } from 'src/filters/date.js';
|
|||
import { dashIfEmpty } from 'src/filters';
|
||||
import { toCurrency } from 'filters/index';
|
||||
import { useArrayData } from 'composables/useArrayData';
|
||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
|
@ -35,26 +36,8 @@ const exprBuilder = (param, value) => {
|
|||
}
|
||||
};
|
||||
|
||||
const datedRange = reactive({
|
||||
from: null,
|
||||
to: null,
|
||||
});
|
||||
|
||||
const from = computed({
|
||||
get: () => datedRange.from,
|
||||
set: (val) => {
|
||||
updateFrom(val);
|
||||
updateFilter();
|
||||
},
|
||||
});
|
||||
|
||||
const to = computed({
|
||||
get: () => datedRange.to,
|
||||
set: (val) => {
|
||||
updateTo(val);
|
||||
updateFilter();
|
||||
},
|
||||
});
|
||||
const from = ref();
|
||||
const to = ref();
|
||||
|
||||
const arrayData = useArrayData('ItemLastEntries', {
|
||||
url: 'Items/lastEntriesFilter',
|
||||
|
@ -162,41 +145,48 @@ const fetchItemLastEntries = async () => {
|
|||
itemLastEntries.value = data;
|
||||
};
|
||||
|
||||
const updateFrom = async (date) => {
|
||||
date.setHours(0, 0, 0, 0);
|
||||
datedRange.from = date.toISOString();
|
||||
};
|
||||
|
||||
const updateTo = async (date) => {
|
||||
date.setHours(23, 59, 59, 59);
|
||||
datedRange.to = date.toISOString();
|
||||
const getDate = (date, type) => {
|
||||
if (type == 'from') {
|
||||
date.setHours(0, 0, 0, 0);
|
||||
} else if (type == 'to') {
|
||||
date.setHours(23, 59, 59, 999);
|
||||
}
|
||||
return date.toISOString();
|
||||
};
|
||||
|
||||
const updateFilter = async () => {
|
||||
arrayData.store.userFilter.where.landed = {
|
||||
between: [datedRange.from, datedRange.to],
|
||||
};
|
||||
let filter;
|
||||
if (!from.value && to.value) filter = { lte: to.value };
|
||||
else if (from.value && !to.value) filter = { gte: from.value };
|
||||
else if (from.value && to.value) filter = { between: [from.value, to.value] };
|
||||
|
||||
arrayData.store.userFilter.where.landed = filter;
|
||||
await fetchItemLastEntries();
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
const _from = Date.vnNew();
|
||||
_from.setDate(_from.getDate() - 75);
|
||||
updateFrom(_from);
|
||||
|
||||
from.value = getDate(_from, 'from');
|
||||
const _to = Date.vnNew();
|
||||
_to.setDate(_to.getDate() + 10);
|
||||
updateTo(_to);
|
||||
to.value = getDate(Date.vnNew(), 'to');
|
||||
|
||||
updateFilter();
|
||||
|
||||
watch([from, to], ([nFrom, nTo], [oFrom, oTo]) => {
|
||||
if (nFrom && nFrom != oFrom) nFrom = getDate(new Date(nFrom), 'from');
|
||||
if (nTo && nTo != oTo) nTo = getDate(new Date(nTo), 'to');
|
||||
updateFilter();
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => (stateStore.rightDrawer = false));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QToolbar class="justify-end">
|
||||
<div id="st-data" class="row">
|
||||
<VnSubToolbar>
|
||||
<template #st-data>
|
||||
<VnInputDate
|
||||
:label="t('lastEntries.since')"
|
||||
dense
|
||||
|
@ -204,11 +194,9 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
|||
class="q-mr-lg"
|
||||
/>
|
||||
<VnInputDate :label="t('lastEntries.to')" dense v-model="to" />
|
||||
</div>
|
||||
<QSpace />
|
||||
<div id="st-actions"></div>
|
||||
</QToolbar>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
</template>
|
||||
</VnSubToolbar>
|
||||
<QPage class="column items-center q-pa-xd">
|
||||
<QTable
|
||||
:rows="itemLastEntries"
|
||||
:columns="columns"
|
||||
|
|
|
@ -42,9 +42,10 @@ const onItemTagsFetched = async (itemTags) => {
|
|||
});
|
||||
};
|
||||
|
||||
const handleTagSelected = (rows, index, tag) => {
|
||||
const handleTagSelected = (rows, index, tagId) => {
|
||||
const tag = tagOptions.value.find((t) => t.id === tagId);
|
||||
rows[index].tag = tag;
|
||||
rows[index].tagFk = tag.id;
|
||||
rows[index].tagFk = tagId;
|
||||
rows[index].value = null;
|
||||
getSelectedTagValues(rows[index]);
|
||||
};
|
||||
|
@ -94,7 +95,6 @@ const insertTag = (rows) => {
|
|||
:filter="{
|
||||
fields: ['id', 'itemFk', 'tagFk', 'value', 'priority'],
|
||||
where: { itemFk: route.params.id },
|
||||
order: 'priority ASC',
|
||||
include: {
|
||||
relation: 'tag',
|
||||
scope: {
|
||||
|
@ -102,16 +102,13 @@ const insertTag = (rows) => {
|
|||
},
|
||||
},
|
||||
}"
|
||||
order="priority"
|
||||
auto-load
|
||||
@on-fetch="onItemTagsFetched"
|
||||
>
|
||||
<template #body="{ rows, validate }">
|
||||
<QCard class="q-pl-lg q-py-md">
|
||||
<VnRow
|
||||
v-for="(row, index) in rows"
|
||||
:key="index"
|
||||
class="row q-gutter-md q-mb-md"
|
||||
>
|
||||
<QCard class="q-px-lg q-pt-md q-pb-sm">
|
||||
<VnRow v-for="(row, index) in rows" :key="index">
|
||||
<VnSelect
|
||||
:label="t('itemTags.tag')"
|
||||
:options="tagOptions"
|
||||
|
@ -119,7 +116,7 @@ const insertTag = (rows) => {
|
|||
option-label="name"
|
||||
hide-selected
|
||||
@update:model-value="
|
||||
($event) => handleTagSelected(rows, index, $event)
|
||||
(val) => handleTagSelected(rows, index, val)
|
||||
"
|
||||
:required="true"
|
||||
:rules="validate('itemTag.tagFk')"
|
||||
|
@ -146,7 +143,6 @@ const insertTag = (rows) => {
|
|||
v-model="row.value"
|
||||
:label="t('itemTags.value')"
|
||||
:is-clearable="false"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<VnInput
|
||||
:label="t('itemTags.relevancy')"
|
||||
|
@ -155,7 +151,7 @@ const insertTag = (rows) => {
|
|||
:required="true"
|
||||
:rules="validate('itemTag.priority')"
|
||||
/>
|
||||
<div class="col-1 row justify-center items-center">
|
||||
<div class="row justify-center items-center" style="flex: 0">
|
||||
<QIcon
|
||||
@click="itemTagsRef.remove([row])"
|
||||
class="fill-icon-on-hover"
|
||||
|
@ -169,7 +165,7 @@ const insertTag = (rows) => {
|
|||
</QIcon>
|
||||
</div>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnRow class="justify-center items-center">
|
||||
<QIcon
|
||||
@click="insertTag(rows)"
|
||||
class="cursor-pointer"
|
||||
|
@ -177,6 +173,7 @@ const insertTag = (rows) => {
|
|||
color="primary"
|
||||
name="add"
|
||||
size="sm"
|
||||
style="flex: 0"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('itemTags.addTag') }}
|
||||
|
|
|
@ -25,7 +25,7 @@ itemDiary:
|
|||
showBefore: Show what's before the inventory
|
||||
since: Since
|
||||
warehouse: Warehouse
|
||||
basicData:
|
||||
itemBasicData:
|
||||
type: Type
|
||||
reference: Reference
|
||||
relevancy: Relevancy
|
||||
|
|
|
@ -25,7 +25,7 @@ itemDiary:
|
|||
showBefore: Mostrar lo anterior al inventario
|
||||
since: Desde
|
||||
warehouse: Almacén
|
||||
basicData:
|
||||
itemBasicData:
|
||||
type: Tipo
|
||||
reference: Referencia
|
||||
relevancy: Relevancia
|
||||
|
|
|
@ -105,14 +105,14 @@ async function getVideoList(expeditionId, timed) {
|
|||
label
|
||||
markers
|
||||
snap
|
||||
color="orange"
|
||||
color="primary"
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="lastExpedition && videoList.length">
|
||||
<QItemSection>
|
||||
<QSelect
|
||||
color="orange"
|
||||
color="primary"
|
||||
v-model="slide"
|
||||
:options="videoList"
|
||||
:label="t('ticket.boxing.selectVideo')"
|
||||
|
|
|
@ -34,7 +34,7 @@ const cancel = () => {
|
|||
<template>
|
||||
<QPopupProxy ref="QPopupProxyRef">
|
||||
<div class="container">
|
||||
<QSpinner v-if="!mana" color="orange" size="md" />
|
||||
<QSpinner v-if="!mana" color="primary" size="md" />
|
||||
<div v-else>
|
||||
<div class="header">Mana: {{ toCurrency(mana) }}</div>
|
||||
<div class="q-pa-md">
|
||||
|
|
|
@ -64,7 +64,12 @@ function confirm() {
|
|||
<QList class="row q-mx-auto q-mt-xl">
|
||||
<QItem v-for="(props, name) in counters" :key="name" class="col-6">
|
||||
<QItemSection>
|
||||
<VnImg :id="props.id" width="130px" @click="handleEvent(name, 'add')" />
|
||||
<VnImg
|
||||
:id="props.id"
|
||||
width="130px"
|
||||
@click="handleEvent(name, 'add')"
|
||||
:zoom="false"
|
||||
/>
|
||||
<p class="title">{{ props.title }}</p>
|
||||
</QItemSection>
|
||||
<QItemSection class="q-ma-none">
|
||||
|
|
|
@ -147,7 +147,7 @@ const refetch = async () => await cardDescriptorRef.value.getData();
|
|||
<VnImg
|
||||
:id="parseInt(entityId)"
|
||||
collection="user"
|
||||
size="520x520"
|
||||
resolution="520x520"
|
||||
class="photo"
|
||||
>
|
||||
<template #error>
|
||||
|
|
|
@ -7,9 +7,7 @@ describe('Logout', () => {
|
|||
});
|
||||
describe('by user', () => {
|
||||
it('should logout', () => {
|
||||
cy.get(
|
||||
'#user > .q-btn__content > .q-avatar > .q-avatar__content > .q-img > .q-img__container > .q-img__image'
|
||||
).click();
|
||||
cy.get('#user').click();
|
||||
cy.get('.block').click();
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue