7383-testToMaster #370

Merged
alexm merged 365 commits from 7383-testToMaster into master 2024-05-14 05:46:56 +00:00
12 changed files with 577 additions and 2 deletions
Showing only changes of commit 78561c5f42 - Show all commits

View File

@ -1119,6 +1119,8 @@ item:
tags: Tags
wasteBreakdown: Waste breakdown
itemCreate: New item
itemTypeCreate: New item type
family: Item Type
descriptor:
item: Item
buyer: Buyer
@ -1153,6 +1155,23 @@ item:
type: Type
intrastat: Intrastat
origin: Origin
itemType:
pageTitles:
itemType: Item type
basicData: Basic data
summary: Summary
shared:
code: Code
name: Name
worker: Worker
category: Category
temperature: Temperature
summary:
id: id
life: Life
promo: Promo
itemPackingType: Item packing type
isUnconventionalSize: Is unconventional size
components:
topbar: {}
userPanel:

View File

@ -1118,6 +1118,8 @@ item:
tags: Etiquetas
wasteBreakdown: Deglose de mermas
itemCreate: Nuevo artículo
itemTypeCreate: Nueva familia
family: Familia
descriptor:
item: Artículo
buyer: Comprador
@ -1152,6 +1154,28 @@ item:
type: Tipo
intrastat: Intrastat
origin: Origen
itemType:
pageTitles:
itemType: Familia
basicData: Datos básicos
summary: Resumen
shared:
code: Código
name: Nombre
worker: Trabajador
category: Reino
temperature: Temperatura
summary:
id: id
code: Código
name: Nombre
worker: Trabajador
category: Reino
temperature: Temperatura
life: Vida
promo: Promoción
itemPackingType: Tipo de embalaje
isUnconventionalSize: Es de tamaño no convencional
components:
topbar: {}
userPanel:

View File

@ -0,0 +1,91 @@
<script setup>
import { reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import FetchData from 'components/FetchData.vue';
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
const { t } = useI18n();
const router = useRouter();
const newItemTypeForm = reactive({});
const workersOptions = ref([]);
const categoriesOptions = ref([]);
const temperaturesOptions = ref([]);
const redirectToItemTypeBasicData = (_, { id }) => {
router.push({ name: 'ItemTypeBasicData', params: { id } });
};
</script>
<template>
<FetchData
url="Workers"
@on-fetch="(data) => (workersOptions = data)"
:filter="{ order: 'firstName ASC', fields: ['id', 'firstName'] }"
auto-load
/>
<FetchData
url="ItemCategories"
@on-fetch="(data) => (categoriesOptions = data)"
:filter="{ order: 'name ASC', fields: ['id', 'name'] }"
auto-load
/>
<FetchData
url="Temperatures"
@on-fetch="(data) => (temperaturesOptions = data)"
:filter="{ order: 'name ASC', fields: ['code', 'name'] }"
auto-load
/>
<QPage>
<VnSubToolbar />
<FormModel
url-create="ItemTypes"
model="itemTypeCreate"
:form-initial-data="newItemTypeForm"
observe-form-changes
@on-data-saved="redirectToItemTypeBasicData"
>
<template #form="{ data }">
<VnRow class="row q-gutter-md q-mb-md">
<VnInput v-model="data.code" :label="t('itemType.shared.code')" />
<VnInput v-model="data.name" :label="t('itemType.shared.name')" />
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<VnSelectFilter
v-model="data.workerFk"
:label="t('itemType.shared.worker')"
:options="workersOptions"
option-value="id"
option-label="firstName"
hide-selected
/>
<VnSelectFilter
v-model="data.categoryFk"
:label="t('itemType.shared.category')"
:options="categoriesOptions"
option-value="id"
option-label="name"
hide-selected
/>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<VnSelectFilter
v-model="data.temperatureFk"
:label="t('itemType.shared.temperature')"
:options="temperaturesOptions"
option-value="code"
option-label="name"
hide-selected
/>
</VnRow>
</template>
</FormModel>
</QPage>
</template>

View File

@ -0,0 +1,86 @@
<script setup>
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import VnPaginate from 'src/components/ui/VnPaginate.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import CardList from 'src/components/ui/CardList.vue';
import ItemTypeSummary from 'src/pages/ItemType/Card/ItemTypeSummary.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
import { useStateStore } from 'stores/useStateStore';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
const stateStore = useStateStore();
const router = useRouter();
const { t } = useI18n();
const { viewSummary } = useSummaryDialog();
const redirectToItemTypeSummary = (id) => {
router.push({ name: 'ItemTypeSummary', params: { id } });
};
const redirectToCreateView = () => {
router.push({ name: 'ItemTypeCreate' });
};
</script>
<template>
<template v-if="stateStore.isHeaderMounted()">
<Teleport to="#searchbar">
<VnSearchbar
data-key="ItemTypeList"
url="ItemTypes"
custom-route-redirect-name="ItemTypeSummary"
:label="t('Search item type')"
:info="t('Search itemType by id, name or code')"
/>
</Teleport>
</template>
<QPage class="column items-center q-pa-md">
<div class="vn-card-list">
<VnPaginate
data-key="ItemTypeList"
url="ItemTypes"
:order="['name']"
auto-load
>
<template #body="{ rows }">
<CardList
v-for="row of rows"
:key="row.id"
:title="row.code"
@click="redirectToItemTypeSummary(row.id)"
:id="row.id"
>
<template #list-items>
<VnLv :label="t('Name')" :value="row.name" />
</template>
<template #actions>
<QBtn
:label="t('components.smartCard.openSummary')"
@click.stop="viewSummary(row.id, ItemTypeSummary)"
color="primary"
type="submit"
/>
</template>
</CardList>
</template>
</VnPaginate>
</div>
</QPage>
<QPageSticky :offset="[20, 20]">
<QBtn fab icon="add" color="primary" @click="redirectToCreateView()" />
<QTooltip>
{{ t('New item type') }}
</QTooltip>
</QPageSticky>
</template>
<i18n>
es:
New item type: Nueva familia
Name: Nombre
Search item type: Buscar familia
Search itemType by id, name or code: Buscar familia por id, nombre o código
</i18n>

View File

@ -0,0 +1,79 @@
<script setup>
import { ref } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import FetchData from 'components/FetchData.vue';
import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
const route = useRoute();
const { t } = useI18n();
const workersOptions = ref([]);
const categoriesOptions = ref([]);
const temperaturesOptions = ref([]);
</script>
<template>
<FetchData
url="Workers"
@on-fetch="(data) => (workersOptions = data)"
:filter="{ order: 'firstName ASC', fields: ['id', 'firstName'] }"
auto-load
/>
<FetchData
url="ItemCategories"
@on-fetch="(data) => (categoriesOptions = data)"
:filter="{ order: 'name ASC', fields: ['id', 'name'] }"
auto-load
/>
<FetchData
url="Temperatures"
@on-fetch="(data) => (temperaturesOptions = data)"
:filter="{ order: 'name ASC', fields: ['code', 'name'] }"
auto-load
/>
<FormModel
:url="`ItemTypes/${route.params.id}`"
:url-update="`ItemTypes/${route.params.id}`"
model="itemTypeBasicData"
auto-load
>
<template #form="{ data }">
<VnRow class="row q-gutter-md q-mb-md">
<VnInput v-model="data.code" :label="t('itemType.shared.code')" />
<VnInput v-model="data.name" :label="t('itemType.shared.name')" />
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<VnSelectFilter
v-model="data.workerFk"
:label="t('itemType.shared.worker')"
:options="workersOptions"
option-value="id"
option-label="firstName"
hide-selected
/>
<VnSelectFilter
v-model="data.categoryFk"
:label="t('itemType.shared.category')"
:options="categoriesOptions"
option-value="id"
option-label="name"
hide-selected
/>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<VnSelectFilter
v-model="data.temperatureFk"
:label="t('itemType.shared.temperature')"
:options="temperaturesOptions"
option-value="code"
option-label="name"
hide-selected
/>
</VnRow>
</template>
</FormModel>
</template>

View File

@ -0,0 +1,26 @@
<script setup>
import ItemTypeDescriptor from 'src/pages/ItemType/Card/ItemTypeDescriptor.vue';
import LeftMenu from 'components/LeftMenu.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import { useStateStore } from 'stores/useStateStore';
const stateStore = useStateStore();
</script>
<template>
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
<QScrollArea class="fit">
<ItemTypeDescriptor />
<QSeparator />
<LeftMenu source="card" />
</QScrollArea>
</QDrawer>
<QPageContainer>
<QPage>
<VnSubToolbar />
<div class="q-pa-md column items-center">
<RouterView></RouterView>
</div>
</QPage>
</QPageContainer>
</template>

View File

@ -0,0 +1,82 @@
<script setup>
import { ref, computed } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import useCardDescription from 'src/composables/useCardDescription';
const $props = defineProps({
id: {
type: Number,
required: false,
default: null,
},
summary: {
type: Object,
default: null,
},
});
const route = useRoute();
const { t } = useI18n();
const itemTypeFilter = {
include: [
{ relation: 'worker' },
{ relation: 'category' },
{ relation: 'itemPackingType' },
{ relation: 'temperature' },
],
};
const entityId = computed(() => {
return $props.id || route.params.id;
});
const data = ref(useCardDescription());
const setData = (entity) => (data.value = useCardDescription(entity.code, entity.id));
</script>
<template>
<CardDescriptor
module="ItemType"
:url="`ItemTypes/${entityId}`"
:filter="itemTypeFilter"
:title="data.title"
:subtitle="data.subtitle"
@on-fetch="setData"
data-key="entry"
>
<template #header-extra-action>
<QBtn
round
flat
size="sm"
icon="vn:item"
color="white"
:to="{ name: 'ItemTypeList' }"
>
<QTooltip>
{{ t('Go to module index') }}
</QTooltip>
</QBtn>
</template>
<template #body="{ entity }">
<VnLv :label="t('itemType.shared.code')" :value="entity.code" />
<VnLv :label="t('itemType.shared.name')" :value="entity.name" />
<VnLv
:label="t('itemType.shared.worker')"
:value="entity.worker?.firstName"
/>
<VnLv :label="t('itemType.shared.category')" :value="entity.category?.name" />
</template>
</CardDescriptor>
</template>
<i18n>
es:
Go to module index: Ir al índice del módulo
</i18n>

View File

@ -0,0 +1,102 @@
<script setup>
import { ref, computed, onUpdated } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'src/components/ui/VnLv.vue';
onUpdated(() => summaryRef.value.fetch());
const route = useRoute();
const { t } = useI18n();
const $props = defineProps({
id: {
type: Number,
required: false,
default: null,
},
});
const itemTypeFilter = {
include: [
{ relation: 'worker' },
{ relation: 'category' },
{ relation: 'itemPackingType' },
{ relation: 'temperature' },
],
};
const entityId = computed(() => $props.id || route.params.id);
const summaryRef = ref();
const itemType = ref();
async function setItemTypeData(data) {
if (data) itemType.value = data;
}
</script>
<template>
<CardSummary
ref="summaryRef"
:url="`ItemTypes/${entityId}`"
data-key="ItemTypeSummary"
:filter="itemTypeFilter"
@on-fetch="(data) => setItemTypeData(data)"
class="full-width"
>
<template #header-left>
<router-link
v-if="route.name !== 'ItemTypeSummary'"
:to="{ name: 'ItemTypeSummary', params: { id: entityId } }"
class="header link"
>
<QIcon name="open_in_new" color="white" size="sm" />
</router-link>
</template>
<template #header>
<span>
{{ itemType.id }} - {{ itemType.name }} -
{{ itemType.worker?.firstName }}
{{ itemType.worker?.lastName }}
</span>
</template>
<template #body>
<QCard class="vn-one">
<router-link
:to="{ name: 'ItemTypeBasicData', params: { id: entityId } }"
class="header header-link"
>
{{ t('globals.summary.basicData') }}
<QIcon name="open_in_new" />
</router-link>
<VnLv :label="t('itemType.summary.id')" :value="itemType.id" />
<VnLv :label="t('itemType.shared.code')" :value="itemType.code" />
<VnLv :label="t('itemType.shared.name')" :value="itemType.name" />
<VnLv
:label="t('itemType.shared.worker')"
:value="itemType.worker?.firstName"
/>
<VnLv
:label="t('itemType.shared.category')"
:value="itemType.category?.name"
/>
<VnLv
:label="t('itemType.shared.temperature')"
:value="itemType.temperature?.name"
/>
<VnLv :label="t('itemType.summary.life')" :value="itemType.life" />
<VnLv :label="t('itemType.summary.promo')" :value="itemType.promo" />
<VnLv
:label="t('itemType.summary.itemPackingType')"
:value="itemType.itemPackingType?.description"
/>
<VnLv
:label="t('itemType.summary.isUnconventionalSize')"
:value="itemType.isUnconventionalSize"
/>
</QCard>
</template>
</CardSummary>
</template>

View File

@ -15,6 +15,7 @@ import Department from './department';
import Entry from './entry';
import roadmap from './roadmap';
import Parking from './parking';
import ItemType from './itemType';
export default [
Item,
@ -34,4 +35,5 @@ export default [
Entry,
roadmap,
Parking,
ItemType,
];

View File

@ -10,7 +10,7 @@ export default {
component: RouterView,
redirect: { name: 'ItemMain' },
menus: {
main: ['ItemList', 'WasteBreakdown'],
main: ['ItemList', 'WasteBreakdown', 'ItemTypeList'],
card: ['ItemBasicData'],
},
children: [
@ -33,7 +33,7 @@ export default {
path: 'create',
name: 'ItemCreate',
meta: {
title: 'create',
title: 'itemCreate',
},
component: () => import('src/pages/Item/ItemCreate.vue'),
},
@ -50,6 +50,23 @@ export default {
'https://grafana.verdnatura.es/d/TTNXQAxVk';
},
},
{
path: 'item-type-list',
name: 'ItemTypeList',
meta: {
title: 'family',
icon: 'contact_support',
},
component: () => import('src/pages/Item/ItemTypeList.vue'),
},
{
path: 'item-type-list/create',
name: 'ItemTypeCreate',
meta: {
title: 'itemTypeCreate',
},
component: () => import('src/pages/Item/ItemTypeCreate.vue'),
},
],
},
{

View File

@ -0,0 +1,45 @@
import { RouterView } from 'vue-router';
export default {
path: '/item-type',
name: 'ItemType',
meta: {
title: 'itemType',
icon: 'contact_support',
},
component: RouterView,
redirect: { name: 'ItemTypeCard' },
menus: {
main: [],
card: ['ItemTypeBasicData'],
},
children: [
{
name: 'ItemTypeCard',
path: ':id',
component: () => import('src/pages/ItemType/Card/ItemTypeCard.vue'),
redirect: { name: 'ItemTypeSummary' },
children: [
{
name: 'ItemTypeSummary',
path: 'summary',
meta: {
title: 'summary',
},
component: () =>
import('src/pages/ItemType/Card/ItemTypeSummary.vue'),
},
{
name: 'ItemTypeBasicData',
path: 'basic-data',
meta: {
title: 'basicData',
icon: 'vn:settings',
},
component: () =>
import('src/pages/ItemType/Card/ItemTypeBasicData.vue'),
},
],
},
],
};

View File

@ -10,6 +10,7 @@ import supplier from './modules/Supplier';
import route from './modules/route';
import travel from './modules/travel';
import department from './modules/department';
import ItemType from './modules/itemType';
import shelving from 'src/router/modules/shelving';
import order from 'src/router/modules/order';
import entry from 'src/router/modules/entry';
@ -71,6 +72,7 @@ const routes = [
roadmap,
entry,
parking,
ItemType,
{
path: '/:catchAll(.*)*',
name: 'NotFound',