#7283 finish item card sections #588
|
@ -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
|
||||
jorgep
commented
Es la foto de un usuario. Es la foto de un usuario.
|
||||
:worker-id="user.id"
|
||||
:title="user.name"
|
||||
size="xxl"
|
||||
jgallego
commented
en otros sitios se usa size="md" posible usar los genericos. en otros sitios se usa size="md" posible usar los genericos.
Pregunta: no he encontrado donde esta en nuestro caso md a cuantos px equivale, donde se está?
jorgep
commented
No lo tenemos definido, es nativo de quasar. He probado a poner xl pero se queda muy pequeño. Creo un tamaño personalizado para q-avatar[size="xxxl"] que sea 80px? No lo tenemos definido, es nativo de quasar. He probado a poner **xl** pero se queda muy pequeño. Creo un tamaño personalizado para q-avatar[size="xxxl"] que sea 80px?
jgallego
commented
si si
|
||||
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" />
|
||||
jorgep
commented
Ese lg no hacía nada. Ese lg no hacía nada.
|
||||
<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 },
|
||||
jorgep marked this conversation as resolved
Outdated
jorgep
commented
No siempre se quiere poner un title, ej. cuando hay un desplegable. No siempre se quiere poner un title, ej. cuando hay un desplegable.
jgallego
commented
se puede directamente no definir la propiedad? así no es necesario el boolean? se puede directamente no definir la propiedad? así no es necesario el boolean?
|
||||
size: { type: String, default: null },
|
||||
title: { type: String, default: null },
|
||||
jorgep
commented
Habilita Habilita
|
||||
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: {
|
||||
jorgep
commented
Realmente no se le estaba indicando el tamaño, solo la resolución Realmente no se le estaba indicando el tamaño, solo la resolución
|
||||
type: String,
|
||||
default: '200x200',
|
||||
},
|
||||
zoomSize: {
|
||||
zoomResolution: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'lg',
|
||||
default: null,
|
||||
},
|
||||
zoom: {
|
||||
jorgep
commented
No siempre se quiere hacer zoom, ej. contador de carros. No siempre se quiere hacer zoom, ej. contador de carros.
|
||||
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 />
|
||||
jorgep
commented
wrap no hace nada, se deshicieron los cambios. wrap no hace nada, se deshicieron los cambios.
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scopped>
|
||||
<style lang="scss" scoped>
|
||||
.vn-row {
|
||||
jorgep
commented
scopped lleva solo una p, antes era un style global. Con :deep y scoped funciona correctamente scopped lleva solo una p, antes era un style global. Con **:deep** y **scoped** funciona correctamente
|
||||
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>
|
||||
jorgep marked this conversation as resolved
Outdated
jgallego
commented
los colores estan en quasar.variables.scss los colores estan en quasar.variables.scss
usa las variables, de paso puedes reemplazar los orange que encuentres
|
||||
<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')"
|
||||
jorgep
commented
hay otro archivo donde ya se usa la clave basicData, por lo que daba conflicto hay otro archivo donde ya se usa la clave basicData, por lo que daba conflicto
|
||||
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) => {
|
||||
jorgep
commented
Ahora se recoge correctamente el tag Ahora se recoge correctamente el tag
|
||||
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"
|
||||
jorgep
commented
No hacía nada. No hacía nada.
|
||||
>
|
||||
<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)
|
||||
jorgep
commented
más descriptivo, es un evt/fn personalizado. más descriptivo, es un evt/fn personalizado.
|
||||
"
|
||||
: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">
|
||||
jorgep
commented
El basurero se alinea a la derecha y ocupa el mínimo espacio posible. El basurero se alinea a la derecha y ocupa el mínimo espacio posible.
|
||||
<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"
|
||||
jorgep
commented
El area "clicable" era bastante más ancha que el propio icono. ahora ocupa solo el espacio del icono. El area "clicable" era bastante más ancha que el propio icono. ahora ocupa solo el espacio del icono.
|
||||
>
|
||||
<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
|
||||
jorgep
commented
si haces click para sumar 1 también te hace zoom. No tenía sentido. si haces click para sumar 1 también te hace zoom. No tenía sentido.
|
||||
: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();
|
||||
});
|
||||
});
|
||||
|
|
Es la foto de un usuario