- Generazione della Raccolta dei Cataloghi (web e Stampa), e creazione del PDF Online.

- Lista Raccolta Cataloghi, aggiungi/togli catalogo.
This commit is contained in:
Surya Paolo
2025-05-14 15:02:14 +02:00
parent 85faf11d27
commit fc8a954eb0
39 changed files with 6149 additions and 4069 deletions

View File

@@ -161,6 +161,7 @@ export const shared_consts = {
VISUVIDEOPROMOANDPDF: 290,
ECOMMERCE: 300,
CATALOGO: 310,
RACCOLTA: 315,
TOOLSAI: 320,
MAPPA: 350,
MAPPAUTENTI: 360,
@@ -171,6 +172,7 @@ export const shared_consts = {
QRCODE: 410,
CATALOGLIST: 420,
SEARCHPRODUCT: 430,
RACCOLTE_CATALOGHI: 450,
},
QUERYTYPE_MYGROUP: 1,
@@ -327,6 +329,7 @@ export const shared_consts = {
TABLES_ATTIVITAS: 'attivitas',
TABLES_CATALOG: 'catalogs',
TABLES_LISTA_EDITORI: 'lista_editori',
TABLES_RACCOLTACATALOGHIS: 'raccoltacataloghis',
TABFILTRI_UTENTE: 'filtriutente',
@@ -426,7 +429,7 @@ export const shared_consts = {
TABLES_UPDATE_LASTIFIED: ['myskills', 'mybachecas', 'myhosps', 'mygoods', 'bots'],
TABLES_FINDER: ['myskills', 'mybachecas', 'myhosps', 'mygoods', 'mygroups'],
TABLES_VISU_CMYSRECCARD: ['myskills', 'mybachecas', 'myhosps', 'mygoods', 'mygroups', 'catalogs'],
TABLES_VISU_CMYSRECCARD: ['myskills', 'mybachecas', 'myhosps', 'mygoods', 'mygroups', 'catalogs', 'raccoltacataloghis'],
TABLES_SHOW_ADTYPE: ['myskills', 'mygoods', 'myhosps'],
TABLES_VISU_LISTA_USER: ['myskills', 'mybachecas', 'myhosps', 'mygoods', 'users'],
@@ -438,10 +441,10 @@ export const shared_consts = {
TABLES_VISU_IMG: ['myskills', 'myhosps', 'mygoods', 'mygroups'],
TABLES_DIRECTORY_A_PARTE: ['mygroups'],
TABLES_WITH_ADMINS: ['mygroups', 'circuits'],
TABLES_DIRECTORY_SINGLE_IMG: ['circuits', 'catalogs'],
TABLES_DIRECTORY_SINGLE_IMG: ['circuits', 'catalogs', 'raccoltacataloghis'],
TABLES_IMAGEFILE_SINGOLO: ['productInfos'],
TABLES_PER_EDITORI: ['catalogs'],
TABLES_PER_EDITORI: ['catalogs', 'raccoltacataloghis'],
TABLES_VISU_MAP: 'attivitas',
@@ -1824,6 +1827,10 @@ export const shared_consts = {
value: 420,
label: 'Lista Cataloghi',
},
{
value: 450,
label: 'Raccolte Cataloghi',
},
{
value: 430, // SEARCHPRODUCT
label: 'Cerca Prodotto',
@@ -1927,6 +1934,10 @@ export const shared_consts = {
value: 310,
label: 'CATALOGO',
},
{
value: 315,
label: 'RACCOLTA CATALOGHI',
},
{
value: 350,
label: 'MAPPA',
@@ -2510,5 +2521,10 @@ export const shared_consts = {
{value: 10, label: 'TEST'},
],
WHERE_INSERT: {
ONTOP: '0',
ONBOTTOM: '1',
},
}

View File

@@ -94,6 +94,7 @@ export default defineComponent({
const searchList_Hosp = ref(<ISearchList[]>[])
const searchList_Attivita = ref(<ISearchList[]>[])
const searchList_Cataloghi = ref(<ISearchList[]>[])
const searchList_RaccoltaCataloghi = ref(<ISearchList[]>[])
const search = ref('')
const myrecfiltertoggle = ref(tools.FILTER_ALL)
@@ -105,7 +106,7 @@ export default defineComponent({
function gettablesList() {
if (props.table === 'catalogs')
if (props.table === 'catalogs' || props.table === 'raccoltarataloghis')
return func.gettablesListByTable(props.table)
}
@@ -183,6 +184,8 @@ export default defineComponent({
return { sortBy: 'numMembers', descending: true, page: 1, rowsNumber: 0, rowsPerPage: 20 }
else if (props.table === shared_consts.TABLES_CATALOG)
return { sortBy: 'title', descending: false, page: 1, rowsNumber: 0, rowsPerPage: 25 }
else if (props.table === shared_consts.TABLES_RACCOLTACATALOGHIS)
return { sortBy: 'title', descending: false, page: 1, rowsNumber: 0, rowsPerPage: 25 }
else if (props.table === toolsext.TABUSER)
return userStore.getMypaginationMembers()
else if (shared_consts.TABLES_ORDER_DATE_UPDATED.includes(props.table))
@@ -210,6 +213,8 @@ export default defineComponent({
return searchList_Attivita.value
else if (props.table === shared_consts.TABLES_CATALOG)
return searchList_Cataloghi.value
else if (props.table === shared_consts.TABLES_RACCOLTACATALOGHIS)
return searchList_RaccoltaCataloghi.value
return []
})
@@ -656,6 +661,7 @@ export default defineComponent({
]
searchList_Cataloghi.value = tools.getsearchList_Cataloghi(props.isCatalogoGenerale)
searchList_RaccoltaCataloghi.value = tools.getsearchList_RaccoltaCataloghi()
searchList_Hosp.value = [
{

View File

@@ -32,6 +32,7 @@ import { CMyGroups } from '../CMyGroups'
import { CMyFieldDb } from '../CMyFieldDb'
import { CMyRecCard } from '../CMyRecCard'
import { CMyRecCatalog } from '../CMyRecCatalog'
import { CMyRecRaccoltaCataloghi } from '../CMyRecRaccoltaCataloghi'
import { CMapByTable } from '../CMapByTable'
import { CMyRecGrpCard } from '../CMyRecGrpCard'
import { CMyRecCircuitCard } from '../CMyRecCircuitCard'
@@ -361,7 +362,7 @@ export default defineComponent({
components: {
CMyPopupEdit, CTitleBanner, CMyFieldDb, CMySelect, CMyFriends, CMyGroups,
CMyUser, CMyRecCard, CMyRecCatalog, CMyCardPopup, CMyRecGrpCard, CMyCardGrpPopup, CMyCardCircuitPopup,
CMyRecCircuitCard, CMyCardService, CNotifSettings, CMapByTable, CSingleMovement,
CMyRecCircuitCard, CMyCardService, CNotifSettings, CMapByTable, CSingleMovement, CMyRecRaccoltaCataloghi,
},
setup(props, { emit }) {
const $q = useQuasar()
@@ -2853,6 +2854,16 @@ export default defineComponent({
}
function getisDettagliByRaccolta() {
const rec = searchList.value.find((myrec) => myrec.table === ('finto_racc_' + myrec.key) && myrec.key === 'dettagli')
if (rec) {
return rec.value
}
return false
}
created()
return {
@@ -2989,6 +3000,7 @@ export default defineComponent({
onIntersection,
showfilteradv,
getisDettagliByCatalog,
getisDettagliByRaccolta,
}
}
})

View File

@@ -584,6 +584,17 @@
:margin_right="margin_right"
>
</CMyRecCatalog>
<CMyRecRaccoltaCataloghi
v-else-if="tablesel === shared_consts.TABLES_RACCOLTACATALOGHIS"
:table="tablesel"
:prop_myrec="row"
:opt="opt"
:dettagli="getisDettagliByRaccolta()"
@cmdext="cmdExt"
:editOn="editOn"
:margin_right="margin_right"
>
</CMyRecRaccoltaCataloghi>
<CMyRecCard
v-else
:table="tablesel"

View File

@@ -227,7 +227,8 @@
v-if="
myel.type === shared_consts.ELEMTYPE.CARD ||
myel.type === shared_consts.ELEMTYPE.GRID_ORIZ ||
myel.type === shared_consts.ELEMTYPE.CATALOGLIST
myel.type === shared_consts.ELEMTYPE.CATALOGLIST ||
myel.type === shared_consts.ELEMTYPE.RACCOLTE_CATALOGHI
"
label="Altezza Carosello:"
v-model="myel.heightcarousel"
@@ -240,7 +241,10 @@
</div>
<div class="row">
<CMySlider
v-if="myel.type === shared_consts.ELEMTYPE.CATALOGLIST"
v-if="
myel.type === shared_consts.ELEMTYPE.CATALOGLIST ||
myel.type === shared_consts.ELEMTYPE.RACCOLTE_CATALOGHI
"
label="Lunghezza Card:"
v-model="myel.widthcard"
:min="10"
@@ -252,7 +256,10 @@
</div>
<div class="row">
<CMySlider
v-if="myel.type === shared_consts.ELEMTYPE.CATALOGLIST"
v-if="
myel.type === shared_consts.ELEMTYPE.CATALOGLIST ||
myel.type === shared_consts.ELEMTYPE.RACCOLTE_CATALOGHI
"
label="Altezza Card:"
v-model="myel.heightcard"
:min="10"
@@ -1354,6 +1361,7 @@
{ label: 'Eventi', value: 'mybachecas' },
{ label: 'Servizi', value: 'myskills' },
{ label: 'Lista Cataloghi', value: 'catalogs' },
{ label: 'Raccolta Cataloghi', value: 'raccoltacataloghis' },
]"
label="Tabella"
emit-value
@@ -1405,6 +1413,7 @@
></q-toggle>
</div>
</div>
<div v-else-if="myel.type === shared_consts.ELEMTYPE.RACCOLTE_CATALOGHI"></div>
<div v-else-if="myel.type === shared_consts.ELEMTYPE.CATALOGLIST">
<div
v-if="enableEdit"

View File

@@ -13,6 +13,7 @@ import { CImgPoster } from '@src/components/CImgPoster'
import { CTitle } from '@src/components/CTitle/index'
import { CGridOriz } from '@src/components/CGridOriz/index'
import { CCatalogList } from '@src/components/CCatalogList/index'
import { CRaccoltaCataloghi } from '@src/components/CRaccoltaCataloghi/index'
import { tools } from '@tools'
import { shared_consts } from '@src/common/shared_vuejs'
import { LandingFooter } from '@src/components/LandingFooter'
@@ -23,6 +24,7 @@ import { CSearchProduct } from '@src/components/CSearchProduct'
import { CQRCode } from '@src/components/CQRCode'
import { CAITools } from '@src/components/CAITools'
import { CCatalogo } from '@src/components/CCatalogo'
import { CRaccolta } from '@src/components/CRaccolta'
// import { CMapMarker } from '@src/components/CMapMarker.off'
import { CMapUsers } from '@src/components/CMapUsers'
import { CMapGetCoordinates } from '@src/components/CMapGetCoordinates'
@@ -73,10 +75,10 @@ export default defineComponent({
CPresentazione, CMyActivities,
CMyProfileTutorial, CSendRISTo,
CTitleBanner, CShareSocial, CCheckAppRunning, CRegistration,
CVisuVideoPromoAndPDF, CECommerce, CCatalogo, CAITools, CStatMacro,
CVisuVideoPromoAndPDF, CECommerce, CCatalogo, CRaccolta, CAITools, CStatMacro,
CMapComuni, CMapUsers, CMapGetCoordinates, CMapEditAddressByCoord,
CDashGroup, CMovements, CGridOriz, CQRCode, CCatalogList,
CSearchProduct,
CSearchProduct, CRaccoltaCataloghi,
// , //CMapMarker,
},
emits: ['selElemClick'],

View File

@@ -342,7 +342,7 @@
:prop_modif="myel.parambool4"></CGridOriz>
</div>
<div v-else-if="myel.type === shared_consts.ELEMTYPE.SEARCHPRODUCT">
<CSearchProduct v-model="myel.catalogo">
<CSearchProduct v-model="myel.catalogo" table="products">
</CSearchProduct>
</div>
<div v-else-if="myel.type === shared_consts.ELEMTYPE.CATALOGLIST">
@@ -379,6 +379,28 @@
</q-tab-panel>
</q-tab-panels>
</div>
<div v-else-if="myel.type === shared_consts.ELEMTYPE.RACCOLTE_CATALOGHI">
<div v-if="editOn" class="elemEdit">Raccolte Cataloghi</div>
<q-tabs v-if="tools.isEditor() || tools.isGrafico()" v-model="tabcatalogo" dense class="bg-green text-white">
<q-tab name="griglia" icon="fas fa-eye" label="Griglia"> </q-tab>
<q-tab name="lista" icon="fas fa-list" label="Lista"> </q-tab>
</q-tabs>
<q-tab-panels v-model="tabcatalogo" animated keep-alive>
<q-tab-panel name="lista">
<CGridOriz table="raccoltacataloghis" :tipovisu="costanti.VISUTABLE_TABLELIST" :prop_search="true" :finder="true"
:isCatalogoGenerale="myel.parambool3"
:showMap="false" :prop_modif="tools.isAdmin()" :enableExport="true"></CGridOriz>
</q-tab-panel>
<q-tab-panel name="griglia">
<CRaccoltaCataloghi :prop_search="myel.parambool" :finder="myel.parambool2"
:heightcarousel="myel.heightcarousel" :heightimg="myel.heightimg" :widthimg="myel.widthimg"
:heightcard="myel.heightcard" :widthcard="myel.widthcard"
:isCatalogoGenerale="myel.parambool3">
</CRaccoltaCataloghi>
</q-tab-panel>
</q-tab-panels>
</div>
<div v-else-if="myel.type === shared_consts.ELEMTYPE.STATUSREG">
<div v-if="editOn" class="elemEdit">CStatusReg</div>
<CStatusReg> </CStatusReg>
@@ -443,6 +465,9 @@
<div v-else-if="myel.type === shared_consts.ELEMTYPE.CATALOGO">
<CCatalogo v-model="myel.catalogo" :idPage="idPage" @updateCatalogo="updateCatalogoEmit(myel.catalogo)" />
</div>
<div v-else-if="myel.type === shared_consts.ELEMTYPE.RACCOLTA">
<CRaccolta v-model="myel.catalogo" :idPage="idPage" @updateCatalogo="updateCatalogoEmit(myel.catalogo)" />
</div>
<div v-else-if="myel.type === shared_consts.ELEMTYPE.MAPPA">
<div v-if="editOn" class="elemEdit">MAPPA:</div>
<!--<CMapMarker :coord_center="{lat: 47.41322, long: -1.219482}"

View File

@@ -0,0 +1,83 @@
.cardrec {
/* Aggiungi un bordo sottile */
border: 1px solid #ddd;
/* Applica un'ombreggiatura per dare l'effetto di elevazione */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
/* Arrotonda leggermente gli angoli */
border-radius: 8px;
/* Aggiungi un po' di spazio interno intorno ai contenuti */
padding: 8px;
/* Colore di sfondo bianco per separare dal resto del contenuto */
background-color: #eff;
margin: 4px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
@media (min-width: 500px) {
margin: 1px;
padding: 4px;
}
}
.catalog-image {
max-width: 100%;
height: auto;
margin-bottom: 20px;
}
.imgcatalog {
border: 4px solid #ffffff;
/* Bordo bianco */
border-radius: 12px;
/* Angoli arrotondati */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
/* Ombra per un effetto 3D */
transition: transform 0.3s ease, box-shadow 0.3s ease;
/* Transizione fluida */
object-fit: cover;
/* Mantiene l'aspetto dell'immagine senza distorsioni */
}
.imgcatalog:hover {
transform: scale(1.05);
/* Effetto di ingrandimento al passaggio del mouse */
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
/* Ombra più pronunciata al passaggio del mouse */
}
.back_img {
background-repeat: no-repeat !important;
background-size: cover;
background-position: center;
}
.flex-grow {
flex-grow: 1;
/* Usa flex-grow per occupare spazio disponibile */
}
.title-container {
background-color: rgba(0, 0, 0, 0.3);
/* Sfondo bianco con trasparenza */
padding: 4px;
/* Aggiunta di padding per creare spazio attorno al testo */
border-radius: 8px;
/* Arrotonda gli angoli dello sfondo */
}
.clickable-image {
cursor: pointer;
/* Cambia il cursore a puntatore quando si passa sopra */
transition: transform 0.2s;
/* Aggiunge una transizione dolce */
}
.clickable-image:hover {
transform: scale(1.05);
/* Aumenta leggermente l'immagine al passaggio del mouse */
}

View File

@@ -0,0 +1,195 @@
import type { PropType } from 'vue';
import { defineComponent, onMounted, ref, watch, computed } from 'vue'
import { useUserStore } from '@store/UserStore'
import type { IRaccoltaCatalogo, IOptGrid, IUserFields } from 'model';
import { IImgGallery, IUserProfile } from 'model'
import { costanti } from '@costanti'
import { shared_consts } from '@src/common/shared_vuejs'
import { fieldsTable } from '@store/Modules/fieldsTable'
import { tools } from '@tools'
import { toolsext } from '@store/Modules/toolsext'
import { useQuasar } from 'quasar'
import { useI18n } from 'vue-i18n'
import { CLabel } from '@src/components/CLabel'
import { CMyCardPopup } from '@src/components/CMyCardPopup'
import { useRouter } from 'vue-router'
import { useCalendarStore } from '@src/store/CalendarStore'
import { useGlobalStore } from '@src/store/globalStore'
import type { ICatProd, ICollana, IPublisher } from "@src/model/Products"
import { useProducts } from '@src/store/Products'
export default defineComponent({
name: 'CMyRecRaccoltaCataloghi',
components: { CMyCardPopup, CLabel },
emits: ['setCmd', 'cmdext'],
props: {
table: {
type: String,
required: true,
},
prop_myrec: {
type: Object as PropType<any>,
required: false,
default: null,
},
editOn: {
type: Boolean,
required: false,
default: false,
},
dettagli: {
type: Boolean,
required: false,
default: false,
},
margin_right: {
type: Number,
required: false,
default: 0,
},
opt: {
type: Object as PropType<IOptGrid>,
required: false,
default: () => {
return {}
},
},
},
setup(props, { emit }) {
const userStore = useUserStore()
const calendarStore = useCalendarStore()
const globalStore = useGlobalStore()
const $q = useQuasar()
const { t } = useI18n()
const $router = useRouter()
const myrec = ref(<IRaccoltaCatalogo>{})
const statecolor = ref('negative')
const apriInfo = ref(false)
const collanestr = ref('')
const argomentistr = ref('')
const numprodtot = ref(0)
const editorestr = ref('')
const products = useProducts()
const visupage = ref(false)
const disabilita = computed(() => {
return props.table === shared_consts.TABLES_MYBACHECAS
})
const pagina_collegata = computed(() => {
let linkpage = ''
const idpag = myrec.value.idPageAssigned
if (idpag) {
const mypage = globalStore.getPageById(idpag)
if (mypage)
linkpage = mypage.path!
}
return linkpage
})
const numcataloghistr = computed(() => {
return myrec.value?.lista_cataloghi?.length || 0
})
watch(() => props.prop_myrec, (newval, oldval) => {
mounted()
})
function mounted() {
if (props.prop_myrec) {
myrec.value = props.prop_myrec
}
}
function showBadge() {
if (shared_consts.TABLES_SHOW_ADTYPE.includes(props.table)) {
return true
}
return false
}
function getImgUser(profile: IUserFields) {
return userStore.getImgByProfile(profile)
}
function naviga(path: string) {
$router.push(path)
}
function setCmd($q: any, cmd: number, myusername: string, value: any, groupname: string) {
emit('setCmd', $q, cmd, myusername, value, groupname)
}
function cmdExt(cmd: any, val1: any, val2: any) {
emit('cmdext', cmd, val1, val2)
}
function navigaExt(obj: any) {
cmdExt(costanti.CMD_SHOW_PAGE, null, obj)
//let link = shared_consts.getDirectoryByTable(props.table) + '/' + obj._id
//console.log('link', link)
//$router.push(link)
}
function getNameToShow(user: IUserFields, col = null) {
if (myrec.value.groupname)
return myrec.value.groupname
else
return userStore.getNameToShow(user, col)
}
function computedWidth() {
const width = tools.getwidth($q) - 20;
return `${Math.min(width, 600)}px`; // Limita la larghezza massima a 600px
}
onMounted(mounted)
return {
t,
myrec,
costanti,
getImgUser,
naviga,
navigaExt,
setCmd,
shared_consts,
userStore,
tools,
toolsext,
fieldsTable,
cmdExt,
visupage,
showBadge,
getNameToShow,
calendarStore,
disabilita,
globalStore,
computedWidth,
statecolor,
apriInfo,
collanestr,
editorestr,
pagina_collegata,
argomentistr,
numprodtot,
numcataloghistr,
}
},
})

View File

@@ -0,0 +1,196 @@
<template>
<q-card
v-if="myrec"
bordered
class="full-height flex flex-column justify-evenly"
:style="`width: ` + opt.widthcard + `; ` + (opt.heightcard ? `height: ` + opt.heightcard + `;` : '')"
>
<q-img
:width="opt.widthimg"
@click="naviga(pagina_collegata)"
:height="opt.heightimg"
class="clickable-image"
fit="cover"
:src="tools.getFullFileName([myrec.foto_raccolta], table, '', myrec._id)"
>
<template v-slot:error>
<div class="absolute-full flex flex-center text-white">immagine non impostata</div>
</template>
<!--<div class="text-h6 absolute-bottom text-left">
{{ myrec.title }}
</div>-->
</q-img>
<q-card-section class="q-px-sm" style="margin-top: 0; flex-grow: 0; align-self: flex-start;">
<div
class="q-mb-md text-center text-bold"
style="font-size: 1.15rem"
>
<a
:href="pagina_collegata"
target="_blank"
>{{ myrec.title }}</a
>
</div>
<div class="q-px-md">
<div class="text-caption text-h7 text-grey q-pb-xs">
<q-icon name="fas fa-list-ol" /> {{ $t('racccat.numcataloghi') }}:
<span :class="`text-` + (numcataloghistr === 0 ? 'red' : 'blue')">{{ numcataloghistr }}</span>
</div>
<div
v-if="myrec.pdf_online"
class="text-caption text-h7 text-blue q-pb-xs"
>
<q-icon name="fas fa-book" />&nbsp;
<a
:href="myrec.pdf_online"
target="_blank"
>PDF OnLine</a
>
aggiornato al ({{ tools.getstrDate(myrec.data_online) }})
</div>
<div
v-if="!tools.isUtente() && myrec.pdf_online_stampa && dettagli"
class="text-caption text-h7 text-blue q-pb-xs"
>
<q-icon name="fas fa-print" />&nbsp;
<a
:href="myrec.pdf_online_stampa"
target="_blank"
>PDF per Stampa</a
>
aggiornato al ({{ tools.getstrDate(myrec.data_online_stampa) }})
</div>
<div
v-if="!tools.isUtente() && dettagli"
class="text-caption text-h7 text-grey q-pb-xs"
>
<q-icon name="fas fa-list" /> Lista generata il:
<span :class="`text-` + (tools.isDateValid(myrec.data_lista_generata) ? 'blue' : 'red')"
>{{ tools.getstrDate(myrec.data_lista_generata) || '(non ancora generata)' }} da
{{ myrec.username_lista_generata }}
</span>
</div>
</div>
<!--<div class="text-overline text-orange-9">{{collanestr}}</div>-->
</q-card-section>
<q-card-actions
v-if="!tools.isUtente() && dettagli"
align="center"
class="q-mt-auto q-mx-auto q-mb-sm"
>
<q-fab
color="primary"
icon="fas fa-caret-down"
label="Menu"
direction="up"
flat
dense
>
<q-fab-action
v-if="tools.canModifyThisRec(myrec, table) || tools.isManager() || editOn"
@click="cmdExt(costanti.CMD_DELETE, myrec._id, null)"
color="negative"
:label="$t('reg.elimina')"
icon="fas fa-trash-alt"
/>
<!--<q-fab-action
v-if="tools.canModifyThisRec(myrec, table) || tools.isManager() || editOn"
@click="cmdExt(costanti.CMD_CLONE, myrec._id, null)"
color="accent"
:label="$t('event.duplicate')"
icon="fas fa-copy"
/>-->
<q-fab-action
v-if="tools.canModifyThisRec(myrec, table) || editOn"
:disable="!pagina_collegata"
color="positive"
label="Gestisci"
icon="fas fa-book-open"
@click="naviga(pagina_collegata)"
/>
<q-fab-action
v-if="tools.canModifyThisRec(myrec, table) || editOn"
@click="cmdExt(costanti.CMD_MODIFY, myrec._id, null)"
color="primary"
:label="$t('reg.edit')"
icon="fas fa-pencil-alt"
/>
</q-fab>
<q-btn
flat
color="primary"
label="Info"
icon="fas fa-info"
@click="apriInfo = true"
/>
</q-card-actions>
</q-card>
<q-dialog v-model="apriInfo">
<q-card>
<q-toolbar class="bg-primary text-white">
<q-toolbar-title>
{{ myrec.title }}
</q-toolbar-title>
<q-btn
flat
round
color="white"
label="CHIUDI"
icon="close"
v-close-popup
></q-btn>
</q-toolbar>
<q-card-section>
<div class="row justify-center q-ma-sm q-pb-xs">
<div
style="width: 300px"
class="q-ma-sm"
>
<CLabel
:value="
tools.getstrDate(myrec.data_lista_generata) + ' da ' + myrec.username_lista_generata ||
'ancora non è stata generata'
"
label="Lista generata"
:color="myrec.pdf_generato ? 'green' : 'red'"
/>
</div>
<CLabel
:value="myrec.pdf_generato || 'ancora non è stato generato'"
label="PDF generato"
:color="myrec.pdf_generato ? 'green' : 'red'"
:copy="true"
/>
<CLabel
:value="myrec.pdf_online || 'ancora non è andato ONLINE'"
label="PDF On-Line Ufficiale"
:color="myrec.pdf_online ? 'green' : 'red'"
:copy="true"
/>
<CLabel
:value="myrec.pdf_generato_stampa || 'ancora non è stato generato'"
label="PDF per Stampa"
:color="myrec.pdf_generato_stampa ? 'green' : 'red'"
:copy="true"
/>
</div>
</q-card-section>
</q-card>
<q-card-actions align="center">
<q-btn
color="primary"
label="Chiudi"
@click="apriInfo = false"
/>
</q-card-actions>
</q-dialog>
</template>
<script lang="ts" src="./CMyRecRaccoltaCataloghi.ts"></script>
<style lang="scss" scoped>
@import './CMyRecRaccoltaCataloghi.scss';
</style>

View File

@@ -0,0 +1 @@
export { default as CMyRecRaccoltaCataloghi } from './CMyRecRaccoltaCataloghi.vue'

View File

@@ -1,35 +1,35 @@
import { PropType, computed, defineComponent, onMounted, ref, watch } from "vue";
import draggable from 'vuedraggable'
import { PropType, computed, defineComponent, onMounted, ref, watch } from 'vue';
import draggable from 'vuedraggable';
import { tools } from '@tools'
import { tools } from '@tools';
import { useGlobalStore } from '@src/store/globalStore'
import { useGlobalStore } from '@src/store/globalStore';
import { CMyValueDb } from '@src/components/CMyValueDb'
import { CSchedaProdotto } from '@src/components/CSchedaProdotto'
import { CSearchProduct } from '@src/components/CSearchProduct'
import { CMyDialog } from '@src/components/CMyDialog'
import { CMyValueDb } from '@src/components/CMyValueDb';
import { CSchedaProdotto } from '@src/components/CSchedaProdotto';
import { CSearchProduct } from '@src/components/CSearchProduct';
import { CMyDialog } from '@src/components/CMyDialog';
import { costanti } from '@costanti'
import { IAuthor, ICatProd } from "app/src/model";
import type {
IMyScheda,
IOptCatalogo,
IProduct
} from '@src/model';
import { shared_consts } from "app/src/common/shared_vuejs";
import { useProducts } from "app/src/store/Products";
import { CViewTable } from "../CViewTable";
import { CLabel } from "../CLabel";
import { useI18n } from "vue-i18n";
import { costanti } from '@costanti';
import { IAuthor, ICatProd } from 'app/src/model';
import type { IMyScheda, IOptCatalogo, IProduct } from '@src/model';
import { shared_consts } from 'app/src/common/shared_vuejs';
import { useProducts } from 'app/src/store/Products';
import { CViewTable } from '../CViewTable';
import { CLabel } from '../CLabel';
import { useI18n } from 'vue-i18n';
export default defineComponent({
name: "CProductTable",
emits: ["update:lista_prodotti", "update:optcatalogo", "rigenera"],
name: 'CProductTable',
emits: ['update:lista_prodotti', 'update:optcatalogo', 'rigenera'],
components: {
draggable, CSearchProduct, CMyDialog, CMyValueDb, CViewTable, CLabel,
draggable,
CSearchProduct,
CMyDialog,
CMyValueDb,
CViewTable,
CLabel,
CSchedaProdotto,
},
props: {
@@ -37,6 +37,10 @@ export default defineComponent({
type: Array,
required: true,
},
table: {
type: String,
required: true,
},
optcatalogo: {
type: Object as PropType<IOptCatalogo>,
required: false,
@@ -45,53 +49,52 @@ export default defineComponent({
scheda: {
type: Object as PropType<IMyScheda>,
required: false,
default: () => ({
}),
default: () => ({}),
},
},
setup(props, { emit }) {
// Copia locale della lista_prodotti per manipolazione interna
const internalProducts = ref([...props.lista_prodotti || []]);
const internalProducts = ref([...(props.lista_prodotti || [])]);
const { t } = useI18n()
const { t } = useI18n();
const globalStore = useGlobalStore()
const products = useProducts()
const globalStore = useGlobalStore();
const products = useProducts();
const showProd = ref(false)
const selProd = ref(<IProduct | null>null)
const showProd = ref(false);
const selProd = ref(<IProduct | null>null);
const cmd = ref(shared_consts.SCHEDA_PRODOTTO.CMD_NONE)
const cmd = ref(shared_consts.SCHEDA_PRODOTTO.CMD_NONE);
const showQtaDisponibile = ref(false)
const loading = ref(true)
const visufromgm = ref(false)
const updatefromgm = ref(false)
const field_updated_fromGM = ref('')
const showQtaDisponibile = ref(false);
const loading = ref(true);
const visufromgm = ref(false);
const updatefromgm = ref(false);
const field_updated_fromGM = ref('');
const modifOn = ref(false)
const modifOn = ref(false);
const sortAttribute = ref('')
const sortDirection = ref(1)
const sortAttribute = ref('');
const sortDirection = ref(1);
const optionscatalogo = ref(<any>{ maxlength: 0 })
const addstr = ref('');
const optionscatalogo = ref(<any>{ maxlength: 0 });
function handleUpdate(newList) {
internalProducts.value = newList
emit('update:lista_prodotti', internalProducts.value)
internalProducts.value = newList;
emit('update:lista_prodotti', internalProducts.value);
}
const editOn = computed({
get(): boolean {
return globalStore.editOn ? globalStore.editOn : false
return globalStore.editOn ? globalStore.editOn : false;
},
set(value: boolean) {
return tools.updateEditOn(value)
}
})
return tools.updateEditOn(value);
},
});
// Aggiorna la copia locale quando il prop cambia
watch(
@@ -99,172 +102,276 @@ export default defineComponent({
(newVal) => {
internalProducts.value = [...newVal];
}
), { deep: true };
),
{ deep: true };
const allColumns = ref([]);
// Colonne della tabella
const allColumns = [
{ name: "pos", label: "Ind", field: "pos", align: "left", style: "width: 50px", notsortable: true },
{ name: "drag", label: "Ord", field: "", align: "left", style: "width: 50px", edit: true, noexp: true, notsortable: true },
{ name: "validato", label: "Val", field: "validato", align: "left", style: "", },
{ name: "image", label: "Foto", field: "image", align: "center", noexp: true, notsortable: true },
{ name: "name", label: "Titolo", field: "name", align: "left" },
{ name: "sottotitolo", label: "Sottotitolo", field: "sottotitolo", align: "left" },
{ name: "authors", label: "Autore", field: "authors", align: "left" },
{ name: "isbn", label: "ISBN", field: "isbn", align: "left" },
{ name: "trafiletto", label: "Sinossi", field: "trafiletto", align: "left" },
{ name: "catprods", label: "Argomento", field: "catprods", align: "left" },
{ name: "edizione", label: "Edizione", field: "edizione", align: "left" },
{ name: "casaeditrice", label: "Casa Editrice", field: "casaeditrice", align: "left" },
{ name: "idCollana", label: "Collana", field: "idCollana", align: "left" },
{ name: "stato", label: "Stato", field: "stato", align: "left" },
{ name: "tipologia", label: "Tipologia", field: "tipologia", align: "left" },
{ name: "tipoformato", label: "Formato", field: "tipoformato", align: "left" },
{ name: "pagine", label: "Pag.", field: "pagine", align: "right" },
{ name: "prezzo", label: "€", field: "prezzo", align: "right" },
{ name: "prezzo_sconto", label: "€ (sconto)", field: "prezzo_sconto", align: "right" },
{ name: "date_pub", label: "Pubblicato", field: "date_pub", align: "left" },
const allColumns_Raccolta = ref([
{ name: 'pos', label: 'Ind', field: 'pos', align: 'left', style: 'width: 50px', notsortable: true },
{
name: 'drag',
label: 'Ord',
field: '',
align: 'left',
style: 'width: 50px',
edit: true,
noexp: true,
notsortable: true,
},
{ name: 'image', label: 'Foto', field: 'image', align: 'center', noexp: true, notsortable: true },
{ name: 'title', label: 'Titolo', field: 'title', align: 'left' },
{ name: 'pdf_generato', label: 'Generato', field: 'pdf_generato', align: 'center' },
{ name: 'data_generato', label: 'Data Generato', field: 'data_generato', align: 'center' },
{ name: 'pdf_generato_stampa', label: 'Generato Stampa', field: 'pdf_generato_stampa', align: 'center' },
{ name: 'data_generato_stampa', label: 'Data Generato Stampa', field: 'data_generato_stampa', align: 'center' },
{ name: 'pdf_online', label: 'PDF OnLine', field: 'pdf_online', align: 'center' },
{ name: 'pdf_online_stampa', label: 'PDF OnLine Stampa', field: 'pdf_online_stampa', align: 'center' },
{ name: 'data_online', label: 'Data Online', field: 'data_online', align: 'center' },
{ name: 'data_online_stampa', label: 'Data Online Stampa', field: 'data_online_stampa', align: 'center' },
{
name: 'actions',
label: 'Azioni',
field: '',
align: 'center',
visu: costanti.VISUCAMPI.PER_EDITORE,
noexp: true,
notsortable: true,
},
]);
const allColumns_Catalog = ref([
{ name: 'pos', label: 'Ind', field: 'pos', align: 'left', style: 'width: 50px', notsortable: true },
{
name: 'drag',
label: 'Ord',
field: '',
align: 'left',
style: 'width: 50px',
edit: true,
noexp: true,
notsortable: true,
},
{ name: 'validato', label: 'Val', field: 'validato', align: 'left', style: '' },
{ name: 'image', label: 'Foto', field: 'image', align: 'center', noexp: true, notsortable: true },
{ name: 'name', label: 'Titolo', field: 'name', align: 'left' },
{ name: 'sottotitolo', label: 'Sottotitolo', field: 'sottotitolo', align: 'left' },
{ name: 'authors', label: 'Autore', field: 'authors', align: 'left' },
{ name: 'isbn', label: 'ISBN', field: 'isbn', align: 'left' },
{ name: 'trafiletto', label: 'Sinossi', field: 'trafiletto', align: 'left' },
{ name: 'catprods', label: 'Argomento', field: 'catprods', align: 'left' },
{ name: 'edizione', label: 'Edizione', field: 'edizione', align: 'left' },
{ name: 'casaeditrice', label: 'Casa Editrice', field: 'casaeditrice', align: 'left' },
{ name: 'idCollana', label: 'Collana', field: 'idCollana', align: 'left' },
{ name: 'stato', label: 'Stato', field: 'stato', align: 'left' },
{ name: 'tipologia', label: 'Tipologia', field: 'tipologia', align: 'left' },
{ name: 'tipoformato', label: 'Formato', field: 'tipoformato', align: 'left' },
{ name: 'pagine', label: 'Pag.', field: 'pagine', align: 'right' },
{ name: 'prezzo', label: '€', field: 'prezzo', align: 'right' },
{ name: 'prezzo_sconto', label: '€ (sconto)', field: 'prezzo_sconto', align: 'right' },
{ name: 'date_pub', label: 'Pubblicato', field: 'date_pub', align: 'left' },
//{ name: "ranking", label: "Class.", field: "ranking", align: "right" },
//{ name: "rank3M", label: "Class. 3M", field: "rank3M", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
//{ name: "rank6M", label: "Class. 6M", field: "rank6M", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
//{ name: "rank1Y", label: "Class. 1Y", field: "rank1Y", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: "totVen", label: "Vend", field: "totVen", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: "vLast6M", label: "Ven 6M", field: "vLast6M", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: "fatLast6M", label: "Fat 6M", field: "fatLast6M", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: "fatLast1Y", label: "Fat 1A", field: "fatLast1Y", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: "fatLast2Y", label: "Fat 2A", field: "fatLast2Y", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: "totFat", label: "Fat 5A", field: "totFat", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: "ult_ord", label: "Ult. Ordine", field: "ult_ord", align: "left", visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: "quantity", label: "Magazz.", field: "quantity", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: "actions", label: "Azioni", field: "", align: "center", visu: costanti.VISUCAMPI.PER_EDITORE, noexp: true, notsortable: true },
];
{ name: 'totVen', label: 'Vend', field: 'totVen', align: 'right', visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: 'vLast6M', label: 'Ven 6M', field: 'vLast6M', align: 'right', visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: 'fatLast6M', label: 'Fat 6M', field: 'fatLast6M', align: 'right', visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: 'fatLast1Y', label: 'Fat 1A', field: 'fatLast1Y', align: 'right', visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: 'fatLast2Y', label: 'Fat 2A', field: 'fatLast2Y', align: 'right', visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: 'totFat', label: 'Fat 5A', field: 'totFat', align: 'right', visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: 'ult_ord', label: 'Ult. Ordine', field: 'ult_ord', align: 'left', visu: costanti.VISUCAMPI.PER_EDITORE },
{ name: 'quantity', label: 'Magazz.', field: 'quantity', align: 'right', visu: costanti.VISUCAMPI.PER_EDITORE },
{
name: 'actions',
label: 'Azioni',
field: '',
align: 'center',
visu: costanti.VISUCAMPI.PER_EDITORE,
noexp: true,
notsortable: true,
},
]);
async function mounted() {
console.log('mounted CProductTable')
loading.value = true
console.log('mounted CProductTable');
loading.value = true;
optionscatalogo.value = {
maxlength: props.scheda?.testo_bottom?.maxlength
if (props.table === shared_consts.TABLES_CATALOG) {
selectedColumns.value = selectedColumns_Catalogs.value;
} else {
selectedColumns.value = tools.isUtente() ? selectedColumns_Utenti.value : selectedColumns_Editori.value;
}
const savedColumns = tools.getCookie("selColCat_2");
addstr.value = tools.addstrCookie(props.table);
if (props.table === 'products') {
allColumns.value = allColumns_Catalog.value;
} else if (props.table === 'catalogs') {
allColumns.value = allColumns_Raccolta.value;
}
optionscatalogo.value = {
maxlength: props.scheda?.testo_bottom?.maxlength,
};
const savedColumns = tools.getCookie(addstr.value + 'selColCat_2');
if (savedColumns) {
selectedColumns.value = savedColumns;
}
const savedSortAttribute = tools.getCookie("sortAttr");
const savedSortAttribute = tools.getCookie(addstr.value + 'sortAttr');
if (savedSortAttribute && props.optcatalogo.showListaArgomenti) {
if (isColumnVisible(savedSortAttribute)) {
sortAttribute.value = savedSortAttribute;
const savedSortDir = tools.getCookie("sortDir");
const savedSortDir = tools.getCookie(addstr.value + 'sortDir');
if (savedSortDir) {
sortDirection.value = savedSortDir;
}
}
}
loading.value = false
loading.value = false;
}
function getFieldValue(element: any, field: any): any {
if (!element)
return ''
if (!element) return '';
try {
switch (field.field) {
case 'image':
return element.productInfo?.imagefile
? tools.getFullFileNameByImageFile('productInfos', element.productInfo?.imagefile)
: element.productInfo?.image_link;
if (props.table === shared_consts.TABLES_CATALOG) {
const catalog = element;
switch (field.field) {
case 'active':
return catalog.active;
case 'title':
return catalog.title;
case 'pdf_generato':
return catalog.pdf_generato
? `<a href="${catalog.pdf_generato}" target="_blank" rel="noopener noreferrer">PDF</a>`
: '';
case 'pdf_generato_stampa':
return catalog.pdf_generato_stampa
? `<a href="${catalog.pdf_generato_stampa}" target="_blank" rel="noopener noreferrer">PDF</a>`
: '';
case 'data_generato':
return tools.getstrDate(catalog.data_generato);
case 'data_generato_stampa':
return tools.getstrDate(catalog.data_generato_stampa);
case 'pdf_online':
return catalog.pdf_online
? `<a href="${catalog.pdf_online}" target="_blank" rel="noopener noreferrer">PDF</a>`
: '';
case 'pdf_online_stampa':
return catalog.pdf_online_stampa
? `<a href="${catalog.pdf_online_stampa}" target="_blank" rel="noopener noreferrer">PDF</a>`
: '';
case 'data_online':
return tools.getstrDate(catalog.data_online);
case 'data_online_stampa':
return tools.getstrDate(catalog.data_online_stampa);
case 'image':
return catalog.foto_collana?.imagefile
? tools.getFullFileNameByImageFile(shared_consts.TABLES_CATALOG, catalog.foto_collana?.imagefile)
: '';
}
} else {
switch (field.field) {
case 'image':
return element.productInfo?.imagefile
? tools.getFullFileNameByImageFile('productInfos', element.productInfo?.imagefile)
: element.productInfo?.image_link;
case 'name':
return element.productInfo?.name;
case 'name':
return element.productInfo?.name;
case 'sottotitolo':
return element.productInfo?.sottotitolo;
case 'sottotitolo':
return element.productInfo?.sottotitolo;
case 'authors':
return formatAuthors(element.productInfo?.authors);
case 'authors':
return formatAuthors(element.productInfo?.authors);
case 'validato':
return element.validaprod?.esito === costanti.VALIDATO.SI ? '<span class="text-bold">SI</span>' : (element.validaprod?.esito === costanti.VALIDATO.TO_RESOLV ? '<span class="text-bold">ERR</span>' : 'NO');
case 'validato':
return element.validaprod?.esito === costanti.VALIDATO.SI
? '<span class="text-bold">SI</span>'
: element.validaprod?.esito === costanti.VALIDATO.TO_RESOLV
? '<span class="text-bold">ERR</span>'
: 'NO';
case 'isbn':
return element.isbn;
case 'isbn':
return element.isbn;
case 'trafiletto':
return element.productInfo?.descr_trafiletto_catalogo?.length > 100 ? 'SI' : 'NO';
case 'trafiletto':
return element.productInfo?.descr_trafiletto_catalogo?.length > 100 ? 'SI' : 'NO';
case 'catprods':
return tools.formatCatProds(element.productInfo?.catprods);
case 'catprods':
return tools.formatCatProds(element.productInfo?.catprods);
case 'edizione':
return element.arrvariazioni?.[0]?.edizione;
case 'edizione':
return element.arrvariazioni?.[0]?.edizione;
case 'casaeditrice':
return products.getCasaEditriceByIdPublisher(element.productInfo?.idPublisher);
case 'casaeditrice':
return products.getCasaEditriceByIdPublisher(element.productInfo?.idPublisher);
case 'idCollana':
return tools.formatCollane(element.productInfo?.idCollana);
case 'idCollana':
return tools.formatCollane(element.productInfo?.idCollana);
case 'stato':
return products.getDescrStatiProdottoByIdStatoProdotto(element.productInfo?.idStatoProdotto || '');
case 'stato':
return products.getDescrStatiProdottoByIdStatoProdotto(element.productInfo?.idStatoProdotto || '');
case 'tipologia':
return products.getDescrByIdTipologia(element.arrvariazioni?.[0]?.idTipologia || '');
case 'tipologia':
return products.getDescrByIdTipologia(element.arrvariazioni?.[0]?.idTipologia || '');
case 'tipoformato':
return products.getDescrByIdTipoFormato(element.arrvariazioni?.[0]?.idTipoFormato || '');
case 'tipoformato':
return products.getDescrByIdTipoFormato(element.arrvariazioni?.[0]?.idTipoFormato || '');
case 'date_pub':
return tools.getstrDate(element.productInfo?.date_pub);
case 'date_pub':
return tools.getstrDate(element.productInfo?.date_pub);
case 'prezzo':
return element.price ? '€ ' + element.price.toFixed(2) : '';
case 'prezzo':
return element.price ? '€ ' + element.price.toFixed(2) : '';
case 'prezzo_sconto':
return element.sale_price ? '€ ' + element.sale_price.toFixed(2) : '';
case 'prezzo_sconto':
return element.sale_price ? '€ ' + element.sale_price.toFixed(2) : '';
case 'rank3M':
return element.productInfo?.rank3M;
case 'rank3M':
return element.productInfo?.rank3M;
case 'rank6M':
return element.productInfo?.rank6M;
case 'rank6M':
return element.productInfo?.rank6M;
case 'rank1Y':
return element.productInfo?.rank1Y;
case 'rank1Y':
return element.productInfo?.rank1Y;
case 'pagine':
return element.arrvariazioni?.[0]?.pagine;
case 'pagine':
return element.arrvariazioni?.[0]?.pagine;
case 'totVen':
return element.productInfo?.totVen;
case 'totVen':
return element.productInfo?.totVen;
case 'totFat':
return element.productInfo?.totFat;
case 'totFat':
return element.productInfo?.totFat;
case 'fatLast6M':
return element.productInfo?.fatLast6M;
case 'fatLast6M':
return element.productInfo?.fatLast6M;
case 'fatLast1Y':
return element.productInfo?.fatLast1Y;
case 'fatLast1Y':
return element.productInfo?.fatLast1Y;
case 'fatLast2Y':
return element.productInfo?.fatLast2Y;
case 'fatLast2Y':
return element.productInfo?.fatLast2Y;
case 'ult_ord':
return tools.getstrDate(element.productInfo?.dataUltimoOrdine);
case 'ult_ord':
return tools.getstrDate(element.productInfo?.dataUltimoOrdine);
case 'quantity':
if (tools.isUtente())
return tools.getDescrQuantitàByQuantity(element.arrvariazioni?.[0]?.quantita);
else
return element.arrvariazioni?.[0]?.quantita;
case 'quantity':
if (tools.isUtente()) return tools.getDescrQuantitàByQuantity(element.arrvariazioni?.[0]?.quantita);
else return element.arrvariazioni?.[0]?.quantita;
default:
return null;
default:
return null;
}
}
} catch (e) {
console.error('Errore getFieldValue:', e, element, field);
@@ -273,13 +380,10 @@ export default defineComponent({
}
function getFieldClass(element: any, field: any): string {
if (!element)
return ''
if (!element) return '';
switch (field.field) {
case 'trafiletto':
return element.productInfo?.descr_trafiletto_catalogo?.length > 100
? 'text-green'
: 'text-red';
return element.productInfo?.descr_trafiletto_catalogo?.length > 100 ? 'text-green' : 'text-red';
case 'stato':
if (products.isProssimaUscita(element.productInfo)) {
@@ -332,8 +436,7 @@ export default defineComponent({
}
function getFieldStyle(element: any, field: any): Record<string, string> {
if (!element)
return {}
if (!element) return {};
switch (field.field) {
case 'prezzo':
@@ -344,11 +447,11 @@ export default defineComponent({
cursor: 'pointer',
textAlign: 'center',
color: 'white',
}
};
case 'image':
return {
width: '50px',
height: '50px'
height: '50px',
};
case 'pagine':
@@ -359,12 +462,12 @@ export default defineComponent({
case 'fatLast2Y':
case 'quantity':
return {
textAlign: 'right'
textAlign: 'right',
};
case 'trafiletto':
return {
textAlign: 'center'
textAlign: 'center',
};
default:
@@ -374,9 +477,8 @@ export default defineComponent({
let cookieValue: [] | null = null;
let keyvalue = 'selColCat_2'
if (tools.isUtente())
keyvalue += '_utente'
let keyvalue = addstr.value + 'selColCat_2';
if (tools.isUtente()) keyvalue += '_utente';
try {
cookieValue = tools.getCookie(keyvalue);
// Se il cookie esiste e contiene una stringa JSON valida
@@ -386,100 +488,139 @@ export default defineComponent({
cookieValue = []; // In caso di errore, inizializza come array vuoto
}
const selectedColumns_Editori = ref(cookieValue.length > 0 ? cookieValue : ["pos", "drag", "validato", "image", "name", "authors", "isbn", "catprods", "stato", "date_pub", "pagine", "trafiletto", "fatLast1Y", "quantity", "actions"]);
const selectedColumns_Utenti = ref(cookieValue.length > 0 ? cookieValue : ["pos", "image", "name", "authors", "isbn", "catprods", "stato", "date_pub", "pagine", "trafiletto", "quantity"]);
const selectedColumns_Editori = ref(
cookieValue.length > 0
? cookieValue
: [
'pos',
'drag',
'validato',
'image',
'name',
'authors',
'isbn',
'catprods',
'stato',
'date_pub',
'pagine',
'trafiletto',
'fatLast1Y',
'quantity',
'actions',
]
);
const selectedColumns_Utenti = ref(
cookieValue.length > 0
? cookieValue
: [
'pos',
'image',
'name',
'authors',
'isbn',
'catprods',
'stato',
'date_pub',
'pagine',
'trafiletto',
'quantity',
]
);
const selectedColumns_Catalogs = ref(
cookieValue.length > 0 ? cookieValue : ['pos', 'drag', 'image', 'title', 'pdf_generato', 'actions']
);
const selectedColumns = computed({
get: () => tools.isUtente() ? selectedColumns_Utenti.value : selectedColumns_Editori.value,
set: (value) => {
if (tools.isUtente()) {
selectedColumns_Utenti.value = value;
} else {
selectedColumns_Editori.value = value;
}
}
});
const selectedColumns = ref([]);
// 3. Funzione per verificare se una colonna è visibile (isColumnVisible)
const isColumnVisible = (column, real?: boolean) => {
if (column === 'actions' && !real) {
return false
return false;
}
if (internalProducts.value?.length > 1000) {
if (column === 'image') {
return false
return false;
}
}
const ok = allColumns.some((col) => col.name === column) && (!props.optcatalogo.showListaArgomenti || (props.optcatalogo.showListaArgomenti && !column.edit))
const ok =
allColumns.value.some((col) => col.name === column) &&
(!props.optcatalogo.showListaArgomenti || (props.optcatalogo.showListaArgomenti && !column.edit));
return selectedColumns.value.includes(column) && ok;
}
};
const getColumnLabelByName = (name: string): string => {
const column = allColumns.find((col) => col.name === name);
const column = allColumns.value.find((col) => col.name === name);
return column ? column.label : '';
}
};
// Funzione per eliminare un prodotto
const removeProduct = (product) => {
internalProducts.value = internalProducts.value.filter((p: any) => p._id !== product._id);
emit("update:lista_prodotti", internalProducts.value); // Notifica il parent del cambiamento
}
emit('update:lista_prodotti', internalProducts.value); // Notifica il parent del cambiamento
};
// 8. Salvataggio delle colonne selezionate in un cookie
const saveSelectedColumns = () => {
tools.setCookie("selColCat_2", JSON.stringify(selectedColumns.value));
tools.setCookie(addstr.value + 'selColCat_2', JSON.stringify(selectedColumns.value));
};
// 9. Watcher per salvare automaticamente le preferenze quando cambiano
watch(() => selectedColumns.value, () => {
saveSelectedColumns();
});
watch(
() => selectedColumns.value,
() => {
saveSelectedColumns();
}
);
watch(() => sortAttribute.value, (newVal) => {
tools.setCookie("sortAttr", newVal);
});
watch(() => sortDirection.value, (newVal) => {
tools.setCookie("sortDir", newVal);
});
watch(
() => sortAttribute.value,
(newVal) => {
tools.setCookie(addstr.value + 'sortAttr', newVal);
}
);
watch(
() => sortDirection.value,
(newVal) => {
tools.setCookie(addstr.value + 'sortDir', newVal);
}
);
// Funzione chiamata alla fine del drag-and-drop
const onDragEnd = () => {
// console.log("Nuovo ordine:", internalProducts.value);
emit("update:lista_prodotti", internalProducts.value); // Notifica il parent del cambiamento
}
emit('update:lista_prodotti', internalProducts.value); // Notifica il parent del cambiamento
};
function formatAuthors(authors: IAuthor[] | undefined | null): string {
if (!authors || !Array.isArray(authors)) {
return ""; // Restituisci una stringa vuota se authors non è un array valido
return ''; // Restituisci una stringa vuota se authors non è un array valido
}
// Estrai il nome e il cognome di ogni autore e uniscili con ', '
return authors
.map((author) => `${author.name ?? ""} ${author.surname ?? ""}`.trim())
.map((author) => `${author.name ?? ''} ${author.surname ?? ''}`.trim())
.filter((name) => name.length > 0) // Filtra eventuali nomi vuoti
.join(", ");
.join(', ');
}
function showProduct(element: any) {
selProd.value = element
selProd.value = element;
showProd.value = true
showProd.value = true;
}
function modifyProduct(element: any) {
if (element) {
selProd.value = element
selProd.value = element;
cmd.value = shared_consts.SCHEDA_PRODOTTO.CMD_MODIFICA
modifOn.value = true
cmd.value = shared_consts.SCHEDA_PRODOTTO.CMD_MODIFICA;
modifOn.value = true;
}
}
function updateProduct(element: any) {
selProd.value = element
selProd.value = element;
// Aggiorna l'elemento nella lista interna
internalProducts.value = internalProducts.value.map((prod: any) => {
@@ -489,17 +630,16 @@ export default defineComponent({
return prod;
});
emit("update:lista_prodotti", internalProducts.value); // Notifica il parent del cambiamento
emit('update:lista_prodotti', internalProducts.value); // Notifica il parent del cambiamento
}
async function updateproductmodif(element: any) {
console.log('PRODUCT TABLE: updateproductmodif')
console.log('PRODUCT TABLE: updateproductmodif');
try {
if (element?._id) {
selProd.value = await products.getProductById(element?._id)
selProd.value = await products.getProductById(element?._id);
} else {
selProd.value = await products.getProductById(selProd.value?._id)
selProd.value = await products.getProductById(selProd.value?._id);
}
// update record inside internalProducts
@@ -509,36 +649,34 @@ export default defineComponent({
}
return prod;
});
} catch (e) {
console.error('err', e)
console.error('err', e);
}
}
async function refreshFieldFromGM(field: string) {
if (selProd.value) {
loading.value = true
updatefromgm.value = true
field_updated_fromGM.value = ''
field_updated_fromGM.value = await globalStore.getGM_FieldOf_T_Web_Articoli(selProd.value.productInfo.sku!, field, shared_consts.CmdQueryMs.GET)
loading.value = false
loading.value = true;
updatefromgm.value = true;
field_updated_fromGM.value = '';
field_updated_fromGM.value = await globalStore.getGM_FieldOf_T_Web_Articoli(
selProd.value.productInfo.sku!,
field,
shared_consts.CmdQueryMs.GET
);
loading.value = false;
}
}
const sortTable = (sortAttributeToSort: string) => {
if (!props.optcatalogo.showListaArgomenti)
return false
if (!props.optcatalogo.showListaArgomenti) return false;
if (sortAttributeToSort) {
if (sortAttribute.value === sortAttributeToSort) {
sortDirection.value = -sortDirection.value
sortDirection.value = -sortDirection.value;
} else {
sortAttribute.value = sortAttributeToSort
sortDirection.value = 1
sortAttribute.value = sortAttributeToSort;
sortDirection.value = 1;
}
internalProducts.value = internalProducts.value.sort((a: any, b: any) => {
const aVal = getFieldValue(a, { field: sortAttributeToSort });
@@ -546,7 +684,12 @@ export default defineComponent({
if (aVal instanceof Date && bVal instanceof Date) {
return sortDirection.value === 1 ? aVal.getTime() - bVal.getTime() : bVal.getTime() - aVal.getTime();
}
if (typeof aVal === 'string' && typeof bVal === 'string' && aVal.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/) && bVal.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/)) {
if (
typeof aVal === 'string' &&
typeof bVal === 'string' &&
aVal.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/) &&
bVal.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/)
) {
const aDate = new Date(aVal.split('/').reverse().join('-'));
const bDate = new Date(bVal.split('/').reverse().join('-'));
return sortDirection.value === 1 ? aDate.getTime() - bDate.getTime() : bDate.getTime() - aDate.getTime();
@@ -557,19 +700,21 @@ export default defineComponent({
if (typeof aVal === 'string' && typeof bVal === 'string') {
return sortDirection.value === 1 ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal);
}
return sortDirection.value === 1 ? String(aVal).localeCompare(String(bVal)) : String(bVal).localeCompare(String(aVal));
})
return sortDirection.value === 1
? String(aVal).localeCompare(String(bVal))
: String(bVal).localeCompare(String(aVal));
});
}
}
};
function rigenera() {
emit('rigenera')
emit('rigenera');
}
function getFieldClick(element: any, field: any): (() => void) | null {
switch (field.field) {
case 'validato':
return () => modifyProduct(element)
return () => modifyProduct(element);
case 'image':
return () => showProduct(element);
@@ -593,16 +738,19 @@ export default defineComponent({
function exportToCSV() {
const csvContent = [
selectedColumns.value
.filter((col) => !allColumns.find((c) => c.name === col)?.noexp)
.filter((col) => !allColumns.value.find((c) => c.name === col)?.noexp)
.map((col) => getColumnLabelByName(col))
.join('|'),
...internalProducts.value.map((product: any) => {
return selectedColumns.value
.filter((col) => !allColumns.find((c) => c.name === col)?.noexp)
.filter((col) => !allColumns.value.find((c) => c.name === col)?.noexp)
.map((col: string) => {
const field = { field: col };
return field.field === 'pos' ? internalProducts.value.indexOf(product) + 1 : getFieldValue(product, field);
}).join('|');
const field = { field: col };
return field.field === 'pos'
? internalProducts.value.indexOf(product) + 1
: getFieldValue(product, field);
})
.join('|');
}),
].join('\r\n');
@@ -618,14 +766,24 @@ export default defineComponent({
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
function isSortable(field: string) : boolean {
return allColumns && !allColumns.find((col) => col.name === field)?.notsortable;
function isSortable(field: string): boolean {
return allColumns && !allColumns.value.find((col) => col.name === field)?.notsortable;
}
onMounted(mounted)
function getImageByElement(element) {
let image = '';
if (props.table === shared_consts.TABLES_CATALOG) {
image = element.foto_collana?.imagefile;
} else {
image = element.productInfo?.imagefile;
}
return image;
}
onMounted(mounted);
return {
allColumns,
@@ -666,6 +824,7 @@ export default defineComponent({
handleUpdate,
exportToCSV,
isSortable,
}
}
})
getImageByElement,
};
},
});

View File

@@ -111,8 +111,8 @@
<td v-else-if="field.name === 'image' && isColumnVisible('image')">
<q-img
:src="
element.productInfo?.imagefile
? tools.getFullFileNameByImageFile('productInfos', element.productInfo?.imagefile)
getImageByElement(element)
? tools.getFullFileNameByImageFile(table, getImageByElement(element))
: element.productInfo?.image_link
"
style="width: 50px; height: 50px"
@@ -174,6 +174,7 @@
:idprodtoshow="selProd?._id"
nameLinkTemplate="SEARCH_Prima"
@updateproductmodif="updateproductmodif"
table="products"
>
</CSearchProduct>
</CMyDialog>

View File

View File

@@ -0,0 +1,57 @@
import type { PropType} from 'vue';
import { defineComponent, ref, watch } from 'vue'
import { RaccoltaCataloghi } from '@src/views/ecommerce/raccoltacataloghi'
import type { IOptCatalogo } from '@src/model'
export default defineComponent({
name: 'CRaccolta',
components: { RaccoltaCataloghi },
emits: ['update:modelValue', 'updateCatalogo'],
props: {
// add options IOptCatalogo
modelValue: {
type: Object as PropType<IOptCatalogo>,
required: true,
},
idPage: {
type: String,
required: false,
default: '',
},
},
setup(props, { emit }) {
// Crea una copia locale reattiva di modelValue
const localCatalogo = ref<IOptCatalogo>({ ...props.modelValue });
// Watcher per sincronizzare le modifiche di modelValue
watch(() => props.modelValue, (newVal) => {
localCatalogo.value = { ...newVal };
// updateCatalogoPadre()
}, { deep: true });
function updateCatalogoPadre() {
emit('update:modelValue', localCatalogo.value);
emit('updateCatalogo', localCatalogo.value);
}
// Metodo per aggiornare il valore del catalogo
const updateCatalogo = (updatedCatalogo: IOptCatalogo) => {
localCatalogo.value = updatedCatalogo; // Aggiorna la copia locale
updateCatalogoPadre()
};
function updateCatalogoEmit(updatedCatalogo: IOptCatalogo) {
console.log('updateCatalogoEmit')
localCatalogo.value = updatedCatalogo; // Aggiorna la copia locale
updateCatalogoPadre()
}
return {
localCatalogo,
updateCatalogoEmit,
};
}
})

View File

@@ -0,0 +1,14 @@
<template>
<div>
<RaccoltaCataloghi v-model="localCatalogo" @updateCatalogo="updateCatalogoEmit()" :idPage="idPage">
</RaccoltaCataloghi>
</div>
</template>
<script lang="ts" src="./CRaccolta.ts">
</script>
<style lang="scss" scoped>
@import './CRaccolta.scss';
</style>

View File

@@ -0,0 +1 @@
export {default as CRaccolta} from './CRaccolta.vue'

View File

@@ -0,0 +1,231 @@
import {
computed,
provide, defineComponent, onBeforeMount, onBeforeUnmount, onMounted, ref, toRef, toRefs, watch,
} from 'vue'
import { tools } from '@tools'
import { CMyFieldDb } from '@src/components/CMyFieldDb'
import { costanti } from '@costanti'
import { useGlobalStore } from '@store/globalStore'
import { useUserStore } from '@store/UserStore'
import { CTitlePage } from '@src/components/CTitlePage'
import { CGridTableRec } from '@src/components/CGridTableRec'
import type { IColGridTable, ISearchList } from 'model';
import { IMyBacheca, IMySkill, ISkill } from 'model'
import { shared_consts } from '@src/common/shared_vuejs'
import { useI18n } from 'vue-i18n'
import { toolsext } from '@store/Modules/toolsext'
import { fieldsTable } from '@store/Modules/fieldsTable'
import { useQuasar } from 'quasar'
export default defineComponent({
name: 'CRaccoltaCataloghi',
emits: ['clickButtBar'],
props: {
ind: {
type: Number,
required: false,
default: -1,
},
prop_search: {
type: Boolean,
required: false,
default: true,
},
finder: {
type: Boolean,
required: false,
default: true,
},
heightcarousel: {
type: String,
required: false,
default: '',
},
heightcard: {
type: String,
required: false,
default: '400px',
},
widthcard: {
type: String,
required: false,
default: '300px',
},
heightimg: {
type: String,
required: false,
default: '150px',
},
widthimg: {
type: String,
required: false,
default: '300px',
},
},
components: {
CMyFieldDb, CGridTableRec, CTitlePage,
},
setup(props, { attrs, slots, emit }) {
const { t } = useI18n()
const $q = useQuasar()
const globalStore = useGlobalStore()
const userStore = useUserStore()
const table = ref('raccoltacataloghis')
const arrfilterand: any = ref([])
const filtercustom: any = ref([])
const search = ref('')
const myrecfiltertoggle = ref(tools.FILTER_ALL)
const prop_colkey = ref('')
const col_title = ref('')
const col_footer = ref('')
const col_tabfooter = ref('')
const strextra = ref('')
const myoptions = ref(<any>[])
const col = ref(<IColGridTable[]>[])
const myCatRef = ref(<any>null)
const getRaccoltaCataloghiByMyPage = computed((): IRaccoltaCatalogo | undefined => {
return catalogStore.raccoltacataloghis?.find((raccolta: IRaccoltaCatalogo) => raccolta.idPageAssigned === props.idPage);
});
function updatefilter(value: any) {
//
}
const pagina_collegata = computed(() => {
let linkpage = ''
const idpag = myrec.value.idPageAssigned
if (idpag) {
const mypage = globalStore.getPageById(idpag)
if (mypage)
linkpage = mypage.path!
}
return linkpage
})
watch(() => myrecfiltertoggle.value, (value: any, oldval: any) => {
updatefilter(value)
},
)
const mypagination = computed(() => {
return { sortBy: 'title', descending: false, page: 1, rowsNumber: 0, rowsPerPage: 10 }
})
function naviga(path: string) {
$router.push(path)
}
const showType = computed(() => {
return costanti.SHOW_MYCARD
})
const hint = computed(() => {
return 'digita la Raccolta da cercare'
})
const visuType = computed(() => {
return false // $q.screen.gt.xs
})
const noMsgRecord = computed(() => {
return 'Nessun dato trovato con i filtri selezionati'
})
function mounted() {
const obj = tools.getParamsByTable(table.value)
prop_colkey.value = obj.prop_colkey
col_title.value = obj.col_title
col_footer.value = obj.col_footer
col_tabfooter.value = obj.col_tabfooter
filtercustom.value = []
col.value = fieldsTable.getArrColsByTable(table.value)
}
function salvaListaRaccoltaCataloghi(ricarica: boolean) {
// Estrai solo gli ID dei prodotti filtrati
const myarr = [...getRaccoltaCataloghiByMyPage.value.lista_cataloghi];
const catalogIds = myarr.map((catalog) => catalog._id);
let mydata = {
lista_cataloghi: catalogIds,
};
// Salva gli ID dei prodotti nel catalogo
tools.saveFieldToServer($q, 'raccoltacataloghis', getRaccoltaCataloghiByMyPage.value._id, mydata, true, true);
}
function mySortFieldsAvailable() {
if (table.value === toolsext.TABUSER) {
return userStore.getSortFieldsAvailable()
}
return []
}
function doSearch() {
//
}
function clickButtBar(item: any) {
if (myCatRef.value) {
myCatRef.value.clickButtBar(item)
}
// emit('clickButtBar', item)
}
onMounted(mounted)
return {
t,
tools,
costanti,
arrfilterand,
filtercustom,
search,
doSearch,
myrecfiltertoggle,
prop_colkey,
col_title,
col_footer,
col_tabfooter,
col,
toolsext,
mypagination,
noMsgRecord,
showType,
visuType,
hint,
myoptions,
mySortFieldsAvailable,
clickButtBar,
myCatRef,
table,
pagina_collegata,
naviga,
}
},
})

View File

@@ -0,0 +1,47 @@
<template>
<div class="q-ma-xs">
<CGridTableRec
v-if="col && col.length > 0"
ref="myCatRef"
:prop_mytable="table"
:options="tools.optionsTable(table)"
:prop_mytitlenew="tools.getTitleAnnuncio(table)"
prop_mytitle="Raccolte"
:prop_mycolumns="col"
:prop_colkey="prop_colkey"
:col_title="col_title"
:col_footer="col_footer"
:col_tabfooter="col_tabfooter"
:vertical="costanti.VISUTABLE_LISTA"
:prop_pagination="mypagination"
:showType="showType"
:hint="hint"
:nodataLabel="noMsgRecord"
:prop_search="prop_search"
:finder="finder"
labelElemFind="trovati"
:choose_visutype="visuType"
:butt_modif_new="!tools.isUtente()"
:noresultLabel="t('grid.nosearchfound')"
:arrfilters="arrfilterand"
:filtercustom="filtercustom"
:prop_searchList="tools.getsearchList_RaccoltaCataloghi()"
:defaultnewrec="tools.getdefaultnewrec(table)"
labelBtnAddRow="NONE"
:prop_SortFieldsAvailable="mySortFieldsAvailable()"
labelBtnAddExtra="Aggiungi Raccolta"
:extraparams="tools.extraparams(table, { myrecfiltertoggle })"
:prop_showMap="false"
:heightcarousel="heightcarousel"
@clickButtBar="clickButtBar"
:enableExport="true"
:opt="{ rowclass: true, widthcard, heightcard, widthimg, heightimg }"
>
</CGridTableRec>
</div>
</template>
<script lang="ts" src="./CRaccoltaCataloghi.ts"></script>
<style lang="scss" scoped>
@import './CRaccoltaCataloghi.scss';
</style>

View File

@@ -0,0 +1 @@
export { default as CRaccoltaCataloghi } from './CRaccoltaCataloghi.vue'

View File

@@ -1,28 +1,25 @@
import type { PropType } from 'vue';
import { defineComponent, onMounted, ref, watch, computed } from 'vue'
import { tools } from '@tools'
import { useUserStore } from '@store/UserStore'
import { useRouter } from 'vue-router'
import { useGlobalStore } from '@store/globalStore'
import { useProducts } from '@store/Products'
import { useI18n } from 'vue-i18n'
import { toolsext } from '@store/Modules/toolsext'
import { useQuasar } from 'quasar'
import { costanti } from '@costanti'
import { defineComponent, onMounted, ref, watch, computed } from 'vue';
import { tools } from '@tools';
import { useUserStore } from '@store/UserStore';
import { useCatalogStore } from '@store/CatalogStore'
import { useRouter } from 'vue-router';
import { useGlobalStore } from '@store/globalStore';
import { useProducts } from '@store/Products';
import { useI18n } from 'vue-i18n';
import { toolsext } from '@store/Modules/toolsext';
import { useQuasar } from 'quasar';
import { costanti } from '@costanti';
import { shared_consts } from '@src/common/shared_vuejs'
import { CProductCard } from '@src/components/CProductCard'
import { shared_consts } from '@src/common/shared_vuejs';
import { CProductCard } from '@src/components/CProductCard';
import { CMySelect } from '@src/components/CMySelect'
import { CContainerCatalogoCard } from '@src/components/CContainerCatalogoCard'
import { CSelectUserActive } from '@src/components/CSelectUserActive'
import type {
IOptCatalogo,
IProduct, ISearchList
} from 'model';
import { CMySelect } from '@src/components/CMySelect';
import { CContainerCatalogoCard } from '@src/components/CContainerCatalogoCard';
import { CSelectUserActive } from '@src/components/CSelectUserActive';
import type { IOptCatalogo, IProduct, ISearchList } from 'model';
import { fieldsTable } from '@store/Modules/fieldsTable'
import { fieldsTable } from '@store/Modules/fieldsTable';
import Products from 'app/src/rootgen/admin/products/products.vue';
export default defineComponent({
@@ -35,6 +32,10 @@ export default defineComponent({
required: false,
default: null,
},
table: {
type: String,
required: true,
},
idprodtoshow: {
type: String,
required: false,
@@ -57,124 +58,155 @@ export default defineComponent({
},
},
setup(props, { emit }) {
const userStore = useUserStore()
const globalStore = useGlobalStore()
const productStore = useProducts()
const router = useRouter()
const $q = useQuasar()
const { t } = useI18n()
const userStore = useUserStore();
const globalStore = useGlobalStore();
const productStore = useProducts();
const catalogStore = useCatalogStore();
const router = useRouter();
const $q = useQuasar();
const { t } = useI18n();
const search = ref('')
const focus = ref(false)
const search = ref('');
const focus = ref(false);
const loadpage = ref(false)
const refreshpage = ref(false)
const show_hide = ref(false)
const loadpage = ref(false);
const refreshpage = ref(false);
const show_hide = ref(false);
const mycolumns = ref([])
const mycolumns = ref([]);
const idPage = ref('')
const selauthor = ref('')
const where = ref('')
const searchList = ref(<ISearchList[]>[])
const idPage = ref('');
const selauthor = ref('');
const searchList = ref(<ISearchList[]>[]);
const optcatalogo = ref<IOptCatalogo | null>(null);
const myproduct = ref(<IProduct>{})
const myproduct = ref(<IProduct>{});
const addstr = ref('')
const labelcombo = computed(() => (item: any) => {
let lab = item.label
if (item.showcount)
lab += ' (' + valoriopt.value(item, false, false).length + ')'
return lab
})
let lab = item.label;
if (item.showcount) lab += ' (' + valoriopt.value(item, false, false).length + ')';
return lab;
});
const listaRicerca = computed(() => {
const mylist = searchList.value.find((rec: any) => rec.table === 'products' && rec.key === 'titolo')
return mylist
})
let key = ''
if (props.table === shared_consts.TABLES_CATALOG) {
key = 'title'
} else {
key = 'titolo'
}
const mylist = searchList.value.find((rec: any) => rec.table === props.table && rec.key === key);
return mylist;
});
const searchText = computed(() => {
const lista = listaRicerca.value
return lista && lista.value && tools.existProp(lista.value, 'name') ? lista.value.name : ''
})
const lista = listaRicerca.value;
let key = ''
if (props.table === shared_consts.TABLES_CATALOG) {
key = 'title'
} else {
key = 'name'
}
return lista && lista.value && tools.existProp(lista.value, key) ? lista.value[key] : '';
});
const valoriopt = computed(() => (item: any, addall: boolean, addnone: boolean = false) => {
// console.log('valoriopt', item.table)
return globalStore.getTableJoinByName(item.table, addall, addnone, item.filter)
})
return globalStore.getTableJoinByName(item.table, addall, addnone, item.filter);
});
watch(() => searchText.value, (newval, oldval) => {
console.log('searchText=', searchText.value)
const id = getSearchId()
loadProduct(id)
})
watch(() => myproduct.value, (newval, oldval) => {
console.log('myproduct', myproduct.value)
// loadProduct(myproduct.value._id)
updateproductmodif(myproduct.value)
})
watch(
() => searchText.value,
(newval, oldval) => {
console.log('searchText=', searchText.value);
const id = getSearchId();
loadProduct(id);
}
);
watch(
() => myproduct.value,
(newval, oldval) => {
console.log('myproduct', myproduct.value);
// loadProduct(myproduct.value._id)
updateproductmodif(myproduct.value);
}
);
async function loadProduct(id: string) {
// Carica il prodotto
console.log('loadProduct', id)
console.log('loadProduct', id);
if (id) {
myproduct.value = await productStore.loadProductById(id)
} else {
myproduct.value = null
if (props.table === 'products') {
if (id) {
myproduct.value = await productStore.loadProductById(id);
} else {
myproduct.value = null;
}
} else if (props.table === 'catalogs') {
if (id) {
myproduct.value = await catalogStore.getCatalogById(id);
} else {
myproduct.value = null;
}
}
saveSearch();
saveSearch()
console.log('myproduct.value', myproduct.value)
console.log('myproduct.value', myproduct.value);
}
watch(
() => where.value,
(newval, oldval) => {
tools.setCookie(addstr.value + 'WHE', newval);
}
);
function saveSearch() {
if (!props.idprodtoshow && !props.empty) {
if (myproduct.value) {
tools.setCookie(tools.COOK_LAST_PROD_SEARCH, myproduct.value._id.toString())
tools.setCookie(addstr.value + tools.COOK_LAST_PROD_SEARCH, myproduct.value._id.toString());
} else {
tools.setCookie(tools.COOK_LAST_PROD_SEARCH, '')
tools.setCookie(addstr.value + tools.COOK_LAST_PROD_SEARCH, '');
}
}
if (!myproduct.value) {
tools.setCookie(tools.COOK_LAST_PROD_SEARCH, '')
tools.setCookie(addstr.value + tools.COOK_LAST_PROD_SEARCH, '');
}
}
function resetSearch() {
const mialista = listaRicerca.value
const mialista = listaRicerca.value;
if (mialista && mialista.value && tools.existProp(mialista.value, 'name')) {
mialista.value = null
mialista.value = null;
}
search.value = ''
search.value = '';
}
function getSearchId(): string {
const lista = listaRicerca.value
return lista && lista.value && lista.value._id ? lista.value._id : ''
const lista = listaRicerca.value;
return lista && lista.value && lista.value._id ? lista.value._id : '';
}
function populateDataWithlinkIdTemplate() {
// console.log('populateDataWithlinkIdTemplate')
if (optcatalogo.value) {
for (const recscheda of optcatalogo.value.arrSchede!) {
if (recscheda.scheda?.linkIdTemplate) {
// ricopia da Template:
const myscheda = globalStore.sovrascriviSchedaFromTemplate(recscheda.scheda?.linkIdTemplate, recscheda)
const myscheda = globalStore.sovrascriviSchedaFromTemplate(recscheda.scheda?.linkIdTemplate, recscheda);
if (myscheda) {
recscheda.scheda = { ...myscheda }
recscheda.scheda = { ...myscheda };
}
}
}
}
@@ -182,139 +214,164 @@ export default defineComponent({
// console.log(' FINE - populateDataWithlinkIdTemplate')
}
function isProductLibro() {
return props.table === 'products';
}
async function mounted() {
// console.log('mounted Catalogo')
addstr.value = tools.addstrCookie(props.table)
where.value = tools.getCookie(addstr.value + 'WHE', shared_consts.WHERE_INSERT.ONTOP);
if (props.modelValue) {
optcatalogo.value = props.modelValue
optcatalogo.value = props.modelValue;
} else {
optcatalogo.value = globalStore.createCatalogoVuoto()
productStore.addNewScheda(optcatalogo.value)
optcatalogo.value = globalStore.createCatalogoVuoto();
productStore.addNewScheda(optcatalogo.value);
if (props.nameLinkTemplate) {
const linkIdTemplate = globalStore.getLinkIdTemplateByName(props.nameLinkTemplate)
if (linkIdTemplate)
optcatalogo.value.arrSchede[0].scheda.linkIdTemplate = linkIdTemplate
const linkIdTemplate = globalStore.getLinkIdTemplateByName(props.nameLinkTemplate);
if (linkIdTemplate) optcatalogo.value.arrSchede[0].scheda.linkIdTemplate = linkIdTemplate;
} else {
optcatalogo.value.arrSchede[0].scheda.name = 'SEARCH_NEW'
optcatalogo.value.arrSchede[0].scheda.name = 'SEARCH_NEW';
}
}
const id = props.idprodtoshow || (!props.empty ? tools.getCookie(tools.COOK_LAST_PROD_SEARCH, '') : '')
let id = null;
if (props.table === 'products') {
id = props.idprodtoshow || (!props.empty ? tools.getCookie(addstr.value + tools.COOK_LAST_PROD_SEARCH, '') : '');
}
if (props.nameLinkTemplate) {
populateDataWithlinkIdTemplate()
populateDataWithlinkIdTemplate();
}
if (props.visu === shared_consts.VISU_SEARCHPROD_MODE.INSERT) {
focus.value = true
focus.value = true;
}
loadpage.value = false
loadpage.value = false;
if (id) {
await loadProduct(id)
await loadProduct(id);
}
mycolumns.value = fieldsTable.getArrColsByTable(props.table);
mycolumns.value = fieldsTable.getArrColsByTable('products')
if (isProductLibro()) {
searchList.value = [
{
visible: true,
label: 'Cerca un Titolo o un Autore',
table: 'products',
key: 'titolo',
type: costanti.FieldType.select_by_server,
value: myproduct.value,
collabel: collabel,
arrvalue: [],
useinput: true,
filter: null,
tablesel: 'products',
dense: false,
},
];
} else {
searchList.value = [
{
visible: true,
label: 'Cerca un Catalogo',
table: 'catalogs',
key: 'title',
type: costanti.FieldType.select_by_server,
value: myproduct.value,
collabel: 'title',
arrvalue: [],
useinput: true,
filter: null,
tablesel: 'catalogs',
dense: false,
},
];
searchList.value = [
{
visible: true,
label: 'Cerca un Titolo o un Autore',
table: 'products',
key: 'titolo',
type: costanti.FieldType.select_by_server,
value: myproduct.value,
collabel: collabel,
arrvalue: [],
useinput: true,
filter: null,
tablesel: 'products',
dense: false,
},
]
}
// Inizializza
loadpage.value = true
loadpage.value = true;
}
function naviga(path: string) {
router.push(path)
router.push(path);
}
function collabel(rec: any) {
let label = ''
if (rec && rec.productInfo) {
if (productStore.isNovitaById(rec.productInfo.date_pub))
label += `🌟 `
let label = '';
if (rec && rec.productInfo && props.table === 'products') {
if (productStore.isNovitaById(rec.productInfo.date_pub)) label += `🌟 `;
label += `${rec.productInfo.name}`;
if (Array.isArray(rec.productInfo.authors)) {
const authors = rec.productInfo.authors.map((a: any) => `${a.name} ${a.surname}`).join(', ');
label += ` - (${authors})`;
} else {
label += rec.productInfo.authors ? ` - (${rec.productInfo.authors.name} ${rec.productInfo.authors.surname}) ` : '';
label += rec.productInfo.authors
? ` - (${rec.productInfo.authors.name} ${rec.productInfo.authors.surname}) `
: '';
}
if (rec.productInfo.idStatoProdotto) {
if (!productStore.isPubblicatoById(rec.productInfo.idStatoProdotto))
label += ' (' + productStore.getDescrStatiProdottoByIdStatoProdotto(rec.productInfo.idStatoProdotto || '') + ')'
label +=
' (' + productStore.getDescrStatiProdottoByIdStatoProdotto(rec.productInfo.idStatoProdotto || '') + ')';
}
if (productStore.isEsaurito(rec)) {
label += ' (Attualmente non disponibile)'
label += ' (Attualmente non disponibile)';
}
// console.log('Computed label:', label)
} else {
if (rec && rec.name) label = rec.name;
else label = '';
}
return label
return label;
}
function insertProd() {
// console.log('insertProd')
emit('insert', myproduct.value)
console.log('insertProd', myproduct.value)
emit('insert', myproduct.value, where.value);
}
function clickClose() {
searchList.value[0].value = ''
myproduct.value = null
emit('close')
searchList.value[0].value = '';
myproduct.value = null;
emit('close');
}
function updateproductmodif(element: IProduct) {
console.log('CSEARCHPRODUCT: updateproductmodif')
emit('updateproductmodif', element)
console.log('CSEARCHPRODUCT: updateproductmodif');
emit('updateproductmodif', element);
}
async function searchOnGM(mystr: string) {
// refreshSingleBookFromGM({usaDBGMLocale: false})
const options = {
}
const ris = await globalStore.updateAllBookFromGM_T_Web_Articoli({ sku: '', isbn: mystr, ...options })
const options = {};
const ris = await globalStore.updateAllBookFromGM_T_Web_Articoli({ sku: '', isbn: mystr, ...options });
if (ris) {
const id = getSearchId()
loadProduct(id)
updateproductmodif(myproduct.value)
const id = getSearchId();
loadProduct(id);
updateproductmodif(myproduct.value);
// await updateproduct(false)
if (ris.error) {
tools.showNegativeNotif($q, ris.error)
tools.showNegativeNotif($q, ris.error);
} else {
tools.showPositiveNotif($q, t('dbgm.updateLocalDb_OK'))
tools.showPositiveNotif($q, t('dbgm.updateLocalDb_OK'));
}
// updatefromgm.value = false
}
}
onMounted(mounted)
onMounted(mounted);
return {
userStore,
@@ -345,7 +402,7 @@ export default defineComponent({
saveSearch,
updateproductmodif,
searchOnGM,
}
}
})
where,
};
},
});

View File

@@ -51,6 +51,25 @@
</CMySelect>
</div>
<div
v-if="visu === shared_consts.VISU_SEARCHPROD_MODE.INSERT"
class="row justify-center q-mt-md"
>
<q-select
v-model="where"
:options="[
{ label: 'Inserisci in cima', value: shared_consts.WHERE_INSERT.ONTOP },
{ label: 'Inserisci in fondo', value: shared_consts.WHERE_INSERT.ONBOTTOM },
]"
style="width: 250px"
label="Dove inserire?"
emit-value
map-options
outlined
dense
/>
</div>
<div
v-if="myproduct?._id && optcatalogo.arrSchede?.length > 0"
class="row justify-center"

View File

@@ -211,6 +211,13 @@ export default function () {
const myfield = key as keyof ICatalog
catalogStore.catalogs[idcat][myfield] = value
}
} else if (table === 'raccoltacataloghis') {
const catalogStore = useCatalogStore()
const idcat = catalogStore.raccoltacataloghis.findIndex((rec: IRaccoltaCatalogo) => rec._id === id)
if (idcat >= 0 && key) {
const myfield = key as keyof IRaccoltaCatalogo
catalogStore.raccoltacataloghis[idcat][myfield] = value
}
}
console.log('mydatatosave', mydatatosave)

View File

@@ -42,7 +42,32 @@ export interface ICatalog {
lista_prodotti?: IProduct[]
isCatalogoGenerale?: boolean
}
export interface IRaccoltaCatalogo {
_id: string
idapp: string
active?: boolean
title: string
foto_raccolta?: IImg,
idPageAssigned?: string
idPageAssigned_stampa?: string
nomefile_da_generare?: string
pdf_generato?: string
data_generato?: Date
pdf_online?: string
data_online?: Date
pdf_generato_stampa?: string
data_generato_stampa?: Date
pdf_online_stampa?: string
data_online_stampa?: Date
lista_cataloghi?: ICatalog[]
}
export interface ICatalogState {
catalogs?: ICatalog[]
raccoltacataloghis?: IRaccoltaCatalogo[]
}

View File

@@ -2111,6 +2111,12 @@ const msg_it = {
status: 'Stato',
},
racccat: {
title: 'Titolo',
numcataloghi: 'Numero di Cataloghi',
foto_raccolta: 'Foto Raccolta',
}
},
};

View File

@@ -28,7 +28,12 @@ export const useCatalogStore = defineStore('CatalogStore', {
catalogs: [{ _id: '', idapp: '', title: '' }]
}),
getters: {},
getters: {
getCatalogById: (state) => (id: string) => {
return state.catalogs.find((cat: ICatalog) => cat._id === id);
},
},
actions: {

View File

@@ -124,6 +124,58 @@ export const colmailinglist = [
AddCol(DeleteRec),
]
export const colTableRaccoltaCataloghi = [
AddCol({ name: 'title', label_trans: 'racccat.title' }),
AddCol({
name: 'foto_raccolta',
label_trans: 'racccat.foto_raccolta',
fieldtype: costanti.FieldType.image,
jointable: '',
showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit,
isadvanced_field: false,
}),
AddCol({
name: 'idPageAssigned',
label_trans: 'cataloglist.idPageAssigned',
fieldtype: costanti.FieldType.select,
jointable: 'mypages_id',
}),
AddCol({
name: 'idPageAssigned_stampa',
label_trans: 'cataloglist.idPageAssigned_stampa',
fieldtype: costanti.FieldType.select,
jointable: 'mypages_id',
}),
AddCol({
name: 'nomefile_da_generare',
label_trans: 'cataloglist.nomefile_generare',
}),
/*AddCol({
name: 'pdf_generato',
label_trans: 'cataloglist.pdf_generato',
}),
AddCol({
name: 'pdf_generato_stampa',
label_trans: 'cataloglist.pdf_generato_stampa',
}),
AddCol({
name: 'pdf_online',
label_trans: 'cataloglist.pdf_online',
}),
AddCol({
name: 'pdf_online_stampa',
label_trans: 'cataloglist.pdf_online_stampa',
}),*/
AddCol(ModifRec),
AddCol(DuplicateRec),
AddCol(DeleteRec),
]
export const colTableCatalogList = [
AddCol({ name: 'active', label_trans: 'myelems.pubblica_online', fieldtype: costanti.FieldType.boolean }),
AddCol({ name: 'title', label_trans: 'gallery.title' }),
@@ -4311,11 +4363,13 @@ export const fieldsTable = {
// Tabelle che hanno il /pickup
tableRemotePickup: [
'countries',
'phones',
'cities',
'products',
'catalogs',
],
tableWithUsername: [
@@ -5213,6 +5267,13 @@ export const fieldsTable = {
colkey: '_id',
collabel: 'title',
},
{
value: 'raccoltacataloghis',
label: 'Raccolta Cataloghi',
columns: colTableRaccoltaCataloghi,
colkey: '_id',
collabel: 'title',
},
{
value: 'schedeopt',
label: 'Template Cataloghi',

File diff suppressed because it is too large Load Diff

View File

@@ -84,6 +84,7 @@ export const toolsext = {
TABNEWSLETTER: 'newstosent',
TABGALLERY: 'gallery',
TABCATALOGS: 'catalogs',
TABRACCOLTA_CATALOGHI: 'raccoltacataloghis',
TABMAILINGLIST: 'mailinglist',
TABGROUPS: 'groups',
TABMYPAGE: 'mypages',

View File

@@ -898,6 +898,7 @@ export const useProducts = defineStore('Products', {
return ris
},
async loadOrders() {
// console.log('loadOrders')

View File

@@ -432,6 +432,7 @@ export const useGlobalStore = defineStore('GlobalStore', {
else if (table === 'mypages_id') ris = state.mypage;
else if (table === toolsext.TABMYELEMS) ris = state.myelems;
else if (table === toolsext.TABCATALOGS) ris = catalogStore.catalogs!;
else if (table === toolsext.TABRACCOLTA_CATALOGHI) ris = catalogStore.raccoltacataloghis!;
else if (table === toolsext.TABCALZOOM) ris = state.calzoom;
else if (table === 'producers') ris = state.producers;
else if (table === 'storehouses') ris = state.storehouses;
@@ -1852,6 +1853,7 @@ export const useGlobalStore = defineStore('GlobalStore', {
circuitStore.listaccounts = res.data.listaccounts ? res.data.listaccounts : [];
catalogStore.catalogs = res.data.catalogs;
catalogStore.raccoltacataloghis = res.data.raccoltacataloghis;
this.settings = res.data.settings ? [...res.data.settings] : [];
this.disciplines = res.data.disciplines ? [...res.data.disciplines] : [];
@@ -2466,6 +2468,21 @@ export const useGlobalStore = defineStore('GlobalStore', {
areadistampa: tools.resetRecIAreaDiStampa(null),
};
},
createRaccoltaCataloghiVuoto(): IOptCatalogo {
return {
productTypes: [0],
excludeproductTypes: [],
idTipologie: [],
formato: [],
Categoria: [],
editore: [],
pdf: false,
dimensioni_def: {
pagina: tools.resetRecIDimensioni(null),
},
areadistampa: tools.resetRecIAreaDiStampa(null),
};
},
async prepareAddNewElem(order: any, $q: any, t: any, myelem: any, newtype: any) {
const newrec: IMyElem = {
@@ -2487,6 +2504,8 @@ export const useGlobalStore = defineStore('GlobalStore', {
newrec.catalogo = this.createCatalogoVuoto();
} else if (newrec.type === shared_consts.ELEMTYPE.CATALOGO) {
newrec.catalogo = this.createCatalogoVuoto();
} else if (newrec.type === shared_consts.ELEMTYPE.RACCOLTA) {
newrec.catalogo = this.createRaccoltaCataloghiVuoto();
}
const mynewrec = await this.addNewElem($q, t, newrec);
@@ -2528,6 +2547,15 @@ export const useGlobalStore = defineStore('GlobalStore', {
return false;
});
},
async execJoinPDF(paramquery: any) {
return Api.SendReq('/admin/join-pdf', 'POST', paramquery)
.then((res) => {
return res.data;
})
.catch((error) => {
return false;
});
},
async execOnlinePDF(paramquery: any) {
return Api.SendReq('/admin/online-pdf', 'POST', paramquery)
.then((res) => {
@@ -2824,6 +2852,11 @@ export const useGlobalStore = defineStore('GlobalStore', {
const prec_lista_prodotti = mytablerec![index].lista_prodotti;
mytablerec![index] = { ...mytablerec[index], ...resdata.rec };
mytablerec![index].lista_prodotti = prec_lista_prodotti;
} else if (datain.table === 'raccoltacataloghis') {
// salva lista_cataloghi
const prec_lista_cataloghi = mytablerec![index].lista_cataloghi;
mytablerec![index] = { ...mytablerec[index], ...resdata.rec };
mytablerec![index].lista_cataloghi = prec_lista_cataloghi;
} else {
mytablerec![index] = { ...mytablerec[index], ...resdata.rec };
console.log('Aggiorna il record mantenendo reattività');

View File

@@ -1702,15 +1702,18 @@ export default defineComponent({
}
}
function addProductToList(element: IProduct) {
function addProductToList(element: IProduct, where: string) {
// console.log('addProductToList', element)
if (element) {
// add this record to lista_prodotti
if (getCatalogoByMyPage.value && !getCatalogoByMyPage.value.lista_prodotti.some((p) => p._id === element._id)) {
if (getCatalogoByMyPage.value && !getCatalogoByMyPage.value.lista_prodotti?.some((p) => p._id === element._id)) {
// inserire il record in cima
const arr = getCatalogoByMyPage.value.lista_prodotti;
arr.unshift(element);
const arr = getCatalogoByMyPage.value.lista_prodotti || [];
if (where === shared_consts.WHERE_INSERT.ONTOP)
arr.unshift(element);
else if (where === shared_consts.WHERE_INSERT.ONBOTTOM)
arr.push(element)
updateProducts(arr);
@@ -1944,9 +1947,9 @@ export default defineComponent({
const ris = await globalStore.execOnlinePDF({ id_catalog: catalog._id, stampa: false });
if (ris) {
if (ris.catalog?.pdf_online) {
catalog.pdf_online = ris.catalog.pdf_online;
catalog.data_online = ris.catalog.data_online;
if (ris.record?.pdf_online) {
catalog.pdf_online = ris.record.pdf_online;
catalog.data_online = ris.record.data_online;
}
$q.notify({
color: 'positive',
@@ -1969,9 +1972,9 @@ export default defineComponent({
const ris = await globalStore.execOnlinePDF({ id_catalog: catalog._id, stampa: true });
if (ris) {
if (ris.catalog.pdf_online_stampa) {
catalog.pdf_online_stampa = ris.catalog.pdf_online_stampa;
catalog.data_online_stampa = ris.catalog.data_online_stampa;
if (ris.record.pdf_online_stampa) {
catalog.pdf_online_stampa = ris.record.pdf_online_stampa;
catalog.data_online_stampa = ris.record.data_online_stampa;
}
$q.notify({
color: 'positive',

View File

@@ -231,6 +231,7 @@
:lista_prodotti="lista_prodotti"
@update:lista_prodotti="updateProducts"
:optcatalogo="optcatalogo"
table="products"
@rigenera="generaListaLibri()"
/>
</q-tab-panel>
@@ -1072,6 +1073,7 @@
@close="addnewProd = false"
nameLinkTemplate="SEARCH_Prima"
:empty="true"
table="catalogs"
>
</CSearchProduct>
</CMyDialog>

View File

@@ -0,0 +1 @@
export {default as RaccoltaCataloghi} from './raccoltacataloghi.vue'

View File

@@ -0,0 +1,166 @@
$heightBtn: 100%;
$colore_titolo_libro: rgb(210, 12, 12);
body {
line-height: 1.2 !important;
}
.card .product-image {
height: 300px;
}
.container {
margin-top: 4px;
margin-bottom: 4px;
}
.prod_trov {
font-style: italic;
color: grey;
}
.fixed-group {
position: fixed;
top: 0;
left: 0;
width: 100%;
background-color: #ffffff;
/* Customize the background color as needed */
z-index: 1000;
/* Adjust the z-index to ensure it's above other elements */
transition: all 1s ease;
}
.category-title {
font-weight: bold;
font-size: 1.1rem;
margin-bottom: 0.5rem;
margin-top: 0.5rem;
color: black;
text-align: center;
}
.fixed-width {
width: var(--width) !important;
/* Usa una variabile CSS */
}
.fixed-height {
height: var(--height) !important;
/* Usa una variabile CSS */
}
.break {
flex-basis: 100%;
height: 0;
}
.book-title {
font-family: 'DINPro-Condensed-Bold', sans-serif;
color: $colore_titolo_libro;
text-transform: uppercase;
margin-top: calc(5 * var(--scalecatalog) * 1px);
margin-bottom: calc(5 * var(--scalecatalog) * 1px);
font-size: calc(18 * var(--scalecatalog) * 1px);
line-height: 100%;
font-weight: bold;
}
.book-author {
font-family: 'DINPro-Condensed-Regular', sans-serif;
font-size: calc(16 * var(--scalecatalog) * 1px);
}
.book-descr {
font-family: 'DINPro-Condensed-Bold-Italic', sans-serif;
font-size: calc(16 * var(--scalecatalog) * 1px);
}
.book-details {
font-family: 'DINPro-Condensed-Regular', sans-serif;
margin-bottom: calc(5 * var(--scalecatalog) * 1px);
font-size: calc(16 * var(--scalecatalog) * 1px);
text-align: left !important;
&.big {
font-size: calc(22 * var(--scalecatalog) * 1px);
}
}
.book-descr-estesa {
font-family: 'AGaramondPro-Regular', sans-serif;
font-size: calc(15 * var(--scalecatalog) * 1px);
text-align: justify;
word-wrap: break-word;
}
.book-link {
font-style: italic;
font-size: calc(14 * var(--scalecatalog) * 1px);
}
.book-novita {
font-size: calc(20 * var(--scalecatalog) * 1px);
}
.book-text-up {
font-family: 'DINPro', sans-serif;
margin-bottom: calc(5 * var(--scalecatalog) * 1px);
font-size: calc(20 * var(--scalecatalog) * 1px);
height: calc(380 * var(--scalecatalog) * 1px);
line-height: 130%;
}
.book-text-down {
font-family: 'DINPro', sans-serif;
margin-bottom: calc(5 * var(--scalecatalog) * 1px);
}
.book-pagina-title {
font-family: 'DINPro', sans-serif;
margin-top: calc(20 * var(--scalecatalog) * 1px);
margin-bottom: calc(5 * var(--scalecatalog) * 1px);
font-size: calc(35 * var(--scalecatalog) * 1px);
height: calc(100 * var(--scalecatalog) * 1px);
}
.categories {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 8px;
padding: 12px;
border-radius: 24px;
background-color: #e6f0ff;
}
.category {
font-family: 'Segoe UI', Arial, sans-serif;
font-size: 0.95rem;
padding: 8px 16px;
background-color: white;
color: #2c3e50;
border: 1px solid #b0c4de;
border-radius: 20px;
cursor: pointer;
transition: all 0.2s ease-in-out;
user-select: none;
}
.category:hover {
background-color: #dbe9ff;
color: #1a3f8a;
border-color: #89aef0;
}
.category_sel {
background-color: #5c8ef4 !important;
color: white !important;
font-weight: 600;
border-color: #5c8ef4 !important;
box-shadow: 0 0 0 2px rgba(92, 142, 244, 0.3);
}

View File

@@ -0,0 +1,430 @@
import type { PropType } from 'vue';
import { defineComponent, onMounted, ref, watch, computed, onBeforeUnmount, nextTick } from 'vue';
import { tools } from '@tools';
import { useUserStore } from '@store/UserStore';
import { useRouter } from 'vue-router';
import { useGlobalStore } from '@store/globalStore';
import { useProducts } from '@store/Products';
import { useI18n } from 'vue-i18n';
import { toolsext } from '@store/Modules/toolsext';
import { useQuasar } from 'quasar';
import { costanti } from '@costanti';
import { shared_consts } from '@src/common/shared_vuejs';
import { CProductCard } from '@src/components/CProductCard';
import { CMyDialog } from '@src/components/CMyDialog';
import { CMySelect } from '@src/components/CMySelect';
import { CMyValueDb } from '@src/components/CMyValueDb';
import { CProductTable } from '@src/components/CProductTable';
import { CSearchProduct } from '@src/components/CSearchProduct';
import { CContainerCatalogoCard } from '@src/components/CContainerCatalogoCard';
import { CSelectUserActive } from '@src/components/CSelectUserActive';
import html2pdf from 'html2pdf.js';
import { PDFDocument } from 'pdf-lib';
import { saveAs } from 'file-saver';
import type {
IOptCatalogo,
IDimensioni,
IFilterCatalogo,
IProdView,
IProduct,
ISearchList,
ICatalog,
IImg,
IText,
ICollana,
IOptRigenera,
IOpAndOr,
} from 'model';
import { IMyPage } from 'model';
import { fieldsTable } from '@store/Modules/fieldsTable';
import { useCatalogStore } from '@src/store/CatalogStore';
export default defineComponent({
name: 'RaccoltaCataloghi',
components: {
CContainerCatalogoCard,
CProductCard,
CSelectUserActive,
CMySelect,
CProductTable,
CSearchProduct,
CMyDialog,
CMyValueDb,
},
emits: ['update:modelValue', 'updateCatalogo'],
props: {
modelValue: {
type: Object as PropType<IOptCatalogo>,
required: true,
},
idPage: {
type: String,
required: false,
default: '',
},
},
setup(props, { emit }) {
const userStore = useUserStore();
const globalStore = useGlobalStore();
const productStore = useProducts();
const router = useRouter();
const $q = useQuasar();
const { t } = useI18n();
const rigeneraLibri = ref(false);
const search = ref('');
const optauthors = ref(<any>[]);
const loadpage = ref(false)
const pdfContent = ref(null);
const addnewProd = ref(false);
const widthpdf = ref('8.88');
const heightpdf = ref('12.31');
const compressionepdf = ref('prepress');
const optcatalogo = ref(<IOptCatalogo>{ ...props.modelValue });
const getRaccoltaCataloghiByMyPage = computed(() => {
return catalogStore.raccoltacataloghis?.find((raccolta: IRaccoltaCatalogo) => raccolta.idPageAssigned === props.idPage);
});
const lista_cataloghi = computed(() => {
const arr = catalogStore.raccoltacataloghis?.find(
(raccolta: IRaccoltaCatalogo) => raccolta.idPageAssigned === props.idPage
);
return arr?.lista_cataloghi;
});
const ispageCatalogata = computed(() => {
return !!getRaccoltaCataloghiByMyPage.value;
});
const mycolumns = ref([]);
const catalogStore = useCatalogStore();
const tabraccolta = ref('lista');
const searchList = ref([] as ISearchList[]);
const numRecLoaded = ref(0);
// Create a ref for the component to fix
const componentToFixRef = ref(<any>null);
const isFixed = ref(false);
watch(
() => tabraccolta.value,
() => {
tools.setCookie('RACC_TAB_CAT', tabraccolta.value);
}
);
const labelcombo = computed(() => (item: any) => {
let lab = item.label;
if (item.showcount) lab += ' (' + valoriopt.value(item, false, false).length + ')';
return lab;
});
const arrLoaded = computed(() => {
if (arrCataloghi.value && numRecLoaded.value) return arrCataloghi.value.slice(0, numRecLoaded.value);
else {
return [];
}
});
function getTitoloRaccolta(): string {
const trovatoraccolta = getRaccoltaCataloghiByMyPage.value;
return trovatoraccolta ? trovatoraccolta.title : 'Raccolta';
}
function getSfondoImgCatalogo(scheda?: IMyScheda | null, mypage?: IDimensioni): IImg {
const trovatoraccolta = getRaccoltaCataloghiByMyPage.value;
let imagefile = '';
let fit = 'contain';
if (trovatoraccolta) {
// Poi cerca se c'è l'immagine di sfondo
const recimg = trovatoraccolta.img_bordata!;
if (!imagefile && recimg) {
imagefile = recimg.imagefile!;
fit = recimg.fit! || 'contain';
imagefile = imagefile
? `url(${tools.getDirUpload() + shared_consts.getDirectoryByTable(shared_consts.TABLES_CATALOG) + '/' + trovatoraccolta._id + '/' + imagefile})`
: '';
}
}
if (!imagefile) {
let myimg = costanti.CATALOGHI.PAG_SFONDO_DEFAULT;
// Se non c'è un immagine di sfondo, allora prende quella di default
imagefile = `url(${tools.getDirUpload() + shared_consts.getDirectoryByTable(shared_consts.TABLES_CATALOG) + '/' + myimg})`;
}
if (!imagefile && mypage) {
imagefile = mypage.imgsfondo!.imagefile!;
imagefile = imagefile ? `url(${tools.getDirUpload() + costanti.DIR_CATALOGO + imagefile})` : '';
fit = mypage.imgsfondo!.fit!;
}
return { imagefile, fit };
}
function salvaListaRaccolte(ricarica: boolean) {
// Estrai solo gli ID dei prodotti filtrati
const myarr = [...getRaccoltaCataloghiByMyPage.value.lista_cataloghi];
const catalogoIds = myarr.map((catalog) => (catalog._id ? catalog._id : null)).filter((id) => id !== null);
let mydata = {
lista_cataloghi: catalogoIds,
};
// Salva gli ID dei prodotti nel catalogo
tools.saveFieldToServer($q, 'raccoltacataloghis', getRaccoltaCataloghiByMyPage.value._id, mydata, true, false);
}
async function mounted() {
// console.log('mounted Catalogo')
if (getRaccoltaCataloghiByMyPage.value) {
tabraccolta.value = tools.getCookie('RACC_TAB_CAT', 'lista');
} else {
tabraccolta.value = 'lista';
}
loadpage.value = false;
// await productStore.loadProducts(true);
mycolumns.value = fieldsTable.getArrColsByTable('raccoltacataloghis');
// Inizializza
loadpage.value = true;
calcArrCataloghi();
}
function calcArrCataloghi() {}
function loaddata() {
numRecLoaded.value = 20;
}
function naviga(path: string) {
router.push(path);
}
function updateRaccolta(arr: any) {
if (getRaccoltaCataloghiByMyPage.value) {
getRaccoltaCataloghiByMyPage.value.lista_cataloghi = [...arr];
salvaListaRaccolte(true);
}
}
function addCatalogToList(element: ICatalog, where: string) {
// console.log('addCatalogToList', element)
if (element) {
// add this record to lista_cataloghi
if (
getRaccoltaCataloghiByMyPage.value &&
element._id && !getRaccoltaCataloghiByMyPage.value.lista_cataloghi?.some((p) => p?._id === element._id)
) {
// inserire il record in cima
const arr = getRaccoltaCataloghiByMyPage.value.lista_cataloghi || [];
if (where === shared_consts.WHERE_INSERT.ONTOP)
arr.unshift(element);
else if (where === shared_consts.WHERE_INSERT.ONBOTTOM)
arr.push(element)
updateRaccolta(arr);
addnewProd.value = false;
}
}
}
function clickaddNewBook() {
addnewProd.value = true;
}
function toggleDebug() {
optcatalogo.value.indebug = !optcatalogo.value.indebug;
}
const preparePDF = (stampa: boolean) => {
let addstr = stampa ? ' per la STAMPA' : ''
$q.dialog({
message: `Generare il PDF ${addstr}?`,
ok: {
label: t('dialog.yes'),
push: true,
},
cancel: {
label: t('dialog.cancel'),
},
title: 'Generazione PDF',
}).onOk(async () => {
generaPDF(stampa);
});
};
async function saveRaccolta() {
const raccolta = getRaccoltaCataloghiByMyPage.value
const mydata = {
table: 'raccoltacataloghis',
data: raccolta,
};
await globalStore.saveTable(mydata);
}
async function generaPDF(stampa: boolean) {
$q.loading.show({
message: 'Generazione della Raccolta Catalogo in PDF in corso ...',
});
try {
const options = {
id_raccolta: getRaccoltaCataloghiByMyPage.value._id,
stampa,
metti_online: false,
dir_out: '/upload/raccolte/',
}
const ris = await globalStore.execJoinPDF({options});
if (ris) {
const raccolta = getRaccoltaCataloghiByMyPage.value;
if (!stampa && ris.raccolta.pdf_generato) {
raccolta.pdf_generato = ris.raccolta.pdf_generato;
raccolta.data_generato = tools.getDateNow();
}
if (stampa && ris.raccolta.pdf_generato_stampa) {
raccolta.pdf_generato_stampa = ris.raccolta.pdf_generato_stampa;
raccolta.data_generato_stampa = tools.getDateNow();
}
await saveRaccolta();
}
$q.loading.hide();
$q.notify({
color: 'positive',
message: 'PDF generato con successo!',
icon: 'check',
});
} catch (error) {
$q.loading.hide();
$q.notify({
color: 'negative',
message: 'Errore nella generazione del PDF',
icon: 'error',
});
console.error('Errore nella generazione del PDF:', error);
}
}
const pubblicaPDF = async () => {
const raccolta = getRaccoltaCataloghiByMyPage.value;
const ris = await globalStore.execOnlinePDF({ id_raccolta: raccolta._id, stampa: false });
if (ris) {
if (ris.record?.pdf_online) {
raccolta.pdf_online = ris.record.pdf_online;
raccolta.data_online = ris.record.data_online;
}
$q.notify({
color: 'positive',
message: 'PDF inviato ONLINE!',
icon: 'check',
});
} else {
$q.loading.hide();
$q.notify({
color: 'negative',
message: "Errore nell'invio del PDF OnLine",
icon: 'error',
});
}
};
const pubblicaPDFStampa = async () => {
const raccolta = getRaccoltaCataloghiByMyPage.value;
const ris = await globalStore.execOnlinePDF({ id_raccolta: raccolta._id, stampa: true });
if (ris) {
if (ris.record.pdf_online_stampa) {
raccolta.pdf_online_stampa = ris.record.pdf_online_stampa;
raccolta.data_online_stampa = ris.record.data_online_stampa;
}
await saveRaccolta();
$q.notify({
color: 'positive',
message: 'PDF STAMPA inviato ONLINE!',
icon: 'check',
});
} else {
$q.loading.hide();
$q.notify({
color: 'negative',
message: "Errore nell'invio del PDF STAMPA OnLine",
icon: 'error',
});
}
}
onMounted(mounted);
return {
userStore,
costanti,
tools,
toolsext,
search,
shared_consts,
productStore,
t,
componentToFixRef,
isFixed,
numRecLoaded,
arrLoaded,
mycolumns,
tabraccolta,
naviga,
getTitoloRaccolta,
lista_cataloghi,
updateRaccolta,
clickaddNewBook,
addCatalogToList,
addnewProd,
rigeneraLibri,
getRaccoltaCataloghiByMyPage,
preparePDF,
pubblicaPDF,
pubblicaPDFStampa,
loadpage,
ispageCatalogata,
optcatalogo,
};
},
});

View File

@@ -0,0 +1,184 @@
<template>
<q-page>
<div>
<div
v-if="ispageCatalogata"
class="text-bold text-h6 text-center text-blue"
>
{{ getTitoloRaccolta() }}
</div>
<q-tabs
v-model="tabraccolta"
dense
class="bg-green text-white"
>
<q-tab
name="lista"
icon="fas fa-list"
label="Lista"
>
</q-tab>
<q-tab
v-if="!tools.isUtente()"
name="genera"
icon="fas fa-book"
label="Genera"
>
</q-tab>
</q-tabs>
<q-tab-panels
v-model="tabraccolta"
animated
class=""
keep-alive
>
<q-tab-panel
name="lista"
>
<q-btn
rounded
label="Aggiungi"
icon="fas fa-plus"
color="primary"
@click="clickaddNewBook()"
></q-btn>
<CProductTable
v-if="loadpage && lista_cataloghi?.length > 0"
:lista_prodotti="lista_cataloghi"
@update:lista_prodotti="updateRaccolta"
table="catalogs"
:optcatalogo="optcatalogo"
/>
</q-tab-panel>
<q-tab-panel name="genera">
<div
v-if="!tools.isUtente()"
class="row justify-center"
>
<q-btn
v-if="!optcatalogo.generazionePDFInCorso"
:label="`GENERA PDF per WEB`"
@click="preparePDF(false)"
></q-btn>
<q-btn
v-if="!optcatalogo.generazionePDFInCorso"
:label="`GENERA PDF per STAMPA`"
@click="preparePDF(true)"
></q-btn>
<q-btn
v-if="optcatalogo.generazionePDFInCorso"
:label="`Termina Generazione`"
@click="terminaPDF"
></q-btn>
</div>
<div
v-if="getRaccoltaCataloghiByMyPage?.pdf_generato"
class="bg-green-1 q-ma-sm q-pa-sm"
>
<div class="bg-blue-1 text-red text-bold text-h6 q-ma-sm q-pa-sm">
<strong>PDF generati Temporanei</strong>
</div>
<div v-if="getRaccoltaCataloghiByMyPage?.data_generato !== getRaccoltaCataloghiByMyPage?.data_online">
PDF Generato:
<a
:href="tools.getHost() + getRaccoltaCataloghiByMyPage?.pdf_generato"
target="_blank"
v-if="getRaccoltaCataloghiByMyPage?.pdf_generato"
class="text-bold"
>
{{ tools.getHost() + getRaccoltaCataloghiByMyPage?.pdf_generato }}
</a>
<span v-else>-</span>
<br />(del {{ tools.getstrDateTime(getRaccoltaCataloghiByMyPage?.data_generato) }})
<br />
<q-btn
v-if="getRaccoltaCataloghiByMyPage?.data_generato !== getRaccoltaCataloghiByMyPage?.data_online"
rounded
label="Pubblica PDF OnLine"
color="positive"
@click="pubblicaPDF()"
></q-btn>
</div>
<br />
<div v-if="getRaccoltaCataloghiByMyPage?.data_generato_stampa !== getRaccoltaCataloghiByMyPage?.data_online_stampa">
PDF Generato Stampa:
<a
:href="tools.getHost() + getRaccoltaCataloghiByMyPage?.pdf_generato_stampa"
target="_blank"
v-if="getRaccoltaCataloghiByMyPage?.pdf_generato_stampa"
class="text-bold"
>
{{ tools.getHost() + getRaccoltaCataloghiByMyPage?.pdf_generato_stampa }}
</a>
<span v-else>-</span>
<br />(del {{ tools.getstrDateTime(getRaccoltaCataloghiByMyPage?.data_generato_stampa) }})
<br />
<q-btn
v-if="getRaccoltaCataloghiByMyPage?.data_generato_stampa !== getRaccoltaCataloghiByMyPage?.data_online_stampa"
rounded
label="Pubblica PDF Stampa"
color="positive"
@click="pubblicaPDFStampa()"
></q-btn>
</div>
<div class="bg-green-1">
<div class="bg-blue-1 text-green text-bold text-h6 q-ma-sm q-pa-sm">
<strong>PDF Pubblicati OnLine</strong>
</div>
<div v-if="getRaccoltaCataloghiByMyPage?.data_online">
PDF OnLine:
<a
:href="tools.getHost() + getRaccoltaCataloghiByMyPage?.pdf_online"
target="_blank"
v-if="getRaccoltaCataloghiByMyPage?.pdf_online"
class="text-bold"
>
{{ tools.getHost() + getRaccoltaCataloghiByMyPage?.pdf_online }}
</a>
<span v-else>-</span>
<br />(del {{ tools.getstrDateTime(getRaccoltaCataloghiByMyPage?.data_online) }})
</div>
<br />
<div v-if="getRaccoltaCataloghiByMyPage?.data_online_stampa">>
PDF OnLine Stampa:
<a
:href="tools.getHost() + getRaccoltaCataloghiByMyPage?.pdf_online_stampa"
target="_blank"
v-if="getRaccoltaCataloghiByMyPage?.pdf_online_stampa"
class="text-bold"
>
{{ tools.getHost() + getRaccoltaCataloghiByMyPage?.pdf_online_stampa }}
</a>
<span v-else>-</span>
<br />(del {{ tools.getstrDateTime(getRaccoltaCataloghiByMyPage?.data_online_stampa) }})
</div>
</div>
</div>
</q-tab-panel>
</q-tab-panels>
</div>
</q-page>
<CMyDialog
v-model="addnewProd"
title="Aggiungi"
class="q-ma-md"
>
<CSearchProduct
:visu="shared_consts.VISU_SEARCHPROD_MODE.INSERT"
table="catalogs"
@insert="addCatalogToList"
@close="addnewProd = false"
nameLinkTemplate="SEARCH_Prima"
:empty="true"
>
</CSearchProduct>
</CMyDialog>
</template>
<script lang="ts" src="./raccoltacataloghi.ts"></script>
<style lang="scss" scoped>
@import './raccoltacataloghi.scss';
</style>

View File

@@ -7,7 +7,7 @@
"resolveJsonModule": true,
"moduleDetection": "force",
"isolatedModules": true,
"module": "preserve",
"module": "ESNext",
"noEmit": true,
"lib": [
"esnext",
@@ -159,7 +159,8 @@
"include": [
"./**/*.d.ts",
"./**/*",
".eslintrc.js"
".eslintrc.js",
"src/**/*",
],
"exclude": [
"./dist",