Merge branch 'dev' into 8322-route
gitea/salix-front/pipeline/pr-dev This commit looks good Details

This commit is contained in:
PAU ROVIRA ROSALENY 2025-01-23 07:28:36 +00:00
commit 2070a142fd
24 changed files with 575 additions and 459 deletions

View File

@ -61,6 +61,7 @@ onMounted(() => stateStore.setMounted());
/> />
<QSpace /> <QSpace />
<div id="searchbar" class="searchbar"></div> <div id="searchbar" class="searchbar"></div>
<div id="searchbar-after"></div>
<QSpace /> <QSpace />
<div class="q-pl-sm q-gutter-sm row items-center no-wrap"> <div class="q-pl-sm q-gutter-sm row items-center no-wrap">
<div id="actions-prepend"></div> <div id="actions-prepend"></div>

View File

@ -181,7 +181,7 @@ onMounted(() => {
watch( watch(
() => $props.columns, () => $props.columns,
(value) => splitColumns(value), (value) => splitColumns(value),
{ immediate: true } { immediate: true },
); );
const isTableMode = computed(() => mode.value == TABLE_MODE); const isTableMode = computed(() => mode.value == TABLE_MODE);
@ -212,7 +212,7 @@ function splitColumns(columns) {
// Status column // Status column
if (splittedColumns.value.chips.length) { if (splittedColumns.value.chips.length) {
splittedColumns.value.columnChips = splittedColumns.value.chips.filter( splittedColumns.value.columnChips = splittedColumns.value.chips.filter(
(c) => !c.isId (c) => !c.isId,
); );
if (splittedColumns.value.columnChips.length) if (splittedColumns.value.columnChips.length)
splittedColumns.value.columns.unshift({ splittedColumns.value.columns.unshift({
@ -484,7 +484,9 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
btn.isPrimary ? 'text-primary-light' : 'color-vn-text ' btn.isPrimary ? 'text-primary-light' : 'color-vn-text '
" "
:style="`visibility: ${ :style="`visibility: ${
(btn.show && btn.show(row)) ?? true ? 'visible' : 'hidden' ((btn.show && btn.show(row)) ?? true)
? 'visible'
: 'hidden'
}`" }`"
@click="btn.action(row)" @click="btn.action(row)"
/> />

View File

@ -0,0 +1,53 @@
<script setup>
import { useI18n } from 'vue-i18n';
import { useStateStore } from 'stores/useStateStore';
import { useHasContent } from 'src/composables/useHasContent';
import { watch } from 'vue';
const { t } = useI18n();
const stateStore = useStateStore();
const hasContent = useHasContent('#advanced-menu');
const $props = defineProps({
isMainSection: {
type: Boolean,
default: false,
},
});
watch(
() => $props.isMainSection,
(val) => {
if (stateStore) stateStore.rightAdvancedDrawer = val;
},
{ immediate: true }
);
</script>
<template>
<Teleport to="#searchbar-after" v-if="stateStore.isHeaderMounted()">
<QBtn
v-if="hasContent || $slots['advanced-menu']"
flat
@click="stateStore.toggleRightAdvancedDrawer()"
round
dense
icon="tune"
>
<QTooltip bottom anchor="bottom right">
{{ t('globals.advancedMenu') }}
</QTooltip>
</QBtn>
</Teleport>
<QDrawer
v-model="stateStore.rightAdvancedDrawer"
side="right"
:width="256"
:overlay="!isMainSection"
v-bind="$attrs"
>
<QScrollArea class="fit">
<div id="advanced-menu"></div>
<slot v-if="!hasContent" name="advanced-menu" />
</QScrollArea>
</QDrawer>
</template>

View File

@ -17,7 +17,7 @@ onMounted(() => {
}); });
</script> </script>
<template> <template>
<Teleport to="#actions-append" v-if="stateStore.isHeaderMounted()"> <Teleport to="#actions-prepend" v-if="stateStore.isHeaderMounted()">
<div class="row q-gutter-x-sm"> <div class="row q-gutter-x-sm">
<QBtn <QBtn
v-if="hasContent || $slots['right-panel']" v-if="hasContent || $slots['right-panel']"

View File

@ -15,6 +15,7 @@ import FetchData from '../FetchData.vue';
import VnSelect from './VnSelect.vue'; import VnSelect from './VnSelect.vue';
import VnUserLink from '../ui/VnUserLink.vue'; import VnUserLink from '../ui/VnUserLink.vue';
import VnPaginate from '../ui/VnPaginate.vue'; import VnPaginate from '../ui/VnPaginate.vue';
import RightMenu from './RightMenu.vue';
const stateStore = useStateStore(); const stateStore = useStateStore();
const validationsStore = useValidator(); const validationsStore = useValidator();
@ -130,7 +131,7 @@ const actionsIcon = {
}; };
const validDate = new RegExp( const validDate = new RegExp(
/^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])/.source + /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])/.source +
/T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/.source /T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/.source,
); );
function castJsonValue(value) { function castJsonValue(value) {
@ -192,7 +193,7 @@ function getLogTree(data) {
user: log.user, user: log.user,
userFk: log.userFk, userFk: log.userFk,
logs: [], logs: [],
}) }),
); );
} }
// Model // Model
@ -210,7 +211,7 @@ function getLogTree(data) {
id: log.changedModelId, id: log.changedModelId,
showValue: log.changedModelValue, showValue: log.changedModelValue,
logs: [], logs: [],
}) }),
); );
nLogs = 0; nLogs = 0;
} }
@ -282,7 +283,7 @@ function setDate(type) {
to = date.adjustDate( to = date.adjustDate(
to, to,
{ hour: 21, minute: 59, second: 59, millisecond: 999 }, { hour: 21, minute: 59, second: 59, millisecond: 999 },
true true,
); );
switch (type) { switch (type) {
@ -365,7 +366,7 @@ async function clearFilter() {
dateTo.value = undefined; dateTo.value = undefined;
userRadio.value = undefined; userRadio.value = undefined;
Object.keys(checkboxOptions.value).forEach( Object.keys(checkboxOptions.value).forEach(
(opt) => (checkboxOptions.value[opt].selected = false) (opt) => (checkboxOptions.value[opt].selected = false),
); );
await applyFilter(); await applyFilter();
} }
@ -378,7 +379,7 @@ watch(
() => router.currentRoute.value.params.id, () => router.currentRoute.value.params.id,
() => { () => {
applyFilter(); applyFilter();
} },
); );
</script> </script>
<template> <template>
@ -391,7 +392,7 @@ watch(
const changedModel = item.changedModel; const changedModel = item.changedModel;
return { return {
locale: useCapitalize( locale: useCapitalize(
validations[changedModel]?.locale?.name ?? changedModel validations[changedModel]?.locale?.name ?? changedModel,
), ),
value: changedModel, value: changedModel,
}; };
@ -507,7 +508,7 @@ watch(
:title=" :title="
date.formatDate( date.formatDate(
log.creationDate, log.creationDate,
'DD/MM/YYYY hh:mm:ss' 'DD/MM/YYYY hh:mm:ss',
) ?? `date:'dd/MM/yyyy HH:mm:ss'` ) ?? `date:'dd/MM/yyyy HH:mm:ss'`
" "
> >
@ -577,7 +578,7 @@ watch(
t( t(
`actions.${ `actions.${
actionsText[log.action] actionsText[log.action]
}` }`,
) )
" "
/> />
@ -677,139 +678,144 @@ watch(
</div> </div>
</template> </template>
</VnPaginate> </VnPaginate>
<Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()"> <RightMenu>
<QList dense> <template #right-panel>
<QSeparator /> <QList dense>
<QItem class="q-mt-sm"> <QSeparator />
<QInput <QItem class="q-mt-sm">
:label="t('globals.search')" <QInput
v-model="searchInput" :label="t('globals.search')"
class="full-width" v-model="searchInput"
clearable class="full-width"
clear-icon="close" clearable
@keyup.enter="() => selectFilter('search')" clear-icon="close"
@focusout="() => selectFilter('search')" @keyup.enter="() => selectFilter('search')"
@clear="() => selectFilter('search')" @focusout="() => selectFilter('search')"
> @clear="() => selectFilter('search')"
<template #append> >
<QIcon name="info" class="cursor-pointer"> <template #append>
<QTooltip>{{ t('tooltips.search') }}</QTooltip> <QIcon name="info" class="cursor-pointer">
</QIcon> <QTooltip>{{ t('tooltips.search') }}</QTooltip>
</template> </QIcon>
</QInput> </template>
</QItem> </QInput>
<QItem> </QItem>
<VnSelect <QItem>
class="full-width"
:label="t('globals.entity')"
v-model="selectedFilters.changedModel"
option-label="locale"
option-value="value"
:options="actions"
@update:model-value="selectFilter('action')"
hide-selected
/>
</QItem>
<QItem class="q-mt-sm">
<QOptionGroup
size="sm"
v-model="userRadio"
:options="userTypes"
color="primary"
@update:model-value="selectFilter('userRadio')"
right-label
>
<template #label="{ label }">
{{ t(`Users.${label}`) }}
</template>
</QOptionGroup>
</QItem>
<QItem class="q-mt-sm">
<QItemSection v-if="userRadio !== null">
<VnSelect <VnSelect
class="full-width" class="full-width"
:label="t('globals.user')" :label="t('globals.entity')"
v-model="userSelect" v-model="selectedFilters.changedModel"
option-label="name" option-label="locale"
option-value="id" option-value="value"
:url="`${model}Logs/${$route.params.id}/editors`" :options="actions"
:fields="['id', 'nickname', 'name', 'image']" @update:model-value="selectFilter('action')"
sort-by="nickname"
@update:model-value="selectFilter('userSelect')"
hide-selected hide-selected
/>
</QItem>
<QItem class="q-mt-sm">
<QOptionGroup
size="sm"
v-model="userRadio"
:options="userTypes"
color="primary"
@update:model-value="selectFilter('userRadio')"
right-label
> >
<template #option="{ opt, itemProps }"> <template #label="{ label }">
<QItem v-bind="itemProps" class="q-pa-xs row items-center"> {{ t(`Users.${label}`) }}
<QItemSection class="col-3 items-center">
<VnAvatar :worker-id="opt.id" />
</QItemSection>
<QItemSection class="col-9 justify-center">
<span>{{ opt.name }}</span>
<span class="text-grey">{{ opt.nickname }}</span>
</QItemSection>
</QItem>
</template> </template>
</VnSelect> </QOptionGroup>
</QItemSection> </QItem>
</QItem> <QItem class="q-mt-sm">
<QItem class="q-mt-sm"> <QItemSection v-if="userRadio !== null">
<QInput <VnSelect
:label="t('globals.changes')" class="full-width"
v-model="changeInput" :label="t('globals.user')"
class="full-width" v-model="userSelect"
clearable option-label="name"
clear-icon="close" option-value="id"
@keyup.enter="selectFilter('change')" :url="`${model}Logs/${route.params.id}/editors`"
@focusout="selectFilter('change')" :fields="['id', 'nickname', 'name', 'image']"
@clear="selectFilter('change')" sort-by="nickname"
@update:model-value="selectFilter('userSelect')"
hide-selected
>
<template #option="{ opt, itemProps }">
<QItem
v-bind="itemProps"
class="q-pa-xs row items-center"
>
<QItemSection class="col-3 items-center">
<VnAvatar :worker-id="opt.id" />
</QItemSection>
<QItemSection class="col-9 justify-center">
<span>{{ opt.name }}</span>
<span class="text-grey">{{ opt.nickname }}</span>
</QItemSection>
</QItem>
</template>
</VnSelect>
</QItemSection>
</QItem>
<QItem class="q-mt-sm">
<QInput
:label="t('globals.changes')"
v-model="changeInput"
class="full-width"
clearable
clear-icon="close"
@keyup.enter="selectFilter('change')"
@focusout="selectFilter('change')"
@clear="selectFilter('change')"
>
<template #append>
<QIcon name="info" class="cursor-pointer">
<QTooltip max-width="250px">{{
t('tooltips.changes')
}}</QTooltip>
</QIcon>
</template>
</QInput>
</QItem>
<QItem
:class="index == 'create' ? 'q-mt-md' : 'q-mt-xs'"
v-for="(checkboxOption, index) in checkboxOptions"
:key="index"
> >
<template #append> <QCheckbox
<QIcon name="info" class="cursor-pointer"> size="sm"
<QTooltip max-width="250px">{{ v-model="checkboxOption.selected"
t('tooltips.changes') :label="t(`actions.${checkboxOption.label}`)"
}}</QTooltip> @update:model-value="selectFilter"
</QIcon> />
</template> </QItem>
</QInput> <QItem class="q-mt-sm">
</QItem> <QInput
<QItem class="full-width"
:class="index == 'create' ? 'q-mt-md' : 'q-mt-xs'" :label="t('globals.date')"
v-for="(checkboxOption, index) in checkboxOptions" @click="dateFromDialog = true"
:key="index" @focus="(evt) => evt.target.blur()"
> @clear="selectFilter('date', 'to')"
<QCheckbox v-model="dateFrom"
size="sm" clearable
v-model="checkboxOption.selected" clear-icon="close"
:label="t(`actions.${checkboxOption.label}`)" />
@update:model-value="selectFilter" </QItem>
/> <QItem class="q-mt-sm">
</QItem> <QInput
<QItem class="q-mt-sm"> class="full-width"
<QInput :label="t('to')"
class="full-width" @click="dateToDialog = true"
:label="t('globals.date')" @focus="(evt) => evt.target.blur()"
@click="dateFromDialog = true" @clear="selectFilter('date', 'from')"
@focus="(evt) => evt.target.blur()" v-model="dateTo"
@clear="selectFilter('date', 'to')" clearable
v-model="dateFrom" clear-icon="close"
clearable />
clear-icon="close" </QItem>
/> </QList>
</QItem> </template>
<QItem class="q-mt-sm"> </RightMenu>
<QInput
class="full-width"
:label="t('to')"
@click="dateToDialog = true"
@focus="(evt) => evt.target.blur()"
@clear="selectFilter('date', 'from')"
v-model="dateTo"
clearable
clear-icon="close"
/>
</QItem>
</QList>
</Teleport>
<QDialog v-model="dateFromDialog"> <QDialog v-model="dateFromDialog">
<QDate <QDate
:years-in-month-view="false" :years-in-month-view="false"

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import RightMenu from './RightMenu.vue'; import RightAdvancedMenu from './RightAdvancedMenu.vue';
import VnSearchbar from 'components/ui/VnSearchbar.vue'; import VnSearchbar from 'components/ui/VnSearchbar.vue';
import VnTableFilter from '../VnTable/VnTableFilter.vue'; import VnTableFilter from '../VnTable/VnTableFilter.vue';
import { onBeforeMount, onMounted, onUnmounted, computed, ref } from 'vue'; import { onBeforeMount, onMounted, onUnmounted, computed, ref } from 'vue';
@ -54,6 +54,7 @@ const sectionValue = computed(() => $props.section ?? $props.dataKey);
const isMainSection = ref(false); const isMainSection = ref(false);
const searchbarId = 'section-searchbar'; const searchbarId = 'section-searchbar';
const advancedMenuSlot = 'advanced-menu';
const hasContent = useHasContent(`#${searchbarId}`); const hasContent = useHasContent(`#${searchbarId}`);
onBeforeMount(() => { onBeforeMount(() => {
@ -93,9 +94,9 @@ function checkIsMain() {
/> />
<div :id="searchbarId"></div> <div :id="searchbarId"></div>
</slot> </slot>
<RightMenu> <RightAdvancedMenu :is-main-section="isMainSection">
<template #right-panel v-if="$slots['rightMenu'] || rightFilter"> <template #advanced-menu v-if="$slots[advancedMenuSlot] || rightFilter">
<slot name="rightMenu"> <slot :name="advancedMenuSlot">
<VnTableFilter <VnTableFilter
v-if="rightFilter && columns" v-if="rightFilter && columns"
:data-key="dataKey" :data-key="dataKey"
@ -104,7 +105,7 @@ function checkIsMain() {
/> />
</slot> </slot>
</template> </template>
</RightMenu> </RightAdvancedMenu>
<slot name="body" v-if="isMainSection" /> <slot name="body" v-if="isMainSection" />
<RouterView v-else /> <RouterView v-else />
</template> </template>

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { defineProps, ref } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
const { t } = useI18n(); const { t } = useI18n();

View File

@ -5,7 +5,7 @@ export function useHasContent(selector) {
const hasContent = ref(); const hasContent = ref();
onMounted(() => { onMounted(() => {
container.value = document.querySelector(selector); container.value = document?.querySelector(selector);
if (!container.value) return; if (!container.value) return;
const observer = new MutationObserver(() => { const observer = new MutationObserver(() => {

View File

@ -7,7 +7,8 @@ globals:
entity: Entity entity: Entity
user: User user: User
details: Details details: Details
collapseMenu: Collapse left menu collapseMenu: Collapse lateral menu
advancedMenu: Advanced menu
backToDashboard: Return to dashboard backToDashboard: Return to dashboard
notifications: Notifications notifications: Notifications
userPanel: User panel userPanel: User panel

View File

@ -8,6 +8,7 @@ globals:
user: Usuario user: Usuario
details: Detalles details: Detalles
collapseMenu: Contraer menú lateral collapseMenu: Contraer menú lateral
advancedMenu: Menú avanzado
backToDashboard: Volver al tablón backToDashboard: Volver al tablón
notifications: Notificaciones notifications: Notificaciones
userPanel: Panel de usuario userPanel: Panel de usuario

View File

@ -4,7 +4,6 @@ import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import axios from 'axios'; import axios from 'axios';
import { useStateStore } from 'src/stores/useStateStore';
import { toDate, toPercentage, toCurrency } from 'filters/index'; import { toDate, toPercentage, toCurrency } from 'filters/index';
import { tMobile } from 'src/composables/tMobile'; import { tMobile } from 'src/composables/tMobile';
import CrudModel from 'src/components/CrudModel.vue'; import CrudModel from 'src/components/CrudModel.vue';
@ -13,11 +12,11 @@ import VnSelect from 'src/components/common/VnSelect.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue'; import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
import { useArrayData } from 'composables/useArrayData'; import { useArrayData } from 'composables/useArrayData';
import RightMenu from 'src/components/common/RightMenu.vue';
const { t } = useI18n(); const { t } = useI18n();
const quasar = useQuasar(); const quasar = useQuasar();
const route = useRoute(); const route = useRoute();
const stateStore = computed(() => useStateStore());
const claim = ref(null); const claim = ref(null);
const claimRef = ref(); const claimRef = ref();
const claimId = route.params.id; const claimId = route.params.id;
@ -201,58 +200,62 @@ async function post(query, params) {
auto-load auto-load
@on-fetch="(data) => (destinationTypes = data)" @on-fetch="(data) => (destinationTypes = data)"
/> />
<Teleport to="#right-panel" v-if="stateStore.isHeaderMounted() && claim"> <RightMenu v-if="claim">
<QCard class="totalClaim q-my-md q-pa-sm no-box-shadow"> <template #right-panel>
{{ `${t('Total claimed')}: ${toCurrency(totalClaimed)}` }} <QCard class="totalClaim q-my-md q-pa-sm no-box-shadow">
</QCard> {{ `${t('Total claimed')}: ${toCurrency(totalClaimed)}` }}
<QCard class="q-mb-md q-pa-sm no-box-shadow"> </QCard>
<QItem class="justify-between"> <QCard class="q-mb-md q-pa-sm no-box-shadow">
<QItemLabel class="slider-container"> <QItem class="justify-between">
<p class="text-primary"> <QItemLabel class="slider-container">
{{ t('claim.actions') }} <p class="text-primary">
</p> {{ t('claim.actions') }}
<QSlider </p>
class="responsibility { 'background-color:primary': quasar.platform.is.mobile }" <QSlider
v-model="claim.responsibility" class="responsibility { 'background-color:primary': quasar.platform.is.mobile }"
:label-value="t('claim.responsibility')" v-model="claim.responsibility"
@change="(value) => save({ responsibility: value })" :label-value="t('claim.responsibility')"
label-always @change="(value) => save({ responsibility: value })"
color="primary" label-always
markers color="primary"
:marker-labels="marker_labels" markers
:min="DEFAULT_MIN_RESPONSABILITY" :marker-labels="marker_labels"
:max="DEFAULT_MAX_RESPONSABILITY" :min="DEFAULT_MIN_RESPONSABILITY"
:max="DEFAULT_MAX_RESPONSABILITY"
/>
</QItemLabel>
</QItem>
</QCard>
<QCard class="q-mb-md q-pa-sm no-box-shadow" style="margin-bottom: 1em">
<QItemLabel class="mana q-mb-md">
<QCheckbox
v-model="claim.isChargedToMana"
@update:model-value="(value) => save({ isChargedToMana: value })"
/> />
<span>{{ t('mana') }}</span>
</QItemLabel> </QItemLabel>
</QItem> </QCard>
</QCard> <QCard class="q-mb-md q-pa-sm no-box-shadow" style="position: static">
<QCard class="q-mb-md q-pa-sm no-box-shadow" style="margin-bottom: 1em"> <QInput
<QItemLabel class="mana q-mb-md"> :disable="
<QCheckbox !(
v-model="claim.isChargedToMana" claim.responsibility >=
@update:model-value="(value) => save({ isChargedToMana: value })" Math.ceil(DEFAULT_MAX_RESPONSABILITY) / 2
)
"
:label="t('confirmGreuges')"
class="q-field__native text-grey-2"
type="number"
placeholder="0"
id="multiplicatorValue"
name="multiplicatorValue"
min="0"
max="50"
v-model="multiplicatorValue"
/> />
<span>{{ t('mana') }}</span> </QCard>
</QItemLabel> </template>
</QCard> </RightMenu>
<QCard class="q-mb-md q-pa-sm no-box-shadow" style="position: static">
<QInput
:disable="
!(claim.responsibility >= Math.ceil(DEFAULT_MAX_RESPONSABILITY) / 2)
"
:label="t('confirmGreuges')"
class="q-field__native text-grey-2"
type="number"
placeholder="0"
id="multiplicatorValue"
name="multiplicatorValue"
min="0"
max="50"
v-model="multiplicatorValue"
/>
</QCard>
</Teleport>
<Teleport to="#st-data" v-if="stateStore.isSubToolbarShown()"> </Teleport>
<CrudModel <CrudModel
v-if="claim" v-if="claim"
data-key="ClaimEnds" data-key="ClaimEnds"

View File

@ -134,7 +134,7 @@ const STATE_COLOR = {
order: ['cs.priority ASC', 'created ASC'], order: ['cs.priority ASC', 'created ASC'],
}" }"
> >
<template #rightMenu> <template #advanced-menu>
<ClaimFilter data-key="ClaimList" ref="claimFilterRef" /> <ClaimFilter data-key="ClaimList" ref="claimFilterRef" />
</template> </template>
<template #body> <template #body>

View File

@ -1,7 +1,7 @@
<script setup> <script setup>
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { onMounted, ref, computed, watch } from 'vue'; import { onMounted, ref, watch } from 'vue';
import axios from 'axios'; import axios from 'axios';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import VnPaginate from 'src/components/ui/VnPaginate.vue'; import VnPaginate from 'src/components/ui/VnPaginate.vue';
@ -9,6 +9,7 @@ import CatalogItem from 'src/components/ui/CatalogItem.vue';
import OrderCatalogFilter from 'src/pages/Order/Card/OrderCatalogFilter.vue'; import OrderCatalogFilter from 'src/pages/Order/Card/OrderCatalogFilter.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
import { useArrayData } from 'src/composables/useArrayData'; import { useArrayData } from 'src/composables/useArrayData';
import RightMenu from 'src/components/common/RightMenu.vue';
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
@ -89,14 +90,16 @@ watch(
:search-remove-params="false" :search-remove-params="false"
/> />
</Teleport> </Teleport>
<Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()"> <RightMenu>
<OrderCatalogFilter <template #right-panel>
:data-key="dataKey" <OrderCatalogFilter
:tag-value="tagValue" :data-key="dataKey"
:tags="tags" :tag-value="tagValue"
:initial-catalog-params="catalogParams" :tags="tags"
/> :initial-catalog-params="catalogParams"
</Teleport> />
</template>
</RightMenu>
<QPage class="column items-center q-pa-md" data-cy="orderCatalogPage"> <QPage class="column items-center q-pa-md" data-cy="orderCatalogPage">
<div class="full-width"> <div class="full-width">
<VnPaginate :data-key="dataKey"> <VnPaginate :data-key="dataKey">
@ -141,5 +144,5 @@ watch(
<i18n> <i18n>
es: es:
You can search items by name or id: Puedes buscar items por nombre o id You can search items by name or id: Puedes buscar items por nombre o id
Search items: Buscar items Search items: Buscar artículos
</i18n> </i18n>

View File

@ -4,7 +4,6 @@ import { useI18n } from 'vue-i18n';
import { ref, computed, watch } from 'vue'; import { ref, computed, watch } from 'vue';
import { useQuasar } from 'quasar'; import { useQuasar } from 'quasar';
import axios from 'axios'; import axios from 'axios';
import { useStateStore } from 'stores/useStateStore';
import { useArrayData } from 'composables/useArrayData'; import { useArrayData } from 'composables/useArrayData';
import { confirm } from 'src/pages/Order/composables/confirmOrder'; import { confirm } from 'src/pages/Order/composables/confirmOrder';
import { toCurrency, toDate } from 'src/filters'; import { toCurrency, toDate } from 'src/filters';
@ -16,9 +15,9 @@ import VnImg from 'src/components/ui/VnImg.vue';
import VnLv from 'src/components/ui/VnLv.vue'; import VnLv from 'src/components/ui/VnLv.vue';
import FetchedTags from 'src/components/ui/FetchedTags.vue'; import FetchedTags from 'src/components/ui/FetchedTags.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
const router = useRouter(); const router = useRouter();
const stateStore = useStateStore();
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const quasar = useQuasar(); const quasar = useQuasar();
@ -264,23 +263,27 @@ watch(
@on-fetch="(data) => (orderSummary.vat = data)" @on-fetch="(data) => (orderSummary.vat = data)"
auto-load auto-load
/> />
<Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()"> <RightMenu>
<QCard <template #right-panel>
class="order-lines-summary q-pa-lg" <QCard
v-if="orderSummary.vat && orderSummary.total" class="order-lines-summary q-pa-lg"
> v-if="orderSummary.vat && orderSummary.total"
<p class="header text-right block"> >
{{ t('summary') }} <p class="header text-right block">
</p> {{ t('summary') }}
<VnLv </p>
:label="t('subtotal') + ': '" <VnLv
:value="toCurrency(orderSummary.total - orderSummary.vat)" :label="t('subtotal') + ': '"
/> :value="toCurrency(orderSummary.total - orderSummary.vat)"
<VnLv :label="t('VAT') + ': '" :value="toCurrency(orderSummary?.vat)" /> />
<VnLv :label="t('total') + ': '" :value="toCurrency(orderSummary?.total)" /> <VnLv :label="t('VAT') + ': '" :value="toCurrency(orderSummary?.vat)" />
</QCard> <VnLv
</Teleport> :label="t('total') + ': '"
:value="toCurrency(orderSummary?.total)"
/>
</QCard>
</template>
</RightMenu>
<VnTable <VnTable
ref="tableLinesRef" ref="tableLinesRef"
data-key="OrderLines" data-key="OrderLines"

View File

@ -190,7 +190,7 @@ const getDateColor = (date) => {
order: ['landed DESC', 'clientFk ASC', 'id DESC'], order: ['landed DESC', 'clientFk ASC', 'id DESC'],
}" }"
> >
<template #rightMenu> <template #advanced-menu>
<OrderFilter data-key="OrderList" /> <OrderFilter data-key="OrderList" />
</template> </template>
<template #body> <template #body>

View File

@ -1,7 +1,7 @@
<script setup> <script setup>
import axios from 'axios'; import axios from 'axios';
import { date, useQuasar } from 'quasar'; import { date, useQuasar } from 'quasar';
import { useStateStore } from 'src/stores/useStateStore'; import RightMenu from 'src/components/common/RightMenu.vue';
import { computed, onMounted, reactive, ref } from 'vue'; import { computed, onMounted, reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
@ -9,9 +9,7 @@ import { useRouter } from 'vue-router';
const router = useRouter(); const router = useRouter();
const { t } = useI18n(); const { t } = useI18n();
const quasar = useQuasar(); const quasar = useQuasar();
const stateStore = useStateStore();
onMounted(async () => { onMounted(async () => {
stateStore.rightDrawer = true;
await fetch(); await fetch();
}); });
@ -86,69 +84,73 @@ async function getVideoList(expeditionId, timed) {
</script> </script>
<template> <template>
<Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()"> <RightMenu>
<QList bordered separator style="max-width: 318px"> <template #right-panel>
<QItem v-if="lastExpedition && videoList.length"> <QList bordered separator style="max-width: 318px">
<QItemSection> <QItem v-if="lastExpedition && videoList.length">
<QItemLabel class="text-h6"> <QItemSection>
{{ t('ticket.boxing.selectTime') }} ({{ time.min }}-{{ <QItemLabel class="text-h6">
time.max {{ t('ticket.boxing.selectTime') }} ({{ time.min }}-{{
}}) time.max
</QItemLabel> }})
<QRange </QItemLabel>
v-model="time" <QRange
@change="getVideoList(lastExpedition, time)" v-model="time"
:min="0" @change="getVideoList(lastExpedition, time)"
:max="24" :min="0"
:step="1" :max="24"
:left-label-value="time.min + ':00'" :step="1"
:right-label-value="time.max + ':00'" :left-label-value="time.min + ':00'"
label :right-label-value="time.max + ':00'"
markers label
snap markers
color="primary" snap
/> color="primary"
</QItemSection> />
</QItem> </QItemSection>
<QItem v-if="lastExpedition && videoList.length"> </QItem>
<QItemSection> <QItem v-if="lastExpedition && videoList.length">
<QSelect <QItemSection>
color="primary" <QSelect
v-model="slide" color="primary"
:options="videoList" v-model="slide"
:label="t('ticket.boxing.selectVideo')" :options="videoList"
emit-value :label="t('ticket.boxing.selectVideo')"
map-options emit-value
> map-options
<template #prepend> >
<QIcon name="schedule" /> <template #prepend>
</template> <QIcon name="schedule" />
</QSelect> </template>
</QItemSection> </QSelect>
</QItem> </QItemSection>
<QItem </QItem>
v-for="expedition in expeditions" <QItem
:key="expedition.id" v-for="expedition in expeditions"
@click="getVideoList(expedition.id)" :key="expedition.id"
clickable @click="getVideoList(expedition.id)"
v-ripple clickable
> v-ripple
<QItemSection> >
<QItemLabel class="text-h6">#{{ expedition.id }}</QItemLabel> <QItemSection>
</QItemSection> <QItemLabel class="text-h6">#{{ expedition.id }}</QItemLabel>
<QItemSection> </QItemSection>
<QItemLabel caption>{{ t('globals.created') }}</QItemLabel> <QItemSection>
<QItemLabel> <QItemLabel caption>{{ t('globals.created') }}</QItemLabel>
{{ date.formatDate(expedition.created, 'YYYY-MM-DD HH:mm:ss') }} <QItemLabel>
</QItemLabel> {{
<QItemLabel caption>{{ t('globals.item') }}</QItemLabel> date.formatDate(expedition.created, 'YYYY-MM-DD HH:mm:ss')
<QItemLabel>{{ expedition.packagingItemFk }}</QItemLabel> }}
<QItemLabel caption>{{ t('ticket.boxing.worker') }}</QItemLabel> </QItemLabel>
<QItemLabel>{{ expedition.userName }}</QItemLabel> <QItemLabel caption>{{ t('globals.item') }}</QItemLabel>
</QItemSection> <QItemLabel>{{ expedition.packagingItemFk }}</QItemLabel>
</QItem> <QItemLabel caption>{{ t('ticket.boxing.worker') }}</QItemLabel>
</QList> <QItemLabel>{{ expedition.userName }}</QItemLabel>
</Teleport> </QItemSection>
</QItem>
</QList>
</template>
</RightMenu>
<QCard> <QCard>
<QCarousel animated v-model="slide" height="max-content"> <QCarousel animated v-model="slide" height="max-content">
<QCarouselSlide <QCarouselSlide

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { ref, computed, onMounted, watch, nextTick } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
@ -9,15 +9,14 @@ import FetchData from 'components/FetchData.vue';
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue'; import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
import VnImg from 'src/components/ui/VnImg.vue'; import VnImg from 'src/components/ui/VnImg.vue';
import { useStateStore } from 'stores/useStateStore';
import { dashIfEmpty } from 'src/filters'; import { dashIfEmpty } from 'src/filters';
import { useArrayData } from 'composables/useArrayData'; import { useArrayData } from 'composables/useArrayData';
import { toCurrency } from 'filters/index'; import { toCurrency } from 'filters/index';
import axios from 'axios'; import axios from 'axios';
import VnTable from 'src/components/VnTable/VnTable.vue'; import VnTable from 'src/components/VnTable/VnTable.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
const route = useRoute(); const route = useRoute();
const stateStore = useStateStore();
const { t } = useI18n(); const { t } = useI18n();
const salesRef = ref(null); const salesRef = ref(null);
const arrayData = useArrayData('ticketData'); const arrayData = useArrayData('ticketData');
@ -164,10 +163,6 @@ const getTicketVolume = async () => {
const { data } = await axios.get(`Tickets/${ticketData.value.id}/getVolume`); const { data } = await axios.get(`Tickets/${ticketData.value.id}/getVolume`);
ticketVolume.value = data[0].volume; ticketVolume.value = data[0].volume;
}; };
onMounted(() => {
stateStore.rightDrawer = true;
});
</script> </script>
<template> <template>
@ -178,93 +173,121 @@ onMounted(() => {
@on-fetch="(data) => (components = data)" @on-fetch="(data) => (components = data)"
auto-load auto-load
/> />
<Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()"> <RightMenu>
<QCard class="q-pa-sm color-vn-text" bordered flat style="border-color: black"> <template #right-panel>
<QCardSection horizontal> <QCard
<span class="text-weight-bold text-subtitle1 text-center full-width"> class="q-pa-sm color-vn-text"
{{ t('basicData.total') }} bordered
</span> flat
</QCardSection> style="border-color: black"
<QCardSection horizontal>
<span class="q-mr-xs color-vn-label"
>{{ t('ticketComponents.baseToCommission') }}:
</span>
<span>{{ toCurrency(getBase) }}</span>
</QCardSection>
<QCardSection horizontal>
<span class="q-mr-xs color-vn-label"
>{{ t('ticketComponents.totalWithoutVat') }}:
</span>
<span>{{ toCurrency(getTotal) }}</span>
</QCardSection>
</QCard>
<QCard class="q-pa-sm color-vn-text" bordered flat style="border-color: black">
<QCardSection horizontal>
<span class="text-weight-bold text-subtitle1 text-center full-width">
{{ t('ticketComponents.components') }}
</span>
</QCardSection>
<QCardSection
v-for="(component, index) in componentsList"
:key="index"
horizontal
> >
<span v-if="component.name" class="q-mr-xs color-vn-label"> <QCardSection horizontal>
{{ component.name }}: <span class="text-weight-bold text-subtitle1 text-center full-width">
</span> {{ t('basicData.total') }}
<span v-if="component.value">{{ </span>
toCurrency(component.value, 'EUR', 3) </QCardSection>
}}</span> <QCardSection horizontal>
</QCardSection> <span class="q-mr-xs color-vn-label"
</QCard> >{{ t('ticketComponents.baseToCommission') }}:
<QCard class="q-pa-sm color-vn-text" bordered flat style="border-color: black"> </span>
<QCardSection horizontal> <span>{{ toCurrency(getBase) }}</span>
<span class="text-weight-bold text-subtitle1 text-center full-width"> </QCardSection>
{{ t('ticketComponents.zoneBreakdown') }} <QCardSection horizontal>
</span> <span class="q-mr-xs color-vn-label"
</QCardSection> >{{ t('ticketComponents.totalWithoutVat') }}:
<QCardSection horizontal> </span>
<span class="q-mr-xs color-vn-label"> {{ t('basicData.price') }}: </span> <span>{{ toCurrency(getTotal) }}</span>
<span>{{ toCurrency(ticketData?.zonePrice, 'EUR', 2) }}</span> </QCardSection>
</QCardSection> </QCard>
<QCardSection horizontal> <QCard
<span class="q-mr-xs color-vn-label"> class="q-pa-sm color-vn-text"
{{ t('ticketComponents.bonus') }}: bordered
</span> flat
<span>{{ toCurrency(ticketData?.zoneBonus, 'EUR', 2) }}</span> style="border-color: black"
</QCardSection> >
<QCardSection horizontal> <QCardSection horizontal>
<span class="q-mr-xs color-vn-label"> {{ t('ticketList.zone') }}: </span> <span class="text-weight-bold text-subtitle1 text-center full-width">
<span class="link"> {{ t('ticketComponents.components') }}
{{ dashIfEmpty(ticketData?.zone?.name) }} </span>
<ZoneDescriptorProxy :id="ticketData?.zone?.id" /> </QCardSection>
</span> <QCardSection
</QCardSection> v-for="(component, index) in componentsList"
<QCardSection v-if="ticketData?.zone?.isVolumetric" horizontal> :key="index"
<span class="q-mr-xs color-vn-label"> {{ t('volume.volume') }}: </span> horizontal
<span>{{ ticketVolume }}</span> >
</QCardSection> <span v-if="component.name" class="q-mr-xs color-vn-label">
<QCardSection horizontal> {{ component.name }}:
<span class="q-mr-xs color-vn-label"> </span>
{{ t('ticketComponents.packages') }}: <span v-if="component.value">{{
</span> toCurrency(component.value, 'EUR', 3)
<span>{{ dashIfEmpty(ticketData?.packages) }}</span> }}</span>
</QCardSection> </QCardSection>
</QCard> </QCard>
<QCard class="q-pa-sm color-vn-text" bordered flat style="border-color: black"> <QCard
<QCardSection horizontal> class="q-pa-sm color-vn-text"
<span class="text-weight-bold text-subtitle1 text-center full-width"> bordered
{{ t('ticketComponents.theoricalCost') }} flat
</span> style="border-color: black"
</QCardSection> >
<QCardSection horizontal> <QCardSection horizontal>
<span class="q-mr-xs color-vn-label"> <span class="text-weight-bold text-subtitle1 text-center full-width">
{{ t('ticketComponents.totalPrice') }}: {{ t('ticketComponents.zoneBreakdown') }}
</span> </span>
<span>{{ toCurrency(theoricalCost, 'EUR', 2) }}</span> </QCardSection>
</QCardSection> <QCardSection horizontal>
</QCard> <span class="q-mr-xs color-vn-label">
</Teleport> {{ t('basicData.price') }}:
</span>
<span>{{ toCurrency(ticketData?.zonePrice, 'EUR', 2) }}</span>
</QCardSection>
<QCardSection horizontal>
<span class="q-mr-xs color-vn-label">
{{ t('ticketComponents.bonus') }}:
</span>
<span>{{ toCurrency(ticketData?.zoneBonus, 'EUR', 2) }}</span>
</QCardSection>
<QCardSection horizontal>
<span class="q-mr-xs color-vn-label">
{{ t('ticketList.zone') }}:
</span>
<span class="link">
{{ dashIfEmpty(ticketData?.zone?.name) }}
<ZoneDescriptorProxy :id="ticketData?.zone?.id" />
</span>
</QCardSection>
<QCardSection v-if="ticketData?.zone?.isVolumetric" horizontal>
<span class="q-mr-xs color-vn-label">
{{ t('volume.volume') }}:
</span>
<span>{{ ticketVolume }}</span>
</QCardSection>
<QCardSection horizontal>
<span class="q-mr-xs color-vn-label">
{{ t('ticketComponents.packages') }}:
</span>
<span>{{ dashIfEmpty(ticketData?.packages) }}</span>
</QCardSection>
</QCard>
<QCard
class="q-pa-sm color-vn-text"
bordered
flat
style="border-color: black"
>
<QCardSection horizontal>
<span class="text-weight-bold text-subtitle1 text-center full-width">
{{ t('ticketComponents.theoricalCost') }}
</span>
</QCardSection>
<QCardSection horizontal>
<span class="q-mr-xs color-vn-label">
{{ t('ticketComponents.totalPrice') }}:
</span>
<span>{{ toCurrency(theoricalCost, 'EUR', 2) }}</span>
</QCardSection>
</QCard>
</template>
</RightMenu>
<VnTable <VnTable
ref="tableRef" ref="tableRef"
data-key="TicketComponents" data-key="TicketComponents"

View File

@ -16,7 +16,6 @@ import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import TicketSaleMoreActions from './TicketSaleMoreActions.vue'; import TicketSaleMoreActions from './TicketSaleMoreActions.vue';
import TicketTransfer from './TicketTransfer.vue'; import TicketTransfer from './TicketTransfer.vue';
import { useStateStore } from 'stores/useStateStore';
import { toCurrency, toPercentage } from 'src/filters'; import { toCurrency, toPercentage } from 'src/filters';
import { useArrayData } from 'composables/useArrayData'; import { useArrayData } from 'composables/useArrayData';
import { useVnConfirm } from 'composables/useVnConfirm'; import { useVnConfirm } from 'composables/useVnConfirm';
@ -25,10 +24,10 @@ import axios from 'axios';
import VnTable from 'src/components/VnTable/VnTable.vue'; import VnTable from 'src/components/VnTable/VnTable.vue';
import VnUsesMana from 'src/components/ui/VnUsesMana.vue'; import VnUsesMana from 'src/components/ui/VnUsesMana.vue';
import VnConfirm from 'src/components/ui/VnConfirm.vue'; import VnConfirm from 'src/components/ui/VnConfirm.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const stateStore = useStateStore();
const { t } = useI18n(); const { t } = useI18n();
const { notify } = useNotify(); const { notify } = useNotify();
const { openConfirmationModal } = useVnConfirm(); const { openConfirmationModal } = useVnConfirm();
@ -419,7 +418,6 @@ const setTransferParams = async () => {
}; };
onMounted(async () => { onMounted(async () => {
stateStore.rightDrawer = true;
getConfig(); getConfig();
}); });
@ -620,29 +618,38 @@ watch(
</QBtnGroup> </QBtnGroup>
</template> </template>
</VnSubToolbar> </VnSubToolbar>
<Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()"> <RightMenu>
<div <template #right-panel>
class="q-pa-md q-mb-md q-ma-md color-vn-text" <div
style="border: 2px solid black" class="q-pa-md q-mb-md q-ma-md color-vn-text"
> style="border: 2px solid black"
<QCardSection class="justify-end text-subtitle1" horizontal> >
<span class="q-mr-xs color-vn-label" <QCardSection class="justify-end text-subtitle1" horizontal>
>{{ t('ticketSale.subtotal') }}: <span class="q-mr-xs color-vn-label"
</span> >{{ t('ticketSale.subtotal') }}:
<span>{{ toCurrency(store.data?.totalWithoutVat) }}</span> </span>
</QCardSection> <span>{{ toCurrency(store.data?.totalWithoutVat) }}</span>
<QCardSection class="justify-end text-subtitle1" horizontal> </QCardSection>
<span class="q-mr-xs color-vn-label"> {{ t('ticketSale.tax') }}: </span> <QCardSection class="justify-end text-subtitle1" horizontal>
<span>{{ <span class="q-mr-xs color-vn-label">
toCurrency(store.data?.totalWithVat - store.data?.totalWithoutVat) {{ t('ticketSale.tax') }}:
}}</span> </span>
</QCardSection> <span>{{
<QCardSection class="justify-end text-weight-bold text-subtitle1" horizontal> toCurrency(store.data?.totalWithVat - store.data?.totalWithoutVat)
<span class="q-mr-xs color-vn-label"> {{ t('basicData.total') }}: </span> }}</span>
<span>{{ toCurrency(store.data?.totalWithVat) }}</span> </QCardSection>
</QCardSection> <QCardSection
</div> class="justify-end text-weight-bold text-subtitle1"
</Teleport> horizontal
>
<span class="q-mr-xs color-vn-label">
{{ t('basicData.total') }}:
</span>
<span>{{ toCurrency(store.data?.totalWithVat) }}</span>
</QCardSection>
</div>
</template>
</RightMenu>
<VnTable <VnTable
ref="tableRef" ref="tableRef"
data-key="TicketSales" data-key="TicketSales"

View File

@ -465,7 +465,7 @@ function setReference(data) {
exprBuilder, exprBuilder,
}" }"
> >
<template #rightMenu> <template #advanced-menu>
<TicketFilter data-key="TicketList" /> <TicketFilter data-key="TicketList" />
</template> </template>
<template #body> <template #body>

View File

@ -1,18 +1,16 @@
<script setup> <script setup>
import { nextTick, ref, watch } from 'vue'; import { nextTick, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import WorkerCalendarFilter from 'pages/Worker/Card/WorkerCalendarFilter.vue'; import WorkerCalendarFilter from 'pages/Worker/Card/WorkerCalendarFilter.vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import WorkerCalendarItem from 'pages/Worker/Card/WorkerCalendarItem.vue'; import WorkerCalendarItem from 'pages/Worker/Card/WorkerCalendarItem.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
import { useStateStore } from 'stores/useStateStore';
import axios from 'axios'; import axios from 'axios';
import { useRouter } from 'vue-router';
const router = useRouter(); const router = useRouter();
const stateStore = useStateStore();
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const workerIsFreelance = ref(); const workerIsFreelance = ref();
@ -171,16 +169,18 @@ watch([year, businessFk], () => refreshData());
ref="WorkerFreelanceRef" ref="WorkerFreelanceRef"
auto-load auto-load
/> />
<Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()"> <RightMenu>
<WorkerCalendarFilter <template #right-panel>
ref="workerCalendarFilterRef" <WorkerCalendarFilter
v-model:business-fk="businessFk" ref="workerCalendarFilterRef"
v-model:year="year" v-model:business-fk="businessFk"
v-model:absence-type="absenceType" v-model:year="year"
:contract-holidays="contractHolidays" v-model:absence-type="absenceType"
:year-holidays="yearHolidays" :contract-holidays="contractHolidays"
/> :year-holidays="yearHolidays"
</Teleport> />
</template>
</RightMenu>
<QPage class="column items-center"> <QPage class="column items-center">
<QCard v-if="workerIsFreelance"> <QCard v-if="workerIsFreelance">
<QCardSection class="text-center"> <QCardSection class="text-center">

View File

@ -10,6 +10,7 @@ import WorkerTimeForm from 'pages/Worker/Card/WorkerTimeForm.vue';
import WorkerTimeReasonForm from 'pages/Worker/Card/WorkerTimeReasonForm.vue'; import WorkerTimeReasonForm from 'pages/Worker/Card/WorkerTimeReasonForm.vue';
import WorkerDateLabel from './WorkerDateLabel.vue'; import WorkerDateLabel from './WorkerDateLabel.vue';
import WorkerTimeControlCalendar from 'pages/Worker/Card/WorkerTimeControlCalendar.vue'; import WorkerTimeControlCalendar from 'pages/Worker/Card/WorkerTimeControlCalendar.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
import useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
import axios from 'axios'; import axios from 'axios';
@ -483,33 +484,35 @@ onMounted(async () => {
</QBtnGroup> </QBtnGroup>
</div> </div>
</Teleport> </Teleport>
<Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()"> <RightMenu>
<div class="q-pa-md q-mb-md" style="border: 2px solid #222"> <template #right-panel>
<QCardSection horizontal> <div class="q-pa-md q-mb-md" style="border: 2px solid #222">
<span class="text-weight-bold text-subtitle1 text-center full-width"> <QCardSection horizontal>
{{ t('Hours') }} <span class="text-weight-bold text-subtitle1 text-center full-width">
</span> {{ t('Hours') }}
</QCardSection> </span>
<QCardSection class="column items-center" horizontal> </QCardSection>
<div> <QCardSection class="column items-center" horizontal>
<span class="details-label">{{ t('Total semana') }} </span> <div>
<span>: {{ formattedWeekTotalHours }}</span> <span class="details-label">{{ t('Total semana') }} </span>
</div> <span>: {{ formattedWeekTotalHours }}</span>
<div> </div>
<span class="details-label">{{ t('Termina a las') }}: </span> <div>
<span>{{ dashIfEmpty(getFinishTime()) }}</span> <span class="details-label">{{ t('Termina a las') }}: </span>
</div> <span>{{ dashIfEmpty(getFinishTime()) }}</span>
</QCardSection> </div>
</div> </QCardSection>
<WorkerTimeControlCalendar </div>
v-model:model-value="selectedDateFormatted" <WorkerTimeControlCalendar
:selected-dates="selectedCalendarDates" v-model:model-value="selectedDateFormatted"
:active-date="false" :selected-dates="selectedCalendarDates"
:worker-time-control-mails="workerTimeControlMails" :active-date="false"
@click-date="onInputChange" :worker-time-control-mails="workerTimeControlMails"
@on-moved="getMailStates" @click-date="onInputChange"
/> @on-moved="getMailStates"
</Teleport> />
</template>
</RightMenu>
<QPage class="column items-center"> <QPage class="column items-center">
<QTable :columns="columns" :rows="['']" hide-bottom class="full-width"> <QTable :columns="columns" :rows="['']" hide-bottom class="full-width">
<template #header="props"> <template #header="props">

View File

@ -199,7 +199,7 @@ async function autofillBic(worker) {
order: 'id DESC', order: 'id DESC',
}" }"
> >
<template #rightMenu> <template #advanced-menu>
<WorkerFilter data-key="WorkerList" /> <WorkerFilter data-key="WorkerList" />
</template> </template>
<template #body> <template #body>

View File

@ -168,7 +168,7 @@ const ticketCard = {
name: 'TicketBoxing', name: 'TicketBoxing',
meta: { meta: {
title: 'boxing', title: 'boxing',
icon: 'science', icon: 'view_in_ar',
}, },
component: () => import('src/pages/Ticket/Card/TicketBoxing.vue'), component: () => import('src/pages/Ticket/Card/TicketBoxing.vue'),
}, },

View File

@ -5,6 +5,7 @@ export const useStateStore = defineStore('stateStore', () => {
const isMounted = ref(false); const isMounted = ref(false);
const leftDrawer = ref(false); const leftDrawer = ref(false);
const rightDrawer = ref(false); const rightDrawer = ref(false);
const rightAdvancedDrawer = ref(false);
const subToolbar = ref(false); const subToolbar = ref(false);
function toggleLeftDrawer() { function toggleLeftDrawer() {
@ -15,6 +16,10 @@ export const useStateStore = defineStore('stateStore', () => {
rightDrawer.value = !rightDrawer.value; rightDrawer.value = !rightDrawer.value;
} }
function toggleRightAdvancedDrawer() {
rightAdvancedDrawer.value = !rightAdvancedDrawer.value;
}
function rightDrawerChangeValue(value) { function rightDrawerChangeValue(value) {
rightDrawer.value = value; rightDrawer.value = value;
} }
@ -46,10 +51,12 @@ export const useStateStore = defineStore('stateStore', () => {
return { return {
leftDrawer, leftDrawer,
rightDrawer, rightDrawer,
rightAdvancedDrawer,
setMounted, setMounted,
isHeaderMounted, isHeaderMounted,
toggleLeftDrawer, toggleLeftDrawer,
toggleRightDrawer, toggleRightDrawer,
toggleRightAdvancedDrawer,
isLeftDrawerShown, isLeftDrawerShown,
isRightDrawerShown, isRightDrawerShown,
isSubToolbarShown, isSubToolbarShown,