Merge pull request 'refactor: refs #8316 used VnSection and VnBetaCard' (!1147) from 8316-itemCardWithVnCardBeta into dev
gitea/salix-front/pipeline/head This commit looks good Details

Reviewed-on: #1147
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
This commit is contained in:
Alex Moreno 2025-01-24 08:06:47 +00:00
commit 10448b9d77
20 changed files with 518 additions and 719 deletions

View File

@ -190,7 +190,10 @@ const getLocale = (label) => {
const globalLocale = `globals.params.${param}`; const globalLocale = `globals.params.${param}`;
if (te(globalLocale)) return t(globalLocale); if (te(globalLocale)) return t(globalLocale);
else if (te(t(`params.${param}`))); else if (te(t(`params.${param}`)));
else return t(`${route.meta.moduleName.toLowerCase()}.params.${param}`); else {
const camelCaseModuleName = route.meta.moduleName.charAt(0).toLowerCase() + route.meta.moduleName.slice(1);
return t(`${camelCaseModuleName}.params.${param}`);
}
}; };
</script> </script>

View File

@ -728,62 +728,6 @@ travel:
destination: Destination destination: Destination
thermograph: Thermograph thermograph: Thermograph
travelFileDescription: 'Travel id { travelId }' travelFileDescription: 'Travel id { travelId }'
item:
descriptor:
buyer: Buyer
color: Color
category: Category
available: Available
warehouseText: 'Calculated on the warehouse of { warehouseName }'
itemDiary: Item diary
list:
id: Identifier
stems: Stems
category: Category
typeName: Type
isActive: Active
userName: Buyer
weightByPiece: Weight/Piece
stemMultiplier: Multiplier
fixedPrice:
itemFk: Item ID
groupingPrice: Grouping price
packingPrice: Packing price
hasMinPrice: Has min price
minPrice: Min price
started: Started
ended: Ended
create:
priority: Priority
buyRequest:
requester: Requester
requested: Requested
attender: Atender
achieved: Achieved
concept: Concept
summary:
otherData: Other data
tax: Tax
botanical: Botanical
barcode: Barcode
completeName: Complete name
family: Familiy
stems: Stems
multiplier: Multiplier
buyer: Buyer
doPhoto: Do photo
intrastatCode: Intrastat code
ref: Reference
relevance: Relevance
weight: Weight (gram)/stem
units: Units/box
expense: Expense
generic: Generic
recycledPlastic: Recycled plastic
nonRecycledPlastic: Non recycled plastic
minSalesQuantity: Min sales quantity
genus: Genus
specie: Specie
components: components:
topbar: {} topbar: {}
itemsFilterPanel: itemsFilterPanel:

View File

@ -724,62 +724,6 @@ travel:
destination: Destino destination: Destino
thermograph: Termógrafo thermograph: Termógrafo
travelFileDescription: 'Id envío { travelId }' travelFileDescription: 'Id envío { travelId }'
item:
descriptor:
buyer: Comprador
color: Color
category: Categoría
available: Disponible
warehouseText: 'Calculado sobre el almacén de { warehouseName }'
itemDiary: Registro de compra-venta
list:
id: Identificador
stems: Tallos
category: Reino
typeName: Tipo
isActive: Activo
weightByPiece: Peso (gramos)/tallo
userName: Comprador
stemMultiplier: Multiplicador
fixedPrice:
itemFk: ID Artículo
groupingPrice: Precio grouping
packingPrice: Precio packing
hasMinPrice: Tiene precio mínimo
minPrice: Precio min
started: Inicio
ended: Fin
create:
priority: Prioridad
summary:
otherData: Otros datos
tax: IVA
botanical: Botánico
barcode: Código de barras
completeName: Nombre completo
family: Familia
stems: Tallos
multiplier: Multiplicador
buyer: Comprador
doPhoto: Hacer foto
intrastatCode: Código intrastat
ref: Referencia
relevance: Relevancia
weight: Peso (gramos)/tallo
units: Unidades/caja
expense: Gasto
generic: Genérico
recycledPlastic: Plástico reciclado
nonRecycledPlastic: Plástico no reciclado
minSalesQuantity: Cantidad mínima de venta
genus: Genus
specie: Specie
buyRequest:
requester: Solicitante
requested: Solicitado
attender: Comprador
achieved: Conseguido
concept: Concepto
components: components:
topbar: {} topbar: {}
itemsFilterPanel: itemsFilterPanel:

View File

@ -408,7 +408,7 @@ function handleLocation(data, location) {
order: ['id DESC'], order: ['id DESC'],
}" }"
> >
<template #rightMenu> <template #advanced-menu>
<CustomerFilter data-key="CustomerList" /> <CustomerFilter data-key="CustomerList" />
</template> </template>
<template #body> <template #body>

View File

@ -205,7 +205,7 @@ const columns = computed(() => [
userFilter: entryFilter, userFilter: entryFilter,
}" }"
> >
<template #rightMenu> <template #advanced-menu>
<EntryFilter data-key="EntryList" /> <EntryFilter data-key="EntryList" />
</template> </template>
<template #body> <template #body>
@ -231,7 +231,7 @@ const columns = computed(() => [
> >
<QTooltip>{{ <QTooltip>{{
t( t(
'entry.list.tableVisibleColumns.isExcludedFromAvailable' 'entry.list.tableVisibleColumns.isExcludedFromAvailable',
) )
}}</QTooltip> }}</QTooltip>
</QIcon> </QIcon>

View File

@ -1,19 +1,11 @@
<script setup> <script setup>
import VnCard from 'components/common/VnCard.vue'; import VnCardBeta from 'components/common/VnCardBeta.vue';
import ItemDescriptor from './ItemDescriptor.vue'; import ItemDescriptor from './ItemDescriptor.vue';
import ItemListFilter from '../ItemListFilter.vue';
</script> </script>
<template> <template>
<VnCard <VnCardBeta
data-key="Item" data-key="Item"
base-url="Items" base-url="Items"
:descriptor="ItemDescriptor" :descriptor="ItemDescriptor"
:filter-panel="ItemListFilter"
search-data-key="ItemList"
:searchbar-props="{
url: 'Items/filter',
label: 'searchbar.label',
info: 'searchbar.info',
}"
/> />
</template> </template>

View File

@ -6,18 +6,17 @@ import VnImg from 'src/components/ui/VnImg.vue';
import VnTable from 'components/VnTable/VnTable.vue'; import VnTable from 'components/VnTable/VnTable.vue';
import { toDate } from 'src/filters'; import { toDate } from 'src/filters';
import FetchedTags from 'src/components/ui/FetchedTags.vue'; import FetchedTags from 'src/components/ui/FetchedTags.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import ItemSummary from '../Item/Card/ItemSummary.vue'; import ItemSummary from '../Item/Card/ItemSummary.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue'; import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue';
import ItemTypeDescriptorProxy from './ItemType/Card/ItemTypeDescriptorProxy.vue'; import ItemTypeDescriptorProxy from './ItemType/Card/ItemTypeDescriptorProxy.vue';
import { cloneItem } from 'src/pages/Item/composables/cloneItem'; import { cloneItem } from 'src/pages/Item/composables/cloneItem';
import RightMenu from 'src/components/common/RightMenu.vue';
import ItemListFilter from './ItemListFilter.vue'; import ItemListFilter from './ItemListFilter.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
import axios from 'axios'; import axios from 'axios';
import VnSection from 'src/components/common/VnSection.vue';
const entityId = computed(() => route.params.id); const entityId = computed(() => route.params.id);
const { openCloneDialog } = cloneItem(); const { openCloneDialog } = cloneItem();
@ -25,9 +24,11 @@ const { viewSummary } = useSummaryDialog();
const { t } = useI18n(); const { t } = useI18n();
const tableRef = ref(); const tableRef = ref();
const route = useRoute(); const route = useRoute();
const dataKey = 'ItemList';
const validPriorities = ref([]); const validPriorities = ref([]);
const defaultTag = ref(); const defaultTag = ref();
const defaultPriority = ref(); const defaultPriority = ref();
const itemFilter = { const itemFilter = {
include: [ include: [
{ {
@ -324,166 +325,174 @@ onBeforeMount(async () => {
}); });
}); });
</script> </script>
<template> <template>
<VnSearchbar <VnSection
data-key="ItemList" :data-key="dataKey"
:label="t('item.searchbar.label')" :columns="columns"
:info="t('item.searchbar.info')" prefix="item"
/> :array-data-props="{
<RightMenu> url: 'Items/filter',
<template #right-panel> order: ['isActive DESC', 'name', 'id'],
userFilter: itemFilter,
}"
>
<template #advanced-menu>
<ItemListFilter data-key="ItemList" /> <ItemListFilter data-key="ItemList" />
</template> </template>
</RightMenu> <template #body>
<VnTable <VnTable
v-if="defaultTag" v-if="defaultTag"
ref="tableRef" ref="tableRef"
data-key="ItemList" :data-key="dataKey"
url="Items/filter" :columns="columns"
:create="{ :right-search="false"
urlCreate: 'Items/new', redirect="Item"
title: t('item.list.newItem'), :create="{
onDataSaved: ({ id }) => tableRef.redirect(`${id}/basic-data`), urlCreate: 'Items/new',
formInitialData: { title: t('item.list.newItem'),
editorFk: entityId, onDataSaved: ({ id }) => tableRef.redirect(`${id}/basic-data`),
tag: defaultTag, formInitialData: {
priority: defaultPriority, editorFk: entityId,
}, tag: defaultTag,
}" priority: defaultPriority,
:order="['isActive DESC', 'name', 'id']" },
:columns="columns" }"
redirect="Item" :is-editable="false"
:is-editable="false"
:right-search="false"
:filter="itemFilter"
>
<template #column-image="{ row }">
<VnImg
:id="row?.id"
zoom-resolution="1600x900"
:zoom="true"
class="rounded"
/>
</template>
<template #column-id="{ row }">
<span class="link" @click.stop>
{{ row.id }}
<ItemDescriptorProxy :id="row.id" />
</span>
</template>
<template #column-typeName="{ row }">
<span class="link" @click.stop>
{{ row.typeName }}
{{ row.typeFk }}
<ItemTypeDescriptorProxy :id="row.typeFk" />
</span>
</template>
<template #column-userName="{ row }">
<span class="link" @click.stop>
{{ row.userName }}
<WorkerDescriptorProxy :id="row.buyerFk" />
</span>
</template>
<template #column-description="{ row }">
<div class="row column full-width justify-between items-start">
{{ row?.name }}
<div v-if="row?.subName" class="subName">
{{ row?.subName.toUpperCase() }}
</div>
</div>
<FetchedTags :item="row" />
</template>
<template #more-create-dialog="{ data }">
<VnInput
v-model="data.provisionalName"
:label="t('globals.description')"
:is-required="true"
/>
<VnSelect
url="Tags"
v-model="data.tag"
:label="t('globals.tag')"
:fields="['id', 'name']"
option-label="name"
option-value="id"
:is-required="true"
:sort-by="['name ASC']"
> >
<template #option="scope"> <template #column-image="{ row }">
<QItem v-bind="scope.itemProps"> <VnImg
<QItemSection> :id="row?.id"
<QItemLabel>{{ scope.opt?.name }}</QItemLabel> zoom-resolution="1600x900"
<QItemLabel caption> #{{ scope.opt?.id }} </QItemLabel> :zoom="true"
</QItemSection> class="rounded"
</QItem> />
</template> </template>
</VnSelect> <template #column-id="{ row }">
<VnSelect <span class="link" @click.stop>
:options="validPriorities" {{ row.id }}
v-model="data.priority" <ItemDescriptorProxy :id="row.id" />
:label="t('item.create.priority')" </span>
:is-required="true"
/>
<VnSelect
url="ItemTypes"
v-model="data.typeFk"
:label="t('item.list.typeName')"
:fields="['id', 'code', 'name']"
option-label="name"
option-value="id"
:is-required="true"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
<QItemLabel caption>
{{ scope.opt?.code }} #{{ scope.opt?.id }}
</QItemLabel>
</QItemSection>
</QItem>
</template> </template>
</VnSelect> <template #column-typeName="{ row }">
<VnSelect <span class="link" @click.stop>
url="Intrastats" {{ row.typeName }}
v-model="data.intrastatFk" {{ row.typeFk }}
:label="t('globals.intrastat')" <ItemTypeDescriptorProxy :id="row.typeFk" />
:fields="['id', 'description']" </span>
option-label="description"
option-value="id"
:is-required="true"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{ scope.opt?.description }}</QItemLabel>
<QItemLabel caption> #{{ scope.opt?.id }} </QItemLabel>
</QItemSection>
</QItem>
</template> </template>
</VnSelect> <template #column-userName="{ row }">
<VnSelect <span class="link" @click.stop>
url="Origins" {{ row.userName }}
v-model="data.originFk" <WorkerDescriptorProxy :id="row.buyerFk" />
:label="t('globals.origin')" </span>
:fields="['id', 'code', 'name']"
option-label="code"
option-value="id"
:is-required="true"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
<QItemLabel caption>
{{ scope.opt?.code }} #{{ scope.opt?.id }}
</QItemLabel>
</QItemSection>
</QItem>
</template> </template>
</VnSelect> <template #column-description="{ row }">
<div class="row column full-width justify-between items-start">
{{ row?.name }}
<div v-if="row?.subName" class="subName">
{{ row?.subName.toUpperCase() }}
</div>
</div>
<FetchedTags :item="row" :columns="3" />
</template>
<template #more-create-dialog="{ data }">
<VnInput
v-model="data.provisionalName"
:label="t('globals.description')"
:is-required="true"
/>
<VnSelect
url="Tags"
v-model="data.tag"
:label="t('globals.tag')"
:fields="['id', 'name']"
option-label="name"
option-value="id"
:is-required="true"
:sort-by="['name ASC']"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
<QItemLabel caption>
#{{ scope.opt?.id }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
<VnSelect
:options="validPriorities"
v-model="data.priority"
:label="t('item.create.priority')"
:is-required="true"
/>
<VnSelect
url="ItemTypes"
v-model="data.typeFk"
:label="t('item.list.typeName')"
:fields="['id', 'code', 'name']"
option-label="name"
option-value="id"
:is-required="true"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
<QItemLabel caption>
{{ scope.opt?.code }} #{{ scope.opt?.id }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
<VnSelect
url="Intrastats"
v-model="data.intrastatFk"
:label="t('globals.intrastat')"
:fields="['id', 'description']"
option-label="description"
option-value="id"
:is-required="true"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{ scope.opt?.description }}</QItemLabel>
<QItemLabel caption>
#{{ scope.opt?.id }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
<VnSelect
url="Origins"
v-model="data.originFk"
:label="t('globals.origin')"
:fields="['id', 'code', 'name']"
option-label="code"
option-value="id"
:is-required="true"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
<QItemLabel caption>
{{ scope.opt?.code }} #{{ scope.opt?.id }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
</template>
</VnTable>
</template> </template>
</VnTable> </VnSection>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.subName { .subName {

View File

@ -1,7 +1,6 @@
<script setup> <script setup>
import { ref } from 'vue'; import { ref, onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { onMounted } from 'vue';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
@ -233,7 +232,7 @@ onMounted(async () => {
<QItemSection> <QItemSection>
<VnSelect <VnSelect
:label="t('params.buyerFk')" :label="t('params.buyerFk')"
v-model="params.buyerFk" v-model="params.workerFk"
@update:model-value="searchFn()" @update:model-value="searchFn()"
:options="buyersOptions" :options="buyersOptions"
option-value="id" option-value="id"
@ -266,10 +265,10 @@ onMounted(async () => {
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">
<QItemSection> <QItemSection>
<QItemLabel> <QItemLabel>
{{ scope.opt?.name}} {{ scope.opt?.name }}
</QItemLabel> </QItemLabel>
<QItemLabel caption> <QItemLabel caption>
{{ `#${scope.opt?.id } , ${ scope.opt?.nickname}` }} {{ `#${scope.opt?.id} , ${scope.opt?.nickname}` }}
</QItemLabel> </QItemLabel>
</QItemSection> </QItemSection>
</QItem> </QItem>
@ -369,7 +368,7 @@ onMounted(async () => {
:model-value="fieldFilter.selectedField" :model-value="fieldFilter.selectedField"
:options="moreFields" :options="moreFields"
option-label="label" option-label="label"
option-value="label" option-value="label"
dense dense
outlined outlined
rounded rounded

View File

@ -1,20 +1,12 @@
<script setup> <script setup>
import VnCard from 'components/common/VnCard.vue'; import VnCardBeta from 'components/common/VnCardBeta.vue';
import ItemTypeDescriptor from 'src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue'; import ItemTypeDescriptor from 'src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue';
import ItemTypeFilter from 'src/pages/Item/ItemType/ItemTypeFilter.vue';
import ItemTypeSearchbar from '../ItemTypeSearchbar.vue';
</script> </script>
<template> <template>
<VnCard <VnCardBeta
data-key="ItemTypeSummary" data-key="ItemTypeSummary"
base-url="ItemTypes" base-url="ItemTypes"
:descriptor="ItemTypeDescriptor" :descriptor="ItemTypeDescriptor"
:filter-panel="ItemTypeFilter" />
search-data-key="ItemTypeList"
search-url="ItemTypes"
>
<template #searchbar>
<ItemTypeSearchbar />
</template>
</VnCard>
</template> </template>

View File

@ -1,90 +0,0 @@
<script setup>
import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnInput from 'src/components/common/VnInput.vue';
const { t } = useI18n();
const props = defineProps({
dataKey: {
type: String,
required: true,
},
});
const emit = defineEmits(['search']);
const exprBuilder = (param, value) => {
switch (param) {
case 'name':
return {
name: { like: `%${value}%` },
};
case 'code':
return {
code: { like: `%${value}%` },
};
case 'search':
if (value) {
if (!isNaN(value)) {
return { id: value };
} else {
return {
or: [
{
name: {
like: `%${value}%`,
},
},
{
code: {
like: `%${value}%`,
},
},
],
};
}
}
}
};
</script>
<template>
<VnFilterPanel
:data-key="props.dataKey"
:search-button="true"
@search="emit('search')"
search-url="table"
:expr-builder="exprBuilder"
>
<template #tags="{ tag, formatFn }">
<div class="q-gutter-x-xs">
<strong>{{ t(`params.${tag.label}`) }}: </strong>
<span>{{ formatFn(tag.value) }}</span>
</div>
</template>
<template #body="{ params }">
<QItem>
<QItemSection>
<VnInput :label="t('Name')" v-model="params.name" is-outlined />
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInput v-model="params.code" :label="t('Code')" is-outlined />
</QItemSection>
</QItem>
</template>
</VnFilterPanel>
</template>
<i18n>
en:
params:
name: Name
code: Code
es:
params:
name: Nombre
code: Código
Name: Nombre
Code: Código
</i18n>

View File

@ -1,19 +0,0 @@
<script setup>
import VnSearchbar from 'components/ui/VnSearchbar.vue';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
</script>
<template>
<VnSearchbar
data-key="ItemTypeList"
url="ItemTypes"
:label="t('Search item type')"
:info="t('Search itemType by id, name or code')"
/>
</template>
<i18n>
es:
Search item type: Buscar familia
Search itemType by id, name or code: Buscar familia por id, nombre o código
</i18n>

View File

@ -15,3 +15,5 @@ itemType:
promo: Promo promo: Promo
itemPackingType: Item packing type itemPackingType: Item packing type
isUnconventionalSize: Is unconventional size isUnconventionalSize: Is unconventional size
search: Search item type
searchInfo: Search item type by id, name or code

View File

@ -15,3 +15,5 @@ itemType:
promo: Promoción promo: Promoción
itemPackingType: Tipo de embalaje itemPackingType: Tipo de embalaje
isUnconventionalSize: Es de tamaño poco convencional isUnconventionalSize: Es de tamaño poco convencional
search: Buscar familia
searchInfo: Buscar familia por id, nombre o código

View File

@ -1,17 +1,50 @@
<script setup> <script setup>
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { ref, computed } from 'vue'; import { ref, computed } from 'vue';
import ItemTypeSearchbar from 'src/pages/Item/ItemType/ItemTypeSearchbar.vue';
import VnTable from 'components/VnTable/VnTable.vue'; import VnTable from 'components/VnTable/VnTable.vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
import ItemTypeFilter from './ItemType/ItemTypeFilter.vue';
import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue'; import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
import VnSection from 'src/components/common/VnSection.vue';
const { t } = useI18n(); const { t } = useI18n();
const tableRef = ref(); const tableRef = ref();
const itemCategoriesOptions = ref([]); const itemCategoriesOptions = ref([]);
const temperatureOptions = ref([]); const temperatureOptions = ref([]);
const dataKey = 'ItemTypeList';
const exprBuilder = (param, value) => {
switch (param) {
case 'name':
return {
name: { like: `%${value}%` },
};
case 'code':
return {
code: { like: `%${value}%` },
};
case 'search':
if (value) {
if (!isNaN(value)) {
return { id: value };
} else {
return {
or: [
{
name: {
like: `%${value}%`,
},
},
{
code: {
like: `%${value}%`,
},
},
],
};
}
}
}
};
const columns = computed(() => [ const columns = computed(() => [
{ {
@ -103,49 +136,53 @@ const columns = computed(() => [
@on-fetch="(data) => (temperatureOptions = data)" @on-fetch="(data) => (temperatureOptions = data)"
auto-load auto-load
/> />
<RightMenu> <VnSection
<template #right-panel> :data-key="dataKey"
<ItemTypeFilter data-key="ItemTypeList" /> :columns="columns"
</template> prefix="itemType"
</RightMenu> :array-data-props="{
<ItemTypeSearchbar /> url: 'ItemTypes',
<VnTable order: 'name ASC',
ref="tableRef" exprBuilder,
data-key="ItemTypeList" userFilter: {
url="ItemTypes" include: {
:create="{ relation: 'worker',
urlCreate: 'ItemTypes', scope: {
title: t('Create ItemTypes'), fields: ['id'],
onDataSaved: () => tableRef.reload(), include: {
formInitialData: {}, relation: 'user',
}" scope: {
:user-filter="{ fields: ['id', 'name'],
include: { },
relation: 'worker',
scope: {
fields: ['id'],
include: {
relation: 'user',
scope: {
fields: ['id', 'name'],
}, },
}, },
}, },
}, },
}" }"
order="name ASC"
:columns="columns"
auto-load
:right-search="false"
redirect="item/item-type"
> >
<template #column-workerFk="{ row }"> <template #body>
<span class="link" @click.stop> <VnTable
{{ row.worker?.user?.name }} ref="tableRef"
<WorkerDescriptorProxy :id="row.workerFk" /> :data-key="dataKey"
</span> :create="{
urlCreate: 'ItemTypes',
title: t('Create ItemTypes'),
onDataSaved: () => tableRef.reload(),
formInitialData: {},
}"
:columns="columns"
auto-load
redirect="item/item-type"
>
<template #column-workerFk="{ row }">
<span class="link" @click.stop>
{{ row.worker?.user?.name }}
<WorkerDescriptorProxy :id="row.workerFk" />
</span>
</template>
</VnTable>
</template> </template>
</VnTable> </VnSection>
</template> </template>
<i18n> <i18n>

View File

@ -180,44 +180,46 @@ item:
intrastat: Intrastat intrastat: Intrastat
origin: Origin origin: Origin
buyRequest: buyRequest:
ticketId: 'Ticket ID' ticketId: Ticket ID
shipped: 'Shipped' shipped: Shipped
requester: 'Requester' requester: Requester
requested: 'Requested' requested: Requested
price: 'Price' price: Price
attender: 'Attender' attender: Attender
item: 'Item' item: Item
achieved: 'Achieved' achieved: Achieved
concept: 'Concept' concept: Concept
state: 'State' state: State
summary: summary:
basicData: 'Basic data' basicData: Basic data
otherData: 'Other data' otherData: Other data
description: 'Description' description: Description
tax: 'Tax' tax: Tax
tags: 'Tags' tags: Tags
botanical: 'Botanical' botanical: Botanical
barcode: 'Barcode' barcode: Barcode
name: 'Nombre' name: Name
completeName: 'Nombre completo' completeName: Complete name
family: 'Familia' family: Family
size: 'Medida' size: Size
origin: 'Origen' origin: Origin
stems: 'Tallos' stems: Stems
multiplier: 'Multiplicador' multiplier: Multiplier
buyer: 'Comprador' buyer: Buyer
doPhoto: 'Do photo' doPhoto: Do photo
intrastatCode: 'Código intrastat' intrastatCode: Intrastat code
intrastat: 'Intrastat' intrastat: 'Intrastat'
ref: 'Referencia' ref: Reference
relevance: 'Relevancia' relevance: Relevance
weight: 'Peso (gramos)/tallo' weight: Weight (gram)/stem
units: 'Unidades/caja' units: Units/box
expense: 'Gasto' expense: Expense
generic: 'Genérico' generic: Generic
recycledPlastic: 'Plástico reciclado' recycledPlastic: Recycled plastic
nonRecycledPlastic: 'Plástico no reciclado' nonRecycledPlastic: Non recycled plastic
minSalesQuantity: 'Cantidad mínima de venta' minSalesQuantity: Min sales quantity
genus: 'Genus' genus: Genus
specie: 'Specie' specie: Specie
regularizeStock: Regularize stock search: 'Search item'
searchInfo: 'You can search by id'
regularizeStock: Regularize stock

View File

@ -73,9 +73,6 @@ itemTags:
addTag: Añadir etiqueta addTag: Añadir etiqueta
tag: Etiqueta tag: Etiqueta
value: Valor value: Valor
searchbar:
label: Buscar artículo
info: Buscar por id de artículo
itemType: itemType:
shared: shared:
code: Código code: Código
@ -108,9 +105,6 @@ item:
concept: Concepto concept: Concepto
denyOptions: Denegado denyOptions: Denegado
scopeDays: Días en adelante scopeDays: Días en adelante
searchbar:
label: Buscar artículo
info: Puedes buscar por id
descriptor: descriptor:
item: Artículo item: Artículo
buyer: Comprador buyer: Comprador
@ -182,35 +176,35 @@ item:
intrastat: Intrastat intrastat: Intrastat
origin: Origen origin: Origen
summary: summary:
basicData: 'Datos básicos' basicData: Datos básicos
otherData: 'Otros datos' otherData: Otros datos
description: 'Descripción' description: Descripción
tax: 'IVA' tax: IVA
tags: 'Etiquetas' tags: Etiquetas
botanical: 'Botánico' botanical: Botánico
barcode: 'Código de barras' barcode: Código de barras
name: 'Nombre' name: Nombre
completeName: 'Nombre completo' completeName: Nombre completo
family: 'Familia' family: Familia
size: 'Medida' size: Medida
origin: 'Origen' origin: Origen
stems: 'Tallos' stems: Tallos
multiplier: 'Multiplicador' multiplier: Multiplicador
buyer: 'Comprador' buyer: Comprador
doPhoto: 'Hacer foto' doPhoto: Hacer foto
intrastatCode: 'Código intrastat' intrastatCode: Código intrastat
intrastat: 'Intrastat' intrastat: Intrastat
ref: 'Referencia' ref: Referencia
relevance: 'Relevancia' relevance: Relevancia
weight: 'Peso (gramos)/tallo' weight: Peso (gramos)/tallo
units: 'Unidades/caja' units: Unidades/caja
expense: 'Gasto' expense: Gasto
generic: 'Genérico' generic: Genérico
recycledPlastic: 'Plástico reciclado' recycledPlastic: Plástico reciclado
nonRecycledPlastic: 'Plástico no reciclado' nonRecycledPlastic: Plástico no reciclado
minSalesQuantity: 'Cantidad mínima de venta' minSalesQuantity: Cantidad mínima de venta
genus: 'Genus' genus: Genus
specie: 'Specie' specie: Specie
regularizeStock: Regularizar stock regularizeStock: Regularizar stock
buyRequest: buyRequest:
ticketId: 'ID Ticket' ticketId: 'ID Ticket'
@ -222,4 +216,6 @@ item:
item: 'Artículo' item: 'Artículo'
achieved: 'Conseguido' achieved: 'Conseguido'
concept: 'Concepto' concept: 'Concepto'
state: 'Estado' state: 'Estado'
search: 'Buscar artículo'
searchInfo: 'Puedes buscar por id'

View File

@ -15,7 +15,6 @@ import Entry from './entry';
import roadmap from './roadmap'; import roadmap from './roadmap';
import Parking from './parking'; import Parking from './parking';
import Agency from './agency'; import Agency from './agency';
import ItemType from './itemType';
import Zone from './zone'; import Zone from './zone';
import Account from './account'; import Account from './account';
import Monitor from './monitor'; import Monitor from './monitor';
@ -38,7 +37,6 @@ export default [
roadmap, roadmap,
Parking, Parking,
Agency, Agency,
ItemType,
Zone, Zone,
Account, Account,
Monitor, Monitor,

View File

@ -1,52 +1,197 @@
import { RouterView } from 'vue-router'; import { RouterView } from 'vue-router';
const itemCard = {
name: 'ItemCard',
path: ':id',
component: () => import('src/pages/Item/Card/ItemCard.vue'),
redirect: { name: 'ItemSummary' },
meta: {
menu: [
'ItemBasicData',
'ItemTags',
'ItemLastEntries',
'ItemTax',
'ItemBotanical',
'ItemShelving',
'ItemBarcode',
'ItemDiary',
'ItemLog',
],
},
children: [
{
name: 'ItemSummary',
path: 'summary',
meta: {
title: 'summary',
icon: 'launch',
},
component: () => import('src/pages/Item/Card/ItemSummary.vue'),
},
{
path: 'basic-data',
name: 'ItemBasicData',
meta: {
title: 'basicData',
icon: 'vn:settings',
},
component: () => import('src/pages/Item/Card/ItemBasicData.vue'),
},
{
path: 'tags',
name: 'ItemTags',
meta: {
title: 'tags',
icon: 'vn:tags',
},
component: () => import('src/pages/Item/Card/ItemTags.vue'),
},
{
path: 'last-entries',
name: 'ItemLastEntries',
meta: {
title: 'lastEntries',
icon: 'vn:regentry',
},
component: () => import('src/pages/Item/Card/ItemLastEntries.vue'),
},
{
path: 'tax',
name: 'ItemTax',
meta: {
title: 'tax',
icon: 'vn:tax',
},
component: () => import('src/pages/Item/Card/ItemTax.vue'),
},
{
path: 'botanical',
name: 'ItemBotanical',
meta: {
title: 'botanical',
icon: 'vn:botanical',
},
component: () => import('src/pages/Item/Card/ItemBotanical.vue'),
},
{
path: 'shelving',
name: 'ItemShelving',
meta: {
title: 'shelving',
icon: 'vn:inventory',
},
component: () => import('src/pages/Item/Card/ItemShelving.vue'),
},
{
path: 'barcode',
name: 'ItemBarcode',
meta: {
title: 'barcode',
icon: 'vn:barcode',
},
component: () => import('src/pages/Item/Card/ItemBarcode.vue'),
},
{
path: 'diary',
name: 'ItemDiary',
meta: {
title: 'diary',
icon: 'vn:transaction',
},
component: () => import('src/pages/Item/Card/ItemDiary.vue'),
},
{
path: 'log',
name: 'ItemLog',
meta: {
title: 'log',
icon: 'vn:History',
},
component: () => import('src/pages/Item/Card/ItemLog.vue'),
},
],
};
const itemTypeCard = {
name: 'ItemTypeCard',
path: ':id',
component: () => import('src/pages/Item/ItemType/Card/ItemTypeCard.vue'),
redirect: { name: 'ItemTypeSummary' },
meta: {
menu: ['ItemTypeBasicData', 'ItemTypeLog'],
},
children: [
{
path: 'summary',
name: 'ItemTypeSummary',
meta: {
title: 'summary',
icon: 'launch',
},
component: () => import('src/pages/Item/ItemType/Card/ItemTypeSummary.vue'),
},
{
path: 'basic-data',
name: 'ItemTypeBasicData',
meta: {
title: 'basicData',
icon: 'vn:settings',
},
component: () => import('src/pages/Item/ItemType/Card/ItemTypeBasicData.vue'),
},
{
path: 'log',
name: 'ItemTypeLog',
meta: {
title: 'log',
icon: 'vn:History',
},
component: () => import('src/pages/Item/ItemType/Card/ItemTypeLog.vue'),
},
],
};
export default { export default {
path: '/item',
name: 'Item', name: 'Item',
path: '/item',
meta: { meta: {
title: 'items', title: 'items',
icon: 'vn:item', icon: 'vn:item',
moduleName: 'Item', moduleName: 'Item',
keyBinding: 'a', keyBinding: 'a',
}, menu: [
component: RouterView,
redirect: { name: 'ItemMain' },
menus: {
main: [
'ItemList', 'ItemList',
'WasteBreakdown', 'WasteBreakdown',
'ItemFixedPrice', 'ItemFixedPrice',
'ItemRequest', 'ItemRequest',
'ItemTypeList', 'ItemTypeList',
], ],
card: [
'ItemBasicData',
'ItemLog',
'ItemDiary',
'ItemTags',
'ItemTax',
'ItemBotanical',
'ItemBarcode',
'ItemShelving',
'ItemLastEntries',
'ItemTags',
],
}, },
component: RouterView,
redirect: { name: 'ItemMain' },
children: [ children: [
{ {
path: '',
name: 'ItemMain', name: 'ItemMain',
path: '',
component: () => import('src/components/common/VnModule.vue'), component: () => import('src/components/common/VnModule.vue'),
redirect: { name: 'ItemList' }, redirect: { name: 'ItemIndexMain' },
children: [ children: [
{ {
path: 'list', path: '',
name: 'ItemList', name: 'ItemIndexMain',
meta: { redirect: { name: 'ItemList' },
title: 'list',
icon: 'view_list',
},
component: () => import('src/pages/Item/ItemList.vue'), component: () => import('src/pages/Item/ItemList.vue'),
children: [
{
name: 'ItemList',
path: 'list',
meta: {
title: 'list',
icon: 'view_list',
},
},
itemCard,
],
}, },
{ {
path: 'request', path: 'request',
@ -80,120 +225,21 @@ export default {
component: () => import('src/pages/Item/ItemFixedPrice.vue'), component: () => import('src/pages/Item/ItemFixedPrice.vue'),
}, },
{ {
path: 'create', path: 'item-type',
name: 'ItemCreate', name: 'ItemTypeMain',
meta: { redirect: { name: 'ItemTypeList' },
title: 'itemCreate',
},
component: () => import('src/pages/Item/ItemCreate.vue'),
},
{
path: 'item-type-list',
name: 'ItemTypeList',
meta: {
title: 'family',
icon: 'contact_support',
},
component: () => import('src/pages/Item/ItemTypeList.vue'), component: () => import('src/pages/Item/ItemTypeList.vue'),
}, children: [
], {
}, name: 'ItemTypeList',
{ path: 'list',
name: 'ItemCard', meta: {
path: ':id', title: 'family',
component: () => import('src/pages/Item/Card/ItemCard.vue'), icon: 'contact_support',
redirect: { name: 'ItemSummary' }, },
children: [ },
{ itemTypeCard,
name: 'ItemSummary', ],
path: 'summary',
meta: {
title: 'summary',
icon: 'launch',
},
component: () => import('src/pages/Item/Card/ItemSummary.vue'),
},
{
path: 'basic-data',
name: 'ItemBasicData',
meta: {
title: 'basicData',
icon: 'vn:settings',
},
component: () => import('src/pages/Item/Card/ItemBasicData.vue'),
},
{
path: 'tags',
name: 'ItemTags',
meta: {
title: 'tags',
icon: 'vn:tags',
},
component: () => import('src/pages/Item/Card/ItemTags.vue'),
},
{
path: 'last-entries',
name: 'ItemLastEntries',
meta: {
title: 'lastEntries',
icon: 'vn:regentry',
},
component: () => import('src/pages/Item/Card/ItemLastEntries.vue'),
},
{
path: 'tax',
name: 'ItemTax',
meta: {
title: 'tax',
icon: 'vn:tax',
},
component: () => import('src/pages/Item/Card/ItemTax.vue'),
},
{
path: 'botanical',
name: 'ItemBotanical',
meta: {
title: 'botanical',
icon: 'local_florist',
},
component: () => import('src/pages/Item/Card/ItemBotanical.vue'),
},
{
path: 'shelving',
name: 'ItemShelving',
meta: {
title: 'shelving',
icon: 'vn:inventory',
},
component: () => import('src/pages/Item/Card/ItemShelving.vue'),
},
{
path: 'barcode',
name: 'ItemBarcode',
meta: {
title: 'barcode',
icon: 'vn:barcode',
},
component: () => import('src/pages/Item/Card/ItemBarcode.vue'),
},
{
path: 'diary',
name: 'ItemDiary',
meta: {
title: 'diary',
icon: 'vn:transaction',
},
component: () => import('src/pages/Item/Card/ItemDiary.vue'),
},
{
path: 'log',
name: 'ItemLog',
meta: {
title: 'log',
icon: 'vn:History',
},
component: () => import('src/pages/Item/Card/ItemLog.vue'),
}, },
], ],
}, },

View File

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

View File

@ -9,7 +9,6 @@ import invoiceIn from './modules/invoiceIn';
import wagon from './modules/wagon'; import wagon from './modules/wagon';
import supplier from './modules/supplier'; import supplier from './modules/supplier';
import travel from './modules/travel'; import travel from './modules/travel';
import ItemType from './modules/itemType';
import shelving from 'src/router/modules/shelving'; import shelving from 'src/router/modules/shelving';
import order from 'src/router/modules/order'; import order from 'src/router/modules/order';
import entry from 'src/router/modules/entry'; import entry from 'src/router/modules/entry';
@ -88,7 +87,6 @@ const routes = [
entry, entry,
parking, parking,
agency, agency,
ItemType,
zone, zone,
account, account,
{ {