231801 test to master #56
|
@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- (Reclamaciones) => Añadida nueva sección "Registros de auditoría"
|
||||
- (Trabajadores) => Añadido módulo de trabajadores
|
||||
- (General) => Añadida barra de búsqueda general en los listados principales
|
||||
- (Vagones) => Añadido módulo de vagones
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
@ -140,8 +140,8 @@ module.exports = configure(function (/* ctx */) {
|
|||
|
||||
// Quasar plugins
|
||||
plugins: ['Notify', 'Dialog'],
|
||||
//all: 'auto',
|
||||
//autoImportComponentCase: 'pascal',
|
||||
all: 'auto',
|
||||
autoImportComponentCase: 'pascal',
|
||||
},
|
||||
|
||||
// animations: 'all', // --- includes all animations
|
||||
|
|
|
@ -36,7 +36,7 @@ quasar.iconMapFn = (iconName) => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<router-view />
|
||||
<RouterView />
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
@ -58,9 +58,12 @@ const onResponseError = (error) => {
|
|||
break;
|
||||
}
|
||||
|
||||
if (session.isLoggedIn && response.status === 401) {
|
||||
if (session.isLoggedIn() && response.status === 401) {
|
||||
session.destroy();
|
||||
Router.push({ path: '/login' });
|
||||
} else if(!session.isLoggedIn())
|
||||
{
|
||||
message = 'login.loginError';
|
||||
}
|
||||
|
||||
Notify.create({
|
||||
|
|
|
@ -99,16 +99,16 @@ watch(formUrl, async () => {
|
|||
});
|
||||
</script>
|
||||
<template>
|
||||
<q-banner v-if="hasChanges" class="text-white bg-warning">
|
||||
<q-icon name="warning" size="md" class="q-mr-md" />
|
||||
<QBanner v-if="hasChanges" class="text-white bg-warning">
|
||||
<QIcon name="warning" size="md" class="q-mr-md" />
|
||||
<span>{{ t('globals.changesToSave') }}</span>
|
||||
</q-banner>
|
||||
<q-form v-if="formData" @submit="save" @reset="reset" class="q-pa-md">
|
||||
</QBanner>
|
||||
<QForm v-if="formData" @submit="save" @reset="reset" class="q-pa-md">
|
||||
<slot name="form" :data="formData" :validate="validate" :filter="filter"></slot>
|
||||
<div class="q-mt-lg">
|
||||
<slot name="actions">
|
||||
<q-btn :label="t('globals.save')" type="submit" color="primary" />
|
||||
<q-btn
|
||||
<QBtn :label="t('globals.save')" type="submit" color="primary" />
|
||||
<QBtn
|
||||
:label="t('globals.reset')"
|
||||
type="reset"
|
||||
class="q-ml-sm"
|
||||
|
@ -118,7 +118,11 @@ watch(formUrl, async () => {
|
|||
/>
|
||||
</slot>
|
||||
</div>
|
||||
</q-form>
|
||||
<skeleton-form v-if="!formData" />
|
||||
<q-inner-loading :showing="isLoading" :label="t('globals.pleaseWait')" color="primary" />
|
||||
</QForm>
|
||||
<SkeletonForm v-if="!formData" />
|
||||
<QInnerLoading
|
||||
:showing="isLoading"
|
||||
:label="t('globals.pleaseWait')"
|
||||
color="primary"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import axios from 'axios';
|
||||
import { onMounted, ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { QSeparator, useQuasar } from 'quasar';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useNavigationStore } from 'src/stores/useNavigationStore';
|
||||
import { toLowerCamel } from 'src/filters';
|
||||
|
@ -65,7 +65,9 @@ function getRoutes() {
|
|||
const modules = Object.assign([], navigation.getModules().value);
|
||||
|
||||
for (const item of modules) {
|
||||
const moduleDef = routes.find((route) => toLowerCamel(route.name) === item.module);
|
||||
const moduleDef = routes.find(
|
||||
(route) => toLowerCamel(route.name) === item.module
|
||||
);
|
||||
item.children = [];
|
||||
|
||||
if (!moduleDef) continue;
|
||||
|
@ -79,7 +81,9 @@ function getRoutes() {
|
|||
if (props.source === 'card') {
|
||||
const currentRoute = route.matched[1];
|
||||
const currentModule = toLowerCamel(currentRoute.name);
|
||||
const moduleDef = routes.find((route) => toLowerCamel(route.name) === currentModule);
|
||||
const moduleDef = routes.find(
|
||||
(route) => toLowerCamel(route.name) === currentModule
|
||||
);
|
||||
|
||||
if (!moduleDef) return;
|
||||
|
||||
|
@ -111,90 +115,96 @@ async function togglePinned(item, event) {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-list padding>
|
||||
<QList padding>
|
||||
<template v-if="$props.source === 'main'">
|
||||
<q-item-label header>
|
||||
<QItemLabel header>
|
||||
{{ t('globals.pinnedModules') }}
|
||||
</q-item-label>
|
||||
</QItemLabel>
|
||||
<template v-for="item in pinnedItems" :key="item.name">
|
||||
<template v-if="item.children">
|
||||
<left-menu-item-group :item="item" group="pinnedModules" class="pinned">
|
||||
<LeftMenuItemGroup :item="item" group="pinnedModules" class="pinned">
|
||||
<template #side>
|
||||
<q-btn
|
||||
<QBtn
|
||||
v-if="item.isPinned === true"
|
||||
@click="togglePinned(item, $event)"
|
||||
icon="vn:pin_off"
|
||||
icon="remove_circle"
|
||||
size="xs"
|
||||
flat
|
||||
round
|
||||
>
|
||||
<q-tooltip>{{ t('components.leftMenu.removeFromPinned') }}</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
<QTooltip>{{
|
||||
t('components.leftMenu.removeFromPinned')
|
||||
}}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
v-if="item.isPinned === false"
|
||||
@click="togglePinned(item, $event)"
|
||||
icon="vn:pin"
|
||||
icon="push_pin"
|
||||
size="xs"
|
||||
flat
|
||||
round
|
||||
>
|
||||
<q-tooltip>{{ t('components.leftMenu.addToPinned') }}</q-tooltip>
|
||||
</q-btn>
|
||||
<QTooltip>{{
|
||||
t('components.leftMenu.addToPinned')
|
||||
}}</QTooltip>
|
||||
</QBtn>
|
||||
</template>
|
||||
</left-menu-item-group>
|
||||
</LeftMenuItemGroup>
|
||||
</template>
|
||||
|
||||
<left-menu-item v-if="!item.children" :item="item" />
|
||||
<LeftMenuItem v-if="!item.children" :item="item" />
|
||||
</template>
|
||||
<q-separator />
|
||||
<q-expansion-item :label="t('moduleIndex.allModules')">
|
||||
<QSeparator />
|
||||
<QExpansionItem :label="t('moduleIndex.allModules')">
|
||||
<template v-for="item in items" :key="item.name">
|
||||
<template v-if="item.children">
|
||||
<left-menu-item-group :item="item" group="modules">
|
||||
<LeftMenuItemGroup :item="item" group="modules">
|
||||
<template #side>
|
||||
<q-btn
|
||||
<QBtn
|
||||
v-if="item.isPinned === true"
|
||||
@click="togglePinned(item, $event)"
|
||||
icon="vn:pin_off"
|
||||
icon="remove_circle"
|
||||
size="xs"
|
||||
flat
|
||||
round
|
||||
>
|
||||
<q-tooltip>{{ t('components.leftMenu.removeFromPinned') }}</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
<QTooltip>
|
||||
{{ t('components.leftMenu.removeFromPinned') }}
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
v-if="item.isPinned === false"
|
||||
@click="togglePinned(item, $event)"
|
||||
icon="vn:pin"
|
||||
icon="push_pin"
|
||||
size="xs"
|
||||
flat
|
||||
round
|
||||
>
|
||||
<q-tooltip>{{ t('components.leftMenu.addToPinned') }}</q-tooltip>
|
||||
</q-btn>
|
||||
<QTooltip>
|
||||
{{ t('components.leftMenu.addToPinned') }}
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</template>
|
||||
</left-menu-item-group>
|
||||
</LeftMenuItemGroup>
|
||||
</template>
|
||||
</template>
|
||||
</q-expansion-item>
|
||||
<q-separator />
|
||||
</QExpansionItem>
|
||||
<QSeparator />
|
||||
</template>
|
||||
<template v-if="$props.source === 'card'">
|
||||
<template v-for="item in items" :key="item.name">
|
||||
<left-menu-item v-if="!item.children" :item="item" />
|
||||
<LeftMenuItem v-if="!item.children" :item="item" />
|
||||
</template>
|
||||
</template>
|
||||
</q-list>
|
||||
</QList>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.pinned .icon-pin,
|
||||
.pinned .icon-pin_off {
|
||||
.pinned .q-btn {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.pinned:hover .icon-pin,
|
||||
.pinned:hover .icon-pin_off {
|
||||
.pinned:hover .q-btn {
|
||||
visibility: visible;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -14,13 +14,13 @@ const props = defineProps({
|
|||
const item = computed(() => props.item);
|
||||
</script>
|
||||
<template>
|
||||
<q-item active-class="text-primary" :to="{ name: item.name }" clickable v-ripple>
|
||||
<q-item-section avatar v-if="item.icon">
|
||||
<q-icon :name="item.icon" />
|
||||
</q-item-section>
|
||||
<q-item-section avatar v-if="!item.icon">
|
||||
<q-icon name="disabled_by_default" />
|
||||
</q-item-section>
|
||||
<q-item-section>{{ t(item.title) }}</q-item-section>
|
||||
</q-item>
|
||||
<QItem active-class="text-primary" :to="{ name: item.name }" clickable v-ripple>
|
||||
<QItemSection avatar v-if="item.icon">
|
||||
<QIcon :name="item.icon" />
|
||||
</QItemSection>
|
||||
<QItemSection avatar v-if="!item.icon">
|
||||
<QIcon name="disabled_by_default" />
|
||||
</QItemSection>
|
||||
<QItemSection>{{ t(item.title) }}</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
|
|
|
@ -27,7 +27,7 @@ const isOpened = computed(() => {
|
|||
});
|
||||
</script>
|
||||
<template>
|
||||
<q-expansion-item
|
||||
<QExpansionItem
|
||||
:group="props.group"
|
||||
active-class="text-primary"
|
||||
:label="item.title"
|
||||
|
@ -36,16 +36,16 @@ const isOpened = computed(() => {
|
|||
:default-opened="isOpened"
|
||||
>
|
||||
<template #header>
|
||||
<q-item-section avatar>
|
||||
<q-icon :name="item.icon"></q-icon>
|
||||
</q-item-section>
|
||||
<q-item-section>{{ t(item.title) }}</q-item-section>
|
||||
<q-item-section side>
|
||||
<QItemSection avatar>
|
||||
<QIcon :name="item.icon"></QIcon>
|
||||
</QItemSection>
|
||||
<QItemSection>{{ t(item.title) }}</QItemSection>
|
||||
<QItemSection side>
|
||||
<slot name="side" :item="item" />
|
||||
</q-item-section>
|
||||
</QItemSection>
|
||||
</template>
|
||||
<template v-for="section in item.children" :key="section.name">
|
||||
<left-menu-item :item="section" />
|
||||
<LeftMenuItem :item="section" />
|
||||
</template>
|
||||
</q-expansion-item>
|
||||
</QExpansionItem>
|
||||
</template>
|
||||
|
|
|
@ -19,9 +19,9 @@ onMounted(() => stateStore.setMounted());
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-header class="bg-dark" color="white" elevated>
|
||||
<q-toolbar class="q-py-sm q-px-md">
|
||||
<q-btn
|
||||
<QHeader class="bg-dark" color="white" elevated>
|
||||
<QToolbar class="q-py-sm q-px-md">
|
||||
<QBtn
|
||||
@click="stateStore.toggleLeftDrawer()"
|
||||
icon="menu"
|
||||
class="q-mr-sm"
|
||||
|
@ -29,54 +29,54 @@ onMounted(() => stateStore.setMounted());
|
|||
dense
|
||||
flat
|
||||
>
|
||||
<q-tooltip bottom anchor="bottom right">
|
||||
<QTooltip bottom anchor="bottom right">
|
||||
{{ t('globals.collapseMenu') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<router-link to="/">
|
||||
<q-btn class="q-ml-xs" color="primary" v-if="$q.screen.gt.xs" flat round>
|
||||
<q-avatar square size="md">
|
||||
<q-img
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
<RouterLink to="/">
|
||||
<QBtn class="q-ml-xs" color="primary" flat round>
|
||||
<QAvatar square size="md">
|
||||
<QImg
|
||||
src="~/assets/logo_icon.svg"
|
||||
:alt="appName"
|
||||
spinner-color="primary"
|
||||
/>
|
||||
</q-avatar>
|
||||
<q-tooltip bottom>
|
||||
</QAvatar>
|
||||
<QTooltip bottom>
|
||||
{{ t('globals.backToDashboard') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</router-link>
|
||||
<q-toolbar-title shrink class="text-weight-bold" v-if="$q.screen.gt.xs">
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</RouterLink>
|
||||
<QToolbarTitle shrink class="text-weight-bold" v-if="$q.screen.gt.sm">
|
||||
{{ appName }}
|
||||
<q-badge label="Beta" align="top" />
|
||||
</q-toolbar-title>
|
||||
<q-space></q-space>
|
||||
<QBadge label="Beta" align="top" />
|
||||
</QToolbarTitle>
|
||||
<QSpace />
|
||||
<div id="searchbar"></div>
|
||||
<q-space></q-space>
|
||||
<QSpace />
|
||||
<div class="q-pl-sm q-gutter-sm row items-center no-wrap">
|
||||
<div id="actions-prepend"></div>
|
||||
<q-btn id="pinnedModules" icon="apps" flat dense rounded>
|
||||
<q-tooltip bottom>
|
||||
<QBtn id="pinnedModules" icon="apps" flat dense rounded>
|
||||
<QTooltip bottom>
|
||||
{{ t('globals.pinnedModules') }}
|
||||
</q-tooltip>
|
||||
</QTooltip>
|
||||
<PinnedModules />
|
||||
</q-btn>
|
||||
<q-btn rounded dense flat no-wrap id="user">
|
||||
<q-avatar size="lg">
|
||||
<q-img
|
||||
</QBtn>
|
||||
<QBtn rounded dense flat no-wrap id="user">
|
||||
<QAvatar size="lg">
|
||||
<QImg
|
||||
:src="`/api/Images/user/160x160/${user.id}/download?access_token=${token}`"
|
||||
spinner-color="primary"
|
||||
>
|
||||
</q-img>
|
||||
</q-avatar>
|
||||
<q-tooltip bottom>
|
||||
</QImg>
|
||||
</QAvatar>
|
||||
<QTooltip bottom>
|
||||
{{ t('globals.userPanel') }}
|
||||
</q-tooltip>
|
||||
</QTooltip>
|
||||
<UserPanel />
|
||||
</q-btn>
|
||||
</QBtn>
|
||||
<div id="actions-append"></div>
|
||||
</div>
|
||||
</q-toolbar>
|
||||
</q-header>
|
||||
</QToolbar>
|
||||
</QHeader>
|
||||
</template>
|
||||
|
|
|
@ -14,10 +14,19 @@ const pinnedModules = computed(() => navigation.getPinnedModules());
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-menu anchor="bottom left" class="row q-pa-md q-col-gutter-lg" max-width="350px" max-height="400px">
|
||||
<QMenu
|
||||
anchor="bottom left"
|
||||
class="row q-pa-md q-col-gutter-lg"
|
||||
max-width="350px"
|
||||
max-height="400px"
|
||||
>
|
||||
<template v-if="pinnedModules.length">
|
||||
<div v-for="item of pinnedModules" :key="item.title" class="row no-wrap q-pa-xs flex-item">
|
||||
<q-btn
|
||||
<div
|
||||
v-for="item of pinnedModules"
|
||||
:key="item.title"
|
||||
class="row no-wrap q-pa-xs flex-item"
|
||||
>
|
||||
<QBtn
|
||||
align="evenly"
|
||||
padding="16px"
|
||||
flat
|
||||
|
@ -31,15 +40,18 @@ const pinnedModules = computed(() => navigation.getPinnedModules());
|
|||
<div class="text-center text-primary button-text">
|
||||
{{ t(item.title) }}
|
||||
</div>
|
||||
</q-btn>
|
||||
</QBtn>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="row no-wrap q-pa-xs flex-item text-center text-grey-5" style="min-width: 200px">
|
||||
<div
|
||||
class="row no-wrap q-pa-xs flex-item text-center text-grey-5"
|
||||
style="min-width: 200px"
|
||||
>
|
||||
{{ t('globals.noPinnedModules') }}
|
||||
</div>
|
||||
</template>
|
||||
</q-menu>
|
||||
</QMenu>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -70,7 +70,7 @@ async function saveDarkMode(value) {
|
|||
}
|
||||
|
||||
async function saveLanguage(value) {
|
||||
const query = `/Accounts/${user.value.id}`;
|
||||
const query = `/VnUsers/${user.value.id}`;
|
||||
await axios.patch(query, {
|
||||
lang: value,
|
||||
});
|
||||
|
@ -84,11 +84,13 @@ function logout() {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-menu anchor="bottom left">
|
||||
<QMenu anchor="bottom left">
|
||||
<div class="row no-wrap q-pa-md">
|
||||
<div class="column panel">
|
||||
<div class="text-h6 q-mb-md">{{ t('components.userPanel.settings') }}</div>
|
||||
<q-toggle
|
||||
<div class="text-h6 q-mb-md">
|
||||
{{ t('components.userPanel.settings') }}
|
||||
</div>
|
||||
<QToggle
|
||||
v-model="userLocale"
|
||||
@update:model-value="saveLanguage"
|
||||
:label="t(`globals.lang['${userLocale}']`)"
|
||||
|
@ -97,7 +99,7 @@ function logout() {
|
|||
false-value="es"
|
||||
true-value="en"
|
||||
/>
|
||||
<q-toggle
|
||||
<QToggle
|
||||
v-model="darkMode"
|
||||
@update:model-value="saveDarkMode"
|
||||
:label="t(`globals.darkMode`)"
|
||||
|
@ -107,22 +109,22 @@ function logout() {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<q-separator vertical inset class="q-mx-lg" />
|
||||
<QSeparator vertical inset class="q-mx-lg" />
|
||||
|
||||
<div class="column items-center panel">
|
||||
<q-avatar size="80px">
|
||||
<q-img
|
||||
<QAvatar size="80px">
|
||||
<QImg
|
||||
:src="`/api/Images/user/160x160/${user.id}/download?access_token=${token}`"
|
||||
spinner-color="white"
|
||||
/>
|
||||
</q-avatar>
|
||||
</QAvatar>
|
||||
|
||||
<div class="text-subtitle1 q-mt-md">
|
||||
<strong>{{ user.nickname }}</strong>
|
||||
</div>
|
||||
<div class="text-subtitle3 text-grey-7 q-mb-xs">@{{ user.name }}</div>
|
||||
|
||||
<q-btn
|
||||
<QBtn
|
||||
id="logout"
|
||||
color="orange"
|
||||
flat
|
||||
|
@ -134,7 +136,7 @@ function logout() {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-menu>
|
||||
</QMenu>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -40,31 +40,31 @@ async function confirm() {
|
|||
}
|
||||
</script>
|
||||
<template>
|
||||
<q-dialog ref="dialogRef" persistent>
|
||||
<q-card class="q-pa-sm">
|
||||
<q-card-section class="row items-center q-pb-none">
|
||||
<QDialog ref="dialogRef" persistent>
|
||||
<QCard class="q-pa-sm">
|
||||
<QCardSection class="row items-center q-pb-none">
|
||||
<span class="text-h6 text-grey">{{ t('Send email notification') }}</span>
|
||||
<q-space />
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
<q-card-section class="row items-center">
|
||||
<QSpace />
|
||||
<QBtn icon="close" flat round dense v-close-popup />
|
||||
</QCardSection>
|
||||
<QCardSection class="row items-center">
|
||||
{{ t('The notification will be sent to the following address') }}
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pt-none">
|
||||
<q-input dense v-model="address" rounded outlined autofocus />
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn :label="t('globals.cancel')" color="primary" flat v-close-popup />
|
||||
<q-btn
|
||||
</QCardSection>
|
||||
<QCardSection class="q-pt-none">
|
||||
<QInput dense v-model="address" rounded outlined autofocus />
|
||||
</QCardSection>
|
||||
<QCardActions align="right">
|
||||
<QBtn :label="t('globals.cancel')" color="primary" flat v-close-popup />
|
||||
<QBtn
|
||||
:label="t('globals.confirm')"
|
||||
color="primary"
|
||||
:loading="isLoading"
|
||||
@click="confirm"
|
||||
unelevated
|
||||
/>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</QCardActions>
|
||||
</QCard>
|
||||
</QDialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -83,27 +83,27 @@ async function send() {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog ref="dialogRef" persistent>
|
||||
<q-card class="q-pa-sm">
|
||||
<q-card-section class="row items-center q-pb-none">
|
||||
<QDialog ref="dialogRef" persistent>
|
||||
<QCard class="q-pa-sm">
|
||||
<QCardSection class="row items-center q-pb-none">
|
||||
<span class="text-h6 text-grey">
|
||||
{{ t('Send SMS') }}
|
||||
</span>
|
||||
<q-space />
|
||||
<q-btn icon="close" :disable="isLoading" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
<q-card-section v-if="props.locale">
|
||||
<q-banner class="bg-amber text-white" rounded dense>
|
||||
<QSpace />
|
||||
<QBtn icon="close" :disable="isLoading" flat round dense v-close-popup />
|
||||
</QCardSection>
|
||||
<QCardSection v-if="props.locale">
|
||||
<QBanner class="bg-amber text-white" rounded dense>
|
||||
<template #avatar>
|
||||
<q-icon name="warning" />
|
||||
<QIcon name="warning" />
|
||||
</template>
|
||||
<span
|
||||
v-html="t('CustomerDefaultLanguage', { locale: t(props.locale) })"
|
||||
></span>
|
||||
</q-banner>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pb-xs">
|
||||
<q-select
|
||||
</QBanner>
|
||||
</QCardSection>
|
||||
<QCardSection class="q-pb-xs">
|
||||
<QSelect
|
||||
:label="t('Language')"
|
||||
:options="languages"
|
||||
v-model="locale"
|
||||
|
@ -115,9 +115,9 @@ async function send() {
|
|||
outlined
|
||||
dense
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pb-xs">
|
||||
<q-input
|
||||
</QCardSection>
|
||||
<QCardSection class="q-pb-xs">
|
||||
<QInput
|
||||
:label="t('Phone')"
|
||||
v-model="phone"
|
||||
rounded
|
||||
|
@ -125,9 +125,9 @@ async function send() {
|
|||
autofocus
|
||||
dense
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pb-xs">
|
||||
<q-input
|
||||
</QCardSection>
|
||||
<QCardSection class="q-pb-xs">
|
||||
<QInput
|
||||
:label="t('Subject')"
|
||||
v-model="subject"
|
||||
rounded
|
||||
|
@ -135,9 +135,9 @@ async function send() {
|
|||
autofocus
|
||||
dense
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-mb-md" q-input>
|
||||
<q-input
|
||||
</QCardSection>
|
||||
<QCardSection class="q-mb-md" q-input>
|
||||
<QInput
|
||||
:label="t('Message')"
|
||||
v-model="message"
|
||||
type="textarea"
|
||||
|
@ -151,7 +151,7 @@ async function send() {
|
|||
autofocus
|
||||
>
|
||||
<template #append>
|
||||
<q-icon
|
||||
<QIcon
|
||||
v-if="message !== ''"
|
||||
name="close"
|
||||
@click="message = ''"
|
||||
|
@ -159,30 +159,30 @@ async function send() {
|
|||
/>
|
||||
</template>
|
||||
<template #counter>
|
||||
<q-chip :color="color" dense>
|
||||
<QChip :color="color" dense>
|
||||
{{ totalLength }}/{{ maxLength }}
|
||||
</q-chip>
|
||||
</QChip>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn
|
||||
</QInput>
|
||||
</QCardSection>
|
||||
<QCardActions align="right">
|
||||
<QBtn
|
||||
:label="t('globals.cancel')"
|
||||
color="primary"
|
||||
:disable="isLoading"
|
||||
flat
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn
|
||||
<QBtn
|
||||
:label="t('globals.confirm')"
|
||||
@click="send()"
|
||||
:loading="isLoading"
|
||||
color="primary"
|
||||
unelevated
|
||||
/>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</QCardActions>
|
||||
</QCard>
|
||||
</QDialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
<script setup>
|
||||
import { onMounted, ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { toCurrency } from 'filters/index';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = defineProps({
|
||||
quantity: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
price: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
discount: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0,
|
||||
},
|
||||
mana: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
promise: {
|
||||
type: Function,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['onUpdate']);
|
||||
|
||||
const discount = ref(0);
|
||||
let canceller;
|
||||
|
||||
onMounted(() => {
|
||||
if (props.discount) {
|
||||
discount.value = props.discount;
|
||||
}
|
||||
});
|
||||
|
||||
const total = computed(() => {
|
||||
const amount = props.price * props.quantity;
|
||||
const appliedDiscount = (discount.value * amount) / 100;
|
||||
|
||||
return amount - appliedDiscount;
|
||||
});
|
||||
|
||||
const newAmount = computed(() => `${t('New amount')}: ${toCurrency(total.value)}`);
|
||||
|
||||
const isLoading = ref(false);
|
||||
async function save({ set }) {
|
||||
isLoading.value = true;
|
||||
const response = {
|
||||
...props.data,
|
||||
...{
|
||||
discount: parseInt(discount.value),
|
||||
},
|
||||
};
|
||||
if (props.promise) {
|
||||
canceller = new AbortController();
|
||||
Object.assign(response, { canceller });
|
||||
|
||||
await props.promise(response);
|
||||
}
|
||||
|
||||
if (set) set();
|
||||
emit('onUpdate', response);
|
||||
isLoading.value = false;
|
||||
}
|
||||
|
||||
function cancel({ cancel }) {
|
||||
if (canceller) {
|
||||
canceller.abort();
|
||||
canceller = null;
|
||||
}
|
||||
|
||||
discount.value = props.discount;
|
||||
if (isLoading.value === true) isLoading.value = false;
|
||||
if (cancel) cancel();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QPopupEdit
|
||||
v-model="discount"
|
||||
v-slot="scope"
|
||||
:title="t('Update discount')"
|
||||
@cancel="cancel"
|
||||
>
|
||||
<QBanner class="bg-primary text-center q-mb-md" rounded dense>
|
||||
{{ t('Mana') }} {{ toCurrency(props.mana) }}
|
||||
</QBanner>
|
||||
<QInput
|
||||
v-model="scope.value"
|
||||
type="number"
|
||||
dense
|
||||
autofocus
|
||||
@keyup.enter="save(scope)"
|
||||
@update:model-value="discount = scope.value"
|
||||
@focus="($event) => $event.target.select()"
|
||||
min="0"
|
||||
max="100"
|
||||
:disable="isLoading"
|
||||
:hint="newAmount"
|
||||
:rules="[
|
||||
(value) => value.length > 0 || t('Enter a value'),
|
||||
(value) => (value >= 0 && value <= 100) || t('Invalid discount amount'),
|
||||
]"
|
||||
/>
|
||||
<QCardActions class="q-px-none q-mt-sm" align="right">
|
||||
<QBtn :label="t('Cancel')" color="primary" flat @click="cancel(scope)" />
|
||||
<QBtn
|
||||
:label="t('Update')"
|
||||
color="primary"
|
||||
:loading="isLoading"
|
||||
unelevated
|
||||
@click="save(scope)"
|
||||
/>
|
||||
</QCardActions>
|
||||
</QPopupEdit>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
New amount: Nuevo importe
|
||||
Update discount: Actualizar descuento
|
||||
Mana: Maná
|
||||
Enter a value: Introduce un valor
|
||||
Invalid discount amount: Cantidad de descuento incorrecta
|
||||
Cancel: Cancelar
|
||||
Update: Actualizar
|
||||
</i18n>
|
|
@ -48,24 +48,22 @@ watch(props, async () => {
|
|||
<div class="descriptor">
|
||||
<template v-if="entity">
|
||||
<div class="header bg-primary q-pa-sm">
|
||||
<router-link :to="{ name: `${module}List` }">
|
||||
<q-btn round flat dense size="md" icon="view_list" color="white">
|
||||
<q-tooltip>
|
||||
<RouterLink :to="{ name: `${module}List` }">
|
||||
<QBtn round flat dense size="md" icon="view_list" color="white">
|
||||
<QTooltip>
|
||||
{{ t('components.cardDescriptor.mainList') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="{ name: `${module}Summary`, params: { id: entity.id } }"
|
||||
>
|
||||
<q-btn round flat dense size="md" icon="launch" color="white">
|
||||
<q-tooltip>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</RouterLink>
|
||||
<RouterLink :to="{ name: `${module}Summary`, params: { id: entity.id } }">
|
||||
<QBtn round flat dense size="md" icon="launch" color="white">
|
||||
<QTooltip>
|
||||
{{ t('components.cardDescriptor.summary') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</router-link>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</RouterLink>
|
||||
|
||||
<q-btn
|
||||
<QBtn
|
||||
v-if="slots.menu"
|
||||
size="md"
|
||||
icon="more_vert"
|
||||
|
@ -74,39 +72,39 @@ watch(props, async () => {
|
|||
flat
|
||||
dense
|
||||
>
|
||||
<q-tooltip>
|
||||
<QTooltip>
|
||||
{{ t('components.cardDescriptor.moreOptions') }}
|
||||
</q-tooltip>
|
||||
<q-menu>
|
||||
<q-list>
|
||||
</QTooltip>
|
||||
<QMenu>
|
||||
<QList>
|
||||
<slot name="menu" :entity="entity" />
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-btn>
|
||||
</QList>
|
||||
</QMenu>
|
||||
</QBtn>
|
||||
</div>
|
||||
<slot name="before" />
|
||||
<div class="body q-py-sm">
|
||||
<q-list dense>
|
||||
<q-item-label header class="ellipsis text-h5" :lines="1">
|
||||
<QList dense>
|
||||
<QItemLabel header class="ellipsis text-h5" :lines="1">
|
||||
<slot name="description" :entity="entity">
|
||||
<span>
|
||||
{{ entity.name }}
|
||||
<q-tooltip>{{ entity.name }}</q-tooltip>
|
||||
<QTooltip>{{ entity.name }}</QTooltip>
|
||||
</span>
|
||||
</slot>
|
||||
</q-item-label>
|
||||
<q-item dense>
|
||||
<q-item-label class="text-subtitle2" caption>
|
||||
</QItemLabel>
|
||||
<QItem dense>
|
||||
<QItemLabel class="text-subtitle2" caption>
|
||||
#{{ entity.id }}
|
||||
</q-item-label>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
</QList>
|
||||
<slot name="body" :entity="entity" />
|
||||
</div>
|
||||
<slot name="after" />
|
||||
</template>
|
||||
<!-- Skeleton -->
|
||||
<skeleton-descriptor v-if="!entity" />
|
||||
<SkeletonDescriptor v-if="!entity" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -41,8 +41,8 @@ watch(props, async () => {
|
|||
|
||||
<template>
|
||||
<div class="summary container">
|
||||
<q-card>
|
||||
<skeleton-summary v-if="!entity" />
|
||||
<QCard>
|
||||
<SkeletonSummary v-if="!entity" />
|
||||
<template v-if="entity">
|
||||
<div class="header bg-primary q-pa-sm q-mb-md">
|
||||
<slot name="header" :entity="entity">
|
||||
|
@ -53,7 +53,7 @@ watch(props, async () => {
|
|||
<slot name="body" :entity="entity" />
|
||||
</div>
|
||||
</template>
|
||||
</q-card>
|
||||
</QCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
<template>
|
||||
<div id="descriptor-skeleton">
|
||||
<div class="col q-pl-sm q-pa-sm">
|
||||
<q-skeleton type="text" square height="45px" />
|
||||
<q-skeleton type="text" square height="18px" />
|
||||
<q-skeleton type="text" square height="18px" />
|
||||
<q-skeleton type="text" square height="18px" />
|
||||
<QSkeleton type="text" square height="45px" />
|
||||
<QSkeleton type="text" square height="18px" />
|
||||
<QSkeleton type="text" square height="18px" />
|
||||
<QSkeleton type="text" square height="18px" />
|
||||
</div>
|
||||
|
||||
<q-card-actions>
|
||||
<q-skeleton size="40px" />
|
||||
<q-skeleton size="40px" />
|
||||
<q-skeleton size="40px" />
|
||||
<q-skeleton size="40px" />
|
||||
<q-skeleton size="40px" />
|
||||
</q-card-actions>
|
||||
<QCardActions>
|
||||
<QSkeleton size="40px" />
|
||||
<QSkeleton size="40px" />
|
||||
<QSkeleton size="40px" />
|
||||
<QSkeleton size="40px" />
|
||||
<QSkeleton size="40px" />
|
||||
</QCardActions>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -2,31 +2,31 @@
|
|||
<div class="q-pa-md">
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-skeleton type="QInput" square />
|
||||
<QSkeleton type="QInput" square />
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-skeleton type="QInput" square />
|
||||
<QSkeleton type="QInput" square />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-skeleton type="QInput" square />
|
||||
<QSkeleton type="QInput" square />
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-skeleton type="QInput" square />
|
||||
<QSkeleton type="QInput" square />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-skeleton type="QInput" square />
|
||||
<QSkeleton type="QInput" square />
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-skeleton type="QInput" square />
|
||||
<QSkeleton type="QInput" square />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-gutter-md">
|
||||
<q-skeleton type="QBtn" />
|
||||
<q-skeleton type="QBtn" />
|
||||
<QSkeleton type="QBtn" />
|
||||
<QSkeleton type="QBtn" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,47 +1,47 @@
|
|||
<template>
|
||||
<div class="header bg-primary q-pa-sm q-mb-md">
|
||||
<q-skeleton type="rect" square />
|
||||
<QSkeleton type="rect" square />
|
||||
</div>
|
||||
<div class="row q-pa-md q-col-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-skeleton type="rect" class="q-mb-md" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<QSkeleton type="rect" class="q-mb-md" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-skeleton type="rect" class="q-mb-md" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<QSkeleton type="rect" class="q-mb-md" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-skeleton type="rect" class="q-mb-md" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<QSkeleton type="rect" class="q-mb-md" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-skeleton type="rect" class="q-mb-md" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<QSkeleton type="rect" class="q-mb-md" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-skeleton type="rect" class="q-mb-md" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
<QSkeleton type="rect" class="q-mb-md" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -51,10 +51,10 @@ async function confirm() {
|
|||
}
|
||||
</script>
|
||||
<template>
|
||||
<q-dialog ref="dialogRef" persistent>
|
||||
<q-card class="q-pa-sm">
|
||||
<q-card-section class="row items-center q-pb-none q-gutter-md">
|
||||
<q-avatar
|
||||
<QDialog ref="dialogRef" persistent>
|
||||
<QCard class="q-pa-sm">
|
||||
<QCardSection class="row items-center q-pb-none">
|
||||
<QAvatar
|
||||
:icon="icon"
|
||||
color="primary"
|
||||
text-color="white"
|
||||
|
@ -62,21 +62,21 @@ async function confirm() {
|
|||
v-if="icon"
|
||||
/>
|
||||
<span class="text-h6 text-grey">{{ title }}</span>
|
||||
<q-space />
|
||||
<q-btn icon="close" :disable="isLoading" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
<q-card-section class="row items-center">
|
||||
{{ message }}
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn
|
||||
<QSpace />
|
||||
<QBtn icon="close" :disable="isLoading" flat round dense v-close-popup />
|
||||
</QCardSection>
|
||||
<QCardSection class="row items-center">
|
||||
<span v-html="message"></span>
|
||||
</QCardSection>
|
||||
<QCardActions align="right">
|
||||
<QBtn
|
||||
:label="t('globals.cancel')"
|
||||
color="primary"
|
||||
:disable="isLoading"
|
||||
flat
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn
|
||||
<QBtn
|
||||
:label="t('globals.confirm')"
|
||||
color="primary"
|
||||
:loading="isLoading"
|
||||
|
@ -84,9 +84,9 @@ async function confirm() {
|
|||
unelevated
|
||||
autofocus
|
||||
/>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</QCardActions>
|
||||
</QCard>
|
||||
</QDialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -99,21 +99,17 @@ function formatValue(value) {
|
|||
}
|
||||
</script>
|
||||
<template>
|
||||
<q-form @submit="search">
|
||||
<q-list dense>
|
||||
<q-item class="q-mt-xs">
|
||||
<q-item-section top>
|
||||
<q-item-label
|
||||
header
|
||||
lines="1"
|
||||
class="text-uppercase q-py-xs q-px-none"
|
||||
>
|
||||
<QForm @submit="search">
|
||||
<QList dense>
|
||||
<QItem class="q-mt-xs">
|
||||
<QItemSection top>
|
||||
<QItemLabel header lines="1" class="text-uppercase q-py-xs q-px-none">
|
||||
{{ t('Applied filters') }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section top side>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection top side>
|
||||
<div class="q-gutter-xs">
|
||||
<q-btn
|
||||
<QBtn
|
||||
@click="clearFilters"
|
||||
icon="filter_list_off"
|
||||
color="primary"
|
||||
|
@ -123,9 +119,9 @@ function formatValue(value) {
|
|||
flat
|
||||
dense
|
||||
>
|
||||
<q-tooltip>{{ t('Remove filters') }}</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
<QTooltip>{{ t('Remove filters') }}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
@click="reload"
|
||||
icon="refresh"
|
||||
color="primary"
|
||||
|
@ -135,12 +131,12 @@ function formatValue(value) {
|
|||
flat
|
||||
dense
|
||||
>
|
||||
<q-tooltip>{{ t('Refresh') }}</q-tooltip>
|
||||
</q-btn>
|
||||
<QTooltip>{{ t('Refresh') }}</QTooltip>
|
||||
</QBtn>
|
||||
</div>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<div
|
||||
v-if="tags.length === 0"
|
||||
class="text-grey font-xs text-center full-width"
|
||||
|
@ -148,7 +144,7 @@ function formatValue(value) {
|
|||
{{ t(`No filters applied`) }}
|
||||
</div>
|
||||
<div>
|
||||
<q-chip
|
||||
<QChip
|
||||
v-for="chip of tags"
|
||||
:key="chip.label"
|
||||
@remove="remove(chip.label)"
|
||||
|
@ -164,14 +160,14 @@ function formatValue(value) {
|
|||
<span>"{{ chip.value }}"</span>
|
||||
</div>
|
||||
</slot>
|
||||
</q-chip>
|
||||
</QChip>
|
||||
</div>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
</QItem>
|
||||
<QSeparator />
|
||||
<template v-if="props.searchButton">
|
||||
<q-item>
|
||||
<q-item-section class="q-py-sm">
|
||||
<q-btn
|
||||
<QItem>
|
||||
<QItemSection class="q-py-sm">
|
||||
<QBtn
|
||||
:label="t('Search')"
|
||||
type="submit"
|
||||
color="primary"
|
||||
|
@ -181,14 +177,14 @@ function formatValue(value) {
|
|||
rounded
|
||||
dense
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QSeparator />
|
||||
</template>
|
||||
</q-list>
|
||||
</QList>
|
||||
<slot name="body" :params="userParams" :search-fn="search"></slot>
|
||||
</q-form>
|
||||
<q-inner-loading
|
||||
</QForm>
|
||||
<QInnerLoading
|
||||
:showing="isLoading"
|
||||
:label="t('globals.pleaseWait')"
|
||||
color="primary"
|
||||
|
|
|
@ -145,31 +145,31 @@ async function onLoad(...params) {
|
|||
</h5>
|
||||
</div>
|
||||
<div v-if="props.autoLoad && !store.data" class="card-list q-gutter-y-md">
|
||||
<q-card class="card" v-for="$index in $props.limit" :key="$index">
|
||||
<q-item v-ripple class="q-pa-none items-start cursor-pointer q-hoverable">
|
||||
<q-item-section class="q-pa-md">
|
||||
<q-skeleton type="rect" class="q-mb-md" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" class="q-mb-md" square />
|
||||
<q-skeleton type="text" square />
|
||||
<q-skeleton type="text" square />
|
||||
</q-item-section>
|
||||
<q-separator vertical />
|
||||
<q-card-actions vertical class="justify-between">
|
||||
<q-skeleton type="circle" class="q-mb-md" size="40px" />
|
||||
<q-skeleton type="circle" class="q-mb-md" size="40px" />
|
||||
<q-skeleton type="circle" class="q-mb-md" size="40px" />
|
||||
</q-card-actions>
|
||||
</q-item>
|
||||
</q-card>
|
||||
<QCard class="card" v-for="$index in $props.limit" :key="$index">
|
||||
<QItem v-ripple class="q-pa-none items-start cursor-pointer q-hoverable">
|
||||
<QItemSection class="q-pa-md">
|
||||
<QSkeleton type="rect" class="q-mb-md" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" class="q-mb-md" square />
|
||||
<QSkeleton type="text" square />
|
||||
<QSkeleton type="text" square />
|
||||
</QItemSection>
|
||||
<QSeparator vertical />
|
||||
<QCardActions vertical class="justify-between">
|
||||
<QSkeleton type="circle" class="q-mb-md" size="40px" />
|
||||
<QSkeleton type="circle" class="q-mb-md" size="40px" />
|
||||
<QSkeleton type="circle" class="q-mb-md" size="40px" />
|
||||
</QCardActions>
|
||||
</QItem>
|
||||
</QCard>
|
||||
</div>
|
||||
</div>
|
||||
<q-infinite-scroll v-if="store.data" @load="onLoad" :offset="offset">
|
||||
<QInfiniteScroll v-if="store.data" @load="onLoad" :offset="offset">
|
||||
<slot name="body" :rows="store.data"></slot>
|
||||
<div v-if="isLoading" class="info-row q-pa-md text-center">
|
||||
<q-spinner color="orange" size="md" />
|
||||
<QSpinner color="orange" size="md" />
|
||||
</div>
|
||||
</q-infinite-scroll>
|
||||
</QInfiniteScroll>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
|
@ -83,8 +83,8 @@ async function search() {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-form @submit="search">
|
||||
<q-input
|
||||
<QForm @submit="search">
|
||||
<QInput
|
||||
id="searchbar"
|
||||
v-model="searchText"
|
||||
:placeholder="props.label"
|
||||
|
@ -93,32 +93,30 @@ async function search() {
|
|||
autofocus
|
||||
>
|
||||
<template #prepend>
|
||||
<q-icon name="search" />
|
||||
<QIcon name="search" />
|
||||
</template>
|
||||
<template #append>
|
||||
<q-icon
|
||||
<QIcon
|
||||
v-if="searchText !== ''"
|
||||
name="close"
|
||||
@click="searchText = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
|
||||
<q-icon v-if="props.info" name="info" class="cursor-info">
|
||||
<q-tooltip>{{ props.info }}</q-tooltip>
|
||||
</q-icon>
|
||||
<QIcon v-if="props.info" name="info" class="cursor-info">
|
||||
<QTooltip>{{ props.info }}</QTooltip>
|
||||
</QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-form>
|
||||
</QInput>
|
||||
</QForm>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@media screen and (max-width: $breakpoint-xs-max) {
|
||||
.q-field {
|
||||
width: 250px;
|
||||
}
|
||||
.q-field {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: $breakpoint-xs-max) {
|
||||
@media screen and (min-width: $breakpoint-sm-max) {
|
||||
.q-field {
|
||||
width: 400px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import axios from 'axios';
|
||||
|
||||
export async function getUrl(route, appName = 'salix') {
|
||||
let url;
|
||||
const env = process.env.NODE_ENV === 'development' ? 'dev' : process.env.NODE_ENV;
|
||||
const filter = {
|
||||
where: {and: [
|
||||
{appName: appName},
|
||||
{environment: env}
|
||||
]}
|
||||
};
|
||||
|
||||
await axios.get('Urls/findOne', {params: {filter}})
|
||||
.then(res => {
|
||||
url = res.data.url + route;
|
||||
});
|
||||
|
||||
return url;
|
||||
}
|
|
@ -5,7 +5,7 @@ export function useRole() {
|
|||
const state = useState();
|
||||
|
||||
async function fetch() {
|
||||
const { data } = await axios.get('Accounts/acl');
|
||||
const { data } = await axios.get('VnUsers/acl');
|
||||
const roles = data.roles.map((userRoles) => userRoles.role.name);
|
||||
|
||||
const userData = {
|
||||
|
|
Binary file not shown.
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 173 KiB |
Binary file not shown.
Binary file not shown.
|
@ -1,399 +1,412 @@
|
|||
@font-face {
|
||||
font-family: 'icomoon';
|
||||
src: url('fonts/icomoon.eot?g6kvgn');
|
||||
src: url('fonts/icomoon.eot?g6kvgn#iefix') format('embedded-opentype'),
|
||||
url('fonts/icomoon.ttf?g6kvgn') format('truetype'),
|
||||
url('fonts/icomoon.woff?g6kvgn') format('woff'),
|
||||
url('fonts/icomoon.svg?g6kvgn#icomoon') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
font-family: 'icomoon';
|
||||
src: url('fonts/icomoon.eot?g6kvgn');
|
||||
src: url('fonts/icomoon.eot?g6kvgn#iefix') format('embedded-opentype'),
|
||||
url('fonts/icomoon.ttf?g6kvgn') format('truetype'),
|
||||
url('fonts/icomoon.woff?g6kvgn') format('woff'),
|
||||
url('fonts/icomoon.svg?g6kvgn#icomoon') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
}
|
||||
|
||||
[class^="icon-"], [class*=" icon-"] {
|
||||
/* use !important to prevent issues with browser extensions that change fonts */
|
||||
font-family: 'icomoon' !important;
|
||||
speak: never;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
[class^='icon-'],
|
||||
[class*=' icon-'] {
|
||||
/* use !important to prevent issues with browser extensions that change fonts */
|
||||
font-family: 'icomoon' !important;
|
||||
speak: never;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
|
||||
/* Better Font Rendering =========== */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
/* Better Font Rendering =========== */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-pin:before {
|
||||
content: "\e950";
|
||||
}
|
||||
.icon-pin_off:before {
|
||||
content: "\e95b";
|
||||
}
|
||||
.icon-frozen:before {
|
||||
content: "\e900";
|
||||
content: '\e900';
|
||||
}
|
||||
.icon-Person:before {
|
||||
content: "\e901";
|
||||
content: '\e901';
|
||||
}
|
||||
.icon-handmadeArtificial:before {
|
||||
content: "\e902";
|
||||
content: '\e902';
|
||||
}
|
||||
.icon-fruit:before {
|
||||
content: "\e903";
|
||||
content: '\e903';
|
||||
}
|
||||
.icon-funeral:before {
|
||||
content: "\e904";
|
||||
content: '\e904';
|
||||
}
|
||||
.icon-noPayMethod:before {
|
||||
content: "\e905";
|
||||
content: '\e905';
|
||||
}
|
||||
.icon-preserved:before {
|
||||
content: "\e906";
|
||||
content: '\e906';
|
||||
}
|
||||
.icon-greenery:before {
|
||||
content: "\e907";
|
||||
content: '\e907';
|
||||
}
|
||||
.icon-planta:before {
|
||||
content: "\e908";
|
||||
.icon-plant:before {
|
||||
content: '\e908';
|
||||
}
|
||||
.icon-handmade:before {
|
||||
content: "\e909";
|
||||
content: '\e909';
|
||||
}
|
||||
.icon-accessory:before {
|
||||
content: "\e90a";
|
||||
content: '\e90a';
|
||||
}
|
||||
.icon-artificial:before {
|
||||
content: "\e90b";
|
||||
content: '\e90b';
|
||||
}
|
||||
.icon-flower:before {
|
||||
content: "\e90c";
|
||||
content: '\e90c';
|
||||
}
|
||||
.icon-fixedPrice:before {
|
||||
content: "\e90d";
|
||||
content: '\e90d';
|
||||
}
|
||||
.icon-addperson:before {
|
||||
content: "\e90e";
|
||||
content: '\e90e';
|
||||
}
|
||||
.icon-supplierfalse:before {
|
||||
content: "\e90f";
|
||||
content: '\e90f';
|
||||
}
|
||||
.icon-invoice-out:before {
|
||||
content: "\e910";
|
||||
content: '\e910';
|
||||
}
|
||||
.icon-invoice-in:before {
|
||||
content: "\e911";
|
||||
content: '\e911';
|
||||
}
|
||||
.icon-invoice-in-create:before {
|
||||
content: "\e912";
|
||||
content: '\e912';
|
||||
}
|
||||
.icon-basketadd:before {
|
||||
content: "\e913";
|
||||
content: '\e913';
|
||||
}
|
||||
.icon-basket:before {
|
||||
content: "\e914";
|
||||
content: '\e914';
|
||||
}
|
||||
.icon-uniE915:before {
|
||||
content: "\e915";
|
||||
content: '\e915';
|
||||
}
|
||||
.icon-uniE916:before {
|
||||
content: "\e916";
|
||||
content: '\e916';
|
||||
}
|
||||
.icon-uniE917:before {
|
||||
content: "\e917";
|
||||
content: '\e917';
|
||||
}
|
||||
.icon-uniE918:before {
|
||||
content: "\e918";
|
||||
content: '\e918';
|
||||
}
|
||||
.icon-uniE919:before {
|
||||
content: "\e919";
|
||||
content: '\e919';
|
||||
}
|
||||
.icon-uniE91A:before {
|
||||
content: "\e91a";
|
||||
content: '\e91a';
|
||||
}
|
||||
.icon-isTooLittle:before {
|
||||
content: "\e91b";
|
||||
content: '\e91b';
|
||||
}
|
||||
.icon-deliveryprices:before {
|
||||
content: "\e91c";
|
||||
content: '\e91c';
|
||||
}
|
||||
.icon-onlinepayment:before {
|
||||
content: "\e91d";
|
||||
content: '\e91d';
|
||||
}
|
||||
.icon-risk:before {
|
||||
content: "\e91e";
|
||||
content: '\e91e';
|
||||
}
|
||||
.icon-noweb:before {
|
||||
content: "\e91f";
|
||||
content: '\e91f';
|
||||
}
|
||||
.icon-no036:before {
|
||||
content: "\e920";
|
||||
content: '\e920';
|
||||
}
|
||||
.icon-disabled:before {
|
||||
content: "\e921";
|
||||
content: '\e921';
|
||||
}
|
||||
.icon-treatments:before {
|
||||
content: "\e922";
|
||||
content: '\e922';
|
||||
}
|
||||
.icon-invoice:before {
|
||||
content: "\e923";
|
||||
content: '\e923';
|
||||
}
|
||||
.icon-photo:before {
|
||||
content: "\e924";
|
||||
content: '\e924';
|
||||
}
|
||||
.icon-supplier:before {
|
||||
content: "\e925";
|
||||
content: '\e925';
|
||||
}
|
||||
.icon-languaje:before {
|
||||
content: "\e926";
|
||||
content: '\e926';
|
||||
}
|
||||
.icon-credit:before {
|
||||
content: "\e927";
|
||||
content: '\e927';
|
||||
}
|
||||
.icon-client:before {
|
||||
content: "\e928";
|
||||
content: '\e928';
|
||||
}
|
||||
.icon-shipment-01:before {
|
||||
content: "\e929";
|
||||
content: '\e929';
|
||||
}
|
||||
.icon-account:before {
|
||||
content: "\e92a";
|
||||
content: '\e92a';
|
||||
}
|
||||
.icon-inventory:before {
|
||||
content: "\e92b";
|
||||
content: '\e92b';
|
||||
}
|
||||
.icon-unavailable:before {
|
||||
content: "\e92c";
|
||||
content: '\e92c';
|
||||
}
|
||||
.icon-wiki:before {
|
||||
content: "\e92d";
|
||||
content: '\e92d';
|
||||
}
|
||||
.icon-attach:before {
|
||||
content: "\e92e";
|
||||
content: '\e92e';
|
||||
}
|
||||
.icon-exit:before {
|
||||
content: "\e92f";
|
||||
content: '\e92f';
|
||||
}
|
||||
.icon-anonymous:before {
|
||||
content: "\e930";
|
||||
content: '\e930';
|
||||
}
|
||||
.icon-net:before {
|
||||
content: "\e931";
|
||||
content: '\e931';
|
||||
}
|
||||
.icon-buyrequest:before {
|
||||
content: "\e932";
|
||||
content: '\e932';
|
||||
}
|
||||
.icon-thermometer:before {
|
||||
content: "\e933";
|
||||
content: '\e933';
|
||||
}
|
||||
.icon-entry:before {
|
||||
content: "\e934";
|
||||
content: '\e934';
|
||||
}
|
||||
.icon-deletedTicket:before {
|
||||
content: "\e935";
|
||||
content: '\e935';
|
||||
}
|
||||
.icon-logout:before {
|
||||
content: "\e936";
|
||||
content: '\e936';
|
||||
}
|
||||
.icon-catalog:before {
|
||||
content: "\e937";
|
||||
content: '\e937';
|
||||
}
|
||||
.icon-agency:before {
|
||||
content: "\e938";
|
||||
content: '\e938';
|
||||
}
|
||||
.icon-delivery:before {
|
||||
content: "\e939";
|
||||
content: '\e939';
|
||||
}
|
||||
.icon-wand:before {
|
||||
content: "\e93a";
|
||||
content: '\e93a';
|
||||
}
|
||||
.icon-buscaman:before {
|
||||
content: "\e93b";
|
||||
content: '\e93b';
|
||||
}
|
||||
.icon-pbx:before {
|
||||
content: "\e93c";
|
||||
content: '\e93c';
|
||||
}
|
||||
.icon-calendar:before {
|
||||
content: "\e93d";
|
||||
content: '\e93d';
|
||||
}
|
||||
.icon-splitline:before {
|
||||
content: "\e93e";
|
||||
content: '\e93e';
|
||||
}
|
||||
.icon-consignatarios:before {
|
||||
content: "\e93f";
|
||||
content: '\e93f';
|
||||
}
|
||||
.icon-tax:before {
|
||||
content: "\e940";
|
||||
content: '\e940';
|
||||
}
|
||||
.icon-notes:before {
|
||||
content: "\e941";
|
||||
content: '\e941';
|
||||
}
|
||||
.icon-lines:before {
|
||||
content: "\e942";
|
||||
content: '\e942';
|
||||
}
|
||||
.icon-zone:before {
|
||||
content: "\e943";
|
||||
content: '\e943';
|
||||
}
|
||||
.icon-greuge:before {
|
||||
content: "\e944";
|
||||
content: '\e944';
|
||||
}
|
||||
.icon-ticketAdd:before {
|
||||
content: "\e945";
|
||||
content: '\e945';
|
||||
}
|
||||
.icon-components:before {
|
||||
content: "\e946";
|
||||
content: '\e946';
|
||||
}
|
||||
.icon-pets:before {
|
||||
content: "\e947";
|
||||
content: '\e947';
|
||||
}
|
||||
.icon-linesprepaired:before {
|
||||
content: "\e948";
|
||||
content: '\e948';
|
||||
}
|
||||
.icon-control:before {
|
||||
content: "\e949";
|
||||
content: '\e949';
|
||||
}
|
||||
.icon-revision:before {
|
||||
content: "\e94a";
|
||||
content: '\e94a';
|
||||
}
|
||||
.icon-deaulter:before {
|
||||
content: "\e94b";
|
||||
content: '\e94b';
|
||||
}
|
||||
.icon-services:before {
|
||||
content: "\e94c";
|
||||
content: '\e94c';
|
||||
}
|
||||
.icon-albaran:before {
|
||||
content: "\e94d";
|
||||
content: '\e94d';
|
||||
}
|
||||
.icon-solunion:before {
|
||||
content: "\e94e";
|
||||
content: '\e94e';
|
||||
}
|
||||
.icon-stowaway:before {
|
||||
content: "\e94f";
|
||||
content: '\e94f';
|
||||
}
|
||||
.icon-apps:before {
|
||||
content: "\e951";
|
||||
content: '\e951';
|
||||
}
|
||||
.icon-info:before {
|
||||
content: "\e952";
|
||||
content: '\e952';
|
||||
}
|
||||
.icon-columndelete:before {
|
||||
content: "\e953";
|
||||
content: '\e953';
|
||||
}
|
||||
.icon-columnadd:before {
|
||||
content: "\e954";
|
||||
content: '\e954';
|
||||
}
|
||||
.icon-deleteline:before {
|
||||
content: "\e955";
|
||||
content: '\e955';
|
||||
}
|
||||
.icon-item:before {
|
||||
content: "\e956";
|
||||
content: '\e956';
|
||||
}
|
||||
.icon-worker:before {
|
||||
content: "\e957";
|
||||
content: '\e957';
|
||||
}
|
||||
.icon-headercol:before {
|
||||
content: "\e958";
|
||||
content: '\e958';
|
||||
}
|
||||
.icon-reserva:before {
|
||||
content: "\e959";
|
||||
content: '\e959';
|
||||
}
|
||||
.icon-100:before {
|
||||
content: "\e95a";
|
||||
content: '\e95a';
|
||||
}
|
||||
.icon-sign:before {
|
||||
content: "\e95d";
|
||||
content: '\e95d';
|
||||
}
|
||||
.icon-polizon:before {
|
||||
content: "\e95e";
|
||||
content: '\e95e';
|
||||
}
|
||||
.icon-solclaim:before {
|
||||
content: "\e95f";
|
||||
content: '\e95f';
|
||||
}
|
||||
.icon-actions:before {
|
||||
content: "\e960";
|
||||
content: '\e960';
|
||||
}
|
||||
.icon-details:before {
|
||||
content: "\e961";
|
||||
content: '\e961';
|
||||
}
|
||||
.icon-traceability:before {
|
||||
content: "\e962";
|
||||
content: '\e962';
|
||||
}
|
||||
.icon-claims:before {
|
||||
content: "\e963";
|
||||
content: '\e963';
|
||||
}
|
||||
.icon-regentry:before {
|
||||
content: "\e964";
|
||||
content: '\e964';
|
||||
}
|
||||
.icon-transaction:before {
|
||||
content: "\e966";
|
||||
content: '\e966';
|
||||
}
|
||||
.icon-History:before {
|
||||
content: "\e968";
|
||||
content: '\e968';
|
||||
}
|
||||
.icon-mana:before {
|
||||
content: "\e96a";
|
||||
content: '\e96a';
|
||||
}
|
||||
.icon-ticket:before {
|
||||
content: "\e96b";
|
||||
content: '\e96b';
|
||||
}
|
||||
.icon-niche:before {
|
||||
content: "\e96c";
|
||||
content: '\e96c';
|
||||
}
|
||||
.icon-tags:before {
|
||||
content: "\e96d";
|
||||
content: '\e96d';
|
||||
}
|
||||
.icon-volume:before {
|
||||
content: "\e96e";
|
||||
content: '\e96e';
|
||||
}
|
||||
.icon-bin:before {
|
||||
content: "\e96f";
|
||||
content: '\e96f';
|
||||
}
|
||||
.icon-splur:before {
|
||||
content: "\e970";
|
||||
content: '\e970';
|
||||
}
|
||||
.icon-barcode:before {
|
||||
content: "\e971";
|
||||
content: '\e971';
|
||||
}
|
||||
.icon-botanical:before {
|
||||
content: "\e972";
|
||||
content: '\e972';
|
||||
}
|
||||
.icon-clone:before {
|
||||
content: "\e973";
|
||||
content: '\e973';
|
||||
}
|
||||
.icon-sms:before {
|
||||
content: "\e975";
|
||||
content: '\e975';
|
||||
}
|
||||
.icon-eye:before {
|
||||
content: "\e976";
|
||||
content: '\e976';
|
||||
}
|
||||
.icon-doc:before {
|
||||
content: "\e977";
|
||||
content: '\e977';
|
||||
}
|
||||
.icon-package:before {
|
||||
content: "\e978";
|
||||
content: '\e978';
|
||||
}
|
||||
.icon-settings:before {
|
||||
content: "\e979";
|
||||
content: '\e979';
|
||||
}
|
||||
.icon-bucket:before {
|
||||
content: "\e97a";
|
||||
content: '\e97a';
|
||||
}
|
||||
.icon-mandatory:before {
|
||||
content: "\e97b";
|
||||
content: '\e97b';
|
||||
}
|
||||
.icon-recovery:before {
|
||||
content: "\e97c";
|
||||
content: '\e97c';
|
||||
}
|
||||
.icon-payment:before {
|
||||
content: "\e97e";
|
||||
content: '\e97e';
|
||||
}
|
||||
.icon-grid:before {
|
||||
content: "\e980";
|
||||
content: '\e980';
|
||||
}
|
||||
.icon-web:before {
|
||||
content: "\e982";
|
||||
content: '\e982';
|
||||
}
|
||||
.icon-dfiscales:before {
|
||||
content: "\e984";
|
||||
content: '\e984';
|
||||
}
|
||||
.icon-trolley:before {
|
||||
content: '\e95c';
|
||||
}
|
||||
.icon-agency-term:before {
|
||||
content: '\e950';
|
||||
}
|
||||
.icon-client-unpaid:before {
|
||||
content: '\e95b';
|
||||
}
|
||||
.icon-trolley:before {
|
||||
content: '\e95c';
|
||||
}
|
||||
.icon-grafana:before {
|
||||
content: '\e965';
|
||||
}
|
||||
.icon-troncales:before {
|
||||
content: '\e967';
|
||||
}
|
||||
|
|
|
@ -241,6 +241,7 @@ export default {
|
|||
rmaList: 'RMA',
|
||||
summary: 'Summary',
|
||||
basicData: 'Basic Data',
|
||||
lines: 'Lines',
|
||||
rma: 'RMA',
|
||||
photos: 'Photos',
|
||||
log: 'Audit logs',
|
||||
|
@ -287,6 +288,14 @@ export default {
|
|||
responsibility: 'Responsibility',
|
||||
company: 'Company',
|
||||
person: 'Employee/Customer',
|
||||
notes: 'Notes',
|
||||
photos: 'Photos',
|
||||
development: 'Development',
|
||||
reason: 'Reason',
|
||||
result: 'Result',
|
||||
responsible: 'Responsible',
|
||||
worker: 'Worker',
|
||||
redelivery: 'Redelivery'
|
||||
},
|
||||
basicData: {
|
||||
customer: 'Customer',
|
||||
|
@ -387,6 +396,49 @@ export default {
|
|||
},
|
||||
imageNotFound: 'Image not found',
|
||||
},
|
||||
wagon: {
|
||||
pageTitles: {
|
||||
wagons: 'Wagons',
|
||||
wagonsList: 'Wagons List',
|
||||
wagonCreate: 'Create wagon',
|
||||
wagonEdit: 'Edit wagon',
|
||||
typesList: 'Types List',
|
||||
typeCreate: 'Create type',
|
||||
typeEdit: 'Edit type'
|
||||
},
|
||||
type: {
|
||||
name: 'Name',
|
||||
submit: 'Submit',
|
||||
reset: 'Reset',
|
||||
trayColor: 'Tray color',
|
||||
removeItem: 'Wagon type removed successfully',
|
||||
},
|
||||
list: {
|
||||
plate: 'Plate',
|
||||
volume: 'Volume',
|
||||
type: 'Type',
|
||||
remove: 'Remove',
|
||||
removeItem: 'Wagon removed successfully',
|
||||
},
|
||||
create: {
|
||||
plate: 'Plate',
|
||||
volume: 'Volume',
|
||||
type: 'Type',
|
||||
label: 'Label'
|
||||
},
|
||||
warnings: {
|
||||
noData: 'No data available',
|
||||
nameNotEmpty: 'Name can not be empty',
|
||||
labelNotEmpty: 'Label can not be empty',
|
||||
plateNotEmpty: 'Plate can not be empty',
|
||||
volumeNotEmpty: 'Volume can not be empty',
|
||||
typeNotEmpty: 'Type can not be empty',
|
||||
maxTrays: 'You have reached the max number of trays',
|
||||
minHeightBetweenTrays: 'The minimum height between trays is ',
|
||||
maxWagonHeight: 'The maximum height of the wagon is ',
|
||||
uncompleteTrays: 'There are incomplete trays',
|
||||
}
|
||||
},
|
||||
components: {
|
||||
topbar: {},
|
||||
userPanel: {
|
||||
|
|
|
@ -240,6 +240,7 @@ export default {
|
|||
rmaList: 'RMA',
|
||||
summary: 'Resumen',
|
||||
basicData: 'Datos básicos',
|
||||
lines: 'Líneas',
|
||||
rma: 'RMA',
|
||||
photos: 'Fotos',
|
||||
log: 'Registros de auditoría',
|
||||
|
@ -286,6 +287,14 @@ export default {
|
|||
responsibility: 'Responsabilidad',
|
||||
company: 'Empresa',
|
||||
person: 'Comercial/Cliente',
|
||||
notes: 'Observaciones',
|
||||
photos: 'Fotos',
|
||||
development: 'Trazabilidad',
|
||||
reason: 'Motivo',
|
||||
result: 'Consecuencias',
|
||||
responsible: 'Responsable',
|
||||
worker: 'Trabajador',
|
||||
redelivery: 'Devolución'
|
||||
},
|
||||
basicData: {
|
||||
customer: 'Cliente',
|
||||
|
@ -387,6 +396,49 @@ export default {
|
|||
},
|
||||
imageNotFound: 'No se ha encontrado la imagen',
|
||||
},
|
||||
wagon: {
|
||||
pageTitles: {
|
||||
wagons: 'Vagones',
|
||||
wagonsList: 'Listado vagones',
|
||||
wagonCreate: 'Crear tipo',
|
||||
wagonEdit: 'Editar tipo',
|
||||
typesList: 'Listado tipos',
|
||||
typeCreate: 'Crear tipo',
|
||||
typeEdit: 'Editar tipo'
|
||||
},
|
||||
type: {
|
||||
name: 'Nombre',
|
||||
submit: 'Guardar',
|
||||
reset: 'Deshacer cambios',
|
||||
trayColor: 'Color de la bandeja',
|
||||
removeItem: 'Tipo de vagón borrado correctamente',
|
||||
},
|
||||
list: {
|
||||
plate: 'Matrícula',
|
||||
volume: 'Volumen',
|
||||
type: 'Tipo',
|
||||
remove: 'Borrar',
|
||||
removeItem: 'Vagón borrado correctamente',
|
||||
},
|
||||
create: {
|
||||
plate: 'Matrícula',
|
||||
volume: 'Volumen',
|
||||
type: 'Tipo',
|
||||
label: 'Etiqueta',
|
||||
},
|
||||
warnings: {
|
||||
noData: 'Sin datos disponibles',
|
||||
nameNotEmpty: 'El nombre no puede estar vacío',
|
||||
labelNotEmpty: 'La etiqueta no puede estar vacía',
|
||||
plateNotEmpty: 'La matrícula no puede estar vacía',
|
||||
volumeNotEmpty: 'El volumen no puede estar vacío',
|
||||
typeNotEmpty: 'El tipo no puede estar vacío',
|
||||
maxTrays: 'Has alcanzado el número máximo de bandejas',
|
||||
minHeightBetweenTrays: 'La distancia mínima entre bandejas es ',
|
||||
maxWagonHeight: 'La altura máxima del vagón es ',
|
||||
uncompleteTrays: 'Hay bandejas sin completar',
|
||||
}
|
||||
},
|
||||
components: {
|
||||
topbar: {},
|
||||
userPanel: {
|
||||
|
|
|
@ -6,11 +6,11 @@ const quasar = useQuasar();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-layout view="hHh LpR fFf">
|
||||
<QLayout view="hHh LpR fFf">
|
||||
<Navbar />
|
||||
<router-view></router-view>
|
||||
<q-footer v-if="quasar.platform.is.mobile"></q-footer>
|
||||
</q-layout>
|
||||
<RouterView></RouterView>
|
||||
<QFooter v-if="quasar.platform.is.mobile"></QFooter>
|
||||
</QLayout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
|
@ -73,17 +73,17 @@ const statesFilter = {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<fetch-data
|
||||
<FetchData
|
||||
url="Workers/activeWithInheritedRole"
|
||||
:filter="{ where: { role: 'salesPerson' } }"
|
||||
@on-fetch="setWorkers"
|
||||
auto-load
|
||||
/>
|
||||
<fetch-data url="ClaimStates" @on-fetch="setClaimStates" auto-load />
|
||||
<FetchData url="ClaimStates" @on-fetch="setClaimStates" auto-load />
|
||||
|
||||
<div class="column items-center">
|
||||
<q-card>
|
||||
<form-model
|
||||
<QCard>
|
||||
<FormModel
|
||||
:url="`Claims/${route.params.id}`"
|
||||
:filter="claimFilter"
|
||||
model="claim"
|
||||
|
@ -91,48 +91,48 @@ const statesFilter = {
|
|||
<template #form="{ data, validate, filter }">
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-input
|
||||
<QInput
|
||||
v-model="data.client.name"
|
||||
:label="t('claim.basicData.customer')"
|
||||
disable
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-input
|
||||
<QInput
|
||||
v-model="data.created"
|
||||
mask="####-##-##"
|
||||
fill-mask="_"
|
||||
autofocus
|
||||
>
|
||||
<template #append>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy
|
||||
<QIcon name="event" class="cursor-pointer">
|
||||
<QPopupProxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-date
|
||||
<QDate
|
||||
v-model="data.created"
|
||||
mask="YYYY-MM-DD"
|
||||
>
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn
|
||||
<QBtn
|
||||
v-close-popup
|
||||
label="Close"
|
||||
color="primary"
|
||||
flat
|
||||
/>
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</QDate>
|
||||
</QPopupProxy>
|
||||
</QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</QInput>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-select
|
||||
<QSelect
|
||||
v-model="data.workerFk"
|
||||
:options="workers"
|
||||
option-value="id"
|
||||
|
@ -148,18 +148,18 @@ const statesFilter = {
|
|||
:input-debounce="0"
|
||||
>
|
||||
<template #before>
|
||||
<q-avatar color="orange">
|
||||
<q-img
|
||||
<QAvatar color="orange">
|
||||
<QImg
|
||||
v-if="data.workerFk"
|
||||
:src="`/api/Images/user/160x160/${data.workerFk}/download?access_token=${token}`"
|
||||
spinner-color="white"
|
||||
/>
|
||||
</q-avatar>
|
||||
</QAvatar>
|
||||
</template>
|
||||
</q-select>
|
||||
</QSelect>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-select
|
||||
<QSelect
|
||||
v-model="data.claimStateFk"
|
||||
:options="claimStates"
|
||||
option-value="id"
|
||||
|
@ -174,19 +174,19 @@ const statesFilter = {
|
|||
:rules="validate('claim.claimStateFk')"
|
||||
:input-debounce="0"
|
||||
>
|
||||
</q-select>
|
||||
</QSelect>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-input
|
||||
<QInput
|
||||
v-model="data.packages"
|
||||
:label="t('claim.basicData.packages')"
|
||||
:rules="validate('claim.packages')"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-input
|
||||
<QInput
|
||||
v-model="data.rma"
|
||||
:label="t('claim.basicData.returnOfMaterial')"
|
||||
:rules="validate('claim.rma')"
|
||||
|
@ -195,15 +195,15 @@ const statesFilter = {
|
|||
</div>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-checkbox
|
||||
<QCheckbox
|
||||
v-model="data.hasToPickUp"
|
||||
:label="t('claim.basicData.picked')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</form-model>
|
||||
</q-card>
|
||||
</FormModel>
|
||||
</QCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,12 +1,36 @@
|
|||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import ClaimDescriptor from './ClaimDescriptor.vue';
|
||||
import LeftMenu from 'components/LeftMenu.vue';
|
||||
import { getUrl } from 'composables/getUrl';
|
||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { computed, onMounted } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
import ClaimDescriptor from './ClaimDescriptor.vue';
|
||||
|
||||
const stateStore = useStateStore();
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
const entityId = computed(() => {
|
||||
return $props.id || route.params.id;
|
||||
});
|
||||
const claimSections = [
|
||||
{ name: 'Notes', url: '/note/index', icon: 'draft' },
|
||||
{ name: 'Development', url: '/development', icon: 'vn:traceability' },
|
||||
{ name: 'Action', url: '/action', icon: 'vn:actions' },
|
||||
];
|
||||
|
||||
let salixUrl;
|
||||
onMounted(async () => {
|
||||
salixUrl = await getUrl(`claim/${entityId.value}`);
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Teleport to="#searchbar" v-if="stateStore.isHeaderMounted()">
|
||||
|
@ -17,22 +41,42 @@ const { t } = useI18n();
|
|||
:info="t('You can search by claim id or customer name')"
|
||||
/>
|
||||
</Teleport>
|
||||
<q-drawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<q-scroll-area class="fit">
|
||||
<claim-descriptor />
|
||||
<q-separator />
|
||||
<left-menu source="card" />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page-container>
|
||||
<q-page class="q-pa-md">
|
||||
<router-view></router-view>
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<QScrollArea class="fit">
|
||||
<ClaimDescriptor />
|
||||
<QSeparator />
|
||||
<LeftMenu source="card" />
|
||||
<QSeparator />
|
||||
<QList>
|
||||
<QItem
|
||||
v-for="section in claimSections"
|
||||
:key="section.name"
|
||||
active-class="text-primary"
|
||||
:href="salixUrl + section.url"
|
||||
clickable
|
||||
v-ripple
|
||||
>
|
||||
<QItemSection avatar>
|
||||
<QIcon :name="section.icon" />
|
||||
</QItemSection>
|
||||
<QItemSection> {{ t(section.name) }} </QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPageContainer>
|
||||
<QPage class="q-pa-md">
|
||||
<RouterView></RouterView>
|
||||
</QPage>
|
||||
</QPageContainer>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Search claim: Buscar reclamación
|
||||
You can search by claim id or customer name: Puedes buscar por id de la reclamación o nombre del cliente
|
||||
Details: Detalles
|
||||
Notes: Notas
|
||||
Development: Trazabilidad
|
||||
Action: Acción
|
||||
</i18n>
|
||||
|
|
|
@ -47,77 +47,77 @@ function stateColor(code) {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<card-descriptor
|
||||
<CardDescriptor
|
||||
ref="descriptor"
|
||||
:url="`Claims/${entityId}`"
|
||||
:filter="filter"
|
||||
module="Claim"
|
||||
>
|
||||
<template #menu="{ entity }">
|
||||
<claim-descriptor-menu :claim="entity" />
|
||||
<ClaimDescriptorMenu :claim="entity" />
|
||||
</template>
|
||||
<template #description="{ entity }">
|
||||
<span>
|
||||
{{ entity.client.name }}
|
||||
<q-tooltip>{{ entity.client.name }}</q-tooltip>
|
||||
<QTooltip>{{ entity.client.name }}</QTooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #body="{ entity }">
|
||||
<q-list>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{ t('claim.card.created') }}</q-item-label>
|
||||
<q-item-label>{{ toDate(entity.created) }}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section v-if="entity.claimState">
|
||||
<q-item-label caption>{{ t('claim.card.state') }}</q-item-label>
|
||||
<q-item-label>
|
||||
<q-chip :color="stateColor(entity.claimState.code)" dense>
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{ t('claim.card.created') }}</QItemLabel>
|
||||
<QItemLabel>{{ toDate(entity.created) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection v-if="entity.claimState">
|
||||
<QItemLabel caption>{{ t('claim.card.state') }}</QItemLabel>
|
||||
<QItemLabel>
|
||||
<QBadge :color="stateColor(entity.claimState.code)" dense>
|
||||
{{ entity.claimState.description }}
|
||||
</q-chip>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QBadge>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.card.ticketId') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
<span class="link">
|
||||
{{ entity.ticketFk }}
|
||||
|
||||
<TicketDescriptorProxy :id="entity.ticketFk" />
|
||||
</span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section v-if="entity.worker">
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection v-if="entity.worker">
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.card.assignedTo') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.worker.user.name }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.worker.user.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
|
||||
<q-card-actions>
|
||||
<q-btn
|
||||
<QCardActions>
|
||||
<QBtn
|
||||
size="md"
|
||||
icon="vn:client"
|
||||
color="primary"
|
||||
:to="{ name: 'CustomerCard', params: { id: entity.clientFk } }"
|
||||
>
|
||||
<q-tooltip>{{ t('claim.card.customerSummary') }}</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
<QTooltip>{{ t('claim.card.customerSummary') }}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
size="md"
|
||||
icon="vn:ticket"
|
||||
color="primary"
|
||||
:to="{ name: 'TicketCard', params: { id: entity.ticketFk } }"
|
||||
>
|
||||
<q-tooltip>{{ t('claim.card.claimedTicket') }}</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
<QTooltip>{{ t('claim.card.claimedTicket') }}</QTooltip>
|
||||
</QBtn>
|
||||
</QCardActions>
|
||||
</template>
|
||||
</card-descriptor>
|
||||
</CardDescriptor>
|
||||
</template>
|
||||
|
|
|
@ -69,43 +69,43 @@ async function remove() {
|
|||
await axios.delete(`Claims/${id}`);
|
||||
quasar.notify({
|
||||
message: t('globals.dataDeleted'),
|
||||
type: 'positive'
|
||||
type: 'positive',
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<q-item v-ripple clickable>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="summarize" />
|
||||
</q-item-section>
|
||||
<q-item-section>{{ t('pickupOrder') }}</q-item-section>
|
||||
<q-item-section side>
|
||||
<q-icon name="keyboard_arrow_right" />
|
||||
</q-item-section>
|
||||
<q-menu anchor="top end" self="top start" auto-close>
|
||||
<q-list>
|
||||
<q-item @click="openPickupOrder" v-ripple clickable>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="picture_as_pdf" />
|
||||
</q-item-section>
|
||||
<q-item-section>{{ t('openPickupOrder') }}</q-item-section>
|
||||
</q-item>
|
||||
<q-item @click="confirmPickupOrder" v-ripple clickable>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="send" />
|
||||
</q-item-section>
|
||||
<q-item-section>{{ t('sendPickupOrder') }}</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<q-item @click="confirmRemove()" v-ripple clickable>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="delete" />
|
||||
</q-item-section>
|
||||
<q-item-section>{{ t('deleteClaim') }}</q-item-section>
|
||||
</q-item>
|
||||
<QItem v-ripple clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="summarize" />
|
||||
</QItemSection>
|
||||
<QItemSection>{{ t('pickupOrder') }}</QItemSection>
|
||||
<QItemSection side>
|
||||
<QIcon name="keyboard_arrow_right" />
|
||||
</QItemSection>
|
||||
<QMenu anchor="top end" self="top start" auto-close>
|
||||
<QList>
|
||||
<QItem @click="openPickupOrder" v-ripple clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="picture_as_pdf" />
|
||||
</QItemSection>
|
||||
<QItemSection>{{ t('openPickupOrder') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem @click="confirmPickupOrder" v-ripple clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="send" />
|
||||
</QItemSection>
|
||||
<QItemSection>{{ t('sendPickupOrder') }}</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QMenu>
|
||||
</QItem>
|
||||
<QSeparator />
|
||||
<QItem @click="confirmRemove()" v-ripple clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="delete" />
|
||||
</QItemSection>
|
||||
<QItemSection>{{ t('deleteClaim') }}</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
|
|
|
@ -0,0 +1,440 @@
|
|||
<script setup>
|
||||
import axios from 'axios';
|
||||
import { ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useArrayData } from 'composables/useArrayData';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import VnConfirm from 'components/ui/VnConfirm.vue';
|
||||
|
||||
import { toDate, toCurrency, toPercentage } from 'filters/index';
|
||||
import VnDiscount from 'components/common/vnDiscount.vue';
|
||||
import ClaimLinesImport from './ClaimLinesImport.vue';
|
||||
|
||||
const quasar = useQuasar();
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
const stateStore = useStateStore();
|
||||
const arrayData = useArrayData('ClaimLines');
|
||||
const store = arrayData.store;
|
||||
|
||||
const claimFilter = {
|
||||
fields: ['ticketFk'],
|
||||
};
|
||||
const linesFilter = {
|
||||
include: {
|
||||
relation: 'sale',
|
||||
scope: {
|
||||
fields: ['concept', 'ticketFk', 'price', 'quantity', 'discount', 'itemFk'],
|
||||
include: {
|
||||
relation: 'ticket',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const claim = ref(null);
|
||||
async function onFetchClaim(data) {
|
||||
claim.value = data;
|
||||
|
||||
fetchMana();
|
||||
}
|
||||
|
||||
const amount = ref(0);
|
||||
const amountClaimed = ref(0);
|
||||
async function onFetch(rows) {
|
||||
amount.value = rows.reduce(
|
||||
(acumulator, { sale }) => acumulator + sale.price * sale.quantity,
|
||||
0
|
||||
);
|
||||
|
||||
amountClaimed.value = rows.reduce(
|
||||
(acumulator, line) => acumulator + line.sale.price * line.quantity,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
name: 'dated',
|
||||
label: t('Delivered'),
|
||||
field: ({ sale: { ticket } }) => toDate(ticket.landed),
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'quantity',
|
||||
label: t('Quantity'),
|
||||
field: ({ sale }) => sale.quantity,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'claimed',
|
||||
label: t('Claimed'),
|
||||
field: (row) => row.quantity,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: t('Description'),
|
||||
field: ({ sale }) => sale.concept,
|
||||
},
|
||||
{
|
||||
name: 'price',
|
||||
label: t('Price'),
|
||||
field: ({ sale }) => sale.price,
|
||||
format: (value) => toCurrency(value),
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'discount',
|
||||
label: t('Discount'),
|
||||
field: ({ sale }) => sale.discount,
|
||||
format: (value) => toPercentage(value / 100),
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'total',
|
||||
label: t('Total'),
|
||||
field: ({ sale }) => {
|
||||
const amount = sale.price * sale.quantity;
|
||||
const appliedDiscount = (sale.discount * amount) / 100;
|
||||
|
||||
return amount - appliedDiscount;
|
||||
},
|
||||
format: (value) => toCurrency(value),
|
||||
sortable: true,
|
||||
},
|
||||
]);
|
||||
|
||||
const selected = ref([]);
|
||||
const mana = ref(0);
|
||||
async function fetchMana() {
|
||||
const ticketId = claim.value.ticketFk;
|
||||
const response = await axios.get(`Tickets/${ticketId}/getSalesPersonMana`);
|
||||
mana.value = response.data;
|
||||
}
|
||||
|
||||
async function updateQuantity({ id, quantity }) {
|
||||
if (!id) return;
|
||||
await axios.patch(`ClaimBeginnings/${id}`, { quantity });
|
||||
}
|
||||
|
||||
async function updateDiscount({ saleFk, discount, canceller }) {
|
||||
const body = { salesIds: [saleFk], newDiscount: discount };
|
||||
const claimId = claim.value.ticketFk;
|
||||
const query = `Tickets/${claimId}/updateDiscount`;
|
||||
|
||||
await axios.post(query, body, {
|
||||
signal: canceller.signal,
|
||||
});
|
||||
}
|
||||
|
||||
function onUpdateDiscount(response) {
|
||||
const row = store.data[response.rowIndex];
|
||||
row.sale.discount = response.discount;
|
||||
quasar.notify({
|
||||
message: t('Discount updated'),
|
||||
type: 'positive',
|
||||
});
|
||||
}
|
||||
|
||||
async function confirmRemove() {
|
||||
const rows = selected.value;
|
||||
const count = rows.length;
|
||||
|
||||
if (count === 0) {
|
||||
return quasar.notify({
|
||||
message: 'You must select at least one row',
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
|
||||
quasar
|
||||
.dialog({
|
||||
component: VnConfirm,
|
||||
componentProps: {
|
||||
title: t('Delete claimed sales'),
|
||||
message: t('You are about to remove {count} rows', count, { count }),
|
||||
data: { rows },
|
||||
promise: remove,
|
||||
},
|
||||
})
|
||||
.onOk(() => {
|
||||
for (const row of rows) {
|
||||
const orgData = store.data;
|
||||
const index = orgData.findIndex((item) => item.id === row.id);
|
||||
store.data.splice(index, 1);
|
||||
selected.value = [];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function remove({ rows }) {
|
||||
if (!rows.length) return;
|
||||
const body = { deletes: rows.map((row) => row.id) };
|
||||
await axios.post(`ClaimBeginnings/crud`, body);
|
||||
quasar.notify({
|
||||
type: 'positive',
|
||||
message: t('globals.rowRemoved'),
|
||||
});
|
||||
}
|
||||
|
||||
function showImportDialog() {
|
||||
quasar
|
||||
.dialog({
|
||||
component: ClaimLinesImport,
|
||||
})
|
||||
.onOk(() => arrayData.refresh());
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<QPageSticky position="top" :offset="[0, 0]" expand>
|
||||
<QToolbar class="bg-dark text-white">
|
||||
<QToolbarTitle> {{ t('Claimed lines') }} </QToolbarTitle>
|
||||
<QSpace />
|
||||
<div class="row q-gutter-md">
|
||||
<div>
|
||||
{{ t('Amount') }}
|
||||
<QChip :dense="$q.screen.lt.sm">
|
||||
{{ toCurrency(amount) }}
|
||||
</QChip>
|
||||
</div>
|
||||
<QSeparator dark vertical />
|
||||
<div>
|
||||
{{ t('Amount Claimed') }}
|
||||
<QChip color="positive" :dense="$q.screen.lt.sm">
|
||||
{{ toCurrency(amountClaimed) }}
|
||||
</QChip>
|
||||
</div>
|
||||
</div>
|
||||
</QToolbar>
|
||||
</QPageSticky>
|
||||
|
||||
<FetchData
|
||||
:url="`Claims/${route.params.id}`"
|
||||
:filter="claimFilter"
|
||||
@on-fetch="onFetchClaim"
|
||||
auto-load
|
||||
/>
|
||||
<div class="column items-center">
|
||||
<div class="list">
|
||||
<VnPaginate
|
||||
data-key="ClaimLines"
|
||||
:url="`Claims/${route.params.id}/lines`"
|
||||
:filter="linesFilter"
|
||||
@on-fetch="onFetch"
|
||||
auto-load
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<QTable
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:dense="$q.screen.lt.md"
|
||||
:pagination="{ rowsPerPage: 0 }"
|
||||
row-key="id"
|
||||
selection="multiple"
|
||||
v-model:selected="selected"
|
||||
hide-pagination
|
||||
:grid="$q.screen.lt.md"
|
||||
>
|
||||
<template #body-cell-claimed="{ row, value }">
|
||||
<QTd auto-width align="right" class="text-primary">
|
||||
<span>{{ value }}</span>
|
||||
|
||||
<QPopupEdit
|
||||
v-model="row.quantity"
|
||||
v-slot="scope"
|
||||
:title="t('Claimed quantity')"
|
||||
@update:model-value="updateQuantity(row)"
|
||||
buttons
|
||||
>
|
||||
<QInput
|
||||
v-model="scope.value"
|
||||
type="number"
|
||||
dense
|
||||
autofocus
|
||||
@keyup.enter="scope.set"
|
||||
@focus="($event) => $event.target.select()"
|
||||
/>
|
||||
</QPopupEdit>
|
||||
</QTd>
|
||||
</template>
|
||||
|
||||
<template #body-cell-discount="{ row, value, rowIndex }">
|
||||
<QTd auto-width align="right" class="text-primary">
|
||||
{{ value }}
|
||||
<VnDiscount
|
||||
:quantity="row.quantity"
|
||||
:price="row.sale.price"
|
||||
:discount="row.sale.discount"
|
||||
:mana="mana"
|
||||
:promise="updateDiscount"
|
||||
:data="{ saleFk: row.sale.id, rowIndex: rowIndex }"
|
||||
@on-update="onUpdateDiscount"
|
||||
/>
|
||||
</QTd>
|
||||
</template>
|
||||
<!-- View for grid mode -->
|
||||
<template #item="props">
|
||||
<div
|
||||
class="q-mb-md col-12 grid-style-transition"
|
||||
:style="props.selected ? 'transform: scale(0.95);' : ''"
|
||||
>
|
||||
<QCard>
|
||||
<QCardSection>
|
||||
<QCheckbox v-model="props.selected" />
|
||||
</QCardSection>
|
||||
<QSeparator inset />
|
||||
<QList dense>
|
||||
<QItem
|
||||
v-for="column of props.cols"
|
||||
:key="column.name"
|
||||
>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ column.label }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection side>
|
||||
<template
|
||||
v-if="column.name === 'claimed'"
|
||||
>
|
||||
<QItemLabel class="text-primary">
|
||||
{{ column.value }}
|
||||
<QPopupEdit
|
||||
v-model="props.row.quantity"
|
||||
v-slot="scope"
|
||||
:title="t('Claimed quantity')"
|
||||
@update:model-value="
|
||||
updateQuantity(props.row)
|
||||
"
|
||||
buttons
|
||||
>
|
||||
<QInput
|
||||
v-model="scope.value"
|
||||
type="number"
|
||||
dense
|
||||
autofocus
|
||||
@keyup.enter="scope.set"
|
||||
@focus="
|
||||
($event) =>
|
||||
$event.target.select()
|
||||
"
|
||||
/>
|
||||
</QPopupEdit>
|
||||
</QItemLabel>
|
||||
</template>
|
||||
<template
|
||||
v-else-if="column.name === 'discount'"
|
||||
>
|
||||
<QItemLabel class="text-primary">
|
||||
{{ column.value }}
|
||||
<VnDiscount
|
||||
:quantity="props.row.quantity"
|
||||
:price="props.row.sale.price"
|
||||
:discount="
|
||||
props.row.sale.discount
|
||||
"
|
||||
:mana="mana"
|
||||
:promise="updateDiscount"
|
||||
:data="{
|
||||
saleFk: props.row.sale.id,
|
||||
rowIndex: props.rowIndex,
|
||||
}"
|
||||
@on-update="onUpdateDiscount"
|
||||
/>
|
||||
</QItemLabel>
|
||||
</template>
|
||||
<template v-else>
|
||||
<QItemLabel>
|
||||
{{ column.value }}
|
||||
</QItemLabel>
|
||||
</template>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QCard>
|
||||
</div>
|
||||
</template>
|
||||
</QTable>
|
||||
</template>
|
||||
</VnPaginate>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Teleport
|
||||
v-if="stateStore.isHeaderMounted() && !$q.screen.lt.sm"
|
||||
to="#actions-prepend"
|
||||
>
|
||||
<div class="row q-gutter-x-sm">
|
||||
<QBtn
|
||||
v-if="selected.length > 0"
|
||||
@click="confirmRemove"
|
||||
icon="delete"
|
||||
color="primary"
|
||||
flat
|
||||
dense
|
||||
rounded
|
||||
>
|
||||
<QTooltip bottom> {{ t('globals.remove') }} </QTooltip>
|
||||
</QBtn>
|
||||
<QBtn @click="showImportDialog" icon="add" color="primary" flat dense rounded>
|
||||
<QTooltip bottom> {{ t('globals.add') }} </QTooltip>
|
||||
</QBtn>
|
||||
<QSeparator vertical />
|
||||
</div>
|
||||
</Teleport>
|
||||
<!-- v-if="quasar.platform.is.mobile" -->
|
||||
<QPageSticky v-if="$q.screen.lt.sm" position="bottom" :offset="[0, 0]" expand>
|
||||
<QToolbar class="bg-primary text-white q-pa-none">
|
||||
<QTabs class="full-width" align="justify" inline-label narrow-indicator>
|
||||
<QTab @click="showImportDialog" icon="add" :label="t('globals.add')" />
|
||||
<QSeparator vertical inset />
|
||||
<QTab
|
||||
@click="confirmRemove"
|
||||
icon="delete"
|
||||
:label="t('globals.remove')"
|
||||
:disable="selected.length === 0"
|
||||
/>
|
||||
</QTabs>
|
||||
</QToolbar>
|
||||
</QPageSticky>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.list {
|
||||
padding-top: 50px;
|
||||
max-width: 900px;
|
||||
width: 100%;
|
||||
}
|
||||
.grid-style-transition {
|
||||
transition: transform 0.28s, background-color 0.28s;
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
en:
|
||||
You are about to remove {count} rows: '
|
||||
You are about to remove <strong>{count}</strong> row |
|
||||
You are about to remove <strong>{count}</strong> rows'
|
||||
es:
|
||||
Claimed lines: Líneas reclamadas
|
||||
Delivered: Entregado
|
||||
Quantity: Cantidad
|
||||
Claimed: Reclamada
|
||||
Description: Descripción
|
||||
Price: Precio
|
||||
Discount: Descuento
|
||||
Actions: Acciones
|
||||
Amount: Total
|
||||
Amount Claimed: Cantidad reclamada
|
||||
Delete claimed sales: Eliminar ventas reclamadas
|
||||
Discount updated: Descuento actualizado
|
||||
Claimed quantity: Cantidad reclamada
|
||||
You are about to remove {count} rows: '
|
||||
Vas a eliminar <strong>{count}</strong> línea |
|
||||
Vas a eliminar <strong>{count}</strong> líneas'
|
||||
</i18n>
|
|
@ -0,0 +1,182 @@
|
|||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useQuasar, useDialogPluginComponent } from 'quasar';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import { toDate, toCurrency, toPercentage } from 'filters/index';
|
||||
import axios from 'axios';
|
||||
|
||||
defineEmits([...useDialogPluginComponent.emits]);
|
||||
|
||||
const { dialogRef, onDialogOK, onDialogCancel } = useDialogPluginComponent();
|
||||
const route = useRoute();
|
||||
const quasar = useQuasar();
|
||||
const { t } = useI18n();
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
name: 'delivered',
|
||||
label: t('Delivered'),
|
||||
field: (row) => row.landed,
|
||||
format: (value) => toDate(value),
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'quantity',
|
||||
label: t('Quantity'),
|
||||
field: (row) => row.quantity,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: t('Description'),
|
||||
field: (row) => row.concept,
|
||||
},
|
||||
{
|
||||
name: 'price',
|
||||
label: t('Price'),
|
||||
field: (row) => row.price,
|
||||
format: (value) => toCurrency(value),
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'discount',
|
||||
label: t('Discount'),
|
||||
field: (row) => row.discount,
|
||||
format: (value) => toPercentage(value),
|
||||
sortable: true,
|
||||
},
|
||||
]);
|
||||
|
||||
const selected = ref([]);
|
||||
const claimableSales = ref([]);
|
||||
const isLoading = ref(false);
|
||||
let canceller;
|
||||
|
||||
async function importLines() {
|
||||
const sales = selected.value;
|
||||
|
||||
if (!sales.length) {
|
||||
return quasar.notify({
|
||||
message: 'You must select at least one',
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
|
||||
const body = sales.map((row) => ({
|
||||
claimFk: route.params.id,
|
||||
saleFk: row.saleFk,
|
||||
quantity: row.quantity,
|
||||
}));
|
||||
|
||||
canceller = new AbortController();
|
||||
isLoading.value = true;
|
||||
|
||||
const { data } = await axios.post('ClaimBeginnings', body, {
|
||||
signal: canceller.signal,
|
||||
});
|
||||
|
||||
quasar.notify({
|
||||
message: 'Lines added to claim',
|
||||
type: 'positive',
|
||||
});
|
||||
|
||||
onDialogOK(data);
|
||||
|
||||
canceller = null;
|
||||
isLoading.value = false;
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
if (canceller) {
|
||||
canceller.abort();
|
||||
canceller = null;
|
||||
}
|
||||
|
||||
onDialogCancel();
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<FetchData
|
||||
url="Sales/getClaimableFromTicket?ticketFk=16"
|
||||
@on-fetch="(data) => (claimableSales = data)"
|
||||
auto-load
|
||||
/>
|
||||
<QDialog ref="dialogRef" persistent>
|
||||
<QCard>
|
||||
<QCardSection class="row items-center">
|
||||
<span class="text-h6 text-grey">{{ t('Available sales lines') }}</span>
|
||||
<QSpace />
|
||||
<QBtn icon="close" flat round dense v-close-popup />
|
||||
</QCardSection>
|
||||
<QTable
|
||||
class="my-sticky-header-table"
|
||||
:columns="columns"
|
||||
:rows="claimableSales"
|
||||
:pagination="{ rowsPerPage: 10 }"
|
||||
row-key="saleFk"
|
||||
selection="multiple"
|
||||
v-model:selected="selected"
|
||||
square
|
||||
flat
|
||||
/>
|
||||
<QSeparator />
|
||||
<QCardActions align="right">
|
||||
<QBtn :label="t('globals.cancel')" color="primary" flat @click="cancel" />
|
||||
<QBtn
|
||||
:label="t('globals.confirm')"
|
||||
color="primary"
|
||||
:loading="isLoading"
|
||||
@click="importLines"
|
||||
unelevated
|
||||
/>
|
||||
</QCardActions>
|
||||
</QCard>
|
||||
</QDialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.q-card {
|
||||
max-width: 800px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.my-sticky-header-table {
|
||||
height: 400px;
|
||||
|
||||
thead tr th {
|
||||
position: sticky;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
thead tr:first-child th {
|
||||
/* this is when the loading indicator appears */
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&.q-table--loading thead tr:last-child th {
|
||||
/* height of all previous header rows */
|
||||
top: 48px;
|
||||
}
|
||||
|
||||
// /* prevent scrolling behind sticky top row on focus */
|
||||
tbody {
|
||||
/* height of all previous header rows */
|
||||
scroll-margin-top: 48px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Available sales lines: Líneas de venta disponibles
|
||||
Delivered: Entrega
|
||||
Quantity: Cantidad
|
||||
Description: Descripción
|
||||
Price: Precio
|
||||
Discount: Descuento
|
||||
Lines added to claim: Lineas añadidas a la reclamación
|
||||
You must select at least one: Debes seleccionar al menos una
|
||||
</i18n>
|
|
@ -3,7 +3,7 @@ import { useI18n } from 'vue-i18n';
|
|||
import { useRoute } from 'vue-router';
|
||||
import { useSession } from 'src/composables/useSession';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import Paginate from 'src/components/PaginateData.vue';
|
||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||
import ClaimLogFilter from './ClaimLogFilter.vue';
|
||||
|
||||
import { toDate } from 'src/filters';
|
||||
|
@ -57,9 +57,9 @@ function actionColor(action) {
|
|||
</script>
|
||||
<template>
|
||||
<div class="column items-center">
|
||||
<q-timeline class="q-pa-md">
|
||||
<q-timeline-entry heading tag="h4"> {{ t('Audit logs') }} </q-timeline-entry>
|
||||
<Paginate
|
||||
<QTimeline class="q-pa-md">
|
||||
<QTimelineEntry heading tag="h4"> {{ t('Audit logs') }} </QTimelineEntry>
|
||||
<VnPaginate
|
||||
data-key="ClaimLogs"
|
||||
:url="`Claims/${route.params.id}/logs`"
|
||||
order="id DESC"
|
||||
|
@ -69,7 +69,7 @@ function actionColor(action) {
|
|||
>
|
||||
<template #body="{ rows }">
|
||||
<template v-for="log of rows" :key="log.id">
|
||||
<q-timeline-entry
|
||||
<QTimelineEntry
|
||||
:avatar="`/api/Images/user/160x160/${log.userFk}/download?access_token=${token}`"
|
||||
>
|
||||
<template #subtitle>
|
||||
|
@ -82,12 +82,12 @@ function actionColor(action) {
|
|||
}}
|
||||
</template>
|
||||
<template #title>
|
||||
<q-chip :color="actionColor(log.action)">
|
||||
<QChip :color="actionColor(log.action)">
|
||||
{{ t(`actions.${log.action}`) }}
|
||||
</q-chip>
|
||||
</QChip>
|
||||
{{ t(`models.${log.model}`) }}
|
||||
</template>
|
||||
<q-table
|
||||
<QTable
|
||||
:rows="log.changes"
|
||||
:columns="columns"
|
||||
row-key="property"
|
||||
|
@ -96,37 +96,37 @@ function actionColor(action) {
|
|||
flat
|
||||
>
|
||||
<template #header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th
|
||||
<QTr :props="props">
|
||||
<QTh
|
||||
v-for="col in props.cols"
|
||||
:key="col.name"
|
||||
:props="props"
|
||||
>
|
||||
{{ t(col.label) }}
|
||||
</q-th>
|
||||
</q-tr>
|
||||
</QTh>
|
||||
</QTr>
|
||||
</template>
|
||||
</q-table>
|
||||
</q-timeline-entry>
|
||||
</QTable>
|
||||
</QTimelineEntry>
|
||||
</template>
|
||||
</template>
|
||||
</Paginate>
|
||||
</q-timeline>
|
||||
</VnPaginate>
|
||||
</QTimeline>
|
||||
</div>
|
||||
<Teleport v-if="stateStore.isHeaderMounted()" to="#actions-append">
|
||||
<div class="row q-gutter-x-sm">
|
||||
<q-btn flat @click="stateStore.toggleRightDrawer()" round dense icon="menu">
|
||||
<q-tooltip bottom anchor="bottom right">
|
||||
<QBtn flat @click="stateStore.toggleRightDrawer()" round dense icon="menu">
|
||||
<QTooltip bottom anchor="bottom right">
|
||||
{{ t('globals.collapseMenu') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</div>
|
||||
</Teleport>
|
||||
<q-drawer v-model="stateStore.rightDrawer" show-if-above side="right" :width="300">
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<QDrawer v-model="stateStore.rightDrawer" show-if-above side="right" :width="300">
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<ClaimLogFilter data-key="ClaimLogs" />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -16,7 +16,7 @@ const workers = ref();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<fetch-data
|
||||
<FetchData
|
||||
url="Workers/activeWithInheritedRole"
|
||||
:filter="{ where: { role: 'salesPerson' } }"
|
||||
@on-fetch="(data) => (workers = data)"
|
||||
|
@ -30,22 +30,22 @@ const workers = ref();
|
|||
</div>
|
||||
</template>
|
||||
<template #body="{ params, searchFn }">
|
||||
<q-date
|
||||
<QDate
|
||||
v-model="params.created"
|
||||
@update:model-value="searchFn()"
|
||||
dense
|
||||
flat
|
||||
minimal
|
||||
>
|
||||
</q-date>
|
||||
<q-list dense>
|
||||
<q-separator />
|
||||
<q-item>
|
||||
<q-item-section v-if="!workers">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="workers">
|
||||
<q-select
|
||||
</QDate>
|
||||
<QList dense>
|
||||
<QSeparator />
|
||||
<QItem>
|
||||
<QItemSection v-if="!workers">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="workers">
|
||||
<QSelect
|
||||
:label="t('User')"
|
||||
v-model="params.userFk"
|
||||
@update:model-value="searchFn()"
|
||||
|
@ -57,9 +57,9 @@ const workers = ref();
|
|||
use-input
|
||||
:input-debounce="0"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</template>
|
||||
</VnFilterPanel>
|
||||
</template>
|
||||
|
|
|
@ -147,7 +147,7 @@ function onDrag() {
|
|||
}
|
||||
</script>
|
||||
<template>
|
||||
<fetch-data
|
||||
<FetchData
|
||||
url="Claims"
|
||||
:filter="claimDmsFilter"
|
||||
@on-fetch="([data]) => setClaimDms(data)"
|
||||
|
@ -155,13 +155,13 @@ function onDrag() {
|
|||
auto-load
|
||||
ref="claimDmsRef"
|
||||
/>
|
||||
<fetch-data
|
||||
<FetchData
|
||||
url="DmsTypes/findOne"
|
||||
:filter="{ where: { code: 'claim' } }"
|
||||
@on-fetch="(data) => (dmsType = data)"
|
||||
auto-load
|
||||
/>
|
||||
<fetch-data
|
||||
<FetchData
|
||||
url="UserConfigs/getUserConfig"
|
||||
@on-fetch="(data) => (config = data)"
|
||||
auto-load
|
||||
|
@ -176,7 +176,7 @@ function onDrag() {
|
|||
class="flex flex-center items-center text-grey q-mt-md column"
|
||||
v-if="dragFile"
|
||||
>
|
||||
<q-icon size="xl" name="file_download" />
|
||||
<QIcon size="xl" name="file_download" />
|
||||
<h5>
|
||||
{{ t('claim.photo.dragDrop') }}
|
||||
</h5>
|
||||
|
@ -186,8 +186,8 @@ function onDrag() {
|
|||
v-if="!claimDms?.length && !dragFile"
|
||||
@click="inputFile.nativeEl.click()"
|
||||
>
|
||||
<q-icon size="xl" name="image"></q-icon>
|
||||
<q-icon size="xl" name="movie"></q-icon>
|
||||
<QIcon size="xl" name="image"></QIcon>
|
||||
<QIcon size="xl" name="movie"></QIcon>
|
||||
<h5>
|
||||
{{ t('claim.photo.noData') }}
|
||||
</h5>
|
||||
|
@ -198,7 +198,7 @@ function onDrag() {
|
|||
:key="index"
|
||||
class="relative-position"
|
||||
>
|
||||
<q-btn
|
||||
<QBtn
|
||||
icon="delete"
|
||||
color="primary"
|
||||
text-color="white"
|
||||
|
@ -207,7 +207,7 @@ function onDrag() {
|
|||
@click.stop="viewDeleteDms(index)"
|
||||
round
|
||||
/>
|
||||
<q-icon
|
||||
<QIcon
|
||||
name="play_circle"
|
||||
color="primary"
|
||||
size="xl"
|
||||
|
@ -215,16 +215,16 @@ function onDrag() {
|
|||
v-if="media.isVideo"
|
||||
@click.stop="openDialog(media.dmsFk)"
|
||||
>
|
||||
<q-tooltip>Video</q-tooltip>
|
||||
</q-icon>
|
||||
<q-card class="multimedia relative-position">
|
||||
<q-img
|
||||
<QTooltip>Video</QTooltip>
|
||||
</QIcon>
|
||||
<QCard class="multimedia relative-position">
|
||||
<QImg
|
||||
:src="media.url"
|
||||
class="rounded-borders cursor-pointer fit"
|
||||
@click="openDialog(media.dmsFk)"
|
||||
v-if="!media.isVideo"
|
||||
>
|
||||
</q-img>
|
||||
</QImg>
|
||||
<video
|
||||
:src="media.url"
|
||||
class="rounded-borders cursor-pointer fit"
|
||||
|
@ -232,7 +232,7 @@ function onDrag() {
|
|||
v-if="media.isVideo"
|
||||
@click="openDialog(media.dmsFk)"
|
||||
/>
|
||||
</q-card>
|
||||
</QCard>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -243,14 +243,14 @@ function onDrag() {
|
|||
>
|
||||
<div class="row q-gutter-x-sm">
|
||||
<label for="fileInput">
|
||||
<q-btn
|
||||
<QBtn
|
||||
@click="inputFile.nativeEl.click()"
|
||||
icon="add"
|
||||
color="primary"
|
||||
dense
|
||||
rounded
|
||||
>
|
||||
<q-input
|
||||
<QInput
|
||||
ref="inputFile"
|
||||
type="file"
|
||||
style="display: none"
|
||||
|
@ -258,27 +258,27 @@ function onDrag() {
|
|||
v-model="files"
|
||||
@update:model-value="create()"
|
||||
/>
|
||||
<q-tooltip bottom> {{ t('globals.add') }} </q-tooltip>
|
||||
</q-btn>
|
||||
<QTooltip bottom> {{ t('globals.add') }} </QTooltip>
|
||||
</QBtn>
|
||||
</label>
|
||||
<q-separator vertical />
|
||||
<QSeparator vertical />
|
||||
</div>
|
||||
</Teleport>
|
||||
|
||||
<q-page-sticky
|
||||
<QPageSticky
|
||||
v-if="quasar.platform.is.mobile"
|
||||
position="bottom"
|
||||
:offset="[0, 0]"
|
||||
expand
|
||||
>
|
||||
<q-toolbar class="bg-primary text-white q-pa-none">
|
||||
<q-tabs class="full-width" align="justify" inline-label narrow-indicator>
|
||||
<q-tab
|
||||
<QToolbar class="bg-primary text-white q-pa-none">
|
||||
<QTabs class="full-width" align="justify" inline-label narrow-indicator>
|
||||
<QTab
|
||||
@click="inputFile.nativeEl.click()"
|
||||
icon="add_circle"
|
||||
:label="t('globals.add')"
|
||||
>
|
||||
<q-input
|
||||
<QInput
|
||||
ref="inputFile"
|
||||
type="file"
|
||||
style="display: none"
|
||||
|
@ -286,29 +286,29 @@ function onDrag() {
|
|||
v-model="files"
|
||||
@update:model-value="create()"
|
||||
/>
|
||||
<q-tooltip bottom> {{ t('globals.add') }} </q-tooltip>
|
||||
</q-tab>
|
||||
</q-tabs>
|
||||
</q-toolbar>
|
||||
</q-page-sticky>
|
||||
<QTooltip bottom> {{ t('globals.add') }} </QTooltip>
|
||||
</QTab>
|
||||
</QTabs>
|
||||
</QToolbar>
|
||||
</QPageSticky>
|
||||
|
||||
<!-- MULTIMEDIA DIALOG START-->
|
||||
<q-dialog
|
||||
<QDialog
|
||||
v-model="multimediaDialog"
|
||||
transition-show="slide-up"
|
||||
transition-hide="slide-down"
|
||||
>
|
||||
<q-toolbar class="absolute zindex close-button">
|
||||
<q-space />
|
||||
<q-btn icon="close" color="primary" round dense v-close-popup />
|
||||
</q-toolbar>
|
||||
<q-carousel swipeable animated v-model="multimediaSlide" arrows class="fit">
|
||||
<q-carousel-slide
|
||||
<QToolbar class="absolute zindex close-button">
|
||||
<QSpace />
|
||||
<QBtn icon="close" color="primary" round dense v-close-popup />
|
||||
</QToolbar>
|
||||
<QCarousel swipeable animated v-model="multimediaSlide" arrows class="fit">
|
||||
<QCarouselSlide
|
||||
v-for="media of claimDms"
|
||||
:key="media.dmsFk"
|
||||
:name="media.dmsFk"
|
||||
>
|
||||
<q-img
|
||||
<QImg
|
||||
:src="media.url"
|
||||
class="fit"
|
||||
fit="scale-down"
|
||||
|
@ -317,9 +317,9 @@ function onDrag() {
|
|||
<video class="q-ma-none fit" v-if="media.isVideo" controls muted autoplay>
|
||||
<source :src="media.url" type="video/mp4" />
|
||||
</video>
|
||||
</q-carousel-slide>
|
||||
</q-carousel>
|
||||
</q-dialog>
|
||||
</QCarouselSlide>
|
||||
</QCarousel>
|
||||
</QDialog>
|
||||
<!-- MULTIMEDIA DIALOG END-->
|
||||
</template>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import { useQuasar } from 'quasar';
|
|||
import { useRoute } from 'vue-router';
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import Paginate from 'src/components/PaginateData.vue';
|
||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||
|
||||
|
@ -86,7 +86,7 @@ async function remove({ id }) {
|
|||
}
|
||||
</script>
|
||||
<template>
|
||||
<fetch-data
|
||||
<FetchData
|
||||
:url="`Claims/${route.params.id}`"
|
||||
:filter="claimFilter"
|
||||
@on-fetch="onFetch"
|
||||
|
@ -94,56 +94,56 @@ async function remove({ id }) {
|
|||
/>
|
||||
<div class="column items-center">
|
||||
<div class="list">
|
||||
<paginate data-key="ClaimRma" url="ClaimRmas">
|
||||
<VnPaginate data-key="ClaimRma" url="ClaimRmas">
|
||||
<template #body="{ rows }">
|
||||
<q-card class="card">
|
||||
<QCard class="card">
|
||||
<template v-for="(row, index) of rows" :key="row.id">
|
||||
<q-item class="q-pa-none items-start">
|
||||
<q-item-section class="q-pa-md">
|
||||
<q-list>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<QItem class="q-pa-none items-start">
|
||||
<QItemSection class="q-pa-md">
|
||||
<QList>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.rma.user') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ row.worker.user.name }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.rma.created') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{
|
||||
toDate(row.created, {
|
||||
timeStyle: 'medium',
|
||||
})
|
||||
}}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-item-section>
|
||||
<q-card-actions vertical class="justify-between">
|
||||
<q-btn
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QItemSection>
|
||||
<QCardActions vertical class="justify-between">
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="orange"
|
||||
icon="vn:bin"
|
||||
@click="confirmRemove(row.id)"
|
||||
>
|
||||
<q-tooltip>{{ t('globals.remove') }}</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-item>
|
||||
<q-separator v-if="index !== rows.length - 1" />
|
||||
<QTooltip>{{ t('globals.remove') }}</QTooltip>
|
||||
</QBtn>
|
||||
</QCardActions>
|
||||
</QItem>
|
||||
<QSeparator v-if="index !== rows.length - 1" />
|
||||
</template>
|
||||
</q-card>
|
||||
</QCard>
|
||||
</template>
|
||||
</paginate>
|
||||
</VnPaginate>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -152,25 +152,25 @@ async function remove({ id }) {
|
|||
to="#actions-prepend"
|
||||
>
|
||||
<div class="row q-gutter-x-sm">
|
||||
<q-btn @click="addRow()" icon="add" color="primary" dense rounded>
|
||||
<q-tooltip bottom> {{ t('globals.add') }} </q-tooltip>
|
||||
</q-btn>
|
||||
<q-separator vertical />
|
||||
<QBtn @click="addRow()" icon="add" color="primary" dense rounded>
|
||||
<QTooltip bottom> {{ t('globals.add') }} </QTooltip>
|
||||
</QBtn>
|
||||
<QSeparator vertical />
|
||||
</div>
|
||||
</Teleport>
|
||||
|
||||
<q-page-sticky
|
||||
<QPageSticky
|
||||
v-if="quasar.platform.is.mobile"
|
||||
position="bottom"
|
||||
:offset="[0, 0]"
|
||||
expand
|
||||
>
|
||||
<q-toolbar class="bg-primary text-white q-pa-none">
|
||||
<q-tabs class="full-width" align="justify" inline-label narrow-indicator>
|
||||
<q-tab @click="addRow()" icon="add_circle" :label="t('globals.add')" />
|
||||
</q-tabs>
|
||||
</q-toolbar>
|
||||
</q-page-sticky>
|
||||
<QToolbar class="bg-primary text-white q-pa-none">
|
||||
<QTabs class="full-width" align="justify" inline-label narrow-indicator>
|
||||
<QTab @click="addRow()" icon="add_circle" :label="t('globals.add')" />
|
||||
</QTabs>
|
||||
</QToolbar>
|
||||
</QPageSticky>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -5,9 +5,13 @@ import { useI18n } from 'vue-i18n';
|
|||
import { toDate, toCurrency } from 'src/filters';
|
||||
import CardSummary from 'components/ui/CardSummary.vue';
|
||||
import WorkerDescriptorProxy from 'pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import { useSession } from 'src/composables/useSession';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
const session = useSession();
|
||||
const token = session.getToken();
|
||||
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
|
@ -76,90 +80,219 @@ function stateColor(code) {
|
|||
if (code === 'managed') return 'orange';
|
||||
if (code === 'resolved') return 'red';
|
||||
}
|
||||
|
||||
const developmentColumns = ref([
|
||||
{
|
||||
name: 'claimReason',
|
||||
label: 'claim.summary.reason',
|
||||
field: (row) => row.claimReason.description,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'claimResult',
|
||||
label: 'claim.summary.result',
|
||||
field: (row) => row.claimResult.description,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'claimResponsible',
|
||||
label: 'claim.summary.responsible',
|
||||
field: (row) => row.claimResponsible.description,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'worker',
|
||||
label: 'claim.summary.worker',
|
||||
field: (row) => row.worker.user.nickname,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'claimRedelivery',
|
||||
label: 'claim.summary.redelivery',
|
||||
field: (row) => row.claimRedelivery.description,
|
||||
sortable: true,
|
||||
},
|
||||
]);
|
||||
const claimDms = ref([]);
|
||||
const multimediaDialog = ref();
|
||||
const multimediaSlide = ref();
|
||||
const claimDmsFilter = ref({
|
||||
include: [
|
||||
{
|
||||
relation: 'dms',
|
||||
},
|
||||
],
|
||||
where: { claimFk: entityId.value },
|
||||
});
|
||||
|
||||
function setClaimDms(data) {
|
||||
if (!data) return;
|
||||
|
||||
data.forEach((media) => {
|
||||
claimDms.value.push({
|
||||
isVideo: media.dms.contentType == 'video/mp4',
|
||||
url: `/api/Claims/${media.dmsFk}/downloadFile?access_token=${token}`,
|
||||
dmsFk: media.dmsFk,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function openDialog(dmsId) {
|
||||
multimediaSlide.value = dmsId;
|
||||
multimediaDialog.value = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<card-summary ref="summary" :url="`Claims/${entityId}/getSummary`">
|
||||
<FetchData
|
||||
url="ClaimDms"
|
||||
:filter="claimDmsFilter"
|
||||
@on-fetch="(data) => setClaimDms(data)"
|
||||
limit="20"
|
||||
auto-load
|
||||
/>
|
||||
<CardSummary ref="summary" :url="`Claims/${entityId}/getSummary`">
|
||||
<template #header="{ entity: { claim } }">
|
||||
{{ claim.id }} - {{ claim.client.name }}
|
||||
</template>
|
||||
<template #body="{ entity: { claim, salesClaimed } }">
|
||||
<q-card-section class="row q-pa-none q-col-gutter-md">
|
||||
<template #body="{ entity: { developments, observations, claim, salesClaimed } }">
|
||||
<QCardSection class="row q-pa-none q-col-gutter-md">
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.summary.created') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ toDate(claim.created) }}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section v-if="claim.claimState">
|
||||
<q-item-label caption>{{
|
||||
t('claim.summary.state')
|
||||
}}</q-item-label>
|
||||
<q-item-label>
|
||||
<q-chip
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ toDate(claim.created) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection v-if="claim.claimState">
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.summary.state') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
<QChip
|
||||
:color="stateColor(claim.claimState.code)"
|
||||
dense
|
||||
>
|
||||
{{ claim.claimState.description }}
|
||||
</q-chip>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="claim.worker && claim.worker.user">
|
||||
<q-item-label caption>
|
||||
</QChip>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="claim.worker && claim.worker.user">
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.summary.assignedTo') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
<span class="link">
|
||||
{{ claim.worker.user.nickname }}
|
||||
<WorkerDescriptorProxy :id="claim.workerFk" />
|
||||
</span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection
|
||||
v-if="claim.client && claim.client.salesPersonUser"
|
||||
>
|
||||
<q-item-label caption>
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.summary.attendedBy') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
<span class="link">
|
||||
{{ claim.client.salesPersonUser.name }}
|
||||
<WorkerDescriptorProxy
|
||||
:id="claim.client.salesPersonFk"
|
||||
/>
|
||||
</span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-md">
|
||||
</QCardSection>
|
||||
<QCardSection class="q-pa-md" v-if="observations.length > 0">
|
||||
<h6>{{ t('claim.summary.notes') }}</h6>
|
||||
<div class="note-list" v-for="note in observations" :key="note.id">
|
||||
<div class="note-caption">
|
||||
<span
|
||||
>{{ note.worker.firstName }} {{ note.worker.lastName }}
|
||||
</span>
|
||||
<span>{{ toDate(note.created) }}</span>
|
||||
</div>
|
||||
<div class="note-text">
|
||||
<span>{{ note.text }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</QCardSection>
|
||||
<QCardSection class="q-pa-md" v-if="salesClaimed.length > 0">
|
||||
<h6>{{ t('claim.summary.details') }}</h6>
|
||||
<q-table :columns="detailsColumns" :rows="salesClaimed" flat>
|
||||
<QTable :columns="detailsColumns" :rows="salesClaimed" flat>
|
||||
<template #header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th
|
||||
v-for="col in props.cols"
|
||||
:key="col.name"
|
||||
:props="props"
|
||||
>
|
||||
<QTr :props="props">
|
||||
<QTh v-for="col in props.cols" :key="col.name" :props="props">
|
||||
{{ t(col.label) }}
|
||||
</q-th>
|
||||
</q-tr>
|
||||
</QTh>
|
||||
</QTr>
|
||||
</template>
|
||||
</q-table>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-md">
|
||||
</QTable>
|
||||
</QCardSection>
|
||||
<QCardSection class="q-pa-md" v-if="claimDms.length > 0">
|
||||
<h6>{{ t('claim.summary.photos') }}</h6>
|
||||
<div class="container">
|
||||
<div class="multimediaParent bg-transparent">
|
||||
<div
|
||||
v-for="(media, index) of claimDms"
|
||||
:key="index"
|
||||
class="relative-position"
|
||||
>
|
||||
<QIcon
|
||||
name="play_circle"
|
||||
color="primary"
|
||||
size="xl"
|
||||
class="absolute-center zindex"
|
||||
v-if="media.isVideo"
|
||||
@click.stop="openDialog(media.dmsFk)"
|
||||
>
|
||||
<QTooltip>Video</QTooltip>
|
||||
</QIcon>
|
||||
<QCard class="multimedia relative-position">
|
||||
<QImg
|
||||
:src="media.url"
|
||||
class="rounded-borders cursor-pointer fit"
|
||||
@click="openDialog(media.dmsFk)"
|
||||
v-if="!media.isVideo"
|
||||
>
|
||||
</QImg>
|
||||
<video
|
||||
:src="media.url"
|
||||
class="rounded-borders cursor-pointer fit"
|
||||
muted="muted"
|
||||
v-if="media.isVideo"
|
||||
@click="openDialog(media.dmsFk)"
|
||||
/>
|
||||
</QCard>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</QCardSection>
|
||||
<QCardSection class="q-pa-md" v-if="developments.length > 0">
|
||||
<h6>{{ t('claim.summary.development') }}</h6>
|
||||
<QTable :columns="developmentColumns" :rows="developments" flat>
|
||||
<template #header="props">
|
||||
<QTr :props="props">
|
||||
<QTh v-for="col in props.cols" :key="col.name" :props="props">
|
||||
{{ t(col.label) }}
|
||||
</QTh>
|
||||
</QTr>
|
||||
</template>
|
||||
</QTable>
|
||||
</QCardSection>
|
||||
<QCardSection class="q-pa-md">
|
||||
<h6>{{ t('claim.summary.actions') }}</h6>
|
||||
<q-separator />
|
||||
<QSeparator />
|
||||
<div id="slider-container">
|
||||
<q-slider
|
||||
<QSlider
|
||||
v-model="claim.responsibility"
|
||||
label
|
||||
:label-value="t('claim.summary.responsibility')"
|
||||
|
@ -175,7 +308,105 @@ function stateColor(code) {
|
|||
readonly
|
||||
/>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</QCardSection>
|
||||
<QDialog
|
||||
v-model="multimediaDialog"
|
||||
transition-show="slide-up"
|
||||
transition-hide="slide-down"
|
||||
>
|
||||
<QToolbar class="absolute zindex close-button">
|
||||
<QSpace />
|
||||
<QBtn icon="close" color="primary" round dense v-close-popup />
|
||||
</QToolbar>
|
||||
<QCarousel
|
||||
swipeable
|
||||
animated
|
||||
v-model="multimediaSlide"
|
||||
arrows
|
||||
class="fit"
|
||||
>
|
||||
<QCarouselSlide
|
||||
v-for="media of claimDms"
|
||||
:key="media.dmsFk"
|
||||
:name="media.dmsFk"
|
||||
>
|
||||
<QImg
|
||||
:src="media.url"
|
||||
class="fit"
|
||||
fit="scale-down"
|
||||
v-if="!media.isVideo"
|
||||
/>
|
||||
<video
|
||||
class="q-ma-none fit"
|
||||
v-if="media.isVideo"
|
||||
controls
|
||||
muted
|
||||
autoplay
|
||||
>
|
||||
<source :src="media.url" type="video/mp4" />
|
||||
</video>
|
||||
</QCarouselSlide>
|
||||
</QCarousel>
|
||||
</QDialog>
|
||||
</template>
|
||||
</card-summary>
|
||||
</CardSummary>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
min-width: 80%;
|
||||
}
|
||||
.q-dialog__inner--minimized > div {
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.multimediaParent {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(500px, 1fr));
|
||||
|
||||
grid-auto-rows: auto;
|
||||
|
||||
grid-gap: 1rem;
|
||||
}
|
||||
|
||||
.multimedia {
|
||||
transition: all 0.5s;
|
||||
opacity: 1;
|
||||
height: 250px;
|
||||
|
||||
.q-img {
|
||||
object-fit: cover;
|
||||
background-color: black;
|
||||
}
|
||||
video {
|
||||
object-fit: cover;
|
||||
background-color: black;
|
||||
}
|
||||
}
|
||||
|
||||
.multimedia:hover {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
top: 1%;
|
||||
right: 10%;
|
||||
}
|
||||
|
||||
.zindex {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.note-list {
|
||||
width: 100%;
|
||||
border: 0.1rem solid $grey-7;
|
||||
padding: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.note-caption {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.5rem;
|
||||
color: $grey-7;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -15,9 +15,9 @@ const { dialogRef, onDialogHide } = useDialogPluginComponent();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog ref="dialogRef" @hide="onDialogHide">
|
||||
<claim-summary v-if="$props.id" :id="$props.id" />
|
||||
</q-dialog>
|
||||
<QDialog ref="dialogRef" @hide="onDialogHide">
|
||||
<ClaimSummary v-if="$props.id" :id="$props.id" />
|
||||
</QDialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
@ -17,8 +17,8 @@ const states = ref();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<fetch-data url="ClaimStates" @on-fetch="(data) => (states = data)" auto-load />
|
||||
<fetch-data
|
||||
<FetchData url="ClaimStates" @on-fetch="(data) => (states = data)" auto-load />
|
||||
<FetchData
|
||||
url="Workers/activeWithInheritedRole"
|
||||
:filter="{ where: { role: 'salesPerson' } }"
|
||||
@on-fetch="(data) => (workers = data)"
|
||||
|
@ -32,35 +32,35 @@ const states = ref();
|
|||
</div>
|
||||
</template>
|
||||
<template #body="{ params, searchFn }">
|
||||
<q-list dense>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
<QList dense>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('Customer ID')"
|
||||
v-model="params.clientFk"
|
||||
lazy-rules
|
||||
>
|
||||
<template #prepend>
|
||||
<q-icon name="badge" size="sm"></q-icon>
|
||||
<QIcon name="badge" size="sm"></QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('Client Name')"
|
||||
v-model="params.clientName"
|
||||
lazy-rules
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="!workers">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="workers">
|
||||
<q-select
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="!workers">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="workers">
|
||||
<QSelect
|
||||
:label="t('Salesperson')"
|
||||
v-model="params.salesPersonFk"
|
||||
@update:model-value="searchFn()"
|
||||
|
@ -72,14 +72,14 @@ const states = ref();
|
|||
use-input
|
||||
:input-debounce="0"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="!workers">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="workers">
|
||||
<q-select
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="!workers">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="workers">
|
||||
<QSelect
|
||||
:label="t('Attender')"
|
||||
v-model="params.attenderFk"
|
||||
@update:model-value="searchFn()"
|
||||
|
@ -91,14 +91,14 @@ const states = ref();
|
|||
use-input
|
||||
:input-debounce="0"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="!workers">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="workers">
|
||||
<q-select
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="!workers">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="workers">
|
||||
<QSelect
|
||||
:label="t('Responsible')"
|
||||
v-model="params.claimResponsibleFk"
|
||||
@update:model-value="searchFn()"
|
||||
|
@ -110,14 +110,14 @@ const states = ref();
|
|||
use-input
|
||||
:input-debounce="0"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-mb-md">
|
||||
<q-item-section v-if="!states">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="states">
|
||||
<q-select
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-mb-md">
|
||||
<QItemSection v-if="!states">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="states">
|
||||
<QSelect
|
||||
:label="t('State')"
|
||||
v-model="params.claimStateFk"
|
||||
@update:model-value="searchFn()"
|
||||
|
@ -127,13 +127,13 @@ const states = ref();
|
|||
emit-value
|
||||
map-options
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<q-expansion-item :label="t('More options')" expand-separator>
|
||||
<!-- <q-item>
|
||||
<q-item-section>
|
||||
<q-select
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QSeparator />
|
||||
<QExpansionItem :label="t('More options')" expand-separator>
|
||||
<!-- <QItem>
|
||||
<QItemSection>
|
||||
<qSelect
|
||||
:label="t('Item')"
|
||||
v-model="params.itemFk"
|
||||
:options="items"
|
||||
|
@ -145,41 +145,41 @@ const states = ref();
|
|||
emit-value
|
||||
map-options
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item> -->
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QItemSection>
|
||||
</QItem> -->
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
v-model="params.created"
|
||||
:label="t('Created')"
|
||||
autofocus
|
||||
readonly
|
||||
>
|
||||
<template #append>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy
|
||||
<QIcon name="event" class="cursor-pointer">
|
||||
<QPopupProxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-date v-model="params.created">
|
||||
<QDate v-model="params.created">
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn
|
||||
<QBtn
|
||||
v-close-popup
|
||||
label="Close"
|
||||
color="primary"
|
||||
flat
|
||||
/>
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</QDate>
|
||||
</QPopupProxy>
|
||||
</QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-expansion-item>
|
||||
</q-list>
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QExpansionItem>
|
||||
</QList>
|
||||
</template>
|
||||
</VnFilterPanel>
|
||||
</template>
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useRouter } from 'vue-router';
|
|||
import { useQuasar } from 'quasar';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { toDate } from 'filters/index';
|
||||
import Paginate from 'components/PaginateData.vue';
|
||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||
import ClaimSummaryDialog from './Card/ClaimSummaryDialog.vue';
|
||||
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
|
||||
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
||||
|
@ -46,143 +46,148 @@ function viewSummary(id) {
|
|||
</Teleport>
|
||||
<Teleport to="#actions-append">
|
||||
<div class="row q-gutter-x-sm">
|
||||
<q-btn
|
||||
<QBtn
|
||||
flat
|
||||
@click="stateStore.toggleRightDrawer()"
|
||||
round
|
||||
dense
|
||||
icon="menu"
|
||||
>
|
||||
<q-tooltip bottom anchor="bottom right">
|
||||
<QTooltip bottom anchor="bottom right">
|
||||
{{ t('globals.collapseMenu') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
<q-drawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<ClaimFilter data-key="ClaimList" />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page class="column items-center q-pa-md">
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
<div class="card-list">
|
||||
<paginate data-key="ClaimList" url="Claims/filter" order="id DESC" auto-load>
|
||||
<VnPaginate
|
||||
data-key="ClaimList"
|
||||
url="Claims/filter"
|
||||
order="id DESC"
|
||||
auto-load
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<q-card class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||
<q-item
|
||||
<QCard class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||
<QItem
|
||||
class="q-pa-none items-start cursor-pointer q-hoverable"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
<q-item-section class="q-pa-md" @click="navigate(row.id)">
|
||||
<QItemSection class="q-pa-md" @click="navigate(row.id)">
|
||||
<div class="text-h6 link">
|
||||
{{ row.clientName }}
|
||||
</div>
|
||||
<q-item-label caption>#{{ row.id }}</q-item-label>
|
||||
<q-list>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<QItemLabel caption>#{{ row.id }}</QItemLabel>
|
||||
<QList>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.list.customer') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ row.clientName }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.list.assignedTo') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ row.workerName }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.list.created') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toDate(row.created) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.list.state') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
<q-badge
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
<QBadge
|
||||
:color="stateColor(row.stateCode)"
|
||||
class="q-ma-none"
|
||||
dense
|
||||
>
|
||||
{{ row.stateDescription }}
|
||||
</q-badge>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-item-section>
|
||||
<q-separator vertical />
|
||||
<q-card-actions vertical class="justify-between">
|
||||
<!-- <q-btn color="grey-7" round flat icon="more_vert">
|
||||
<q-tooltip>{{ t('customer.list.moreOptions') }}</q-tooltip>
|
||||
<q-menu cover auto-close>
|
||||
<q-list>
|
||||
<q-item clickable>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="add" />
|
||||
</q-item-section>
|
||||
<q-item-section>Add a note</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="logs" />
|
||||
</q-item-section>
|
||||
<q-item-section>Display claim logs</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-btn> -->
|
||||
</QBadge>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QItemSection>
|
||||
<QSeparator vertical />
|
||||
<QCardActions vertical class="justify-between">
|
||||
<!-- <QBtn color="grey-7" round flat icon="more_vert">
|
||||
<QTooltip>{{ t('customer.list.moreOptions') }}</QTooltip>
|
||||
<QMenu cover auto-close>
|
||||
<QList>
|
||||
<QItem clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="add" />
|
||||
</QItemSection>
|
||||
<QItemSection>Add a note</QItemSection>
|
||||
</QItem>
|
||||
<QItem clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="logs" />
|
||||
</QItemSection>
|
||||
<QItemSection>Display claim logs</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QMenu>
|
||||
</QBtn> -->
|
||||
|
||||
<q-btn
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="orange"
|
||||
icon="arrow_circle_right"
|
||||
@click="navigate(row.id)"
|
||||
>
|
||||
<q-tooltip>
|
||||
<QTooltip>
|
||||
{{ t('components.smartCard.openCard') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="grey-7"
|
||||
icon="preview"
|
||||
@click="viewSummary(row.id)"
|
||||
>
|
||||
<q-tooltip>
|
||||
<QTooltip>
|
||||
{{ t('components.smartCard.openSummary') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn flat round color="grey-7" icon="vn:client">
|
||||
<q-tooltip>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn flat round color="grey-7" icon="vn:client">
|
||||
<QTooltip>
|
||||
{{ t('components.smartCard.viewDescription') }}
|
||||
</q-tooltip>
|
||||
</QTooltip>
|
||||
|
||||
<CustomerDescriptorProxy :id="row.clientFk" />
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-item>
|
||||
</q-card>
|
||||
</QBtn>
|
||||
</QCardActions>
|
||||
</QItem>
|
||||
</QCard>
|
||||
</template>
|
||||
</paginate>
|
||||
</VnPaginate>
|
||||
</div>
|
||||
</q-page>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -6,12 +6,12 @@ const stateStore = useStateStore();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-drawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<LeftMenu />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page-container>
|
||||
<router-view></router-view>
|
||||
</q-page-container>
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPageContainer>
|
||||
<RouterView></RouterView>
|
||||
</QPageContainer>
|
||||
</template>
|
||||
|
|
|
@ -3,7 +3,7 @@ import { ref } from 'vue';
|
|||
import { useI18n } from 'vue-i18n';
|
||||
import { useQuasar } from 'quasar';
|
||||
import axios from 'axios';
|
||||
import Paginate from 'src/components/PaginateData.vue';
|
||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||
|
||||
|
@ -61,11 +61,11 @@ async function remove({ id }) {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-page class="column items-center q-pa-md sticky">
|
||||
<q-page-sticky expand position="top" :offset="[16, 16]">
|
||||
<q-card class="card q-pa-md">
|
||||
<q-form @submit="submit">
|
||||
<q-input
|
||||
<QPage class="column items-center q-pa-md sticky">
|
||||
<QPageSticky expand position="top" :offset="[16, 16]">
|
||||
<QCard class="card q-pa-md">
|
||||
<QForm @submit="submit">
|
||||
<QInput
|
||||
ref="input"
|
||||
v-model="newRma.code"
|
||||
:label="t('claim.rmaList.code')"
|
||||
|
@ -78,11 +78,11 @@ async function remove({ id }) {
|
|||
<div class="text-caption">
|
||||
{{ arrayData.totalRows }} {{ t('claim.rmaList.records') }}
|
||||
</div>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-page-sticky>
|
||||
</QForm>
|
||||
</QCard>
|
||||
</QPageSticky>
|
||||
<div class="card-list">
|
||||
<paginate
|
||||
<VnPaginate
|
||||
data-key="ClaimRmaList"
|
||||
url="ClaimRmas"
|
||||
order="id DESC"
|
||||
|
@ -90,68 +90,66 @@ async function remove({ id }) {
|
|||
auto-load
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<q-card class="card">
|
||||
<QCard class="card">
|
||||
<template v-if="isLoading">
|
||||
<q-item class="q-pa-none items-start">
|
||||
<q-item-section class="q-pa-md">
|
||||
<q-list>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<q-skeleton />
|
||||
</q-item-label>
|
||||
<q-item-label
|
||||
><q-skeleton type="text"
|
||||
/></q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-item-section>
|
||||
<q-card-actions vertical class="justify-between">
|
||||
<q-skeleton
|
||||
<QItem class="q-pa-none items-start">
|
||||
<QItemSection class="q-pa-md">
|
||||
<QList>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
<QSkeleton />
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
<QSkeleton type="text" />
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QItemSection>
|
||||
<QCardActions vertical class="justify-between">
|
||||
<QSkeleton
|
||||
type="circle"
|
||||
class="q-mb-md"
|
||||
size="40px"
|
||||
/>
|
||||
</q-card-actions>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
</QCardActions>
|
||||
</QItem>
|
||||
<QSeparator />
|
||||
</template>
|
||||
<template v-for="row of rows" :key="row.id">
|
||||
<q-item class="q-pa-none items-start">
|
||||
<q-item-section class="q-pa-md">
|
||||
<q-list>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
<QItem class="q-pa-none items-start">
|
||||
<QItemSection class="q-pa-md">
|
||||
<QList>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('claim.rmaList.code')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{
|
||||
row.code
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-item-section>
|
||||
<q-card-actions vertical class="justify-between">
|
||||
<q-btn
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ row.code }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QItemSection>
|
||||
<QCardActions vertical class="justify-between">
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="vn:bin"
|
||||
@click="confirm(row.id)"
|
||||
>
|
||||
<q-tooltip>{{ t('globals.remove') }}</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<QTooltip>{{ t('globals.remove') }}</QTooltip>
|
||||
</QBtn>
|
||||
</QCardActions>
|
||||
</QItem>
|
||||
<QSeparator />
|
||||
</template>
|
||||
</q-card>
|
||||
</QCard>
|
||||
</template>
|
||||
</paginate>
|
||||
</VnPaginate>
|
||||
</div>
|
||||
</q-page>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -159,7 +157,8 @@ async function remove({ id }) {
|
|||
padding-top: 156px;
|
||||
}
|
||||
|
||||
.card-list, .card {
|
||||
.card-list,
|
||||
.card {
|
||||
width: 100%;
|
||||
max-width: 60em;
|
||||
}
|
||||
|
|
|
@ -59,12 +59,12 @@ const filterOptions = {
|
|||
auto-load
|
||||
/>
|
||||
<div class="column items-center">
|
||||
<q-card>
|
||||
<form-model :url="`Clients/${route.params.id}`" model="customer">
|
||||
<QCard>
|
||||
<FormModel :url="`Clients/${route.params.id}`" model="customer">
|
||||
<template #form="{ data, validate, filter }">
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-input
|
||||
<QInput
|
||||
v-model="data.socialName"
|
||||
:label="t('customer.basicData.socialName')"
|
||||
:rules="validate('client.socialName')"
|
||||
|
@ -72,7 +72,7 @@ const filterOptions = {
|
|||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-select
|
||||
<QSelect
|
||||
v-model="data.businessTypeFk"
|
||||
:options="businessTypes"
|
||||
option-value="code"
|
||||
|
@ -87,7 +87,7 @@ const filterOptions = {
|
|||
</div>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-input
|
||||
<QInput
|
||||
v-model="data.contact"
|
||||
:label="t('customer.basicData.contact')"
|
||||
:rules="validate('client.contact')"
|
||||
|
@ -95,7 +95,7 @@ const filterOptions = {
|
|||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-input
|
||||
<QInput
|
||||
v-model="data.email"
|
||||
type="email"
|
||||
:label="t('customer.basicData.email')"
|
||||
|
@ -106,7 +106,7 @@ const filterOptions = {
|
|||
</div>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-input
|
||||
<QInput
|
||||
v-model="data.phone"
|
||||
:label="t('customer.basicData.phone')"
|
||||
:rules="validate('client.phone')"
|
||||
|
@ -114,7 +114,7 @@ const filterOptions = {
|
|||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-input
|
||||
<QInput
|
||||
v-model="data.mobile"
|
||||
:label="t('customer.basicData.mobile')"
|
||||
:rules="validate('client.mobile')"
|
||||
|
@ -124,7 +124,7 @@ const filterOptions = {
|
|||
</div>
|
||||
<div class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-select
|
||||
<QSelect
|
||||
v-model="data.salesPersonFk"
|
||||
:options="workers"
|
||||
option-value="id"
|
||||
|
@ -141,18 +141,18 @@ const filterOptions = {
|
|||
:input-debounce="0"
|
||||
>
|
||||
<template #prepend>
|
||||
<q-avatar color="orange">
|
||||
<q-img
|
||||
<QAvatar color="orange">
|
||||
<QImg
|
||||
v-if="data.salesPersonFk"
|
||||
:src="`/api/Images/user/160x160/${data.salesPersonFk}/download?access_token=${token}`"
|
||||
spinner-color="white"
|
||||
/>
|
||||
</q-avatar>
|
||||
</QAvatar>
|
||||
</template>
|
||||
</q-select>
|
||||
</QSelect>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-select
|
||||
<QSelect
|
||||
v-model="data.contactChannelFk"
|
||||
:options="contactChannels"
|
||||
option-value="id"
|
||||
|
@ -166,8 +166,8 @@ const filterOptions = {
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</form-model>
|
||||
</q-card>
|
||||
</FormModel>
|
||||
</QCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -17,18 +17,18 @@ const { t } = useI18n();
|
|||
:info="t('You can search by customer id or name')"
|
||||
/>
|
||||
</Teleport>
|
||||
<q-drawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<q-scroll-area class="fit">
|
||||
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<QScrollArea class="fit">
|
||||
<CustomerDescriptor />
|
||||
<q-separator />
|
||||
<left-menu source="card" />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page-container>
|
||||
<q-page class="q-pa-md">
|
||||
<router-view></router-view>
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
<QSeparator />
|
||||
<LeftMenu source="card" />
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPageContainer>
|
||||
<QPage class="q-pa-md">
|
||||
<RouterView></RouterView>
|
||||
</QPage>
|
||||
</QPageContainer>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
|
|
|
@ -23,97 +23,97 @@ const entityId = computed(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<card-descriptor module="Customer" :url="`Clients/${entityId}/getCard`">
|
||||
<CardDescriptor module="Customer" :url="`Clients/${entityId}/getCard`">
|
||||
<template #body="{ entity }">
|
||||
<q-list dense>
|
||||
<q-item v-if="entity.salesPersonUser" class="row">
|
||||
<q-item-label class="col" caption>
|
||||
<QList dense>
|
||||
<QItem v-if="entity.salesPersonUser" class="row">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.card.salesPerson') }}
|
||||
</q-item-label>
|
||||
<q-item-label class="col q-ma-none">
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
<span class="link">
|
||||
{{ entity.salesPersonUser.name }}
|
||||
<WorkerDescriptorProxy :id="entity.salesPersonFk" />
|
||||
</span>
|
||||
</q-item-label>
|
||||
</q-item>
|
||||
<q-item class="row">
|
||||
<q-item-label class="col" caption>
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
<QItem class="row">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.card.credit') }}
|
||||
</q-item-label>
|
||||
<q-item-label class="col q-ma-none">
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ toCurrency(entity.credit) }}
|
||||
</q-item-label>
|
||||
</q-item>
|
||||
<q-item class="row">
|
||||
<q-item-label class="col" caption>
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
<QItem class="row">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.card.securedCredit') }}
|
||||
</q-item-label>
|
||||
<q-item-label class="col q-ma-none">
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ toCurrency(entity.creditInsurance) }}
|
||||
</q-item-label>
|
||||
</q-item>
|
||||
<q-item v-if="entity.payMethod" class="row">
|
||||
<q-item-label class="col" caption>
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
<QItem v-if="entity.payMethod" class="row">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.card.payMethod') }}
|
||||
</q-item-label>
|
||||
<q-item-label class="col q-ma-none">
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ entity.payMethod.name }}
|
||||
</q-item-label>
|
||||
</q-item>
|
||||
<q-item class="row">
|
||||
<q-item-label class="col" caption>
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
<QItem class="row">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.card.debt') }}
|
||||
</q-item-label>
|
||||
<q-item-label class="col q-ma-none">
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ toCurrency(entity.debt) }}
|
||||
</q-item-label>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<q-card-actions class="q-gutter-md">
|
||||
<q-icon
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
</QList>
|
||||
<QCardActions class="q-gutter-md">
|
||||
<QIcon
|
||||
v-if="entity.isActive == false"
|
||||
name="vn:disabled"
|
||||
size="xs"
|
||||
color="primary"
|
||||
>
|
||||
<q-tooltip>{{ t('customer.card.isDisabled') }}</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon
|
||||
<QTooltip>{{ t('customer.card.isDisabled') }}</QTooltip>
|
||||
</QIcon>
|
||||
<QIcon
|
||||
v-if="entity.isFreezed == true"
|
||||
name="vn:frozen"
|
||||
size="xs"
|
||||
color="primary"
|
||||
>
|
||||
<q-tooltip>{{ t('customer.card.isFrozen') }}</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon
|
||||
<QTooltip>{{ t('customer.card.isFrozen') }}</QTooltip>
|
||||
</QIcon>
|
||||
<QIcon
|
||||
v-if="entity.debt > entity.credit"
|
||||
name="vn:risk"
|
||||
size="xs"
|
||||
color="primary"
|
||||
>
|
||||
<q-tooltip>{{ t('customer.card.hasDebt') }}</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon
|
||||
<QTooltip>{{ t('customer.card.hasDebt') }}</QTooltip>
|
||||
</QIcon>
|
||||
<QIcon
|
||||
v-if="entity.isTaxDataChecked == false"
|
||||
name="vn:no036"
|
||||
size="xs"
|
||||
color="primary"
|
||||
>
|
||||
<q-tooltip>{{ t('customer.card.notChecked') }}</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon
|
||||
<QTooltip>{{ t('customer.card.notChecked') }}</QTooltip>
|
||||
</QIcon>
|
||||
<QIcon
|
||||
v-if="entity.account && entity.account.active == false"
|
||||
name="vn:noweb"
|
||||
size="xs"
|
||||
color="primary"
|
||||
>
|
||||
<q-tooltip>{{ t('customer.card.noWebAccess') }}</q-tooltip>
|
||||
</q-icon>
|
||||
</q-card-actions>
|
||||
<q-card-actions>
|
||||
<q-btn
|
||||
<QTooltip>{{ t('customer.card.noWebAccess') }}</QTooltip>
|
||||
</QIcon>
|
||||
</QCardActions>
|
||||
<QCardActions>
|
||||
<QBtn
|
||||
:to="{
|
||||
name: 'TicketList',
|
||||
query: { params: JSON.stringify({ clientFk: entity.id }) },
|
||||
|
@ -122,9 +122,9 @@ const entityId = computed(() => {
|
|||
icon="vn:ticket"
|
||||
color="primary"
|
||||
>
|
||||
<q-tooltip>{{ t('ticketList') }}</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
<QTooltip>{{ t('ticketList') }}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
:to="{
|
||||
name: 'InvoiceOutList',
|
||||
query: { params: JSON.stringify({ clientFk: entity.id }) },
|
||||
|
@ -133,23 +133,23 @@ const entityId = computed(() => {
|
|||
icon="vn:invoice-out"
|
||||
color="primary"
|
||||
>
|
||||
<q-tooltip>{{ t('invoiceOutList') }}</q-tooltip>
|
||||
</q-btn>
|
||||
<QTooltip>{{ t('invoiceOutList') }}</QTooltip>
|
||||
</QBtn>
|
||||
<!--
|
||||
<q-btn size="md" icon="vn:basketadd" color="primary">
|
||||
<q-tooltip>Order list</q-tooltip>
|
||||
</q-btn>
|
||||
<QBtn size="md" icon="vn:basketadd" color="primary">
|
||||
<QTooltip>Order list</QTooltip>
|
||||
</QBtn>
|
||||
|
||||
<q-btn size="md" icon="face" color="primary">
|
||||
<q-tooltip>View user</q-tooltip>
|
||||
</q-btn>
|
||||
<QBtn size="md" icon="face" color="primary">
|
||||
<QTooltip>View user</QTooltip>
|
||||
</QBtn>
|
||||
|
||||
<q-btn size="md" icon="expand_more" color="primary">
|
||||
<q-tooltip>More options</q-tooltip>
|
||||
</q-btn> -->
|
||||
</q-card-actions>
|
||||
<QBtn size="md" icon="expand_more" color="primary">
|
||||
<QTooltip>More options</QTooltip>
|
||||
</QBtn> -->
|
||||
</QCardActions>
|
||||
</template>
|
||||
</card-descriptor>
|
||||
</CardDescriptor>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
|
|
|
@ -9,7 +9,7 @@ const $props = defineProps({
|
|||
});
|
||||
</script>
|
||||
<template>
|
||||
<q-popup-proxy>
|
||||
<QPopupProxy>
|
||||
<CustomerDescriptor v-if="$props.id" :id="$props.id" />
|
||||
</q-popup-proxy>
|
||||
</QPopupProxy>
|
||||
</template>
|
||||
|
|
|
@ -51,478 +51,476 @@ const creditWarning = computed(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<card-summary ref="summary" :url="`Clients/${entityId}/summary`">
|
||||
<CardSummary ref="summary" :url="`Clients/${entityId}/summary`">
|
||||
<template #body="{ entity }">
|
||||
<q-card-section class="row q-pa-none q-col-gutter-md">
|
||||
<QCardSection class="row q-pa-none QCol-gutter-md">
|
||||
<div class="col">
|
||||
<q-list dense>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList dense>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('customer.summary.basicData') }}
|
||||
<router-link
|
||||
<RouterLink
|
||||
:to="{
|
||||
name: 'CustomerBasicData',
|
||||
params: { id: entity.id },
|
||||
}"
|
||||
target="_blank"
|
||||
>
|
||||
<q-icon name="open_in_new" />
|
||||
</router-link>
|
||||
</q-item-label>
|
||||
<q-separator class="q-mb-md" />
|
||||
<QIcon name="open_in_new" />
|
||||
</RouterLink>
|
||||
</QItemLabel>
|
||||
<QSeparator class="q-mb-md" />
|
||||
|
||||
<q-item class="row col">
|
||||
<q-item-label class="col" caption>
|
||||
<QItem class="row col">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.summary.customerId') }}
|
||||
</q-item-label>
|
||||
<q-item-label class="col q-ma-none">
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ entity.id }}
|
||||
</q-item-label>
|
||||
</q-item>
|
||||
<q-item class="row col">
|
||||
<q-item-label class="col" caption>
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
<QItem class="row col">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.summary.name') }}
|
||||
</q-item-label>
|
||||
<q-item-label class="col q-ma-none">{{
|
||||
entity.name
|
||||
}}</q-item-label>
|
||||
</q-item>
|
||||
<q-item class="row col">
|
||||
<q-item-label class="col" caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ entity.name }}
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
<QItem class="row col">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.summary.contact') }}
|
||||
</q-item-label>
|
||||
<q-item-label class="col q-ma-none">{{
|
||||
entity.contact
|
||||
}}</q-item-label>
|
||||
</q-item>
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ entity.contact }}
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
|
||||
<q-item v-if="entity.salesPersonUser" class="row col">
|
||||
<q-item-label class="col" caption>
|
||||
<QItem v-if="entity.salesPersonUser" class="row col">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.summary.salesPerson') }}
|
||||
</q-item-label>
|
||||
<q-item-label class="col q-ma-none">
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ entity.salesPersonUser.name }}
|
||||
</q-item-label>
|
||||
</q-item>
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
|
||||
<q-item class="row col">
|
||||
<q-item-label class="col" caption>
|
||||
<QItem class="row col">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.summary.phone') }}
|
||||
</q-item-label>
|
||||
<q-item-label class="col q-ma-none">{{
|
||||
entity.phone
|
||||
}}</q-item-label>
|
||||
</q-item>
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ entity.phone }}
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
|
||||
<q-item class="row col">
|
||||
<q-item-label class="col" caption>
|
||||
<QItem class="row col">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.summary.mobile') }}
|
||||
</q-item-label>
|
||||
<q-item-label class="col q-ma-none">{{
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">{{
|
||||
entity.mobile
|
||||
}}</q-item-label>
|
||||
</q-item>
|
||||
}}</QItemLabel>
|
||||
</QItem>
|
||||
|
||||
<q-item v-if="entity.contactChannel" class="row col">
|
||||
<q-item-label class="col" caption>
|
||||
<QItem v-if="entity.contactChannel" class="row col">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.summary.contactChannel') }}
|
||||
</q-item-label>
|
||||
<q-item-label class="col q-ma-none">
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ entity.contactChannel.name }}
|
||||
</q-item-label>
|
||||
</q-item>
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.email') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.email }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.email }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('customer.summary.fiscalAddress') }}
|
||||
</q-item-label>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.socialName') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.socialName }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.socialName }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.fiscalId') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.fi }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.fi }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.postcode') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.postcode }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="entity.province">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.postcode }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="entity.province">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.province') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.province.name }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="entity.country">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.province.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="entity.country">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.country') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.country.country }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.country.country }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.street') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.street }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.street }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('customer.summary.fiscalData') }}
|
||||
</q-item-label>
|
||||
<q-item dense>
|
||||
<q-checkbox
|
||||
</QItemLabel>
|
||||
<QItem dense>
|
||||
<QCheckbox
|
||||
v-model="entity.isEqualizated"
|
||||
:label="t('customer.summary.isEqualizated')"
|
||||
disable
|
||||
/>
|
||||
</q-item>
|
||||
<q-item dense>
|
||||
<q-checkbox
|
||||
</QItem>
|
||||
<QItem dense>
|
||||
<QCheckbox
|
||||
v-model="entity.isActive"
|
||||
:label="t('customer.summary.isActive')"
|
||||
disable
|
||||
/>
|
||||
</q-item>
|
||||
<q-item dense>
|
||||
<q-checkbox
|
||||
</QItem>
|
||||
<QItem dense>
|
||||
<QCheckbox
|
||||
v-model="entity.hasToInvoiceByAddress"
|
||||
:label="t('customer.summary.invoiceByAddress')"
|
||||
disable
|
||||
/>
|
||||
</q-item>
|
||||
<q-item dense>
|
||||
<q-checkbox
|
||||
</QItem>
|
||||
<QItem dense>
|
||||
<QCheckbox
|
||||
v-model="entity.isTaxDataChecked"
|
||||
:label="t('customer.summary.verifiedData')"
|
||||
disable
|
||||
/>
|
||||
</q-item>
|
||||
<q-item dense>
|
||||
<q-checkbox
|
||||
</QItem>
|
||||
<QItem dense>
|
||||
<QCheckbox
|
||||
v-model="entity.hasToInvoice"
|
||||
:label="t('customer.summary.hasToInvoice')"
|
||||
disable
|
||||
/>
|
||||
</q-item>
|
||||
<q-item dense>
|
||||
<q-checkbox
|
||||
</QItem>
|
||||
<QItem dense>
|
||||
<QCheckbox
|
||||
v-model="entity.isToBeMailed"
|
||||
:label="t('customer.summary.notifyByEmail')"
|
||||
disable
|
||||
/>
|
||||
</q-item>
|
||||
<q-item dense>
|
||||
<q-checkbox
|
||||
</QItem>
|
||||
<QItem dense>
|
||||
<QCheckbox
|
||||
v-model="entity.isVies"
|
||||
:label="t('customer.summary.vies')"
|
||||
disable
|
||||
/>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('customer.summary.billingData') }}
|
||||
</q-item-label>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.payMethod') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.payMethod.name }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.payMethod.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.bankAccount') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.iban }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.iban }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.dueDay') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.dueDay }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item dense>
|
||||
<q-checkbox
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.dueDay }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem dense>
|
||||
<QCheckbox
|
||||
v-model="entity.hasLcr"
|
||||
:label="t('customer.summary.hasLcr')"
|
||||
disable
|
||||
/>
|
||||
</q-item>
|
||||
<q-item dense>
|
||||
<q-checkbox
|
||||
</QItem>
|
||||
<QItem dense>
|
||||
<QCheckbox
|
||||
v-model="entity.hasCoreVnl"
|
||||
:label="t('customer.summary.hasCoreVnl')"
|
||||
disable
|
||||
/>
|
||||
</q-item>
|
||||
<q-item dense>
|
||||
<q-checkbox
|
||||
</QItem>
|
||||
<QItem dense>
|
||||
<QCheckbox
|
||||
v-model="entity.hasSepaVnl"
|
||||
:label="t('customer.summary.hasB2BVnl')"
|
||||
disable
|
||||
/>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
<div class="col" v-if="entity.defaultAddress">
|
||||
<q-list>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('customer.summary.consignee') }}
|
||||
</q-item-label>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.addressName') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ entity.defaultAddress.nickname }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.addressCity') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{
|
||||
entity.defaultAddress.city
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.defaultAddress.city }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.addressStreet') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ entity.defaultAddress.street }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
<div class="col" v-if="entity.account">
|
||||
<q-list>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('customer.summary.webAccess') }}
|
||||
</q-item-label>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.username') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.account.name }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item dense>
|
||||
<q-checkbox
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.account.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem dense>
|
||||
<QCheckbox
|
||||
v-model="entity.account.active"
|
||||
:label="t('customer.summary.webAccess')"
|
||||
disable
|
||||
/>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('customer.summary.businessData') }}
|
||||
</q-item-label>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.totalGreuge') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toCurrency(entity.totalGreuge) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="entity.mana">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="entity.mana">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.mana') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toCurrency(entity.mana.mana) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="entity.claimsRatio">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="entity.claimsRatio">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.priceIncreasingRate') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toPercentage(priceIncreasingRate) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="entity.averageInvoiced">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="entity.averageInvoiced">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.averageInvoiced') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toCurrency(entity.averageInvoiced.invoiced) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="entity.claimsRatio">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="entity.claimsRatio">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.claimRate') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ toPercentage(claimRate) }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ toPercentage(claimRate) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('customer.summary.financialData') }}
|
||||
</q-item-label>
|
||||
<q-item v-if="entity.debt">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItem v-if="entity.debt">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.risk') }}
|
||||
</q-item-label>
|
||||
<q-item-label :class="debtWarning">
|
||||
</QItemLabel>
|
||||
<QItemLabel :class="debtWarning">
|
||||
{{ toCurrency(entity.debt.debt) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side>
|
||||
<q-icon name="vn:info">
|
||||
<q-tooltip>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection side>
|
||||
<QIcon name="vn:info">
|
||||
<QTooltip>
|
||||
{{ t('customer.summary.riskInfo') }}
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.credit') }}
|
||||
</q-item-label>
|
||||
<q-item-label :class="creditWarning">
|
||||
</QItemLabel>
|
||||
<QItemLabel :class="creditWarning">
|
||||
{{ toCurrency(entity.credit) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side>
|
||||
<q-icon name="vn:info">
|
||||
<q-tooltip>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection side>
|
||||
<QIcon name="vn:info">
|
||||
<QTooltip>
|
||||
{{ t('customer.summary.creditInfo') }}
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="entity.creditInsurance">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="entity.creditInsurance">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.securedCredit') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toCurrency(entity.creditInsurance) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side>
|
||||
<q-icon name="vn:info">
|
||||
<q-tooltip>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection side>
|
||||
<QIcon name="vn:info">
|
||||
<QTooltip>
|
||||
{{ t('customer.summary.securedCreditInfo') }}
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.balance') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toCurrency(entity.sumRisk) || toCurrency(0) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side>
|
||||
<q-icon name="vn:info">
|
||||
<q-tooltip>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection side>
|
||||
<QIcon name="vn:info">
|
||||
<QTooltip>
|
||||
{{ t('customer.summary.balanceInfo') }}
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="entity.defaulters">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="entity.defaulters">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.balanceDue') }}
|
||||
</q-item-label>
|
||||
<q-item-label :class="balanceDueWarning">
|
||||
</QItemLabel>
|
||||
<QItemLabel :class="balanceDueWarning">
|
||||
{{ toCurrency(balanceDue) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side>
|
||||
<q-icon name="vn:info">
|
||||
<q-tooltip>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection side>
|
||||
<QIcon name="vn:info">
|
||||
<QTooltip>
|
||||
{{ t('customer.summary.balanceDueInfo') }}
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="entity.recovery">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="entity.recovery">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.summary.recoverySince') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toDate(entity.recovery.started) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</QCardSection>
|
||||
</template>
|
||||
</card-summary>
|
||||
</CardSummary>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
@ -15,9 +15,9 @@ const { dialogRef, onDialogHide } = useDialogPluginComponent();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog ref="dialogRef" @hide="onDialogHide">
|
||||
<customer-summary v-if="$props.id" :id="$props.id" />
|
||||
</q-dialog>
|
||||
<QDialog ref="dialogRef" @hide="onDialogHide">
|
||||
<CustomerSummary v-if="$props.id" :id="$props.id" />
|
||||
</QDialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
@ -14,10 +14,10 @@ watch(
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-page class="q-pa-md">
|
||||
<q-card class="q-pa-md">
|
||||
<q-form @submit="onSubmit" @reset="onReset" class="q-gutter-md">
|
||||
<q-input
|
||||
<QPage class="q-pa-md">
|
||||
<QCard class="q-pa-md">
|
||||
<QForm @submit="onSubmit" @reset="onReset" class="q-gutter-md">
|
||||
<QInput
|
||||
filled
|
||||
v-model="customer.name"
|
||||
label="Your name *"
|
||||
|
@ -26,7 +26,7 @@ watch(
|
|||
:rules="[(val) => (val && val.length > 0) || 'Please type something']"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
<QInput
|
||||
filled
|
||||
type="number"
|
||||
v-model="age"
|
||||
|
@ -39,12 +39,18 @@ watch(
|
|||
/>
|
||||
|
||||
<div>
|
||||
<q-btn label="Submit" type="submit" color="primary" />
|
||||
<q-btn label="Reset" type="reset" color="primary" flat class="q-ml-sm" />
|
||||
<QBtn label="Submit" type="submit" color="primary" />
|
||||
<QBtn
|
||||
label="Reset"
|
||||
type="reset"
|
||||
color="primary"
|
||||
flat
|
||||
class="q-ml-sm"
|
||||
/>
|
||||
</div>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-page>
|
||||
</QForm>
|
||||
</QCard>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -18,9 +18,9 @@ const zones = ref();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<fetch-data url="Provinces" @on-fetch="(data) => (provinces = data)" auto-load />
|
||||
<fetch-data url="Zones" @on-fetch="(data) => (zones = data)" auto-load />
|
||||
<fetch-data
|
||||
<FetchData url="Provinces" @on-fetch="(data) => (provinces = data)" auto-load />
|
||||
<FetchData url="Zones" @on-fetch="(data) => (zones = data)" auto-load />
|
||||
<FetchData
|
||||
url="Workers/activeWithInheritedRole"
|
||||
:filter="{ where: { role: 'salesPerson' } }"
|
||||
@on-fetch="(data) => (workers = data)"
|
||||
|
@ -34,36 +34,36 @@ const zones = ref();
|
|||
</div>
|
||||
</template>
|
||||
<template #body="{ params, searchFn }">
|
||||
<q-list dense>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input :label="t('FI')" v-model="params.fi" lazy-rules>
|
||||
<QList dense>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput :label="t('FI')" v-model="params.fi" lazy-rules>
|
||||
<template #prepend>
|
||||
<q-icon name="badge" size="sm"></q-icon>
|
||||
<QIcon name="badge" size="sm"></QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input :label="t('Name')" v-model="params.name" lazy-rules />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput :label="t('Name')" v-model="params.name" lazy-rules />
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('Social Name')"
|
||||
v-model="params.socialName"
|
||||
lazy-rules
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="!workers">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="workers">
|
||||
<q-select
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="!workers">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="workers">
|
||||
<QSelect
|
||||
:label="t('Salesperson')"
|
||||
v-model="params.salesPersonFk"
|
||||
@update:model-value="searchFn()"
|
||||
|
@ -75,14 +75,14 @@ const zones = ref();
|
|||
use-input
|
||||
:input-debounce="0"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="!provinces">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="provinces">
|
||||
<q-select
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="!provinces">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="provinces">
|
||||
<QSelect
|
||||
:label="t('Province')"
|
||||
v-model="params.provinceFk"
|
||||
@update:model-value="searchFn()"
|
||||
|
@ -92,47 +92,39 @@ const zones = ref();
|
|||
emit-value
|
||||
map-options
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-mb-md">
|
||||
<q-item-section>
|
||||
<q-input :label="t('City')" v-model="params.city" lazy-rules />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<q-expansion-item :label="t('More options')" expand-separator>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
:label="t('Phone')"
|
||||
v-model="params.phone"
|
||||
lazy-rules
|
||||
>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-mb-md">
|
||||
<QItemSection>
|
||||
<QInput :label="t('City')" v-model="params.city" lazy-rules />
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QSeparator />
|
||||
<QExpansionItem :label="t('More options')" expand-separator>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput :label="t('Phone')" v-model="params.phone" lazy-rules>
|
||||
<template #prepend>
|
||||
<q-icon name="phone" size="sm"></q-icon>
|
||||
<QIcon name="phone" size="sm"></QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
:label="t('Email')"
|
||||
v-model="params.email"
|
||||
lazy-rules
|
||||
>
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput :label="t('Email')" v-model="params.email" lazy-rules>
|
||||
<template #prepend>
|
||||
<q-icon name="email" size="sm"></q-icon>
|
||||
<QIcon name="email" size="sm"></QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="!zones">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="zones">
|
||||
<q-select
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="!zones">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="zones">
|
||||
<QSelect
|
||||
:label="t('Zone')"
|
||||
v-model="params.zoneFk"
|
||||
@update:model-value="searchFn()"
|
||||
|
@ -142,19 +134,19 @@ const zones = ref();
|
|||
emit-value
|
||||
map-options
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('Postcode')"
|
||||
v-model="params.postcode"
|
||||
lazy-rules
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-expansion-item>
|
||||
</q-list>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QExpansionItem>
|
||||
</QList>
|
||||
</template>
|
||||
</VnFilterPanel>
|
||||
</template>
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useI18n } from 'vue-i18n';
|
|||
import { useRouter } from 'vue-router';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import Paginate from 'src/components/PaginateData.vue';
|
||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||
import CustomerSummaryDialog from './Card/CustomerSummaryDialog.vue';
|
||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||
import CustomerFilter from './CustomerFilter.vue';
|
||||
|
@ -38,117 +38,117 @@ function viewSummary(id) {
|
|||
</Teleport>
|
||||
<Teleport to="#actions-append">
|
||||
<div class="row q-gutter-x-sm">
|
||||
<q-btn
|
||||
<QBtn
|
||||
flat
|
||||
@click="stateStore.toggleRightDrawer()"
|
||||
round
|
||||
dense
|
||||
icon="menu"
|
||||
>
|
||||
<q-tooltip bottom anchor="bottom right">
|
||||
<QTooltip bottom anchor="bottom right">
|
||||
{{ t('globals.collapseMenu') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
<q-drawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<CustomerFilter data-key="CustomerList" />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page class="column items-center q-pa-md">
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
<div class="card-list">
|
||||
<paginate
|
||||
<VnPaginate
|
||||
data-key="CustomerList"
|
||||
url="/Clients/filter"
|
||||
order="id DESC"
|
||||
auto-load
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<q-card class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||
<q-item
|
||||
<QCard class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||
<QItem
|
||||
class="q-pa-none items-start cursor-pointer q-hoverable"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
<q-item-section class="q-pa-md" @click="navigate(row.id)">
|
||||
<QItemSection class="q-pa-md" @click="navigate(row.id)">
|
||||
<div class="text-h6">{{ row.name }}</div>
|
||||
<q-item-label caption>#{{ row.id }}</q-item-label>
|
||||
<QItemLabel caption>#{{ row.id }}</QItemLabel>
|
||||
|
||||
<q-list>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<QList>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.list.email') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ row.email }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ row.email }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('customer.list.phone') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ row.phone }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-item-section>
|
||||
<q-separator vertical />
|
||||
<q-card-actions vertical class="justify-between">
|
||||
<!-- <q-btn color="grey-7" round flat icon="more_vert">
|
||||
<q-tooltip>{{ t('customer.list.moreOptions') }}</q-tooltip>
|
||||
<q-menu cover auto-close>
|
||||
<q-list>
|
||||
<q-item clickable>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="add" />
|
||||
</q-item-section>
|
||||
<q-item-section>Add a note</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="history" />
|
||||
</q-item-section>
|
||||
<q-item-section>Display customer history</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-btn> -->
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ row.phone }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QItemSection>
|
||||
<QSeparator vertical />
|
||||
<QCardActions vertical class="justify-between">
|
||||
<!-- <QBtn color="grey-7" round flat icon="more_vert">
|
||||
<QTooltip>{{ t('customer.list.moreOptions') }}</QTooltip>
|
||||
<QMenu cover auto-close>
|
||||
<QList>
|
||||
<QItem clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="add" />
|
||||
</QItemSection>
|
||||
<QItemSection>Add a note</QItemSection>
|
||||
</QItem>
|
||||
<QItem clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="history" />
|
||||
</QItemSection>
|
||||
<QItemSection>Display customer history</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QMenu>
|
||||
</QBtn> -->
|
||||
|
||||
<q-btn
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="arrow_circle_right"
|
||||
@click="navigate(row.id)"
|
||||
>
|
||||
<q-tooltip>
|
||||
<QTooltip>
|
||||
{{ t('components.smartCard.openCard') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="grey-7"
|
||||
icon="preview"
|
||||
@click="viewSummary(row.id)"
|
||||
>
|
||||
<q-tooltip>
|
||||
<QTooltip>
|
||||
{{ t('components.smartCard.openSummary') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<!-- <q-btn flat round color="grey-7" icon="vn:ticket">
|
||||
<q-tooltip>{{ t('customer.list.customerOrders') }}</q-tooltip>
|
||||
</q-btn> -->
|
||||
</q-card-actions>
|
||||
</q-item>
|
||||
</q-card>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
<!-- <QBtn flat round color="grey-7" icon="vn:ticket">
|
||||
<QTooltip>{{ t('customer.list.customerOrders') }}</QTooltip>
|
||||
</QBtn> -->
|
||||
</QCardActions>
|
||||
</QItem>
|
||||
</QCard>
|
||||
</template>
|
||||
</paginate>
|
||||
</VnPaginate>
|
||||
</div>
|
||||
</q-page>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -6,14 +6,14 @@ const stateStore = useStateStore();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-drawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<LeftMenu />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page-container>
|
||||
<router-view></router-view>
|
||||
</q-page-container>
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPageContainer>
|
||||
<RouterView></RouterView>
|
||||
</QPageContainer>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
@ -5,7 +5,7 @@ import { useI18n } from 'vue-i18n';
|
|||
import { useQuasar } from 'quasar';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { useArrayData } from 'composables/useArrayData';
|
||||
import Paginate from 'components/PaginateData.vue';
|
||||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
||||
import VnConfirm from 'components/ui/VnConfirm.vue';
|
||||
import CustomerDescriptorProxy from './Card/CustomerDescriptorProxy.vue';
|
||||
import { toDate, toCurrency } from 'filters/index';
|
||||
|
@ -96,30 +96,30 @@ function stateColor(row) {
|
|||
<template v-if="stateStore.isHeaderMounted()">
|
||||
<Teleport to="#actions-append">
|
||||
<div class="row q-gutter-x-sm">
|
||||
<q-btn
|
||||
<QBtn
|
||||
flat
|
||||
@click="stateStore.toggleRightDrawer()"
|
||||
round
|
||||
dense
|
||||
icon="menu"
|
||||
>
|
||||
<q-tooltip bottom anchor="bottom right">
|
||||
<QTooltip bottom anchor="bottom right">
|
||||
{{ t('globals.collapseMenu') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
<q-drawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<CustomerPaymentsFilter data-key="CustomerTransactions" />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page class="column items-center q-pa-md">
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
<div class="card-list">
|
||||
<q-toolbar class="q-pa-none">
|
||||
<q-toolbar-title>{{ t('Web Payments') }}</q-toolbar-title>
|
||||
<q-btn
|
||||
<QToolbar class="q-pa-none">
|
||||
<QToolbarTitle>{{ t('Web Payments') }}</QToolbarTitle>
|
||||
<QBtn
|
||||
@click="arrayData.refresh()"
|
||||
:loading="isLoading"
|
||||
icon="refresh"
|
||||
|
@ -127,12 +127,12 @@ function stateColor(row) {
|
|||
class="q-mr-sm"
|
||||
round
|
||||
dense
|
||||
></q-btn>
|
||||
<q-btn @click="grid = !grid" icon="list" color="primary" round dense>
|
||||
<q-tooltip>{{ t('Change view') }}</q-tooltip>
|
||||
</q-btn>
|
||||
</q-toolbar>
|
||||
<paginate
|
||||
></QBtn>
|
||||
<QBtn @click="grid = !grid" icon="list" color="primary" round dense>
|
||||
<QTooltip>{{ t('Change view') }}</QTooltip>
|
||||
</QBtn>
|
||||
</QToolbar>
|
||||
<VnPaginate
|
||||
data-key="CustomerTransactions"
|
||||
url="Clients/transactions"
|
||||
order="created DESC"
|
||||
|
@ -141,7 +141,7 @@ function stateColor(row) {
|
|||
auto-load
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<q-table
|
||||
<QTable
|
||||
:dense="$q.screen.lt.md"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
|
@ -152,8 +152,8 @@ function stateColor(row) {
|
|||
hide-pagination
|
||||
>
|
||||
<template #body-cell-actions="{ row }">
|
||||
<q-td auto-width class="text-center">
|
||||
<q-btn
|
||||
<QTd auto-width class="text-center">
|
||||
<QBtn
|
||||
v-if="!row.isConfirmed"
|
||||
icon="check"
|
||||
@click="confirm(row)"
|
||||
|
@ -163,87 +163,75 @@ function stateColor(row) {
|
|||
flat
|
||||
dense
|
||||
>
|
||||
<q-tooltip>{{ t('Confirm transaction') }}</q-tooltip>
|
||||
</q-btn>
|
||||
</q-td>
|
||||
<QTooltip>{{ t('Confirm transaction') }}</QTooltip>
|
||||
</QBtn>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-customerId="{ row }">
|
||||
<q-td align="right">
|
||||
<QTd align="right">
|
||||
<span class="link">
|
||||
{{ row.clientFk }}
|
||||
<CustomerDescriptorProxy :id="row.clientFk" />
|
||||
</span>
|
||||
</q-td>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-state="{ row }">
|
||||
<q-td auto-width class="text-center">
|
||||
<q-badge :color="stateColor(row)">
|
||||
<QTd auto-width class="text-center">
|
||||
<QBadge :color="stateColor(row)">
|
||||
{{
|
||||
row.isConfirmed
|
||||
? t('Confirmed')
|
||||
: t('Unconfirmed')
|
||||
}}
|
||||
</q-badge>
|
||||
</q-td>
|
||||
</QBadge>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #item="{ cols, row }">
|
||||
<div class="q-mb-md col-12">
|
||||
<q-card>
|
||||
<q-item class="q-pa-none items-start">
|
||||
<q-item-section class="q-pa-md">
|
||||
<q-list>
|
||||
<QCard>
|
||||
<QItem class="q-pa-none items-start">
|
||||
<QItemSection class="q-pa-md">
|
||||
<QList>
|
||||
<template
|
||||
v-for="col of cols"
|
||||
:key="col.name"
|
||||
>
|
||||
<q-item
|
||||
<QItem
|
||||
v-if="col.grid !== false"
|
||||
class="q-pa-none"
|
||||
>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ col.label }}
|
||||
</q-item-label>
|
||||
<q-item-label
|
||||
</QItemLabel>
|
||||
<QItemLabel
|
||||
v-if="col.name == 'state'"
|
||||
>
|
||||
<q-badge
|
||||
<QBadge
|
||||
:color="
|
||||
stateColor(row)
|
||||
"
|
||||
>
|
||||
{{ col.value }}
|
||||
</q-badge>
|
||||
</q-item-label>
|
||||
<q-item-label
|
||||
</QBadge>
|
||||
</QItemLabel>
|
||||
<QItemLabel
|
||||
v-if="col.name != 'state'"
|
||||
>
|
||||
{{ col.value }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</q-list>
|
||||
<!-- <q-list>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<q-skeleton />
|
||||
</q-item-label>
|
||||
<q-item-label
|
||||
><q-skeleton type="text"
|
||||
/></q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list> -->
|
||||
</q-item-section>
|
||||
</QList>
|
||||
</QItemSection>
|
||||
<template v-if="!row.isConfirmed">
|
||||
<q-separator vertical />
|
||||
<q-card-actions
|
||||
<QSeparator vertical />
|
||||
<QCardActions
|
||||
vertical
|
||||
class="justify-between"
|
||||
>
|
||||
<q-btn
|
||||
<QBtn
|
||||
icon="check"
|
||||
@click="confirm(row)"
|
||||
color="primary"
|
||||
|
@ -252,21 +240,21 @@ function stateColor(row) {
|
|||
flat
|
||||
dense
|
||||
>
|
||||
<q-tooltip>{{
|
||||
t('Confirm transaction')
|
||||
}}</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
<QTooltip>
|
||||
{{ t('Confirm transaction') }}
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</QCardActions>
|
||||
</template>
|
||||
</q-item>
|
||||
</q-card>
|
||||
</QItem>
|
||||
</QCard>
|
||||
</div>
|
||||
</template>
|
||||
</q-table>
|
||||
</QTable>
|
||||
</template>
|
||||
</paginate>
|
||||
</VnPaginate>
|
||||
</div>
|
||||
</q-page>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -20,43 +20,43 @@ const props = defineProps({
|
|||
</div>
|
||||
</template>
|
||||
<template #body="{ params }">
|
||||
<q-list dense>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
<QList dense>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('Order ID')"
|
||||
v-model="params.orderFk"
|
||||
lazy-rules
|
||||
>
|
||||
<template #prepend>
|
||||
<q-icon name="vn:basket" size="sm"></q-icon>
|
||||
<QIcon name="vn:basket" size="sm"></QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('Customer ID')"
|
||||
v-model="params.clientFk"
|
||||
lazy-rules
|
||||
>
|
||||
<template #prepend>
|
||||
<q-icon name="vn:client" size="sm"></q-icon>
|
||||
<QIcon name="vn:client" size="sm"></QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input :label="t('Amount')" v-model="params.amount" lazy-rules>
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput :label="t('Amount')" v-model="params.amount" lazy-rules>
|
||||
<template #prepend>
|
||||
<q-icon name="euro" size="sm"></q-icon>
|
||||
<QIcon name="euro" size="sm"></QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</template>
|
||||
</VnFilterPanel>
|
||||
</template>
|
||||
|
|
|
@ -15,24 +15,24 @@ const pinnedModules = computed(() => navigation.getPinnedModules());
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-drawer
|
||||
<QDrawer
|
||||
v-model="stateStore.leftDrawer"
|
||||
show-if-above
|
||||
:width="256"
|
||||
:breakpoint="1000"
|
||||
>
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<LeftMenu />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page-container>
|
||||
<q-page class="q-pa-md">
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPageContainer>
|
||||
<QPage class="q-pa-md">
|
||||
<div class="row items-start wrap q-col-gutter-md q-mb-lg">
|
||||
<div class="col-12 col-md">
|
||||
<div class="text-h6 text-grey-8 q-mb-sm">
|
||||
{{ t('globals.pinnedModules') }}
|
||||
</div>
|
||||
<q-card class="row flex-container q-pa-md">
|
||||
<QCard class="row flex-container q-pa-md">
|
||||
<div class="text-grey-5" v-if="pinnedModules.length === 0">
|
||||
{{ t('pinnedInfo') }}
|
||||
</div>
|
||||
|
@ -42,7 +42,7 @@ const pinnedModules = computed(() => navigation.getPinnedModules());
|
|||
:key="item.title"
|
||||
class="row no-wrap q-pa-xs flex-item"
|
||||
>
|
||||
<q-btn
|
||||
<QBtn
|
||||
align="evenly"
|
||||
padding="16px"
|
||||
flat
|
||||
|
@ -56,14 +56,14 @@ const pinnedModules = computed(() => navigation.getPinnedModules());
|
|||
<div class="text-center text-primary button-text">
|
||||
{{ t(item.title) }}
|
||||
</div>
|
||||
</q-btn>
|
||||
</QBtn>
|
||||
</div>
|
||||
</template>
|
||||
</q-card>
|
||||
</QCard>
|
||||
</div>
|
||||
</div>
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
</QPage>
|
||||
</QPageContainer>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -17,18 +17,18 @@ const { t } = useI18n();
|
|||
:info="t('You can search by invoice reference')"
|
||||
/>
|
||||
</Teleport>
|
||||
<q-drawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<q-scroll-area class="fit">
|
||||
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<QScrollArea class="fit">
|
||||
<InvoiceOutDescriptor />
|
||||
<q-separator />
|
||||
<left-menu source="card" />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page-container>
|
||||
<q-page class="q-pa-md">
|
||||
<router-view></router-view>
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
<QSeparator />
|
||||
<LeftMenu source="card" />
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPageContainer>
|
||||
<QPage class="q-pa-md">
|
||||
<RouterView></RouterView>
|
||||
</QPage>
|
||||
</QPageContainer>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
|
|
|
@ -45,7 +45,7 @@ function ticketFilter(invoice) {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<card-descriptor
|
||||
<CardDescriptor
|
||||
ref="descriptor"
|
||||
module="InvoiceOut"
|
||||
:url="`InvoiceOuts/${entityId}`"
|
||||
|
@ -54,54 +54,54 @@ function ticketFilter(invoice) {
|
|||
<template #description="{ entity }">
|
||||
<span>
|
||||
{{ entity.ref }}
|
||||
<q-tooltip>{{ entity.ref }}</q-tooltip>
|
||||
<QTooltip>{{ entity.ref }}</QTooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #body="{ entity }">
|
||||
<q-list>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('invoiceOut.card.issued') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ toDate(entity.issued) }}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ toDate(entity.issued) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('invoiceOut.card.amount') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ toCurrency(entity.amount) }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="entity.client">
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ toCurrency(entity.amount) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="entity.client">
|
||||
<QItemLabel caption>
|
||||
{{ t('invoiceOut.card.client') }}
|
||||
</q-item-label>
|
||||
<q-item-label class="link">
|
||||
</QItemLabel>
|
||||
<QItemLabel class="link">
|
||||
{{ entity.client.name }}
|
||||
<CustomerDescriptorProxy :id="entity.client.id" />
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section v-if="entity.company">
|
||||
<q-item-label caption>{{
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection v-if="entity.company">
|
||||
<QItemLabel caption>{{
|
||||
t('invoiceOut.card.company')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{ entity.company.code }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<q-card-actions>
|
||||
<q-btn
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ entity.company.code }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
<QCardActions>
|
||||
<QBtn
|
||||
v-if="entity.client"
|
||||
size="md"
|
||||
icon="vn:client"
|
||||
color="primary"
|
||||
:to="{ name: 'CustomerCard', params: { id: entity.client.id } }"
|
||||
>
|
||||
<q-tooltip>{{ t('invoiceOut.card.customerCard') }}</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
<QTooltip>{{ t('invoiceOut.card.customerCard') }}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
size="md"
|
||||
icon="vn:ticket"
|
||||
color="primary"
|
||||
|
@ -110,9 +110,9 @@ function ticketFilter(invoice) {
|
|||
query: { q: ticketFilter(entity) },
|
||||
}"
|
||||
>
|
||||
<q-tooltip>{{ t('invoiceOut.card.ticketList') }}</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
<QTooltip>{{ t('invoiceOut.card.ticketList') }}</QTooltip>
|
||||
</QBtn>
|
||||
</QCardActions>
|
||||
</template>
|
||||
</card-descriptor>
|
||||
</CardDescriptor>
|
||||
</template>
|
||||
|
|
|
@ -9,7 +9,7 @@ const $props = defineProps({
|
|||
});
|
||||
</script>
|
||||
<template>
|
||||
<q-popup-proxy>
|
||||
<QPopupProxy>
|
||||
<InvoiceOutDescriptor v-if="$props.id" :id="$props.id" />
|
||||
</q-popup-proxy>
|
||||
</QPopupProxy>
|
||||
</template>
|
||||
|
|
|
@ -96,66 +96,84 @@ const ticketsColumns = ref([
|
|||
|
||||
<template>
|
||||
<div class="summary container">
|
||||
<q-card>
|
||||
<skeleton-summary v-if="!invoiceOut" />
|
||||
<QCard>
|
||||
<SkeletonSummary v-if="!invoiceOut" />
|
||||
<template v-if="invoiceOut">
|
||||
<div class="header bg-primary q-pa-sm q-mb-md">
|
||||
{{ invoiceOut.ref }} - {{ invoiceOut.client.socialName }}
|
||||
</div>
|
||||
<q-list>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{ t('invoiceOut.summary.issued') }}</q-item-label>
|
||||
<q-item-label>{{ toDate(invoiceOut.issued) }}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{ t('invoiceOut.summary.dued') }}</q-item-label>
|
||||
<q-item-label>{{ toDate(invoiceOut.dued) }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{ t('invoiceOut.summary.created') }}</q-item-label>
|
||||
<q-item-label>{{ toDate(invoiceOut.created) }}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{ t('invoiceOut.summary.booked') }}</q-item-label>
|
||||
<q-item-label>{{ toDate(invoiceOut.booked) }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{ t('invoiceOut.summary.company') }}</q-item-label>
|
||||
<q-item-label>{{ invoiceOut.company.code }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<q-card-section class="q-pa-md">
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('invoiceOut.summary.issued')
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ toDate(invoiceOut.issued) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('invoiceOut.summary.dued')
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ toDate(invoiceOut.dued) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('invoiceOut.summary.created')
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ toDate(invoiceOut.created) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('invoiceOut.summary.booked')
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ toDate(invoiceOut.booked) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('invoiceOut.summary.company')
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ invoiceOut.company.code }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
<QCardSection class="q-pa-md">
|
||||
<h6>{{ t('invoiceOut.summary.taxBreakdown') }}</h6>
|
||||
<q-table :columns="taxColumns" :rows="tax" flat>
|
||||
<QTable :columns="taxColumns" :rows="tax" flat>
|
||||
<template #header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||
<QTr :props="props">
|
||||
<QTh
|
||||
v-for="col in props.cols"
|
||||
:key="col.name"
|
||||
:props="props"
|
||||
>
|
||||
{{ t(col.label) }}
|
||||
</q-th>
|
||||
</q-tr>
|
||||
</QTh>
|
||||
</QTr>
|
||||
</template>
|
||||
</q-table>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-md">
|
||||
</QTable>
|
||||
</QCardSection>
|
||||
<QCardSection class="q-pa-md">
|
||||
<h6>{{ t('invoiceOut.summary.tickets') }}</h6>
|
||||
<q-table :columns="ticketsColumns" :rows="tikets" flat>
|
||||
<QTable :columns="ticketsColumns" :rows="tikets" flat>
|
||||
<template #header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||
<QTr :props="props">
|
||||
<QTh
|
||||
v-for="col in props.cols"
|
||||
:key="col.name"
|
||||
:props="props"
|
||||
>
|
||||
{{ t(col.label) }}
|
||||
</q-th>
|
||||
</q-tr>
|
||||
</QTh>
|
||||
</QTr>
|
||||
</template>
|
||||
</q-table>
|
||||
</q-card-section>
|
||||
</QTable>
|
||||
</QCardSection>
|
||||
</template>
|
||||
</q-card>
|
||||
</QCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ const { dialogRef, onDialogHide } = useDialogPluginComponent();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog ref="dialogRef" @hide="onDialogHide">
|
||||
<invoiceOut-summary v-if="$props.id" :id="$props.id" />
|
||||
</q-dialog>
|
||||
<QDialog ref="dialogRef" @hide="onDialogHide">
|
||||
<InvoiceOutSummary v-if="$props.id" :id="$props.id" />
|
||||
</QDialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
@ -23,8 +23,8 @@ function setWorkers(data) {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<fetch-data url="ClaimStates" @on-fetch="(data) => (states = data)" auto-load />
|
||||
<fetch-data
|
||||
<FetchData url="ClaimStates" @on-fetch="(data) => (states = data)" auto-load />
|
||||
<FetchData
|
||||
url="Workers/activeWithInheritedRole"
|
||||
:filter="{ where: { role: 'salesPerson' } }"
|
||||
@on-fetch="setWorkers"
|
||||
|
@ -38,101 +38,101 @@ function setWorkers(data) {
|
|||
</div>
|
||||
</template>
|
||||
<template #body="{ params, searchFn }">
|
||||
<q-list dense>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
<QList dense>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('Customer ID')"
|
||||
v-model="params.clientFk"
|
||||
lazy-rules
|
||||
>
|
||||
<template #prepend>
|
||||
<q-icon name="vn:client" size="sm"></q-icon>
|
||||
<QIcon name="vn:client" size="sm"></QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input :label="t('FI')" v-model="params.fi" lazy-rules>
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput :label="t('FI')" v-model="params.fi" lazy-rules>
|
||||
<template #prepend>
|
||||
<q-icon name="badge" size="sm"></q-icon>
|
||||
<QIcon name="badge" size="sm"></QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input :label="t('Amount')" v-model="params.amount" lazy-rules>
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput :label="t('Amount')" v-model="params.amount" lazy-rules>
|
||||
<template #prepend>
|
||||
<q-icon name="euro" size="sm"></q-icon>
|
||||
<QIcon name="euro" size="sm"></QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('Min')"
|
||||
type="number"
|
||||
v-model.number="params.min"
|
||||
lazy-rules
|
||||
>
|
||||
<template #prepend>
|
||||
<q-icon name="euro" size="sm"></q-icon>
|
||||
<QIcon name="euro" size="sm"></QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('Max')"
|
||||
type="number"
|
||||
v-model.number="params.max"
|
||||
lazy-rules
|
||||
>
|
||||
<template #prepend>
|
||||
<q-icon name="euro" size="sm"></q-icon>
|
||||
<QIcon name="euro" size="sm"></QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-mb-md">
|
||||
<q-item-section>
|
||||
<q-checkbox
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-mb-md">
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
v-model="params.hasPdf"
|
||||
@update:model-value="searchFn()"
|
||||
:label="t('Has PDF')"
|
||||
toggle-indeterminate
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<q-expansion-item :label="t('More options')" expand-separator>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QSeparator />
|
||||
<QExpansionItem :label="t('More options')" expand-separator>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('Issued')"
|
||||
v-model="params.issued"
|
||||
mask="date"
|
||||
>
|
||||
<template #append>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy
|
||||
<QIcon name="event" class="cursor-pointer">
|
||||
<QPopupProxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-date v-model="params.issued" landscape>
|
||||
<QDate v-model="params.issued" landscape>
|
||||
<div
|
||||
class="row items-center justify-end q-gutter-sm"
|
||||
>
|
||||
<q-btn
|
||||
<QBtn
|
||||
:label="t('globals.cancel')"
|
||||
color="primary"
|
||||
flat
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn
|
||||
<QBtn
|
||||
:label="t('globals.confirm')"
|
||||
color="primary"
|
||||
flat
|
||||
|
@ -140,38 +140,38 @@ function setWorkers(data) {
|
|||
v-close-popup
|
||||
/>
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</QDate>
|
||||
</QPopupProxy>
|
||||
</QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('Created')"
|
||||
v-model="params.created"
|
||||
mask="date"
|
||||
>
|
||||
<template #append>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy
|
||||
<QIcon name="event" class="cursor-pointer">
|
||||
<QPopupProxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-date v-model="params.created" landscape>
|
||||
<QDate v-model="params.created" landscape>
|
||||
<div
|
||||
class="row items-center justify-end q-gutter-sm"
|
||||
>
|
||||
<q-btn
|
||||
<QBtn
|
||||
:label="t('globals.cancel')"
|
||||
color="primary"
|
||||
flat
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn
|
||||
<QBtn
|
||||
:label="t('globals.confirm')"
|
||||
color="primary"
|
||||
flat
|
||||
|
@ -179,34 +179,34 @@ function setWorkers(data) {
|
|||
v-close-popup
|
||||
/>
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</QDate>
|
||||
</QPopupProxy>
|
||||
</QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input :label="t('Dued')" v-model="params.dued" mask="date">
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput :label="t('Dued')" v-model="params.dued" mask="date">
|
||||
<template #append>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy
|
||||
<QIcon name="event" class="cursor-pointer">
|
||||
<QPopupProxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-date v-model="params.dued" landscape>
|
||||
<QDate v-model="params.dued" landscape>
|
||||
<div
|
||||
class="row items-center justify-end q-gutter-sm"
|
||||
>
|
||||
<q-btn
|
||||
<QBtn
|
||||
:label="t('globals.cancel')"
|
||||
color="primary"
|
||||
flat
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn
|
||||
<QBtn
|
||||
:label="t('globals.confirm')"
|
||||
color="primary"
|
||||
flat
|
||||
|
@ -214,15 +214,15 @@ function setWorkers(data) {
|
|||
v-close-popup
|
||||
/>
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</QDate>
|
||||
</QPopupProxy>
|
||||
</QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-expansion-item>
|
||||
</q-list>
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QExpansionItem>
|
||||
</QList>
|
||||
</template>
|
||||
</VnFilterPanel>
|
||||
</template>
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n';
|
|||
import { useRouter } from 'vue-router';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import Paginate from 'src/components/PaginateData.vue';
|
||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||
import InvoiceOutSummaryDialog from './Card/InvoiceOutSummaryDialog.vue';
|
||||
import { toDate, toCurrency } from 'src/filters/index';
|
||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||
|
@ -19,7 +19,7 @@ onMounted(() => (stateStore.rightDrawer = true));
|
|||
onUnmounted(() => (stateStore.rightDrawer = false));
|
||||
|
||||
function navigate(id) {
|
||||
router.push({ path: `/invoiceOut/${id}` });
|
||||
router.push({ path: `/invoice-out/${id}` });
|
||||
}
|
||||
|
||||
function viewSummary(id) {
|
||||
|
@ -43,131 +43,129 @@ function viewSummary(id) {
|
|||
</Teleport>
|
||||
<Teleport to="#actions-append">
|
||||
<div class="row q-gutter-x-sm">
|
||||
<q-btn
|
||||
<QBtn
|
||||
flat
|
||||
@click="stateStore.toggleRightDrawer()"
|
||||
round
|
||||
dense
|
||||
icon="menu"
|
||||
>
|
||||
<q-tooltip bottom anchor="bottom right">
|
||||
<QTooltip bottom anchor="bottom right">
|
||||
{{ t('globals.collapseMenu') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
<q-drawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<InvoiceOutFilter data-key="InvoiceOutList" />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page class="column items-center q-pa-md">
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
<div class="card-list">
|
||||
<paginate
|
||||
<VnPaginate
|
||||
data-key="InvoiceOutList"
|
||||
url="InvoiceOuts/filter"
|
||||
order="issued DESC, id DESC"
|
||||
auto-load
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<q-card class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||
<q-item
|
||||
<QCard class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||
<QItem
|
||||
class="q-pa-none items-start cursor-pointer q-hoverable"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
<q-item-section class="q-pa-md" @click="navigate(row.id)">
|
||||
<QItemSection class="q-pa-md" @click="navigate(row.id)">
|
||||
<div class="text-h6">{{ row.ref }}</div>
|
||||
<q-item-label caption>#{{ row.id }}</q-item-label>
|
||||
<q-list>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<QItemLabel caption>#{{ row.id }}</QItemLabel>
|
||||
<QList>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('invoiceOut.list.issued') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toDate(row.issued) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('invoiceOut.list.amount') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toCurrency(row.amount) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('invoiceOut.list.client') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ row.clientSocialName }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('invoiceOut.list.created') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toDate(row.created) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('invoiceOut.list.company') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{
|
||||
row.companyCode
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ row.companyCode }}</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('invoiceOut.list.dued') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toDate(row.dued) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-item-section>
|
||||
<q-separator vertical />
|
||||
<q-card-actions vertical class="justify-between">
|
||||
<q-btn
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QItemSection>
|
||||
<QSeparator vertical />
|
||||
<QCardActions vertical class="justify-between">
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="orange"
|
||||
icon="arrow_circle_right"
|
||||
@click="navigate(row.id)"
|
||||
>
|
||||
<q-tooltip>
|
||||
<QTooltip>
|
||||
{{ t('components.smartCard.openCard') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="grey-7"
|
||||
icon="preview"
|
||||
@click="viewSummary(row.id)"
|
||||
>
|
||||
<q-tooltip>
|
||||
<QTooltip>
|
||||
{{ t('components.smartCard.openSummary') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-item>
|
||||
</q-card>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</QCardActions>
|
||||
</QItem>
|
||||
</QCard>
|
||||
</template>
|
||||
</paginate>
|
||||
</VnPaginate>
|
||||
</div>
|
||||
</q-page>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -6,12 +6,12 @@ const stateStore = useStateStore();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-drawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<LeftMenu />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page-container>
|
||||
<router-view></router-view>
|
||||
</q-page-container>
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPageContainer>
|
||||
<RouterView></RouterView>
|
||||
</QPageContainer>
|
||||
</template>
|
||||
|
|
|
@ -48,36 +48,40 @@ const password = ref('');
|
|||
const keepLogin = ref(true);
|
||||
|
||||
async function onSubmit() {
|
||||
const { data } = await axios.post('Accounts/login', {
|
||||
user: username.value,
|
||||
password: password.value,
|
||||
});
|
||||
try {
|
||||
const { data } = await axios.post('Accounts/login', {
|
||||
user: username.value,
|
||||
password: password.value,
|
||||
});
|
||||
|
||||
if (!data) return;
|
||||
if (!data) return;
|
||||
|
||||
await session.login(data.token, keepLogin.value);
|
||||
await session.login(data.token, keepLogin.value);
|
||||
|
||||
quasar.notify({
|
||||
message: t('login.loginSuccess'),
|
||||
type: 'positive',
|
||||
});
|
||||
quasar.notify({
|
||||
message: t('login.loginSuccess'),
|
||||
type: 'positive',
|
||||
});
|
||||
|
||||
const currentRoute = router.currentRoute.value;
|
||||
if (currentRoute.query && currentRoute.query.redirect) {
|
||||
router.push(currentRoute.query.redirect);
|
||||
} else {
|
||||
router.push({ name: 'Dashboard' });
|
||||
const currentRoute = router.currentRoute.value;
|
||||
if (currentRoute.query && currentRoute.query.redirect) {
|
||||
router.push(currentRoute.query.redirect);
|
||||
} else {
|
||||
router.push({ name: 'Dashboard' });
|
||||
}
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-layout>
|
||||
<q-page-container>
|
||||
<q-page id="login">
|
||||
<q-page-sticky position="top-right">
|
||||
<q-toolbar>
|
||||
<q-btn
|
||||
<QLayout>
|
||||
<QPageContainer>
|
||||
<QPage id="login">
|
||||
<QPageSticky position="top-right">
|
||||
<QToolbar>
|
||||
<QBtn
|
||||
id="switchLanguage"
|
||||
:label="t('globals.language')"
|
||||
icon="translate"
|
||||
|
@ -86,55 +90,55 @@ async function onSubmit() {
|
|||
flat
|
||||
rounded
|
||||
>
|
||||
<q-menu auto-close>
|
||||
<q-list dense>
|
||||
<q-item
|
||||
<QMenu auto-close>
|
||||
<QList dense>
|
||||
<QItem
|
||||
@click="userLocale = 'en'"
|
||||
:active="userLocale == 'en'"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
{{ t('globals.lang.en') }}
|
||||
</q-item>
|
||||
<q-item
|
||||
</QItem>
|
||||
<QItem
|
||||
@click="userLocale = 'es'"
|
||||
:active="userLocale == 'es'"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
{{ t('globals.lang.es') }}
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-btn>
|
||||
<q-list>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
t(`globals.darkMode`)
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side>
|
||||
<q-toggle
|
||||
</QItem>
|
||||
</QList>
|
||||
</QMenu>
|
||||
</QBtn>
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t(`globals.darkMode`) }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection side>
|
||||
<QToggle
|
||||
v-model="darkMode"
|
||||
checked-icon="dark_mode"
|
||||
unchecked-icon="light_mode"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-toolbar>
|
||||
</q-page-sticky>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QToolbar>
|
||||
</QPageSticky>
|
||||
<div class="login-form q-pa-xl">
|
||||
<q-img
|
||||
<QImg
|
||||
src="~/assets/logo.svg"
|
||||
alt="Logo"
|
||||
fit="contain"
|
||||
:ratio="16 / 9"
|
||||
class="q-mb-md"
|
||||
/>
|
||||
<q-form @submit="onSubmit" class="q-gutter-md">
|
||||
<q-input
|
||||
<QForm @submit="onSubmit" class="q-gutter-md">
|
||||
<QInput
|
||||
v-model="username"
|
||||
:label="t('login.username')"
|
||||
lazy-rules
|
||||
|
@ -143,7 +147,7 @@ async function onSubmit() {
|
|||
(val && val.length > 0) || t('login.fieldRequired'),
|
||||
]"
|
||||
/>
|
||||
<q-input
|
||||
<QInput
|
||||
type="password"
|
||||
v-model="password"
|
||||
:label="t('login.password')"
|
||||
|
@ -153,10 +157,10 @@ async function onSubmit() {
|
|||
(val && val.length > 0) || t('login.fieldRequired'),
|
||||
]"
|
||||
/>
|
||||
<q-toggle v-model="keepLogin" :label="t('login.keepLogin')" />
|
||||
<QToggle v-model="keepLogin" :label="t('login.keepLogin')" />
|
||||
|
||||
<div>
|
||||
<q-btn
|
||||
<QBtn
|
||||
:label="t('login.submit')"
|
||||
type="submit"
|
||||
color="primary"
|
||||
|
@ -165,11 +169,11 @@ async function onSubmit() {
|
|||
unelevated
|
||||
/>
|
||||
</div>
|
||||
</q-form>
|
||||
</QForm>
|
||||
</div>
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
</q-layout>
|
||||
</QPage>
|
||||
</QPageContainer>
|
||||
</QLayout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -9,12 +9,14 @@ const { t } = useI18n();
|
|||
<div class="text-center q-pa-md flex flex-center">
|
||||
<div>
|
||||
<div class="text-grey-5" style="opacity: 0.4; font-size: 30vh">
|
||||
<q-icon name="vn:claims" />
|
||||
<QIcon name="vn:claims" />
|
||||
</div>
|
||||
|
||||
<div class="text-h2 text-grey-5" style="opacity: 0.4">{{ t('notFound') }}</div>
|
||||
<div class="text-h2 text-grey-5" style="opacity: 0.4">
|
||||
{{ t('notFound') }}
|
||||
</div>
|
||||
|
||||
<q-btn
|
||||
<QBtn
|
||||
@click="router.go(-1)"
|
||||
:label="t('globals.back')"
|
||||
class="q-mt-xl"
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<template>
|
||||
<q-card>Basic Data</q-card>
|
||||
</template>
|
||||
<QCard>Basic Data</QCard>
|
||||
</template>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { computed, ref, onMounted } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import axios from 'axios';
|
||||
import { date, useQuasar } from 'quasar';
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
|
@ -21,22 +21,25 @@ const expeditions = ref({});
|
|||
const lastExpedition = ref();
|
||||
const slide = ref(null);
|
||||
const videoList = ref([]);
|
||||
const time = ref({
|
||||
const time = reactive({
|
||||
min: 0,
|
||||
max: 24,
|
||||
});
|
||||
|
||||
async function fetch() {
|
||||
const filter = {
|
||||
where: {
|
||||
ticketFk: entityId.value,
|
||||
},
|
||||
};
|
||||
const { data } = await axios.get(`/Expeditions/filter`, {
|
||||
params: { filter },
|
||||
});
|
||||
try {
|
||||
const filter = {
|
||||
where: {
|
||||
ticketFk: entityId.value,
|
||||
},
|
||||
};
|
||||
const { data } = await axios.get(`/Expeditions/filter`, {
|
||||
params: { filter },
|
||||
});
|
||||
|
||||
if (data) expeditions.value = data;
|
||||
if (data) expeditions.value = data;
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
async function getVideoList(expeditionId, timed) {
|
||||
|
@ -46,110 +49,118 @@ async function getVideoList(expeditionId, timed) {
|
|||
};
|
||||
|
||||
if (timed) {
|
||||
if (timed.max == timed.min) {
|
||||
if (timed.max != 24) timed.max += 1;
|
||||
else timed.min -= 1;
|
||||
}
|
||||
Object.assign(params, { from: timed.min, to: timed.max });
|
||||
}
|
||||
const { data } = await axios.get(`/Boxings/getVideoList`, { params: params });
|
||||
await axios.get(`/Boxings/getVideoList`, { params: params }).then((res) => {
|
||||
const data = res.data;
|
||||
if (!data.length) {
|
||||
return quasar.notify({
|
||||
message: t('ticket.boxing.notFound'),
|
||||
type: 'negative',
|
||||
});
|
||||
}
|
||||
const list = [];
|
||||
for (const video of data) {
|
||||
const videoName = video.split('.')[0].split('T')[1].replace(/-/g, ':');
|
||||
list.push({
|
||||
label: videoName,
|
||||
value: video,
|
||||
url: `api/Boxings/getVideo?id=${expeditionId}&filename=${video}`,
|
||||
});
|
||||
}
|
||||
|
||||
const list = [];
|
||||
for (const video of data) {
|
||||
const videName = video.split('.')[0].split('T')[1].replaceAll('-', ':');
|
||||
list.push({
|
||||
label: videName,
|
||||
value: video,
|
||||
url: `api/Boxings/getVideo?id=${expeditionId}&filename=${video}`,
|
||||
});
|
||||
}
|
||||
|
||||
videoList.value = list.reverse();
|
||||
if (list[0]) {
|
||||
slide.value = list[0].value;
|
||||
time.value = {
|
||||
min: parseInt(list[0].label.split(':')[0]),
|
||||
max: parseInt(list[list.length - 1].label.split(':')[0]),
|
||||
};
|
||||
}
|
||||
|
||||
if (!data.length) {
|
||||
return quasar.notify({
|
||||
message: t('ticket.boxing.notFound'),
|
||||
type: 'negative',
|
||||
});
|
||||
}
|
||||
videoList.value = list.reverse();
|
||||
if (list[0]) {
|
||||
slide.value = list[0].value;
|
||||
time.min = parseInt(list[0].label.split(':')[0]);
|
||||
time.max = parseInt(list[list.length - 1].label.split(':')[0]) + 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<teleport to=".q-layout">
|
||||
<q-drawer show-if-above side="right">
|
||||
<q-scroll-area class="fit">
|
||||
<q-list bordered separator style="max-width: 318px">
|
||||
<q-item v-if="lastExpedition && videoList.length">
|
||||
<q-item-section>
|
||||
<q-item-label class="text-h6">
|
||||
{{ t('ticket.boxing.selectTime') }} ({{ time.min }}-{{ time.max }})
|
||||
</q-item-label>
|
||||
<q-range
|
||||
v-model="time"
|
||||
@change="getVideoList(lastExpedition, time)"
|
||||
:min="0"
|
||||
:max="24"
|
||||
:step="1"
|
||||
:left-label-value="time.min + ':00'"
|
||||
:right-label-value="time.max + ':00'"
|
||||
label
|
||||
markers
|
||||
snap
|
||||
color="orange"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="lastExpedition && videoList.length">
|
||||
<q-item-section>
|
||||
<q-select
|
||||
color="orange"
|
||||
v-model="slide"
|
||||
:options="videoList"
|
||||
:label="t('ticket.boxing.selectVideo')"
|
||||
emit-value
|
||||
map-options
|
||||
>
|
||||
<template #prepend>
|
||||
<q-icon name="schedule" />
|
||||
</template>
|
||||
</q-select>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
v-for="expedition in expeditions"
|
||||
:key="expedition.id"
|
||||
@click="getVideoList(expedition.id)"
|
||||
clickable
|
||||
v-ripple
|
||||
>
|
||||
<q-item-section>
|
||||
<q-item-label class="text-h6">#{{ expedition.id }}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{ t('ticket.boxing.created') }}</q-item-label>
|
||||
<q-item-label>
|
||||
{{ date.formatDate(expedition.created, 'YYYY-MM-DD HH:mm:ss') }}
|
||||
</q-item-label>
|
||||
<q-item-label caption>{{ t('ticket.boxing.item') }}</q-item-label>
|
||||
<q-item-label>{{ expedition.packagingItemFk }}</q-item-label>
|
||||
<q-item-label caption>{{ t('ticket.boxing.worker') }}</q-item-label>
|
||||
<q-item-label>{{ expedition.userName }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
</teleport>
|
||||
<QDrawer show-if-above side="right">
|
||||
<QScrollArea class="fit">
|
||||
<QList bordered separator style="max-width: 318px">
|
||||
<QItem v-if="lastExpedition && videoList.length">
|
||||
<QItemSection>
|
||||
<QItemLabel class="text-h6">
|
||||
{{ t('ticket.boxing.selectTime') }} ({{ time.min }}-{{
|
||||
time.max
|
||||
}})
|
||||
</QItemLabel>
|
||||
<QRange
|
||||
v-model="time"
|
||||
@change="getVideoList(lastExpedition, time)"
|
||||
:min="0"
|
||||
:max="24"
|
||||
:step="1"
|
||||
:left-label-value="time.min + ':00'"
|
||||
:right-label-value="time.max + ':00'"
|
||||
label
|
||||
markers
|
||||
snap
|
||||
color="orange"
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="lastExpedition && videoList.length">
|
||||
<QItemSection>
|
||||
<QSelect
|
||||
color="orange"
|
||||
v-model="slide"
|
||||
:options="videoList"
|
||||
:label="t('ticket.boxing.selectVideo')"
|
||||
emit-value
|
||||
map-options
|
||||
>
|
||||
<template #prepend>
|
||||
<QIcon name="schedule" />
|
||||
</template>
|
||||
</QSelect>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem
|
||||
v-for="expedition in expeditions"
|
||||
:key="expedition.id"
|
||||
@click="getVideoList(expedition.id)"
|
||||
clickable
|
||||
v-ripple
|
||||
>
|
||||
<QItemSection>
|
||||
<QItemLabel class="text-h6">#{{ expedition.id }}</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{ t('ticket.boxing.created') }}</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{
|
||||
date.formatDate(expedition.created, 'YYYY-MM-DD HH:mm:ss')
|
||||
}}
|
||||
</QItemLabel>
|
||||
<QItemLabel caption>{{ t('ticket.boxing.item') }}</QItemLabel>
|
||||
<QItemLabel>{{ expedition.packagingItemFk }}</QItemLabel>
|
||||
<QItemLabel caption>{{ t('ticket.boxing.worker') }}</QItemLabel>
|
||||
<QItemLabel>{{ expedition.userName }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
|
||||
<q-card>
|
||||
<q-carousel animated v-model="slide" height="max-content">
|
||||
<q-carousel-slide v-for="video in videoList" :key="video.value" :name="video.value">
|
||||
<q-video :src="video.url" :ratio="16 / 9" />
|
||||
</q-carousel-slide>
|
||||
</q-carousel>
|
||||
</q-card>
|
||||
<QCard>
|
||||
<QCarousel animated v-model="slide" height="max-content">
|
||||
<QCarouselSlide
|
||||
v-for="video in videoList"
|
||||
:key="video.value"
|
||||
:name="video.value"
|
||||
>
|
||||
<QVideo :src="video.url" :ratio="16 / 9" />
|
||||
</QCarouselSlide>
|
||||
</QCarousel>
|
||||
</QCard>
|
||||
</template>
|
||||
|
|
|
@ -17,18 +17,18 @@ const { t } = useI18n();
|
|||
:info="t('You can search by ticket id or alias')"
|
||||
/>
|
||||
</Teleport>
|
||||
<q-drawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<q-scroll-area class="fit">
|
||||
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<QScrollArea class="fit">
|
||||
<TicketDescriptor />
|
||||
<q-separator />
|
||||
<left-menu source="card" />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page-container>
|
||||
<q-page class="q-pa-md">
|
||||
<router-view></router-view>
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
<QSeparator />
|
||||
<LeftMenu source="card" />
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPageContainer>
|
||||
<QPage class="q-pa-md">
|
||||
<RouterView></RouterView>
|
||||
</QPage>
|
||||
</QPageContainer>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
@ -75,91 +75,91 @@ function stateColor(state) {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<card-descriptor module="Ticket" :url="`Tickets/${entityId}`" :filter="filter">
|
||||
<CardDescriptor module="Ticket" :url="`Tickets/${entityId}`" :filter="filter">
|
||||
<template #menu="{ entity }">
|
||||
<TicketDescriptorMenu :ticket="entity" />
|
||||
</template>
|
||||
<template #description="{ entity }">
|
||||
<span>
|
||||
{{ entity.client.name }}
|
||||
<q-tooltip>{{ entity.client.name }}</q-tooltip>
|
||||
<QTooltip>{{ entity.client.name }}</QTooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #body="{ entity }">
|
||||
<q-list>
|
||||
<q-item>
|
||||
<q-item-section v-if="entity.ticketState">
|
||||
<q-item-label caption>{{ t('ticket.card.state') }}</q-item-label>
|
||||
<q-item-label :class="stateColor(entity.ticketState.state)">
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection v-if="entity.ticketState">
|
||||
<QItemLabel caption>{{ t('ticket.card.state') }}</QItemLabel>
|
||||
<QItemLabel :class="stateColor(entity.ticketState.state)">
|
||||
{{ entity.ticketState.state.name }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.card.shipped') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ toDate(entity.shipped) }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ toDate(entity.shipped) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.card.customerId') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
<span class="link">
|
||||
{{ entity.clientFk }}
|
||||
<CustomerDescriptorProxy :id="entity.client.id" />
|
||||
</span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section v-if="entity.client && entity.client.salesPersonUser">
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection v-if="entity.client && entity.client.salesPersonUser">
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.card.salesPerson') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ entity.client.salesPersonUser.name }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="entity.warehouse">
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="entity.warehouse">
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.card.warehouse') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.warehouse.name }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="entity.agencyMode">
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{ t('ticket.card.agency') }}</q-item-label>
|
||||
<q-item-label>{{ entity.agencyMode.name }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<q-card-actions class="q-gutter-md">
|
||||
<q-icon
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.warehouse.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="entity.agencyMode">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{ t('ticket.card.agency') }}</QItemLabel>
|
||||
<QItemLabel>{{ entity.agencyMode.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
<QCardActions class="q-gutter-md">
|
||||
<QIcon
|
||||
v-if="entity.isDeleted == true"
|
||||
name="vn:deletedTicket"
|
||||
size="xs"
|
||||
color="primary"
|
||||
>
|
||||
<q-tooltip>{{ t('This ticket is deleted') }}</q-tooltip>
|
||||
</q-icon>
|
||||
</q-card-actions>
|
||||
<QTooltip>{{ t('This ticket is deleted') }}</QTooltip>
|
||||
</QIcon>
|
||||
</QCardActions>
|
||||
|
||||
<q-card-actions>
|
||||
<q-btn
|
||||
<QCardActions>
|
||||
<QBtn
|
||||
size="md"
|
||||
icon="vn:client"
|
||||
color="primary"
|
||||
:to="{ name: 'CustomerCard', params: { id: entity.clientFk } }"
|
||||
>
|
||||
<q-tooltip>{{ t('ticket.card.customerCard') }}</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
<QTooltip>{{ t('ticket.card.customerCard') }}</QTooltip>
|
||||
</QBtn>
|
||||
</QCardActions>
|
||||
</template>
|
||||
</card-descriptor>
|
||||
</CardDescriptor>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
|
|
|
@ -135,106 +135,106 @@ async function remove() {
|
|||
}
|
||||
</script>
|
||||
<template>
|
||||
<q-item v-ripple clickable>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="picture_as_pdf" />
|
||||
</q-item-section>
|
||||
<q-item-section>{{ t('Open Delivery Note...') }}</q-item-section>
|
||||
<q-item-section side>
|
||||
<q-icon name="keyboard_arrow_right" />
|
||||
</q-item-section>
|
||||
<q-menu anchor="top end" self="top start" auto-close bordered>
|
||||
<q-list>
|
||||
<q-item @click="openDeliveryNote('deliveryNote')" v-ripple clickable>
|
||||
<q-item-section>{{ t('With prices') }}</q-item-section>
|
||||
</q-item>
|
||||
<q-item @click="openDeliveryNote('withoutPrices')" v-ripple clickable>
|
||||
<q-item-section>{{ t('Without prices') }}</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
<QItem v-ripple clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="picture_as_pdf" />
|
||||
</QItemSection>
|
||||
<QItemSection>{{ t('Open Delivery Note...') }}</QItemSection>
|
||||
<QItemSection side>
|
||||
<QIcon name="keyboard_arrow_right" />
|
||||
</QItemSection>
|
||||
<QMenu anchor="top end" self="top start" auto-close bordered>
|
||||
<QList>
|
||||
<QItem @click="openDeliveryNote('deliveryNote')" v-ripple clickable>
|
||||
<QItemSection>{{ t('With prices') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem @click="openDeliveryNote('withoutPrices')" v-ripple clickable>
|
||||
<QItemSection>{{ t('Without prices') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem
|
||||
@click="openDeliveryNote('deliveryNote', 'csv')"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
<q-item-section>{{ t('As CSV') }}</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-item>
|
||||
<q-item v-ripple clickable>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="send" />
|
||||
</q-item-section>
|
||||
<q-item-section>{{ t('Send Delivery Note...') }}</q-item-section>
|
||||
<q-item-section side>
|
||||
<q-icon name="keyboard_arrow_right" />
|
||||
</q-item-section>
|
||||
<q-menu anchor="top end" self="top start" auto-close>
|
||||
<q-list>
|
||||
<q-item
|
||||
<QItemSection>{{ t('As CSV') }}</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QMenu>
|
||||
</QItem>
|
||||
<QItem v-ripple clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="send" />
|
||||
</QItemSection>
|
||||
<QItemSection>{{ t('Send Delivery Note...') }}</QItemSection>
|
||||
<QItemSection side>
|
||||
<QIcon name="keyboard_arrow_right" />
|
||||
</QItemSection>
|
||||
<QMenu anchor="top end" self="top start" auto-close>
|
||||
<QList>
|
||||
<QItem
|
||||
@click="sendDeliveryNoteConfirmation('deliveryNote')"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
<q-item-section>{{ t('With prices') }}</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
<QItemSection>{{ t('With prices') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem
|
||||
@click="sendDeliveryNoteConfirmation('withoutPrices')"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
<q-item-section>{{ t('Without prices') }}</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
<QItemSection>{{ t('Without prices') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem
|
||||
@click="sendDeliveryNoteConfirmation('deliveryNote', 'csv')"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
<q-item-section>{{ t('As CSV') }}</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-item>
|
||||
<q-item @click="openDeliveryNote('proforma')" v-ripple clickable>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="receipt" />
|
||||
</q-item-section>
|
||||
<q-item-section>{{ t('Open Proforma Invoice') }}</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-ripple clickable>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="sms" />
|
||||
</q-item-section>
|
||||
<q-item-section>{{ t('Send SMS...') }}</q-item-section>
|
||||
<q-item-section side>
|
||||
<q-icon name="keyboard_arrow_right" />
|
||||
</q-item-section>
|
||||
<q-menu anchor="top end" self="top start" auto-close>
|
||||
<q-list>
|
||||
<q-item @click="showSmsDialog('pendingPayment')" v-ripple clickable>
|
||||
<q-item-section>{{ t('Pending payment') }}</q-item-section>
|
||||
</q-item>
|
||||
<q-item @click="showSmsDialog('minAmount')" v-ripple clickable>
|
||||
<q-item-section>{{ t('Minimum amount') }}</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
<QItemSection>{{ t('As CSV') }}</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QMenu>
|
||||
</QItem>
|
||||
<QItem @click="openDeliveryNote('proforma')" v-ripple clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="receipt" />
|
||||
</QItemSection>
|
||||
<QItemSection>{{ t('Open Proforma Invoice') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-ripple clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="sms" />
|
||||
</QItemSection>
|
||||
<QItemSection>{{ t('Send SMS...') }}</QItemSection>
|
||||
<QItemSection side>
|
||||
<QIcon name="keyboard_arrow_right" />
|
||||
</QItemSection>
|
||||
<QMenu anchor="top end" self="top start" auto-close>
|
||||
<QList>
|
||||
<QItem @click="showSmsDialog('pendingPayment')" v-ripple clickable>
|
||||
<QItemSection>{{ t('Pending payment') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem @click="showSmsDialog('minAmount')" v-ripple clickable>
|
||||
<QItemSection>{{ t('Minimum amount') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem
|
||||
@click="showSmsDialogWithChanges('orderChanges')"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
<q-item-section>{{ t('Order changes') }}</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-item>
|
||||
<QItemSection>{{ t('Order changes') }}</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QMenu>
|
||||
</QItem>
|
||||
<template v-if="!ticket.isDeleted">
|
||||
<q-separator />
|
||||
<q-item @click="confirmDelete()" v-ripple clickable>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="delete" />
|
||||
</q-item-section>
|
||||
<q-item-section>{{ t('Delete ticket') }}</q-item-section>
|
||||
</q-item>
|
||||
<QSeparator />
|
||||
<QItem @click="confirmDelete()" v-ripple clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="delete" />
|
||||
</QItemSection>
|
||||
<QItemSection>{{ t('Delete ticket') }}</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ const $props = defineProps({
|
|||
});
|
||||
</script>
|
||||
<template>
|
||||
<q-popup-proxy>
|
||||
<QPopupProxy>
|
||||
<TicketDescriptor v-if="$props.id" :id="$props.id" />
|
||||
</q-popup-proxy>
|
||||
</QPopupProxy>
|
||||
</template>
|
||||
|
|
|
@ -81,14 +81,14 @@ async function changeState(value) {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<fetch-data
|
||||
<FetchData
|
||||
url="States/editableStates"
|
||||
@on-fetch="(data) => (editableStates = data)"
|
||||
auto-load
|
||||
/>
|
||||
<div class="summary container">
|
||||
<q-card>
|
||||
<skeleton-summary v-if="!ticket" />
|
||||
<QCard>
|
||||
<SkeletonSummary v-if="!ticket" />
|
||||
<template v-if="ticket">
|
||||
<div class="header bg-primary q-pa-sm q-mb-md">
|
||||
<span>
|
||||
|
@ -97,7 +97,7 @@ async function changeState(value) {
|
|||
}}) -
|
||||
{{ ticket.nickname }}
|
||||
</span>
|
||||
<q-btn-dropdown
|
||||
<QBtnDropdown
|
||||
side
|
||||
top
|
||||
color="orange-11"
|
||||
|
@ -105,284 +105,270 @@ async function changeState(value) {
|
|||
:label="t('ticket.summary.changeState')"
|
||||
:disable="!isEditable()"
|
||||
>
|
||||
<q-list>
|
||||
<q-virtual-scroll
|
||||
<QList>
|
||||
<QVirtualScroll
|
||||
style="max-height: 300px"
|
||||
:items="editableStates"
|
||||
separator
|
||||
v-slot="{ item, index }"
|
||||
>
|
||||
<q-item
|
||||
<QItem
|
||||
:key="index"
|
||||
dense
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="changeState(item.code)"
|
||||
>
|
||||
<q-item-section>
|
||||
<q-item-label>{{ item.name }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-virtual-scroll>
|
||||
</q-list>
|
||||
</q-btn-dropdown>
|
||||
<QItemSection>
|
||||
<QItemLabel>{{ item.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QVirtualScroll>
|
||||
</QList>
|
||||
</QBtnDropdown>
|
||||
</div>
|
||||
<div class="row q-pa-md q-col-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
t('ticket.summary.state')
|
||||
}}</q-item-label>
|
||||
<q-item-label
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.summary.state') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel
|
||||
:class="stateColor(ticket.ticketState.state)"
|
||||
>
|
||||
{{ ticket.ticketState.state.name }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.salesPerson')
|
||||
}}</q-item-label>
|
||||
<q-item-label>
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>
|
||||
<span class="link">
|
||||
{{ ticket.client.salesPersonUser.name }}
|
||||
<WorkerDescriptorProxy
|
||||
:id="ticket.client.salesPersonFk"
|
||||
/>
|
||||
</span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.agency')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{
|
||||
ticket.agencyMode.name
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ ticket.agencyMode.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.zone')
|
||||
}}</q-item-label>
|
||||
<q-item-label class="link">{{
|
||||
}}</QItemLabel>
|
||||
<QItemLabel class="link">{{
|
||||
ticket.routeFk
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
}}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.warehouse')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{
|
||||
ticket.warehouse.name
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ ticket.warehouse.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.invoice')
|
||||
}}</q-item-label>
|
||||
<q-item-label v-if="ticket.refFk">
|
||||
}}</QItemLabel>
|
||||
<QItemLabel v-if="ticket.refFk">
|
||||
<span class="link">
|
||||
{{ ticket.refFk }}
|
||||
<InvoiceOutDescriptorProxy :id="ticket.id" />
|
||||
</span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.shipped')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{
|
||||
toDate(ticket.shipped)
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ toDate(ticket.shipped) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.landed')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{
|
||||
toDate(ticket.landed)
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ toDate(ticket.landed) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.packages')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{ ticket.packages }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ ticket.packages }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.consigneePhone')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{
|
||||
ticket.address.phone
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ ticket.address.phone }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.consigneeMobile')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{
|
||||
ticket.address.mobile
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ ticket.address.mobile }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.clientPhone')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{ ticket.client.phone }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ ticket.client.phone }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.clientMobile')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{
|
||||
ticket.client.mobile
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ ticket.client.mobile }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.consignee')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{ formattedAddress() }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ formattedAddress() }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item v-for="note in ticket.notes" :key="note.id">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<QList>
|
||||
<QItem v-for="note in ticket.notes" :key="note.id">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ note.observationType.description }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ note.description }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-list class="taxes">
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
<QList class="taxes">
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.subtotal')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{
|
||||
toCurrency(ticket.totalWithoutVat)
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
}}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.vat')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{
|
||||
toCurrency(
|
||||
ticket.totalWithVat - ticket.totalWithoutVat
|
||||
)
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
}}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('ticket.summary.total')
|
||||
}}</q-item-label>
|
||||
<q-item-label>{{
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{
|
||||
toCurrency(ticket.totalWithVat)
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
}}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-pa-md" v-if="salesLines.length > 0">
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('ticket.summary.saleLines') }}
|
||||
<router-link
|
||||
<RouterLink
|
||||
:to="{
|
||||
name: 'TicketBasicData',
|
||||
params: { id: entityId },
|
||||
}"
|
||||
target="_blank"
|
||||
>
|
||||
<q-icon name="open_in_new" />
|
||||
</router-link>
|
||||
</q-item-label>
|
||||
<q-table :rows="ticket.sales" flat>
|
||||
<QIcon name="open_in_new" />
|
||||
</RouterLink>
|
||||
</QItemLabel>
|
||||
<QTable :rows="ticket.sales" flat>
|
||||
<template #header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th auto-width></q-th>
|
||||
<q-th auto-width>{{
|
||||
<QTr :props="props">
|
||||
<QTh auto-width></QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.item')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.visible')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.available')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.quantity')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.description')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.price')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.discount')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.amount')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.packing')
|
||||
}}</q-th>
|
||||
</q-tr>
|
||||
}}</QTh>
|
||||
</QTr>
|
||||
</template>
|
||||
<template #body="props">
|
||||
<q-tr :props="props">
|
||||
<q-td>
|
||||
<q-btn
|
||||
<QTr :props="props">
|
||||
<QTd>
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
size="xs"
|
||||
|
@ -396,14 +382,14 @@ async function changeState(value) {
|
|||
},
|
||||
}"
|
||||
>
|
||||
<q-tooltip
|
||||
<QTooltip
|
||||
>{{ t('ticket.summary.claim') }}:
|
||||
{{
|
||||
props.row.claim.claimFk
|
||||
}}</q-tooltip
|
||||
}}</QTooltip
|
||||
>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
</QBtn>
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
size="xs"
|
||||
|
@ -418,60 +404,64 @@ async function changeState(value) {
|
|||
},
|
||||
}"
|
||||
>
|
||||
<q-tooltip
|
||||
<QTooltip
|
||||
>{{ t('ticket.summary.claim') }}:
|
||||
{{
|
||||
props.row.claimBeginning.claimFk
|
||||
}}</q-tooltip
|
||||
}}</QTooltip
|
||||
>
|
||||
</q-btn>
|
||||
<q-icon
|
||||
</QBtn>
|
||||
<QIcon
|
||||
name="warning"
|
||||
v-show="props.row.visible < 0"
|
||||
size="xs"
|
||||
color="primary"
|
||||
>
|
||||
<q-tooltip
|
||||
<QTooltip
|
||||
>{{ t('ticket.summary.visible') }}:
|
||||
{{ props.row.visible }}</q-tooltip
|
||||
{{ props.row.visible }}</QTooltip
|
||||
>
|
||||
</q-icon>
|
||||
<q-icon
|
||||
</QIcon>
|
||||
<QIcon
|
||||
name="vn:reserva"
|
||||
v-show="props.row.reserved"
|
||||
size="xs"
|
||||
color="primary"
|
||||
>
|
||||
<q-tooltip>{{
|
||||
t('ticket.summary.reserved')
|
||||
}}</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon
|
||||
<QTooltip>
|
||||
{{ t('ticket.summary.reserved') }}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
<QIcon
|
||||
name="vn:unavailable"
|
||||
v-show="props.row.itemShortage"
|
||||
size="xs"
|
||||
color="primary"
|
||||
>
|
||||
<q-tooltip>{{
|
||||
t('ticket.summary.itemShortage')
|
||||
}}</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon
|
||||
<QTooltip>
|
||||
{{ t('ticket.summary.itemShortage') }}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
<QIcon
|
||||
name="vn:components"
|
||||
v-show="props.row.hasComponentLack"
|
||||
size="xs"
|
||||
color="primary"
|
||||
>
|
||||
<q-tooltip>{{
|
||||
t('ticket.summary.hasComponentLack')
|
||||
}}</q-tooltip>
|
||||
</q-icon>
|
||||
</q-td>
|
||||
<q-td class="link">{{ props.row.itemFk }}</q-td>
|
||||
<q-td>{{ props.row.visible }}</q-td>
|
||||
<q-td>{{ props.row.available }}</q-td>
|
||||
<q-td>{{ props.row.quantity }}</q-td>
|
||||
<q-td>
|
||||
<QTooltip>
|
||||
{{
|
||||
t(
|
||||
'ticket.summary.hasComponentLack'
|
||||
)
|
||||
}}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</QTd>
|
||||
<QTd class="link">{{ props.row.itemFk }}</QTd>
|
||||
<QTd>{{ props.row.visible }}</QTd>
|
||||
<QTd>{{ props.row.available }}</QTd>
|
||||
<QTd>{{ props.row.quantity }}</QTd>
|
||||
<QTd>
|
||||
<div class="fetched-tags">
|
||||
<span>{{ props.row.item.name }}</span>
|
||||
<span
|
||||
|
@ -484,10 +474,10 @@ async function changeState(value) {
|
|||
:item="props.row.item"
|
||||
:max-length="5"
|
||||
></fetched-tags>
|
||||
</q-td>
|
||||
<q-td>{{ props.row.price }}</q-td>
|
||||
<q-td>{{ props.row.discount }} %</q-td>
|
||||
<q-td
|
||||
</QTd>
|
||||
<QTd>{{ props.row.price }}</QTd>
|
||||
<QTd>{{ props.row.discount }} %</QTd>
|
||||
<QTd
|
||||
>{{
|
||||
toCurrency(
|
||||
props.row.quantity *
|
||||
|
@ -495,14 +485,14 @@ async function changeState(value) {
|
|||
((100 - props.row.discount) / 100)
|
||||
)
|
||||
}}
|
||||
</q-td>
|
||||
<q-td>{{
|
||||
</QTd>
|
||||
<QTd>{{
|
||||
dashIfEmpty(props.row.item.itemPackingTypeFk)
|
||||
}}</q-td>
|
||||
</q-tr>
|
||||
}}</QTd>
|
||||
</QTr>
|
||||
</template>
|
||||
</q-table>
|
||||
</q-list>
|
||||
</QTable>
|
||||
</QList>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
@ -510,137 +500,137 @@ async function changeState(value) {
|
|||
v-if="ticket.packagings.length > 0 || ticket.services.length > 0"
|
||||
>
|
||||
<div class="col" v-if="ticket.packagings.length > 0">
|
||||
<q-list>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('ticket.summary.packages') }}
|
||||
<q-icon name="open_in_new" />
|
||||
</q-item-label>
|
||||
<q-table :rows="ticket.packagings" flat>
|
||||
<QIcon name="open_in_new" />
|
||||
</QItemLabel>
|
||||
<QTable :rows="ticket.packagings" flat>
|
||||
<template #header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th auto-width>{{
|
||||
<QTr :props="props">
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.created')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.package')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.quantity')
|
||||
}}</q-th>
|
||||
</q-tr>
|
||||
}}</QTh>
|
||||
</QTr>
|
||||
</template>
|
||||
<template #body="props">
|
||||
<q-tr :props="props">
|
||||
<q-td>{{ toDate(props.row.created) }}</q-td>
|
||||
<q-td>{{ props.row.packaging.item.name }}</q-td>
|
||||
<q-td>{{ props.row.quantity }}</q-td>
|
||||
</q-tr>
|
||||
<QTr :props="props">
|
||||
<QTd>{{ toDate(props.row.created) }}</QTd>
|
||||
<QTd>{{ props.row.packaging.item.name }}</QTd>
|
||||
<QTd>{{ props.row.quantity }}</QTd>
|
||||
</QTr>
|
||||
</template>
|
||||
</q-table>
|
||||
</q-list>
|
||||
</QTable>
|
||||
</QList>
|
||||
</div>
|
||||
<div class="col" v-if="ticket.services.length > 0">
|
||||
<q-list>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('ticket.summary.services') }}
|
||||
<q-icon name="open_in_new" />
|
||||
</q-item-label>
|
||||
<q-table :rows="ticket.services" flat>
|
||||
<QIcon name="open_in_new" />
|
||||
</QItemLabel>
|
||||
<QTable :rows="ticket.services" flat>
|
||||
<template #header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th auto-width>{{
|
||||
<QTr :props="props">
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.quantity')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.description')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.price')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.taxClass')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.amount')
|
||||
}}</q-th>
|
||||
</q-tr>
|
||||
}}</QTh>
|
||||
</QTr>
|
||||
</template>
|
||||
<template #body="props">
|
||||
<q-tr :props="props">
|
||||
<q-td>{{ props.row.quantity }}</q-td>
|
||||
<q-td>{{ props.row.description }}</q-td>
|
||||
<q-td>{{ toCurrency(props.row.price) }}</q-td>
|
||||
<q-td>{{ props.row.taxClass.description }}</q-td>
|
||||
<q-td>{{
|
||||
<QTr :props="props">
|
||||
<QTd>{{ props.row.quantity }}</QTd>
|
||||
<QTd>{{ props.row.description }}</QTd>
|
||||
<QTd>{{ toCurrency(props.row.price) }}</QTd>
|
||||
<QTd>{{ props.row.taxClass.description }}</QTd>
|
||||
<QTd>{{
|
||||
toCurrency(
|
||||
props.row.quantity * props.row.price
|
||||
)
|
||||
}}</q-td>
|
||||
</q-tr>
|
||||
}}</QTd>
|
||||
</QTr>
|
||||
</template>
|
||||
</q-table>
|
||||
</q-list>
|
||||
</QTable>
|
||||
</QList>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-pa-md" v-if="ticket.requests.length > 0">
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('ticket.summary.request') }}
|
||||
<q-icon name="open_in_new" />
|
||||
</q-item-label>
|
||||
<q-table :rows="ticket.requests" flat>
|
||||
<QIcon name="open_in_new" />
|
||||
</QItemLabel>
|
||||
<QTable :rows="ticket.requests" flat>
|
||||
<template #header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th auto-width>{{
|
||||
<QTr :props="props">
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.description')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.created')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.requester')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.atender')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.quantity')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.price')
|
||||
}}</q-th>
|
||||
<q-th auto-width>{{
|
||||
}}</QTh>
|
||||
<QTh auto-width>{{
|
||||
t('ticket.summary.item')
|
||||
}}</q-th>
|
||||
<q-th auto-width>Ok</q-th>
|
||||
</q-tr>
|
||||
}}</QTh>
|
||||
<QTh auto-width>Ok</QTh>
|
||||
</QTr>
|
||||
</template>
|
||||
<template #body="props">
|
||||
<q-tr :props="props">
|
||||
<q-td>{{ props.row.description }}</q-td>
|
||||
<q-td>{{ toDate(props.row.created) }}</q-td>
|
||||
<q-td>{{ props.row.requester.user.name }}</q-td>
|
||||
<q-td>{{ props.row.atender.user.name }}</q-td>
|
||||
<q-td>{{ props.row.quantity }}</q-td>
|
||||
<q-td>{{ toCurrency(props.row.price) }}</q-td>
|
||||
<q-td v-if="!props.row.sale">-</q-td>
|
||||
<q-td v-if="props.row.sale" class="link">{{
|
||||
<QTr :props="props">
|
||||
<QTd>{{ props.row.description }}</QTd>
|
||||
<QTd>{{ toDate(props.row.created) }}</QTd>
|
||||
<QTd>{{ props.row.requester.user.name }}</QTd>
|
||||
<QTd>{{ props.row.atender.user.name }}</QTd>
|
||||
<QTd>{{ props.row.quantity }}</QTd>
|
||||
<QTd>{{ toCurrency(props.row.price) }}</QTd>
|
||||
<QTd v-if="!props.row.sale">-</QTd>
|
||||
<QTd v-if="props.row.sale" class="link">{{
|
||||
props.row.sale.itemFk
|
||||
}}</q-td>
|
||||
<q-td
|
||||
><q-checkbox
|
||||
}}</QTd>
|
||||
<QTd
|
||||
><QCheckbox
|
||||
v-model="props.row.isOk"
|
||||
:disable="true"
|
||||
/></q-td>
|
||||
</q-tr>
|
||||
/></QTd>
|
||||
</QTr>
|
||||
</template>
|
||||
</q-table>
|
||||
</q-list>
|
||||
</QTable>
|
||||
</QList>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</q-card>
|
||||
</QCard>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -15,9 +15,9 @@ const { dialogRef, onDialogHide } = useDialogPluginComponent();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog ref="dialogRef" @hide="onDialogHide">
|
||||
<ticket-summary v-if="$props.id" :id="$props.id" />
|
||||
</q-dialog>
|
||||
<QDialog ref="dialogRef" @hide="onDialogHide">
|
||||
<TicketSummary v-if="$props.id" :id="$props.id" />
|
||||
</QDialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
@ -13,9 +13,9 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const from = Date.vnNew()
|
||||
const from = Date.vnNew();
|
||||
const to = Date.vnNew();
|
||||
to.setDate(to.getDate() + 1)
|
||||
to.setDate(to.getDate() + 1);
|
||||
|
||||
const defaultParams = {
|
||||
from: toDateString(from),
|
||||
|
@ -30,11 +30,11 @@ const warehouses = ref();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<fetch-data url="Provinces" @on-fetch="(data) => (provinces = data)" auto-load />
|
||||
<fetch-data url="States" @on-fetch="(data) => (states = data)" auto-load />
|
||||
<fetch-data url="AgencyModes" @on-fetch="(data) => (agencies = data)" auto-load />
|
||||
<fetch-data url="Warehouses" @on-fetch="(data) => (warehouses = data)" auto-load />
|
||||
<fetch-data
|
||||
<FetchData url="Provinces" @on-fetch="(data) => (provinces = data)" auto-load />
|
||||
<FetchData url="States" @on-fetch="(data) => (states = data)" auto-load />
|
||||
<FetchData url="AgencyModes" @on-fetch="(data) => (agencies = data)" auto-load />
|
||||
<FetchData url="Warehouses" @on-fetch="(data) => (warehouses = data)" auto-load />
|
||||
<FetchData
|
||||
url="Workers/activeWithInheritedRole"
|
||||
:filter="{ where: { role: 'salesPerson' } }"
|
||||
@on-fetch="(data) => (workers = data)"
|
||||
|
@ -52,76 +52,76 @@ const warehouses = ref();
|
|||
</div>
|
||||
</template>
|
||||
<template #body="{ params, searchFn }">
|
||||
<q-list dense>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
<QList dense>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
v-model="params.clientFk"
|
||||
:label="t('Customer ID')"
|
||||
lazy-rules
|
||||
/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
v-model="params.orderFk"
|
||||
:label="t('Order ID')"
|
||||
lazy-rules
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input v-model="params.from" :label="t('From')" mask="date">
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput v-model="params.from" :label="t('From')" mask="date">
|
||||
<template #append>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy
|
||||
<QIcon name="event" class="cursor-pointer">
|
||||
<QPopupProxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-date v-model="params.from" landscape>
|
||||
<QDate v-model="params.from" landscape>
|
||||
<div
|
||||
class="row items-center justify-end q-gutter-sm"
|
||||
>
|
||||
<q-btn
|
||||
<QBtn
|
||||
:label="t('globals.cancel')"
|
||||
color="primary"
|
||||
flat
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn
|
||||
<QBtn
|
||||
:label="t('globals.confirm')"
|
||||
color="primary"
|
||||
flat
|
||||
v-close-popup
|
||||
/>
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</QDate>
|
||||
</QPopupProxy>
|
||||
</QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-input v-model="params.to" :label="t('To')" mask="date">
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QInput v-model="params.to" :label="t('To')" mask="date">
|
||||
<template #append>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy
|
||||
<QIcon name="event" class="cursor-pointer">
|
||||
<QPopupProxy
|
||||
cover
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-date v-model="params.to" landscape>
|
||||
<QDate v-model="params.to" landscape>
|
||||
<div
|
||||
class="row items-center justify-end q-gutter-sm"
|
||||
>
|
||||
<q-btn
|
||||
<QBtn
|
||||
:label="t('globals.cancel')"
|
||||
color="primary"
|
||||
flat
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn
|
||||
<QBtn
|
||||
:label="t('globals.confirm')"
|
||||
color="primary"
|
||||
flat
|
||||
|
@ -129,19 +129,19 @@ const warehouses = ref();
|
|||
v-close-popup
|
||||
/>
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</QDate>
|
||||
</QPopupProxy>
|
||||
</QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="!workers">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="workers">
|
||||
<q-select
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="!workers">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="workers">
|
||||
<QSelect
|
||||
:label="t('Salesperson')"
|
||||
v-model="params.salesPersonFk"
|
||||
:options="workers"
|
||||
|
@ -152,14 +152,14 @@ const warehouses = ref();
|
|||
use-input
|
||||
:input-debounce="0"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="!states">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="states">
|
||||
<q-select
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="!states">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="states">
|
||||
<QSelect
|
||||
:label="t('State')"
|
||||
v-model="params.stateFk"
|
||||
@update:model-value="searchFn()"
|
||||
|
@ -169,71 +169,71 @@ const warehouses = ref();
|
|||
emit-value
|
||||
map-options
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
v-model="params.refFk"
|
||||
:label="t('Invoice Ref.')"
|
||||
lazy-rules
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-checkbox
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
v-model="params.myTeam"
|
||||
@update:model-value="searchFn()"
|
||||
:label="t('My team')"
|
||||
toggle-indeterminate
|
||||
/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-checkbox
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
v-model="params.pending"
|
||||
@update:model-value="searchFn()"
|
||||
:label="t('Pending')"
|
||||
toggle-indeterminate
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-checkbox
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
v-model="params.hasInvoice"
|
||||
@update:model-value="searchFn()"
|
||||
:label="t('Invoiced')"
|
||||
toggle-indeterminate
|
||||
/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-checkbox
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
v-model="params.hasRoute"
|
||||
@update:model-value="searchFn()"
|
||||
:label="t('Routed')"
|
||||
toggle-indeterminate
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-checkbox
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
v-model="params.problems"
|
||||
@update:model-value="searchFn()"
|
||||
:label="t('With problems')"
|
||||
toggle-indeterminate
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<q-expansion-item :label="t('More options')" expand-separator>
|
||||
<q-item>
|
||||
<q-item-section v-if="!provinces">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="provinces">
|
||||
<q-select
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QSeparator />
|
||||
<QExpansionItem :label="t('More options')" expand-separator>
|
||||
<QItem>
|
||||
<QItemSection v-if="!provinces">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="provinces">
|
||||
<QSelect
|
||||
:label="t('Province')"
|
||||
v-model="params.provinceFk"
|
||||
@update:model-value="searchFn()"
|
||||
|
@ -243,14 +243,14 @@ const warehouses = ref();
|
|||
emit-value
|
||||
map-options
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="!states">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="!states">
|
||||
<q-select
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="!agencies">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="agencies">
|
||||
<QSelect
|
||||
:label="t('Agency')"
|
||||
v-model="params.agencyModeFk"
|
||||
@update:model-value="searchFn()"
|
||||
|
@ -260,14 +260,14 @@ const warehouses = ref();
|
|||
emit-value
|
||||
map-options
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="!warehouses">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="warehouses">
|
||||
<q-select
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="!warehouses">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="warehouses">
|
||||
<QSelect
|
||||
:label="t('Warehouse')"
|
||||
v-model="params.warehouseFk"
|
||||
@update:model-value="searchFn()"
|
||||
|
@ -277,10 +277,10 @@ const warehouses = ref();
|
|||
emit-value
|
||||
map-options
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-expansion-item>
|
||||
</q-list>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QExpansionItem>
|
||||
</QList>
|
||||
</template>
|
||||
</VnFilterPanel>
|
||||
</template>
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n';
|
|||
import { useQuasar } from 'quasar';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import Paginate from 'src/components/PaginateData.vue';
|
||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||
import { toDate, toDateString, toCurrency } from 'src/filters/index';
|
||||
import TicketSummaryDialog from './Card/TicketSummaryDialog.vue';
|
||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||
|
@ -88,28 +88,28 @@ function viewSummary(id) {
|
|||
</Teleport>
|
||||
<Teleport to="#actions-append">
|
||||
<div class="row q-gutter-x-sm">
|
||||
<q-btn
|
||||
<QBtn
|
||||
flat
|
||||
@click="stateStore.toggleRightDrawer()"
|
||||
round
|
||||
dense
|
||||
icon="menu"
|
||||
>
|
||||
<q-tooltip bottom anchor="bottom right">
|
||||
<QTooltip bottom anchor="bottom right">
|
||||
{{ t('globals.collapseMenu') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
<q-drawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<TicketFilter data-key="TicketList" />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page class="column items-center q-pa-md">
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
<div class="card-list">
|
||||
<paginate
|
||||
<VnPaginate
|
||||
data-key="TicketList"
|
||||
url="Tickets/filter"
|
||||
:filter="filter"
|
||||
|
@ -118,109 +118,109 @@ function viewSummary(id) {
|
|||
auto-load
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<q-card class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||
<q-item
|
||||
<QCard class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||
<QItem
|
||||
class="q-pa-none items-start cursor-pointer q-hoverable"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
<q-item-section class="q-pa-md" @click="navigate(row.id)">
|
||||
<QItemSection class="q-pa-md" @click="navigate(row.id)">
|
||||
<div class="text-h6">{{ row.name }}</div>
|
||||
<q-item-label caption>#{{ row.id }}</q-item-label>
|
||||
<q-list>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<QItemLabel caption>#{{ row.id }}</QItemLabel>
|
||||
<QList>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.list.nickname') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ row.nickname }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.list.state') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
<q-badge
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
<QBadge
|
||||
:color="stateColor(row)"
|
||||
class="q-ma-none"
|
||||
dense
|
||||
>
|
||||
{{ row.state }}
|
||||
</q-badge>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QBadge>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.list.shipped') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toDate(row.shipped) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('Zone') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ row.zoneName }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.list.salesPerson') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ row.salesPerson }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.list.total') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ toCurrency(row.totalWithVat) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-item-section>
|
||||
<q-separator vertical />
|
||||
<q-card-actions vertical class="justify-between">
|
||||
<q-btn
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QItemSection>
|
||||
<QSeparator vertical />
|
||||
<QCardActions vertical class="justify-between">
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="orange"
|
||||
icon="arrow_circle_right"
|
||||
@click="navigate(row.id)"
|
||||
>
|
||||
<q-tooltip>
|
||||
<QTooltip>
|
||||
{{ t('components.smartCard.openCard') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="grey-7"
|
||||
icon="preview"
|
||||
@click="viewSummary(row.id)"
|
||||
>
|
||||
<q-tooltip>
|
||||
<QTooltip>
|
||||
{{ t('components.smartCard.openSummary') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-item>
|
||||
</q-card>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</QCardActions>
|
||||
</QItem>
|
||||
</QCard>
|
||||
</template>
|
||||
</paginate>
|
||||
</VnPaginate>
|
||||
</div>
|
||||
</q-page>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -6,12 +6,12 @@ const stateStore = useStateStore();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-drawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<LeftMenu />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page-container>
|
||||
<router-view></router-view>
|
||||
</q-page-container>
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPageContainer>
|
||||
<RouterView></RouterView>
|
||||
</QPageContainer>
|
||||
</template>
|
||||
|
|
|
@ -0,0 +1,419 @@
|
|||
<script setup>
|
||||
import axios from 'axios';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { computed, ref, onMounted, onUpdated } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
onMounted(() => fetch());
|
||||
onUpdated(() => fetch());
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const quasar = useQuasar();
|
||||
const router = useRouter();
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
const entityId = computed(() => $props.id || route.params.id);
|
||||
|
||||
const wagon = ref([]);
|
||||
const divisible = ref(false);
|
||||
const name = ref('');
|
||||
const colorPickerActive = ref(false);
|
||||
let originalData = { trays: [] };
|
||||
let wagonConfig;
|
||||
let wagonTypeColors;
|
||||
let currentTrayColorPicked;
|
||||
|
||||
async function fetch() {
|
||||
try {
|
||||
await axios.get('WagonConfigs').then(async (res) => {
|
||||
if (res.data) {
|
||||
wagonConfig = res.data[0];
|
||||
}
|
||||
});
|
||||
|
||||
await axios.get(`WagonTypeColors`).then(async (res) => {
|
||||
if (res.data) {
|
||||
wagonTypeColors = res.data;
|
||||
if (!entityId.value)
|
||||
wagon.value.push({
|
||||
id: 0,
|
||||
position: 0,
|
||||
color: { ...wagonTypeColors[0] },
|
||||
action: 'add',
|
||||
});
|
||||
else {
|
||||
await axios
|
||||
.get(`WagonTypeTrays`, {
|
||||
params: { filter: { where: { typeFk: entityId.value } } },
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (res.data) {
|
||||
for (let i = 0; i < res.data.length; i++) {
|
||||
const tray = res.data[i];
|
||||
wagon.value.push({
|
||||
id: res.data.length - i - 1,
|
||||
position: tray.height,
|
||||
color: {
|
||||
...wagonTypeColors.find((color) => {
|
||||
return color.id === tray.colorFk;
|
||||
}),
|
||||
},
|
||||
action: tray.height == 0 ? 'add' : 'delete',
|
||||
});
|
||||
}
|
||||
wagon.value.forEach((value) => {
|
||||
originalData.trays.push({ ...value });
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (entityId.value) {
|
||||
await axios.get(`WagonTypes/${entityId.value}`).then((res) => {
|
||||
if (res.data) {
|
||||
originalData.name = name.value = res.data.name;
|
||||
originalData.divisible = divisible.value = res.data.divisible;
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
function addTray() {
|
||||
if (
|
||||
wagon.value.find((tray) => {
|
||||
return tray.position == null;
|
||||
})
|
||||
) {
|
||||
quasar.notify({
|
||||
message: t('wagon.warnings.uncompleteTrays'),
|
||||
type: 'warning',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (wagon.value.length < wagonConfig.maxTrays) {
|
||||
wagon.value.unshift({
|
||||
id: wagon.value.length,
|
||||
position: null,
|
||||
color: { ...wagonTypeColors[0] },
|
||||
action: 'delete',
|
||||
});
|
||||
} else {
|
||||
quasar.notify({
|
||||
message: t('wagon.warnings.maxTrays'),
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function deleteTray(trayToDelete) {
|
||||
wagon.value = wagon.value.filter((tray) => tray.id !== trayToDelete.id);
|
||||
reorderIds();
|
||||
}
|
||||
|
||||
function reorderIds() {
|
||||
for (let index = wagon.value.length - 1; index >= 0; index--) {
|
||||
wagon.value[index].id = index;
|
||||
}
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
try {
|
||||
const path = entityId.value
|
||||
? 'WagonTypes/editWagonType'
|
||||
: 'WagonTypes/createWagonType';
|
||||
|
||||
const params = {
|
||||
id: entityId.value,
|
||||
name: name.value,
|
||||
divisible: divisible.value,
|
||||
trays: wagon.value,
|
||||
};
|
||||
|
||||
await axios.patch(path, params).then((res) => {
|
||||
if (res.status == 204) router.push({ path: `/wagon/type/list` });
|
||||
});
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
function onReset() {
|
||||
name.value = entityId.value ? originalData.name : null;
|
||||
divisible.value = entityId.value ? originalData.divisible : false;
|
||||
wagon.value = entityId.value
|
||||
? [...originalData.trays]
|
||||
: [
|
||||
{
|
||||
id: 0,
|
||||
position: 0,
|
||||
color: { ...wagonTypeColors[0] },
|
||||
action: 'add',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function doAction(tray) {
|
||||
if (tray.action == 'add') {
|
||||
addTray();
|
||||
} else {
|
||||
deleteTray(tray);
|
||||
}
|
||||
}
|
||||
|
||||
function showColorPicker(tray) {
|
||||
colorPickerActive.value = true;
|
||||
currentTrayColorPicked = wagon.value.findIndex((val) => {
|
||||
return val.id === tray.id;
|
||||
});
|
||||
}
|
||||
|
||||
function updateColor(newColor) {
|
||||
wagon.value[currentTrayColorPicked].color = {
|
||||
...wagonTypeColors.find((color) => {
|
||||
return color.rgb === newColor;
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
function onPositionBlur(tray) {
|
||||
if (tray.position) {
|
||||
if (tray.position == '' || tray.position < 0) {
|
||||
tray.position = null;
|
||||
return;
|
||||
}
|
||||
tray.position = parseInt(tray.position);
|
||||
wagon.value.sort((a, b) => b.position - a.position);
|
||||
reorderIds();
|
||||
for (let index = wagon.value.length - 1; index > 0; index--) {
|
||||
if (exceedMaxHeight(index - 1)) continue;
|
||||
if (
|
||||
wagon.value[index - 1].position - wagon.value[index].position >=
|
||||
wagonConfig.minHeightBetweenTrays
|
||||
) {
|
||||
continue;
|
||||
} else {
|
||||
wagon.value[index - 1].position +=
|
||||
wagonConfig.minHeightBetweenTrays -
|
||||
(wagon.value[index - 1].position - wagon.value[index].position);
|
||||
|
||||
quasar.notify({
|
||||
message:
|
||||
t('wagon.warnings.minHeightBetweenTrays') +
|
||||
wagonConfig.minHeightBetweenTrays +
|
||||
' cm',
|
||||
type: 'warning',
|
||||
});
|
||||
|
||||
exceedMaxHeight(index - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function exceedMaxHeight(pos) {
|
||||
if (wagon.value[pos].position > wagonConfig.maxWagonHeight) {
|
||||
wagon.value.splice(pos, 1);
|
||||
quasar.notify({
|
||||
message:
|
||||
t('wagon.warnings.maxWagonHeight') + wagonConfig.maxWagonHeight + ' cm',
|
||||
type: 'warning',
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QPage class="q-pa-sm q-mx-xl">
|
||||
<QCard class="q-pa-sm">
|
||||
<QForm @submit="onSubmit()" @reset="onReset()" class="q-pa-md">
|
||||
<QInput
|
||||
filled
|
||||
v-model="name"
|
||||
:label="t('wagon.type.name')"
|
||||
:rules="[(val) => !!val || t('wagon.warnings.nameNotEmpty')]"
|
||||
/>
|
||||
<QCheckbox class="q-mb-sm" v-model="divisible" label="Divisible" />
|
||||
<div class="wagon-tray q-mx-xl" v-for="tray in wagon" :key="tray.id">
|
||||
<div class="position">
|
||||
<QInput
|
||||
autofocus
|
||||
filled
|
||||
type="number"
|
||||
:class="{ isVisible: tray.action == 'add' }"
|
||||
v-model="tray.position"
|
||||
@blur="onPositionBlur(tray)"
|
||||
>
|
||||
<QTooltip :delay="2000">
|
||||
{{
|
||||
t('wagon.warnings.minHeightBetweenTrays') +
|
||||
wagonConfig.minHeightBetweenTrays +
|
||||
' cm'
|
||||
}}
|
||||
<QSpace />
|
||||
{{
|
||||
t('wagon.warnings.maxWagonHeight') +
|
||||
wagonConfig.maxWagonHeight +
|
||||
' cm'
|
||||
}}
|
||||
</QTooltip>
|
||||
</QInput>
|
||||
</div>
|
||||
<div class="shelving">
|
||||
<div class="shelving-half">
|
||||
<div class="shelving-up"></div>
|
||||
<div
|
||||
class="shelving-down"
|
||||
:style="{ backgroundColor: tray.color.rgb }"
|
||||
@click="showColorPicker(tray)"
|
||||
></div>
|
||||
</div>
|
||||
<div
|
||||
class="shelving-divisible"
|
||||
:class="{ isVisible: !divisible }"
|
||||
></div>
|
||||
<div class="shelving-half">
|
||||
<div class="shelving-up"></div>
|
||||
<div
|
||||
class="shelving-down"
|
||||
:style="{ backgroundColor: tray.color.rgb }"
|
||||
@click="showColorPicker(tray)"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="action-button">
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
:icon="tray.action"
|
||||
@click="doAction(tray)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="q-mb-sm wheels">
|
||||
<QIcon color="grey-6" name="trip_origin" size="3rem" />
|
||||
<QIcon color="grey-6" name="trip_origin" size="3rem" />
|
||||
</div>
|
||||
<div>
|
||||
<QBtn :label="t('wagon.type.submit')" type="submit" color="primary" />
|
||||
<QBtn
|
||||
:label="t('wagon.type.reset')"
|
||||
type="reset"
|
||||
color="primary"
|
||||
flat
|
||||
class="q-ml-sm"
|
||||
/>
|
||||
</div>
|
||||
<QDialog
|
||||
v-model="colorPickerActive"
|
||||
position="right"
|
||||
:no-backdrop-dismiss="false"
|
||||
>
|
||||
<QCard>
|
||||
<QCardSection>
|
||||
<div class="text-h6">{{ t('wagon.type.trayColor') }}</div>
|
||||
</QCardSection>
|
||||
<QCardSection class="row items-center no-wrap">
|
||||
<QColor
|
||||
flat
|
||||
v-model="wagon[currentTrayColorPicked].color.rgb"
|
||||
no-header
|
||||
no-footer
|
||||
default-view="palette"
|
||||
:palette="
|
||||
wagonTypeColors.map((color) => {
|
||||
return color.rgb;
|
||||
})
|
||||
"
|
||||
@change="updateColor($event)"
|
||||
/>
|
||||
<QBtn flat round icon="close" v-close-popup />
|
||||
</QCardSection>
|
||||
</QCard>
|
||||
</QDialog>
|
||||
</QForm>
|
||||
</QCard>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.q-page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.q-card {
|
||||
width: 70%;
|
||||
}
|
||||
.q-dialog {
|
||||
.q-card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.wheels {
|
||||
margin-left: 5%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.wagon-tray {
|
||||
display: flex;
|
||||
height: 6rem;
|
||||
.position {
|
||||
width: 15%;
|
||||
border-right: 1rem solid gray;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: flex-end;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
.shelving {
|
||||
display: flex;
|
||||
width: 75%;
|
||||
.shelving-half {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
.shelving-up {
|
||||
height: 80%;
|
||||
width: 100%;
|
||||
}
|
||||
.shelving-down {
|
||||
height: 20%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.shelving-divisible {
|
||||
width: 1%;
|
||||
height: 100%;
|
||||
border-left: 0.5rem dashed grey;
|
||||
border-right: 0.5rem dashed grey;
|
||||
}
|
||||
}
|
||||
.action-button {
|
||||
width: 10%;
|
||||
border-left: 1rem solid gray;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: flex-start;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.isVisible {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,102 @@
|
|||
<script setup>
|
||||
import axios from 'axios';
|
||||
import { useQuasar } from 'quasar';
|
||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
const quasar = useQuasar();
|
||||
const arrayData = useArrayData('WagonTypeList');
|
||||
const store = arrayData.store;
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
|
||||
function navigate(id) {
|
||||
router.push({ path: `/wagon/type/${id}/edit` });
|
||||
}
|
||||
|
||||
function create() {
|
||||
router.push({ path: `/wagon/type/create` });
|
||||
}
|
||||
|
||||
async function remove(row) {
|
||||
try {
|
||||
const id = row.id;
|
||||
await axios
|
||||
.delete(`WagonTypes/deleteWagonType`, { params: { id } })
|
||||
.then(async () => {
|
||||
quasar.notify({
|
||||
message: t('wagon.type.removeItem'),
|
||||
type: 'positive',
|
||||
});
|
||||
store.data.splice(store.data.indexOf(row), 1);
|
||||
});
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
<div class="card-list">
|
||||
<VnPaginate
|
||||
data-key="WagonTypeList"
|
||||
url="/WagonTypes"
|
||||
order="id DESC"
|
||||
auto-load
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<QCard class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||
<QItem
|
||||
class="q-pa-none items-start cursor-pointer q-hoverable"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
<QItemSection class="q-pa-md" @click="navigate(row.id)">
|
||||
<div class="text-h6">{{ row.name }}</div>
|
||||
<QItem-label caption>#{{ row.id }}</QItem-label>
|
||||
</QItemSection>
|
||||
<QSeparator vertical />
|
||||
<QCardActions vertical class="justify-between">
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="arrow_circle_right"
|
||||
@click="navigate(row.id)"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('components.smartCard.openCard') }}
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="delete"
|
||||
@click="remove(row)"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('wagon.list.remove') }}
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</QCardActions>
|
||||
</QItem>
|
||||
</QCard>
|
||||
</template>
|
||||
</VnPaginate>
|
||||
</div>
|
||||
<QPageSticky position="bottom-right" :offset="[18, 18]">
|
||||
<QBtn @click="create" fab icon="add" color="primary" />
|
||||
</QPageSticky>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
width: 100%;
|
||||
max-width: 60em;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,182 @@
|
|||
<script setup>
|
||||
import axios from 'axios';
|
||||
import { QIcon, QInput, QItem, QItemSection, QSelect } from 'quasar';
|
||||
import { computed, onMounted, onUpdated, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
onMounted(() => fetch());
|
||||
onUpdated(() => fetch());
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
const entityId = computed(() => $props.id || route.params.id);
|
||||
|
||||
let wagonTypes;
|
||||
let originalData = {};
|
||||
const wagon = ref({});
|
||||
const filteredWagonTypes = ref(wagonTypes);
|
||||
|
||||
async function onSubmit() {
|
||||
try {
|
||||
const params = {
|
||||
id: entityId.value,
|
||||
label: wagon.value.label,
|
||||
plate: wagon.value.plate,
|
||||
volume: wagon.value.volume,
|
||||
typeFk: wagon.value.typeFk,
|
||||
};
|
||||
await axios.patch('Wagons', params).then((res) => {
|
||||
if (res.status == 200) router.push({ path: `/wagon/list` });
|
||||
});
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
async function onReset() {
|
||||
if (entityId.value) {
|
||||
wagon.value = { ...originalData };
|
||||
} else {
|
||||
wagon.value = {};
|
||||
}
|
||||
}
|
||||
|
||||
async function fetch() {
|
||||
try {
|
||||
await axios.get('WagonTypes').then(async (res) => {
|
||||
if (res.data) {
|
||||
filteredWagonTypes.value = wagonTypes = res.data;
|
||||
}
|
||||
});
|
||||
if (entityId.value) {
|
||||
await axios.get(`Wagons/${entityId.value}`).then(async (res) => {
|
||||
const data = res.data;
|
||||
if (data) {
|
||||
wagon.value.label = data.label;
|
||||
wagon.value.plate = data.plate;
|
||||
wagon.value.volume = data.volume;
|
||||
wagon.value.typeFk = data.typeFk;
|
||||
originalData = { ...wagon.value };
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
function filterType(val, update) {
|
||||
update(() => {
|
||||
const needle = val.toLowerCase();
|
||||
filteredWagonTypes.value = wagonTypes.filter(
|
||||
(v) => v.name.toLowerCase().indexOf(needle) > -1
|
||||
);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QPage class="q-pa-sm q-mx-xl">
|
||||
<QCard class="q-pa-sm">
|
||||
<QForm @submit="onSubmit()" @reset="onReset()" class="q-pa-md">
|
||||
<div class="row q-col-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<QInput
|
||||
filled
|
||||
v-model="wagon.label"
|
||||
:label="t('wagon.create.label')"
|
||||
type="number"
|
||||
min="0"
|
||||
:rules="[(val) => !!val || t('wagon.warnings.labelNotEmpty')]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<QInput
|
||||
filled
|
||||
v-model="wagon.plate"
|
||||
:label="t('wagon.create.plate')"
|
||||
:rules="[(val) => !!val || t('wagon.warnings.plateNotEmpty')]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-col-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<QInput
|
||||
filled
|
||||
v-model="wagon.volume"
|
||||
:label="t('wagon.create.volume')"
|
||||
type="number"
|
||||
min="0"
|
||||
:rules="[
|
||||
(val) => !!val || t('wagon.warnings.volumeNotEmpty'),
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<QSelect
|
||||
filled
|
||||
v-model="wagon.typeFk"
|
||||
use-input
|
||||
fill-input
|
||||
hide-selected
|
||||
input-debounce="0"
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
emit-value
|
||||
map-options
|
||||
:label="t('wagon.create.type')"
|
||||
:options="filteredWagonTypes"
|
||||
:rules="[(val) => !!val || t('wagon.warnings.typeNotEmpty')]"
|
||||
@filter="filterType"
|
||||
>
|
||||
<template v-if="wagon.typeFk" #append>
|
||||
<QIcon
|
||||
name="cancel"
|
||||
@click.stop.prevent="wagon.typeFk = null"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
<template #no-option>
|
||||
<QItem>
|
||||
<QItemSection class="text-grey">
|
||||
{{ t('wagon.warnings.noData') }}
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</QSelect>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<QBtn :label="t('wagon.type.submit')" type="submit" color="primary" />
|
||||
<QBtn
|
||||
:label="t('wagon.type.reset')"
|
||||
type="reset"
|
||||
color="primary"
|
||||
flat
|
||||
class="q-ml-sm"
|
||||
/>
|
||||
</div>
|
||||
</QForm>
|
||||
</QCard>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.q-page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.q-card {
|
||||
width: 70%;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,135 @@
|
|||
<script setup>
|
||||
import axios from 'axios';
|
||||
import { useQuasar } from 'quasar';
|
||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
const quasar = useQuasar();
|
||||
const arrayData = useArrayData('WagonList');
|
||||
const store = arrayData.store;
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
|
||||
const filter = {
|
||||
include: {
|
||||
relation: 'type',
|
||||
scope: {
|
||||
fields: 'name',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
function navigate(id) {
|
||||
router.push({ path: `/wagon/${id}/edit` });
|
||||
}
|
||||
|
||||
function create() {
|
||||
router.push({ path: `/wagon/create` });
|
||||
}
|
||||
|
||||
async function remove(row) {
|
||||
try {
|
||||
await axios.delete(`Wagons/${row.id}`).then(async () => {
|
||||
quasar.notify({
|
||||
message: t('wagon.list.removeItem'),
|
||||
type: 'positive',
|
||||
});
|
||||
store.data.splice(store.data.indexOf(row), 1);
|
||||
});
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
<div class="card-list">
|
||||
<VnPaginate
|
||||
data-key="WagonList"
|
||||
url="/Wagons"
|
||||
order="id DESC"
|
||||
:filter="filter"
|
||||
auto-load
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<QCard class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||
<QItem
|
||||
class="q-pa-none items-start cursor-pointer q-hoverable"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
<QItemSection class="q-pa-md" @click="navigate(row.id)">
|
||||
<div class="text-h6">{{ row.label }}</div>
|
||||
<QItemLabel caption>#{{ row.id }}</QItemLabel>
|
||||
<QList>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('wagon.list.plate') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ row.plate }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('wagon.list.volume') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ row.volume }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('wagon.list.type') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ row.type.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QItemSection>
|
||||
<QSeparator vertical />
|
||||
<QCardActions vertical class="justify-between">
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="arrow_circle_right"
|
||||
@click="navigate(row.id)"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('components.smartCard.openCard') }}
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="delete"
|
||||
@click="remove(row)"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('wagon.list.remove') }}
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</QCardActions>
|
||||
</QItem>
|
||||
</QCard>
|
||||
</template>
|
||||
</VnPaginate>
|
||||
</div>
|
||||
<QPageSticky position="bottom-right" :offset="[18, 18]">
|
||||
<QBtn @click="create" fab icon="add" color="primary" />
|
||||
</QPageSticky>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
width: 100%;
|
||||
max-width: 60em;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,17 @@
|
|||
<script setup>
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import LeftMenu from 'src/components/LeftMenu.vue';
|
||||
|
||||
const stateStore = useStateStore();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<LeftMenu />
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPageContainer>
|
||||
<RouterView></RouterView>
|
||||
</QPageContainer>
|
||||
</template>
|
|
@ -17,18 +17,18 @@ const { t } = useI18n();
|
|||
:info="t('You can search by worker id or name')"
|
||||
/>
|
||||
</Teleport>
|
||||
<q-drawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<q-scroll-area class="fit">
|
||||
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<QScrollArea class="fit">
|
||||
<WorkerDescriptor />
|
||||
<q-separator />
|
||||
<left-menu source="card" />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page-container>
|
||||
<q-page class="q-pa-md">
|
||||
<router-view></router-view>
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
<QSeparator />
|
||||
<LeftMenu source="card" />
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPageContainer>
|
||||
<QPage class="q-pa-md">
|
||||
<RouterView></RouterView>
|
||||
</QPage>
|
||||
</QPageContainer>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
|
|
|
@ -54,21 +54,21 @@ function getWorkerAvatar() {
|
|||
}
|
||||
</script>
|
||||
<template>
|
||||
<card-descriptor
|
||||
<CardDescriptor
|
||||
module="Worker"
|
||||
:url="`Workers/${entityId}`"
|
||||
:filter="filter"
|
||||
@on-fetch="(data) => (worker = data)"
|
||||
>
|
||||
<template #before>
|
||||
<q-img :src="getWorkerAvatar()" class="photo">
|
||||
<QImg :src="getWorkerAvatar()" class="photo">
|
||||
<template #error>
|
||||
<div
|
||||
class="absolute-full bg-grey-10 text-center q-pa-md flex flex-center"
|
||||
>
|
||||
<div>
|
||||
<div class="text-grey-5" style="opacity: 0.4; font-size: 5vh">
|
||||
<q-icon name="vn:claims" />
|
||||
<QIcon name="vn:claims" />
|
||||
</div>
|
||||
<div class="text-grey-5" style="opacity: 0.4">
|
||||
{{ t('worker.imageNotFound') }}
|
||||
|
@ -76,59 +76,59 @@ function getWorkerAvatar() {
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</q-img>
|
||||
</QImg>
|
||||
</template>
|
||||
<template #description="{ entity }">
|
||||
<span>
|
||||
{{ entity.user.nickname }}
|
||||
<q-tooltip>{{ entity.user.nickname }}</q-tooltip>
|
||||
<QTooltip>{{ entity.user.nickname }}</QTooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #body="{ entity }">
|
||||
<q-list>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption> {{ t('worker.card.name') }} </q-item-label>
|
||||
<q-item-label>{{ entity.user.nickname }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption> {{ t('worker.card.name') }} </QItemLabel>
|
||||
<QItemLabel>{{ entity.user.nickname }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('worker.card.email') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.user.email }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.user.email }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('worker.list.department') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ entity.department.department.name }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('worker.card.phone') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ entity.phone }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.phone }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption
|
||||
>{{ t('worker.summary.sipExtension') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ sip }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ sip }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</template>
|
||||
</card-descriptor>
|
||||
</CardDescriptor>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -10,7 +10,7 @@ const $props = defineProps({
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-popup-proxy>
|
||||
<QPopupProxy>
|
||||
<WorkerDescriptor v-if="$props.id" :id="$props.id" />
|
||||
</q-popup-proxy>
|
||||
</QPopupProxy>
|
||||
</template>
|
||||
|
|
|
@ -75,7 +75,7 @@ function sipExtension() {
|
|||
|
||||
<template>
|
||||
<div class="summary container">
|
||||
<q-card>
|
||||
<QCard>
|
||||
<SkeletonSummary v-if="!worker" />
|
||||
<template v-if="worker">
|
||||
<div class="header bg-primary q-pa-sm q-mb-md">
|
||||
|
@ -83,144 +83,140 @@ function sipExtension() {
|
|||
</div>
|
||||
<div class="row q-pa-md q-col-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('worker.summary.basicData') }}
|
||||
</q-item-label>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption> ID </q-item-label>
|
||||
<q-item-label>{{ worker.id }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption
|
||||
</QItemLabel>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption> ID </QItemLabel>
|
||||
<QItemLabel>{{ worker.id }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption
|
||||
>{{ t('worker.card.name') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ worker.user.nickname }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption
|
||||
>{{ t('worker.list.department') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{
|
||||
worker.department.department.name
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption
|
||||
}}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption
|
||||
>{{ t('worker.list.email') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ worker.user.email }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ worker.user.email }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem
|
||||
class="items-start cursor-pointer q-hoverable"
|
||||
v-if="worker.boss"
|
||||
>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('worker.summary.boss') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
<span class="link">
|
||||
{{ worker.boss.name }}
|
||||
<WorkerDescriptorProxy :id="worker.bossFk" />
|
||||
</span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption
|
||||
>{{ t('worker.summary.phoneExtension') }}
|
||||
</q-item-label>
|
||||
<q-item-label>
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{
|
||||
worker.mobileExtension == ''
|
||||
? worker.mobileExtension
|
||||
: '-'
|
||||
}}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption
|
||||
>{{ t('worker.summary.entPhone') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{
|
||||
worker.phone == '' ? worker.phone : '-'
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption
|
||||
}}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption
|
||||
>{{ t('worker.summary.personalPhone') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{
|
||||
worker.client.phone == ''
|
||||
? worker.client.phone
|
||||
: '-'
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
}}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-list>
|
||||
<q-item-label header class="text-h6">
|
||||
<QList>
|
||||
<QItemLabel header class="text-h6">
|
||||
{{ t('worker.summary.userData') }}
|
||||
</q-item-label>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('worker.summary.userId') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ worker.user.id }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ worker.user.id }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption
|
||||
>{{ t('worker.card.name') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{
|
||||
worker.user.nickname
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ worker.user.nickname }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption
|
||||
>{{ t('worker.summary.role') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{
|
||||
worker.user.role.name
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ worker.user.role.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption
|
||||
>{{ t('worker.summary.sipExtension') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ sipExtension() }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ sipExtension() }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</q-card>
|
||||
</QCard>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -15,7 +15,7 @@ const { dialogRef, onDialogHide } = useDialogPluginComponent();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog ref="dialogRef" @hide="onDialogHide">
|
||||
<worker-summary v-if="$props.id" :id="$props.id" />
|
||||
</q-dialog>
|
||||
<QDialog ref="dialogRef" @hide="onDialogHide">
|
||||
<WorkerSummary v-if="$props.id" :id="$props.id" />
|
||||
</QDialog>
|
||||
</template>
|
||||
|
|
|
@ -16,7 +16,7 @@ const departments = ref();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<fetch-data url="Departments" @on-fetch="(data) => (departments = data)" auto-load />
|
||||
<FetchData url="Departments" @on-fetch="(data) => (departments = data)" auto-load />
|
||||
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
|
||||
<template #tags="{ tag, formatFn }">
|
||||
<div class="q-gutter-x-xs">
|
||||
|
@ -25,49 +25,49 @@ const departments = ref();
|
|||
</div>
|
||||
</template>
|
||||
<template #body="{ params, searchFn }">
|
||||
<q-list dense>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input :label="t('FI')" v-model="params.fi" lazy-rules>
|
||||
<QList dense>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput :label="t('FI')" v-model="params.fi" lazy-rules>
|
||||
<template #prepend>
|
||||
<q-icon name="badge" size="sm"></q-icon>
|
||||
<QIcon name="badge" size="sm"></QIcon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('First Name')"
|
||||
v-model="params.firstName"
|
||||
lazy-rules
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('Last Name')"
|
||||
v-model="params.lastName"
|
||||
lazy-rules
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('User Name')"
|
||||
v-model="params.userName"
|
||||
lazy-rules
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section v-if="!departments">
|
||||
<q-skeleton type="QInput" class="full-width" />
|
||||
</q-item-section>
|
||||
<q-item-section v-if="departments">
|
||||
<q-select
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="!departments">
|
||||
<QSkeleton type="QInput" class="full-width" />
|
||||
</QItemSection>
|
||||
<QItemSection v-if="departments">
|
||||
<QSelect
|
||||
:label="t('Department')"
|
||||
v-model="params.departmentFk"
|
||||
@update:model-value="searchFn()"
|
||||
|
@ -79,18 +79,18 @@ const departments = ref();
|
|||
use-input
|
||||
:input-debounce="0"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-mb-md">
|
||||
<q-item-section>
|
||||
<q-input
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-mb-md">
|
||||
<QItemSection>
|
||||
<QInput
|
||||
:label="t('Extension')"
|
||||
v-model="params.extension"
|
||||
lazy-rules
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</template>
|
||||
</VnFilterPanel>
|
||||
</template>
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useI18n } from 'vue-i18n';
|
|||
import { useRouter } from 'vue-router';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import Paginate from 'src/components/PaginateData.vue';
|
||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||
import WorkerSummaryDialog from './Card/WorkerSummaryDialog.vue';
|
||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||
import WorkerFilter from './WorkerFilter.vue';
|
||||
|
@ -38,107 +38,105 @@ function viewSummary(id) {
|
|||
</Teleport>
|
||||
<Teleport to="#actions-append">
|
||||
<div class="row q-gutter-x-sm">
|
||||
<q-btn
|
||||
<QBtn
|
||||
flat
|
||||
@click="stateStore.toggleRightDrawer()"
|
||||
round
|
||||
dense
|
||||
icon="menu"
|
||||
>
|
||||
<q-tooltip bottom anchor="bottom right">
|
||||
<QTooltip bottom anchor="bottom right">
|
||||
{{ t('globals.collapseMenu') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
<q-drawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<WorkerFilter data-key="WorkerList" />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page class="column items-center q-pa-md">
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
<div class="card-list">
|
||||
<paginate
|
||||
<VnPaginate
|
||||
data-key="WorkerList"
|
||||
url="Workers/filter"
|
||||
order="id DESC"
|
||||
auto-load
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<q-card class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||
<q-item
|
||||
<QCard class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||
<QItem
|
||||
class="q-pa-none items-start cursor-pointer q-hoverable"
|
||||
v-ripple
|
||||
clickable
|
||||
>
|
||||
<q-item-section class="q-pa-md" @click="navigate(row.id)">
|
||||
<q-item-label class="text-h6">
|
||||
<QItemSection class="q-pa-md" @click="navigate(row.id)">
|
||||
<QItemLabel class="text-h6">
|
||||
{{ row.nickname }}
|
||||
</q-item-label>
|
||||
<q-item-label caption>#{{ row.id }}</q-item-label>
|
||||
<q-list>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel caption>#{{ row.id }}</QItemLabel>
|
||||
<QList>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('worker.list.name') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{
|
||||
row.userName
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ row.userName }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('worker.list.email') }}
|
||||
</q-item-label>
|
||||
<q-item-label>{{ row.email }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="q-pa-none">
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ row.email }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-pa-none">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{
|
||||
t('worker.list.department')
|
||||
}}</q-item-label>
|
||||
<q-item-label>
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ row.department }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-item-section>
|
||||
<q-separator vertical />
|
||||
<q-card-actions vertical class="justify-between">
|
||||
<q-btn
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QItemSection>
|
||||
<QSeparator vertical />
|
||||
<QCardActions vertical class="justify-between">
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="arrow_circle_right"
|
||||
@click="navigate(row.id)"
|
||||
>
|
||||
<q-tooltip>
|
||||
<QTooltip>
|
||||
{{ t('components.smartCard.openCard') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
flat
|
||||
round
|
||||
color="grey-7"
|
||||
icon="preview"
|
||||
@click="viewSummary(row.id)"
|
||||
>
|
||||
<q-tooltip>
|
||||
<QTooltip>
|
||||
{{ t('components.smartCard.openSummary') }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-item>
|
||||
</q-card>
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</QCardActions>
|
||||
</QItem>
|
||||
</QCard>
|
||||
</template>
|
||||
</paginate>
|
||||
</VnPaginate>
|
||||
</div>
|
||||
</q-page>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -6,12 +6,12 @@ const stateStore = useStateStore();
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-drawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<LeftMenu />
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
<q-page-container>
|
||||
<router-view></router-view>
|
||||
</q-page-container>
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<QPageContainer>
|
||||
<RouterView></RouterView>
|
||||
</QPageContainer>
|
||||
</template>
|
||||
|
|
|
@ -11,7 +11,7 @@ export default {
|
|||
redirect: { name: 'ClaimMain' },
|
||||
menus: {
|
||||
main: ['ClaimList', 'ClaimRmaList'],
|
||||
card: ['ClaimBasicData', 'ClaimRma', 'ClaimPhotos', 'ClaimLog'],
|
||||
card: ['ClaimBasicData', 'ClaimLines', 'ClaimRma', 'ClaimPhotos', 'ClaimLog'],
|
||||
},
|
||||
children: [
|
||||
{
|
||||
|
@ -66,6 +66,15 @@ export default {
|
|||
},
|
||||
component: () => import('src/pages/Claim/Card/ClaimBasicData.vue'),
|
||||
},
|
||||
{
|
||||
name: 'ClaimLines',
|
||||
path: 'lines',
|
||||
meta: {
|
||||
title: 'lines',
|
||||
icon: 'vn:details',
|
||||
},
|
||||
component: () => import('src/pages/Claim/Card/ClaimLines.vue'),
|
||||
},
|
||||
{
|
||||
name: 'ClaimRma',
|
||||
path: 'rma',
|
||||
|
|
|
@ -3,11 +3,13 @@ import Ticket from './ticket';
|
|||
import Claim from './claim';
|
||||
import InvoiceOut from './invoiceOut';
|
||||
import Worker from './worker';
|
||||
import Wagon from './wagon';
|
||||
|
||||
export default [
|
||||
Customer,
|
||||
Ticket,
|
||||
Claim,
|
||||
InvoiceOut,
|
||||
Worker
|
||||
Worker,
|
||||
Wagon
|
||||
]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { RouterView } from 'vue-router';
|
||||
|
||||
export default {
|
||||
path: '/invoiceOut',
|
||||
path: '/invoice-out',
|
||||
name: 'InvoiceOut',
|
||||
meta: {
|
||||
title: 'invoiceOuts',
|
||||
|
@ -10,7 +10,8 @@ export default {
|
|||
component: RouterView,
|
||||
redirect: { name: 'InvoiceOutMain' },
|
||||
menus: {
|
||||
main: ['InvoiceOutList']
|
||||
main: ['InvoiceOutList'],
|
||||
card: [],
|
||||
},
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
import { RouterView } from 'vue-router';
|
||||
|
||||
export default {
|
||||
path: '/wagon',
|
||||
name: 'Wagon',
|
||||
meta: {
|
||||
title: 'wagons',
|
||||
icon: 'vn:trolley',
|
||||
},
|
||||
component: RouterView,
|
||||
redirect: { name: 'WagonMain' },
|
||||
menus: {
|
||||
main: ['WagonList', 'WagonTypeList'],
|
||||
card: [],
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/wagon',
|
||||
name: 'WagonMain',
|
||||
component: () => import('src/pages/Wagon/WagonMain.vue'),
|
||||
redirect: { name: 'WagonList' },
|
||||
children: [
|
||||
{
|
||||
path: 'list',
|
||||
name: 'WagonList',
|
||||
meta: {
|
||||
title: 'wagonsList',
|
||||
icon: 'vn:trolley',
|
||||
},
|
||||
component: () => import('src/pages/Wagon/WagonList.vue')
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
name: 'WagonCreate',
|
||||
meta: {
|
||||
title: 'wagonCreate',
|
||||
icon: 'create',
|
||||
},
|
||||
component: () => import('src/pages/Wagon/WagonCreate.vue')
|
||||
},
|
||||
{
|
||||
path: ':id/edit',
|
||||
name: 'WagonEdit',
|
||||
meta: {
|
||||
title: 'wagonEdit',
|
||||
icon: 'edit',
|
||||
},
|
||||
component: () => import('src/pages/Wagon/WagonCreate.vue')
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/wagon/type',
|
||||
name: 'WagonTypeMain',
|
||||
component: () => import('src/pages/Wagon/WagonMain.vue'),
|
||||
redirect: { name: 'WagonTypeList' },
|
||||
children: [
|
||||
{
|
||||
path: 'list',
|
||||
name: 'WagonTypeList',
|
||||
meta: {
|
||||
title: 'typesList',
|
||||
icon: 'view_list',
|
||||
},
|
||||
component: () => import('src/pages/Wagon/Type/WagonTypeList.vue')
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
name: 'WagonTypeCreate',
|
||||
meta: {
|
||||
title: 'typeCreate',
|
||||
icon: 'create',
|
||||
},
|
||||
component: () => import('src/pages/Wagon/Type/WagonTypeCreate.vue')
|
||||
},
|
||||
{
|
||||
path: ':id/edit',
|
||||
name: 'WagonTypeEdit',
|
||||
meta: {
|
||||
title: 'typeEdit',
|
||||
icon: 'edit',
|
||||
},
|
||||
component: () => import('src/pages/Wagon/Type/WagonTypeCreate.vue')
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue