- Impostato i Font giusti e la corretta disposizione del testo e dei suoi margini.

- L'immagine del libro, se è piccolo, viene adattato alla dimensione fissa (vedere se va bene).
This commit is contained in:
Surya Paolo
2024-11-24 14:40:29 +01:00
parent 6a6c15b62c
commit e10ff192bf
18 changed files with 392 additions and 123 deletions

BIN
public/images/ombra.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -1,5 +1,5 @@
.barcode-container {
padding: 10px;
padding: 5px;
display: flex;
justify-content: center;
align-items: center;

View File

@@ -25,6 +25,11 @@ export default defineComponent({
default: '',
},
width: {
type: Number,
required: false,
default: 50,
},
widthlines: {
type: Number,
required: false,
default: 2,
@@ -45,18 +50,18 @@ export default defineComponent({
const { t } = useI18n();
// Converti le props in riferimenti reattivi
const { value, format, width, height, fontsize } = toRefs(props);
const { value, format, width, widthlines, height, fontsize } = toRefs(props);
// Funzione per disegnare il codice a barre
const drawBarcode = () => {
JsBarcode("#C" + value.value, value.value, {
format: format.value,
width: width.value,
width: widthlines.value,
height: height.value,
displayValue: true,
lineColor: "#000",
font: "monospace",
margin: 1,
margin: 0,
textMargin: 0,
marginTop: 0,
fontSize: fontsize.value,

View File

@@ -1,7 +1,9 @@
<template>
<div class="row barcode-container justify-center">
<div class="text-center " :style="`font-size: ${fontsize}px`">{{text}}</div>
<svg :id="`C${value}`"></svg>
<div class="row barcode-container justify-center text-center">
<div class="text-center" :style="`font-size: ${fontsize}px`">
{{ text }}
</div>
<img :style="`width:${width}px !important;`" :id="`C${value}`"/>
</div>
</template>

View File

@@ -342,3 +342,22 @@
transition: transform 0.5s ease-in-out;
}
}
.shadow-image-wrapper {
position: relative; /* Necessario per il posizionamento dell'ombra */
}
.shadow-image {
position: absolute; /* Posiziona l'immagine dell'ombra sopra l'immagine principale */
width: 100%; /* Assicurati che l'ombra si adatti all'immagine principale */
height: auto;
top: 0; /* Allineato in alto */
left: 0; /* Allineato a sinistra */
z-index: 1; /* Posiziona l'ombra dietro l'immagine principale */
}
/* Regola z-index per il resto */
.q-img {
position: relative; /* Per la sovrapposizione */
z-index: 2; /* Posiziona l'immagine principale sopra l'ombra */
}

View File

@@ -48,23 +48,58 @@
</q-page-sticky>
<q-card-section>
<!-- per immagine di ombra -->
<div v-if="false" class="shadow-image-wrapper">
<q-img
src="images/ombra.png"
:style="{
position: 'absolute',
justifyContent: 'center',
width:
tools.adjustSize(
optcatalogo,
scheda.dimensioni?.immagine_prodotto?.size.width,
10
) ?? '100%',
height: tools.adjustSize(
optcatalogo,
scheda.dimensioni?.immagine_prodotto?.size.height,
10
),
zIndex: 1,
}"
>
</q-img>
</div>
<div
:class="[
'flex q-pa-xs', // Classi comuni
'flex', // Classi comuni
'image-container',
{ 'shadow-2': options.in_3d }, // Classe condizionale
scheda.posiz_text === costanti.POSIZ_TESTO.IN_BASSO
? 'flex-col'
: 'flex-row', // Layout flessibile
]"
:style="{
justifyContent: 'center',
alignItems: 'center',
gap: '0.5rem',
justifyContent:
scheda.posiz_text === costanti.POSIZ_TESTO.IN_BASSO
? 'center'
: 'flex-start',
alignItems: 'stretch', // Cambiato in 'stretch' per occupare l'altezza
gap:
tools.adjustSize(
optcatalogo,
scheda.dimensioni?.scheda_prodotto?.size.gap
) ?? '0.1rem',
width:
tools.adjustSize(
optcatalogo,
scheda.dimensioni?.scheda_prodotto?.size.width
) ?? '100%',
height: tools.adjustSize(
optcatalogo,
scheda.dimensioni?.scheda_prodotto?.size.height
),
}"
>
<q-img
@@ -85,6 +120,7 @@
'image-wrapper': optcatalogo.pdf,
}"
:style="{
zIndex: 9000,
width:
scheda.posiz_text === costanti.POSIZ_TESTO.IN_BASSO
? '50%'
@@ -102,23 +138,7 @@
display: 'block',
}"
@click="click_opendetail()"
>
<div
class="absolute transparent"
style="left: 90%; top: -18px; transform: translateX(-50%)"
>
<q-btn
v-if="!optcatalogo.pdf"
color="blue-6"
class="semi-transparent"
round
icon="search"
@click.stop="toggleFullScreen"
size="sm"
/>
</div>
</q-img>
<!-- Testo associato all'immagine -->
<div
:style="{
@@ -129,7 +149,7 @@
textAlign: 'center',
marginTop:
scheda.posiz_text === costanti.POSIZ_TESTO.IN_BASSO
? '1rem'
? '0.5rem'
: '0',
}"
>
@@ -138,7 +158,12 @@
:style="{
'--scalecatalog': optcatalogo.areadistampa.scale,
'line-height': scheda.line_height,
height: '100%',
display: 'flex',
flexDirection: 'column',
}"
>
<div
v-html="
products.replaceKeyWordsByProduct(
optcatalogo,
@@ -146,8 +171,8 @@
scheda.testo_right
)
"
style="display: flex; flex-direction: column; justify-content: space-between; height: 100%;"
></div>
<div v-if="scheda.barcode && scheda.barcode.show">
<CBarCode
:value="myproduct.productInfo.code"
@@ -158,14 +183,11 @@
tools.adjustSize(optcatalogo, scheda.barcode.size?.width)
)
"
:height="
parseInt(
tools.adjustSize(optcatalogo, scheda.barcode.size?.height)
)
"
:widthlines="scheda.barcode.widthlines"
:height="scheda.barcode.size?.height"
>
</CBarCode>
<!--:text="`ISBN: ${myproduct.productInfo.code}`"-->
</div>
</div>
</div>
<div
@@ -173,7 +195,27 @@
:style="{
width: '100%',
textAlign: 'center',
marginTop: '1rem',
}"
>
<div
:style="{
'--scalecatalog': optcatalogo.areadistampa.scale,
'line-height': scheda.line_height,
}"
v-html="
products.replaceKeyWordsByProduct(
optcatalogo,
myproduct,
scheda.testo_bottom
)
"
></div>
</div>
<div
v-if="scheda.testo_bottom && scheda.testo_bottom.contenuto"
:style="{
width: '100%',
textAlign: 'center',
}"
>
<div

View File

@@ -121,6 +121,8 @@ export default defineComponent({
const neworder = ref(<number | undefined>0)
const idSchedaDaCopiare = ref('')
const myel = toRef(props, 'myelem')
const newtype = ref(<any>'')
const visuadd = ref(false)
@@ -199,7 +201,7 @@ export default defineComponent({
}
async function dupElem(order?: number) {
const newrec: IMyElem = { ...props.myelem }
const newrec: IMyElem = tools.jsonCopy(props.myelem)
newrec._id = undefined
newrec.order = getNewOrderByThisElem()
@@ -242,6 +244,12 @@ export default defineComponent({
disableSave.value = false
elemChanged.value = true
}
function modifElemAndSchede() {
modifElem()
myel.value.catalogo!.aggiorna++
}
function mounted() {
neworder.value = props.myelem.order
@@ -438,6 +446,7 @@ export default defineComponent({
_id: objectId(),
idapp: tools.appid()!,
isTemplate: false,
show_separatore: true,
name: 'Scheda Nuova',
dimensioni,
line_height: 100,
@@ -459,7 +468,7 @@ export default defineComponent({
},
font: {
name: 'monospace',
size: 16,
size: '16px',
}
},
productTypes: [],
@@ -486,6 +495,51 @@ export default defineComponent({
modifElem()
}
function copyfromTemplate(indscheda: number) {
// Estrai l'id da copiare e sostituisci tutto con questo
if (!idSchedaDaCopiare.value) {
return false
}
const arrschede: ISchedaSingola[] = globalStore.getMySchede()
if (arrschede.length <= 0) {
return false
}
const myschedatocopy = arrschede.find((recscheda: ISchedaSingola) => recscheda.scheda!._id === idSchedaDaCopiare.value)
const schedadest = myel.value.catalogo!.arrSchede![indscheda]
if (myschedatocopy) {
let newscheda = myschedatocopy.scheda!.name
const msg = 'Sostituisci questa scheda (' + schedadest.scheda?.name + ') con "' + newscheda + '" ?'
$q.dialog({
message: msg,
html: true,
ok: {
label: 'Sostituisci',
push: true,
},
title: '',
cancel: true,
persistent: false,
}).onOk(async () => {
const myschedadest: ISchedaSingola = myel.value.catalogo!.arrSchede![indscheda]
myschedadest.scheda = tools.jsonCopy(myschedatocopy.scheda!)
myschedadest.scheda!._id = objectId()
myschedadest.order = 20
myschedadest.scheda!.name = myschedadest.scheda!.name + '_copia'
myschedadest.scheda!.isTemplate = false
})
}
}
function dupNewScheda(id: string) {
if (!myel.value.catalogo!.arrSchede)
return
@@ -493,14 +547,19 @@ export default defineComponent({
const myfindscheda = myel.value.catalogo!.arrSchede.find((scheda: ISchedaSingola) => scheda._id === id)
if (myfindscheda) {
let myscheda = { ...myfindscheda }
let myscheda = tools.jsonCopy(myfindscheda)
delete myscheda._id
delete myscheda.scheda!._id
myscheda.numSchede = 1
myscheda.order = myscheda.order + 10,
myscheda._id = objectId()
myscheda.scheda!._id = objectId()
myscheda.scheda!.name = myscheda.scheda!.name + '_copia'
myscheda.scheda!.isTemplate = false
const bakscheda = [...myel.value.catalogo!.arrSchede]
myel.value.catalogo!.arrSchede = []
myel.value.catalogo!.arrSchede = [...bakscheda, myscheda]
myel.value.catalogo!.arrSchede.push(myscheda)
modifElem()
}
@@ -514,7 +573,7 @@ export default defineComponent({
const myfindcard = myel.value.listcards[tabCard.value]
if (myfindcard) {
let mycard = { ...myfindcard }
let mycard = tools.jsonCopy(myfindcard)
delete mycard._id
mycard._id = objectId()
@@ -568,10 +627,28 @@ export default defineComponent({
}
function delRecScheda(id: string, myel: IMyElem) {
const myscheda = myel.catalogo!.arrSchede!.find((scheda: ISchedaSingola) => scheda._id === id)
if (myscheda) {
$q.dialog({
message: 'Eliminare la scheda "' + myscheda?.scheda?.name + '" ?',
html: true,
ok: {
label: 'Elimina',
push: true,
},
title: '',
cancel: true,
persistent: false,
}).onOk(async () => {
//
myel.catalogo!.arrSchede = myel.catalogo!.arrSchede!.filter((scheda: ISchedaSingola) => scheda._id !== id)
modifElem()
})
}
}
@@ -678,13 +755,13 @@ export default defineComponent({
}
function SchedeOpt() {
const arrschede = globalStore.getMySchede()
const arrschede: ISchedaSingola[] = globalStore.getMySchede()
let arr: any = []
if (arrschede) {
arrschede.forEach(scheda => {
arr.push({ label: scheda.name, value: scheda._id })
arrschede.forEach((recscheda: ISchedaSingola) => {
arr.push({ label: recscheda.scheda!.name, value: recscheda.scheda!._id })
});
}
@@ -865,6 +942,9 @@ export default defineComponent({
addProdSpeciale,
formatOptions,
fontSizeOptions,
idSchedaDaCopiare,
copyfromTemplate,
modifElemAndSchede,
}
},

View File

@@ -1473,7 +1473,7 @@
>
<q-tab
v-for="(rec, ind) in myel.catalogo.arrSchede"
:key="ind"
:key="rec._id"
:name="ind"
:label="`Scheda ` + (ind + 1)"
icon="fas fa-pencil-alt"
@@ -1484,7 +1484,7 @@
<q-tab-panels v-model="tabScheda" animated>
<q-tab-panel
v-for="(recscheda, ind) in myel.catalogo.arrSchede"
:key="ind"
:key="recscheda._id"
:name="ind"
>
<q-bar v-if="recscheda" class="bg-primary text-white">
@@ -1545,14 +1545,15 @@
>
</q-input>
<!--<q-select
<div class="row">
<q-select
:behavior="
$q.platform.is.ios === true ? 'dialog' : 'menu'
"
v-if="enableEdit"
rounded
outlined
v-model="recscheda._id"
v-model="idSchedaDaCopiare"
:options="SchedeOpt()"
@update:model-value="modifElem"
dense
@@ -1561,7 +1562,17 @@
emit-value
map-options
>
</q-select>-->
</q-select>
<q-btn
icon="far fa-copy"
label="Copia da Template"
dense
:disable="!idSchedaDaCopiare"
color="primary"
@click="copyfromTemplate(ind)"
>
</q-btn>
</div>
<CMySlider
label="Schede da ripetere"
@@ -1716,7 +1727,7 @@
:min="1"
:max="10"
color="green"
@update:model-value="modifElem"
@update:model-value="modifElemAndSchede"
></CMySlider>
<CMySlider
label="Schede per Colonna"
@@ -1724,7 +1735,7 @@
:min="1"
:max="10"
color="red"
@update:model-value="modifElem"
@update:model-value="modifElemAndSchede"
></CMySlider>
<CMySize
@@ -1732,6 +1743,7 @@
v-model="
recscheda.scheda.dimensioni.scheda_prodotto.size
"
:gap="true"
@update:model-value="modifElem"
></CMySize>
@@ -1877,20 +1889,24 @@
text-color="white"
>
</q-select>
<q-select
v-model="recscheda.scheda.barcode.font.size"
:options="fontSizeOptions"
label="Font Size"
options-dense
dense
emit-value
map-options
style="width: 100px"
<CMySlider
label="Width Linee:"
v-model="recscheda.scheda.barcode.widthlines"
:min="1"
:max="10"
color="green"
@update:model-value="modifElem"
fill-input
text-color="white"
>
</q-select>
></CMySlider>
<CMySlider
label="Font Size:"
v-model="recscheda.scheda.barcode.font.size"
:min="8"
:max="40"
color="green"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
<CMySize
label="Dimensioni:"
v-model="recscheda.scheda.barcode.size"
@@ -1971,7 +1987,13 @@
map-options
>
</q-select>
<div v-if="myel.catalogo.areadistampa.format.length > 1">Ratio: {{myel.catalogo.areadistampa.format[0] / myel.catalogo.areadistampa.format[1]}}</div>
<div v-if="myel.catalogo.areadistampa.format.length > 1">
Ratio:
{{
myel.catalogo.areadistampa.format[0] /
myel.catalogo.areadistampa.format[1]
}}
</div>
<q-select
rounded
style="width: 200px"

View File

@@ -32,6 +32,11 @@ export default defineComponent({
required: false,
default: false,
},
gap: {
type: Boolean,
required: false,
default: false,
},
addstr: {
type: Boolean,
required: false,
@@ -67,6 +72,10 @@ export default defineComponent({
}
}
function modifValueGap(value: any) {
emit('update:modelValue', { ...internalModel, gap: value });
}
function modifValueRatio(value: any) {
// modifValueWidth(0)
@@ -94,6 +103,7 @@ export default defineComponent({
modifValueWidth,
modifValueHeight,
modifValueRatio,
modifValueGap,
internalModel,
ratio,
keepRatio,

View File

@@ -47,6 +47,16 @@
:addstr="addstr ? 'px' : ''"
@update:model-value="modifValueHeight"
></CMySlider>
<CMySlider
v-if="gap"
label="Gap:"
v-model="internalModel.gap"
:min="0"
:max="50"
color="red"
addstr="px"
@update:model-value="modifValueGap"
></CMySlider>
</div>
</div>
</template>

View File

@@ -64,7 +64,7 @@ export default defineComponent({
return 5
} else {
if (props.max < 5) {
return (props.max - props.min) / 100
return Math.abs((props.max - props.min) / 20)
} else {
return 1
}
@@ -72,6 +72,7 @@ export default defineComponent({
}
}
function incrementValue() {
if (!sliderValue.value) {
sliderValue.value = '1'

View File

@@ -7,6 +7,41 @@
font-style: normal;
}
@font-face {
font-family: 'DINPro-BoldItalic';
src: url('~src/assets/fonts/DINPro-BoldItalic.otf') format('opentype');
font-weight: bold;
font-style: italic;
}
@font-face {
font-family: 'DINPro-CondBlack';
src: url('~src/assets/fonts/DINPro-CondBlack.otf') format('opentype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'DINPro-CondensedBold';
src: url('~src/assets/fonts/DINPro-CondensedBold.otf') format('opentype');
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: 'DIN-Pro-Condensed-Regular';
src: url('~src/assets/fonts/DINPro-CondensedBold.otf') format('opentype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'DINPro';
src: url('~src/assets/fonts/DINPro.otf') format('opentype');
font-weight: normal;
font-style: normal;
}
body {
font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
-webkit-font-smoothing: antialiased;
@@ -2267,9 +2302,8 @@ $coloreprincipale: lightblue;
display: flex;
flex-wrap: nowrap;
flex-direction: row;
gap: 0.5rem;
height: 100%;
padding: 0.5rem;
/*padding: 0.5rem;*/
}
.flex-card {
@@ -2513,3 +2547,7 @@ body.body--dark {
.q-card-section-small {
padding: 0px;
}
.uppercase {
text-transform: uppercase;
}

View File

@@ -687,6 +687,7 @@ export interface IMyCard {
export interface ISize {
width?: string
height?: string
gap?: string
}
export interface IFont {
name?: string
@@ -710,6 +711,7 @@ export interface IBarCode {
format?: string
size?: ISize
font?: IFont
widthlines?: number
}
export interface IDimensioni {
@@ -799,6 +801,7 @@ export interface ICatalogo {
dimensioni_def?: IElementiPagina
arrSchede?: ISchedaSingola[]
aggiorna: number
}

View File

@@ -1002,11 +1002,11 @@ export const colmyUserGroup = [
AddCol({
name: 'title', label_trans: 'reg.name',
field_toduplicate_nospace: 'groupname',
required: true, noshowlabel: true, maxlength: 40
required: true, noshowlabel: true, maxlength: 50
}),
AddCol({
name: 'groupname', label_trans: 'reg.groupname', required: false,
maxlength: 30,
maxlength: 50,
allowchar: costanti.ALLOWCHAR_CODE,
showLinkResult: '{site}/grp/{value}',
showWhen: costanti.showWhen.InPage + costanti.showWhen.NewRec
@@ -3516,7 +3516,7 @@ export const colTableCircuitComplete = [
// AddCol({ name: 'groupnameId', label_trans: 'circuit.groupnameId', fieldtype: costanti.FieldType.select, jointable: 'mygroups' }), // da togliere poi
AddCol({
name: 'name', label_trans: 'circuit.name',
maxlength: 40,
maxlength: 50,
showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage
}),
AddCol({
@@ -3633,12 +3633,12 @@ export const colTableCircuit = [
AddCol({
name: 'name', label_trans: 'circuit.name',
required: true,
maxlength: 40,
maxlength: 50,
showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InView
}),
AddCol({
name: 'path', label_trans: 'circuit.path', required: true,
maxlength: 40,
maxlength: 50,
showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InView,
allowchar: costanti.ALLOWCHAR_CODE,
}),

View File

@@ -9276,17 +9276,22 @@ export const tools = {
return myrec
},
adjustSize(optcatalogo: ICatalogo, mysize: any) {
adjustSize(optcatalogo: ICatalogo, mysize: any, add: number = 0) {
if (!mysize) {
return '';
}
try {
// Estrae l'unità di misura
const unit = mysize.replace(/[\d.]/g, ''); // Ottiene il suffisso (es. 'px')
const numericalValue = parseFloat(mysize) || 0; // Converti la parte numerica in float
let size = numericalValue; // Inizializza size con il valore numerico
if (add > 0) {
size += add
}
if (optcatalogo.printable && optcatalogo.areadistampa?.scale && optcatalogo.areadistampa?.scale > 0) {
size = size * optcatalogo.areadistampa?.scale; // Applicare la scala se necessaria
}
@@ -9294,6 +9299,9 @@ export const tools = {
let strfinale = `${size}${unit}`
// console.log('mysize', mysize, ' => ', strfinale)
return strfinale; // Restituisce il valore con il suffisso
} catch (e) {
return mysize
}
},
getValueAndSuffix(myvalue: any): {value: number, suffix: string} {

View File

@@ -13,6 +13,7 @@ import {
IStatusSkill,
StateConnection,
IMyScheda,
ISchedaSingola,
} from '@model'
import { static_data } from '@src/db/static_data'
import * as Types from '@src/store/Api/ApiTypes'
@@ -116,7 +117,7 @@ export const useGlobalStore = defineStore('GlobalStore', {
mailinglist: [],
mypage: [],
myelems: [],
myscheda: [],
myschedas: [],
calzoom: [],
producers: [],
groups: [],
@@ -277,7 +278,7 @@ export const useGlobalStore = defineStore('GlobalStore', {
return state.myelems.filter((page: IMyElem) => (page._id === idPage)).sort((a: any, b: any) => a.order - b.order)
},
getMySchede: (state: IGlobalState) => (): IMyScheda[] | [] => {
getMySchede: (state: IGlobalState) => (): ISchedaSingola[] | [] => {
return state.myschedas
},

View File

@@ -68,3 +68,25 @@ body {
flex-basis: 100%;
height: 0;
}
.book-title {
font-family: 'DINPro-CondensedBold', sans-serif;
color: rgba(255, 0, 0, 1);
text-transform: uppercase;
margin-top: calc(5 * var(--scalecatalog) * 1px);
margin-bottom: calc(5 * var(--scalecatalog) * 1px);
}
.book-author {
font-family: 'DIN-Pro-Condensed-Regular', sans-serif;
}
.book-descr {
font-family: 'DINPro-BoldItalic', sans-serif;
}
.book-details {
font-family: 'DINPro', sans-serif;
margin-bottom: calc(5 * var(--scalecatalog) * 1px);
}

View File

@@ -167,6 +167,11 @@ export default defineComponent({
}
})
watch(() => props.optcatalogo.aggiorna, (newval, oldval) => {
console.log('Aggiorna array...')
generatearrProdToViewSorted()
})
function resetSearch() {
const mialista = getSearchList()
if (mialista && mialista.value && mialista.value.hasOwnProperty('name')) {
@@ -689,6 +694,7 @@ export default defineComponent({
orientation: props.optcatalogo.areadistampa!.orientation,
compress: props.optcatalogo.areadistampa!.compress,
},
enableLinks: true,
}
console.log('opt di stampa', opt)