- miglioramenti ricerca titoli e modifica del trafiletto
- miglior visualizzazione delle liste
This commit is contained in:
4
src/components/CMyEditorAI/CMyEditorAI.scss
Executable file
4
src/components/CMyEditorAI/CMyEditorAI.scss
Executable file
@@ -0,0 +1,4 @@
|
||||
.myflex{
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
275
src/components/CMyEditorAI/CMyEditorAI.ts
Executable file
275
src/components/CMyEditorAI/CMyEditorAI.ts
Executable 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,
|
||||
}
|
||||
}
|
||||
})
|
||||
86
src/components/CMyEditorAI/CMyEditorAI.vue
Executable file
86
src/components/CMyEditorAI/CMyEditorAI.vue
Executable 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>
|
||||
1
src/components/CMyEditorAI/index.ts
Executable file
1
src/components/CMyEditorAI/index.ts
Executable file
@@ -0,0 +1 @@
|
||||
export {default as CMyEditorAI} from './CMyEditorAI.vue'
|
||||
Reference in New Issue
Block a user