- miglioramenti ricerca titoli e modifica del trafiletto

- miglior visualizzazione delle liste
This commit is contained in:
Surya Paolo
2025-04-30 13:27:47 +02:00
parent 493ebf51f3
commit 358f0d6816
40 changed files with 1093 additions and 148 deletions

View File

@@ -0,0 +1,4 @@
.myflex{
display: flex;
flex: 1;
}

View File

@@ -0,0 +1,275 @@
import { tools } from '@tools'
import { CTitleBanner } from '../CTitleBanner'
import { defineComponent, onMounted, ref, toRef, watch } from 'vue'
import { useQuasar } from 'quasar'
export default defineComponent({
name: 'CMyEditorAI',
components: { CTitleBanner },
props: {
title: {
type: String,
required: false,
default: '',
},
value: {
type: String,
required: false,
default: '',
},
myclass: {
type: String,
required: false,
default: '',
},
showButtons: {
type: Boolean,
required: false,
default: true,
},
canModify: {
type: Boolean,
required: false,
default: false,
},
hideTools: {
type: Boolean,
required: false,
default: false,
},
maxlength: {
type: Number,
required: false,
default: 0,
}
},
setup(props, { emit }) {
const $q = useQuasar()
const editorRef = ref(<any>null)
const editor = ref('')
const characterCount = ref(0)
//const myvalue = toRef(props, 'value')
const myvalue = ref('')
const mycolor = ref('')
const myfonts = ref({
arial: 'Arial',
arial_black: 'Arial Black',
AGaramondProRegular: 'AGaramondPro-Regular',
comic_sans: 'Comic Sans MS',
courier_new: 'Courier New',
impact: 'Impact',
lucida_grande: 'Lucida Grande',
times_new_roman: 'Times New Roman',
verdana: 'Verdana',
})
const showtools = ref(false)
const toolbarcomp = ref([
['left', 'center', 'right', 'justify'],
['bold', 'italic', 'underline', 'strike'],
['token', 'hr', 'link', 'custom_btn', 'print', 'fullscreen'],
[
{
label: $q.lang.editor.formatting,
icon: $q.iconSet.editor.formatting,
list: 'no-icons',
options: [
'p',
'h4',
'h5',
'h6',
'code'
]
},
{
label: $q.lang.editor.fontSize,
icon: $q.iconSet.editor.fontSize,
fixedLabel: true,
fixedIcon: true,
list: 'no-icons',
options: [
'size-1',
'size-2',
'size-3',
'size-4',
'size-5',
'size-6',
'size-7'
]
},
{
label: $q.lang.editor.defaultFont,
icon: $q.iconSet.editor.font,
fixedIcon: true,
list: 'no-icons',
options: [
'default_font',
'arial',
'arial_black',
'comic_sans',
'courier_new',
'impact',
'lucida_grande',
'times_new_roman',
'verdana'
]
},
'removeFormat'
],
['quote', 'unordered', 'ordered', 'outdent', 'indent'],
['undo', 'redo', 'viewsource'],
])
watch(() => props.value, (newval, oldval) => {
if (props.value === undefined)
myvalue.value = ''
else
myvalue.value = props.value
})
function getTextLength(html: string) {
// Crea un elemento temporaneo per convertire HTML in testo
const div = document.createElement('div');
div.innerHTML = html; // Imposta l'HTML
return div.innerText.length; // Restituisce la lunghezza del testo
}
function changeval(newval: any) {
// console.log('myEditor: changeval', newval)
characterCount.value = getTextLength(newval)
emit('update:value', newval)
}
function annulla() {
emit('annulla', true)
}
function saveval() {
// Converti i <b> in <strong>
myvalue.value = tools.convertiTagHTMLPerBOT(myvalue.value)
console.log('saveval', myvalue.value)
emit('showandsave', myvalue.value)
// emit('update:value', myvalue)
}
function setcolor() {
document.execCommand('foreColor', false, mycolor.value)
}
/**
* Capture the <CTL-V> paste event, only allow plain-text, no images.
*
* see: https://stackoverflow.com/a/28213320
*
* @param {object} evt - array of files
* @author Daniel Thompson-Yvetot
* @license MIT
*/
function pasteCapture(evt: any) {
// let text, onPasteStripFormattingIEPaste
// evt.preventDefault()
// if (evt.originalEvent && evt.originalEvent.clipboardData.getData) {
// text = evt.originalEvent.clipboardData.getData('text/plain')
// $refs.editor_ref.runCmd('insertText', text)
// }
// else if (evt.clipboardData && evt.clipboardData.getData) {
// text = evt.clipboardData.getData('text/plain')
// $refs.editor_ref.runCmd('insertText', text)
// }
// else if (window.clipboardData && window.clipboardData.getData) {
// if (!onPasteStripFormattingIEPaste) {
// onPasteStripFormattingIEPaste = true
// $refs.editor_ref.runCmd('ms-pasteTextOnly', text)
// }
// onPasteStripFormattingIEPaste = false
// }
}
function mounted() {
if (props.value === undefined)
myvalue.value = ''
else
myvalue.value = props.value
showtools.value = tools.getCookie('showtools', '0') === '1'
characterCount.value = getTextLength(myvalue.value)
}
function onPaste(evt: any) {
// Let inputs do their thing, so we don't break pasting of links.
if (evt.target.nodeName === 'INPUT') return
let text, onPasteStripFormattingIEPaste
evt.preventDefault()
evt.stopPropagation()
if (evt.originalEvent && evt.originalEvent.clipboardData.getData) {
text = evt.originalEvent.clipboardData.getData('text/plain')
editorRef.value.runCmd('insertText', text)
}
else if (evt.clipboardData && evt.clipboardData.getData) {
text = evt.clipboardData.getData('text/plain')
editorRef.value.runCmd('insertText', text)
}
/*else if (ClipboardEvent.clipboardData && ClipboardEvent.clipboardData.getData) {
if (!onPasteStripFormattingIEPaste) {
onPasteStripFormattingIEPaste = true
editorRef.value.runCmd('ms-pasteTextOnly', text)
}
onPasteStripFormattingIEPaste = false
}*/
}
const copyToClipboard = (text) => {
navigator.clipboard.writeText(text)
.then(() => {
$q.notify({
message: 'Testo copiato negli appunti!',
color: 'positive',
icon: 'check',
position: 'top'
});
})
.catch(err => {
console.error('Errore durante la copia:', err);
$q.notify({
message: 'Errore nella copia',
color: 'negative',
icon: 'error',
position: 'top'
});
});
};
onMounted(mounted)
return {
myfonts,
toolbarcomp,
editor,
myvalue,
mycolor,
changeval,
annulla,
saveval,
setcolor,
pasteCapture,
tools,
onPaste,
editorRef,
showtools,
characterCount,
copyToClipboard,
}
}
})

View File

@@ -0,0 +1,86 @@
<template>
<div>
<q-card class="dialog_card">
<q-toolbar
v-if="showButtons"
class="bg-primary text-white"
style="min-height: 30px"
>
<q-toolbar-title> Editor </q-toolbar-title>
<q-btn
flat
round
color="white"
icon="close"
v-close-popup
></q-btn>
</q-toolbar>
<q-card-section class="inset-shadow" style="padding: 4px !important">
<CTitleBanner v-if="title" :title="title"></CTitleBanner>
<form autocapitalize="off" autocomplete="off" spellcheck="false">
<q-toggle
v-if="!hideTools"
v-model="showtools"
:label="showtools ? $t('editor.hidetool') : $t('editor.showtool')"
@click="tools.setCookie('showtools', showtools ? '1' : '0')"
></q-toggle>
<br />
<q-btn v-if="showtools && !hideTools" rounded size="sm" color="primary">
<q-icon name="colorize" class="cursor-pointer">
<q-popup-proxy>
<q-color v-model="mycolor" @change="setcolor"></q-color>
</q-popup-proxy>
</q-icon>
</q-btn>
<q-editor
ref="editorRef"
content-class="wrap_anywhere"
toolbar-text-color="white"
toolbar-toggle-color="yellow-8"
toolbar-bg="primary"
:readonly="!canModify"
:toolbar="showtools && !hideTools ? toolbarcomp : []"
:fonts="myfonts"
@update:model-value="changeval"
@paste="onPaste"
@keyup.esc.stop="visueditor = false"
@keyup.enter.stop
v-model="myvalue"
>
</q-editor>
<div v-if="maxlength" class="text-gray text-italic">Caratteri: {{ characterCount }} / {{ maxlength }}</div>
</form>
</q-card-section>
<q-card-actions v-if="showButtons" align="center">
<q-btn
v-if="canModify"
:label="$t('dialog.save')"
color="primary"
@click="saveval"
></q-btn>
<q-btn
v-if="canModify"
flat
:label="$t('dialog.close')"
color="primary"
v-close-popup
@click="annulla"
></q-btn>
<q-btn
v-if="!canModify"
:label="$t('dialog.ok')"
color="primary"
v-close-popup
></q-btn>
</q-card-actions>
</q-card>
</div>
</template>
<script lang="ts" src="./CMyEditorAI.ts">
</script>
<style lang="scss" scoped>
@import './CMyEditorAI.scss';
</style>

View File

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