diff --git a/package-lock.json b/package-lock.json index ca988b9d61c4d61b9f30a49dbad833f969db69e9..8c3565a17c7a8945976f062b0b6eab5eec07f739 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,6 @@ "pinia": "^2.0.28", "sass": "^1.56.2", "serve-static": "^1.15.0", - "tinymce": "^6.4.2", "vue": "3.3", "vue-router": "^4.1.6", "vue-tippy": "^6.0.0", diff --git a/package.json b/package.json index af50f8230f424172e06ff5de20dc72862e7ce09a..ae5c8db6a9d118428d67be1035784861796e931b 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "pinia": "^2.0.28", "sass": "^1.56.2", "serve-static": "^1.15.0", - "tinymce": "^6.4.2", "vue": "3.3", "vue-router": "^4.1.6", "vue-tippy": "^6.0.0", diff --git a/src/features/forms/components/inputs/HtmlInput.vue b/src/features/forms/components/inputs/HtmlInput.vue index d11ec84e66c3d165a58bd8b995ced389a32b2ab1..a7a7ad5f308ccff3b46f119aafc26b125da14e3c 100644 --- a/src/features/forms/components/inputs/HtmlInput.vue +++ b/src/features/forms/components/inputs/HtmlInput.vue @@ -1,6 +1,8 @@ <script setup lang="ts"> import Editor from '@tinymce/tinymce-vue'; +import { getTinymce } from '@tinymce/tinymce-vue/lib/cjs/main/ts/TinyMCE'; import { Ref, ref, watch } from 'vue'; +import {graphService} from '@/src/shared/services'; const props = defineProps<{ label: string; @@ -17,7 +19,6 @@ const editor = ref(null); const content: Ref<string> = ref(''); function textChange() { - console.log('textChange'); emit('input', content.value); } @@ -35,8 +36,8 @@ watch( } ); -const plugins = 'bold italic underline lists align link image searchreplace visualblocks preview wordcount code fullscreen media table template help textpattern'; -const toolbar = 'undo redo | bold italic underline | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | link image | help | template | code'; +const plugins = 'image link lists template code'; +const toolbar = 'bold italic alignleft aligncenter alignright link image bullist numlist outdent indent template code'; const template = ` <details style="border: 1px solid lightgray; border-radius: 4px; padding: .5em .5em 0 .5em"> @@ -50,8 +51,26 @@ function init() { content.value = props.inputValue; } -function drop(event) { - console.log('drop', event); +async function drop(event) { + const file = event.dataTransfer.files[0]; + if (!file) return; + const url = await graphService.importFile(file.path); + const editor = getTinymce().activeEditor; + editor.setContent(editor.getContent() + `<img alt="" src="${url}"/>`); +} + +function handleFilePicker(callback) { + const input = document.createElement('input'); + input.type = 'file'; + document.body.appendChild(input); + input.click(); + input.addEventListener('change', async (e: any) => { + const fileInput = e.target as HTMLInputElement; + const file = fileInput.files[0]; + if (!file) return; + const url = await graphService.importFile(file.path); + callback(url); + }); } </script> @@ -65,16 +84,18 @@ function drop(event) { :plugins="plugins" :toolbar="toolbar" :init="{ - menubar: 'file edit view insert custom', + menubar: false, + statusbar: false, templates: [ - { title: 'title 1', content: template, description: 'this is a test template' } + { title: 'Plier/déplier', content: template, description: 'Plier/déplier avec titre et contenu' } ], - file_picker_callback:(callback, value, meta) => { - console.log('file_picker_callback', callback, value, meta); - drop(value); - } + file_picker_types: 'image', + file_picker_callback: handleFilePicker, + link_default_target: '_blank', + link_target_list: false, + paste_data_images: false }" @init="init" - @drop="drop" + @drop.stop.prevent="drop" /> </template> \ No newline at end of file diff --git a/src/features/forms/components/inputs/QuillEditor.vue b/src/features/forms/components/inputs/QuillEditor.vue deleted file mode 100644 index 35a1b8f04bdd916cd1f65c57fc359239a3c92557..0000000000000000000000000000000000000000 --- a/src/features/forms/components/inputs/QuillEditor.vue +++ /dev/null @@ -1,192 +0,0 @@ -<!-- TODO: Delete this legacy component --> - -<script setup lang="ts"> -import { QuillEditor, Quill } from '@vueup/vue-quill'; -import '@vueup/vue-quill/dist/vue-quill.snow.css'; -import ImageUploader from 'quill-image-uploader/src/quill.imageUploader'; -import { Ref, ref, watch } from 'vue'; -import { graphService } from '@/src/shared/services'; -//@ts-ignore -import htmlEditButton from 'quill-html-edit-button'; - -const props = defineProps<{ - label: string; - inputValue: string; - placeholder?: string; - insideCard?: boolean; -}>(); - -const emit = defineEmits<{ - (e: 'input', value: string): void; -}>(); - -const toolbar = [ - [ - 'bold', - 'italic', - 'underline', - { 'list': 'ordered' }, - { 'list': 'bullet' }, - { 'align': null}, - {'align': 'center'}, - {'align': 'right'}, - 'link', - 'image' - ] -]; - -const image = Quill.import('formats/image'); - -image.sanitize = function(url) { - return url; -}; - -const modules = [ - { - name: 'imageUploader', - module: ImageUploader, - options: { - upload: (file) => graphService.importFile(file.path) - }, - }, - { - name: 'htmlEditButton', - module: htmlEditButton, - option: { - debug: true, - } - } -]; - -const qlEditor = ref(null); - -const content: Ref<string> = ref(''); - - -function textChange() { - emit('input', content.value); -} - -function initQuill() { - content.value = props.inputValue; -} - -watch( - () => props.inputValue, - () => { - content.value = props.inputValue; - } -); - -</script> - -<template> - <label for="ql-editor">{{ label }}</label> - <QuillEditor - id="ql-editor" - ref="qlEditor" - v-model:content="content" - content-type="html" - theme="snow" - :class="{ 'ql-card': insideCard }" - :modules="modules" - :toolbar="toolbar" - :placeholder="placeholder" - @text-change="textChange" - @ready="initQuill" - /> -</template> - -<style lang="scss"> - -.ql { - &-toolbar { - border: none !important; - &:hover { - border-radius: 8px; - } - } - &-container { - border: 1px solid var(--border) !important; - border-radius: 4px; - background-color: var(--item-background); - margin-bottom: 1.5rem; - &:focus-within { - border: 1px solid var(--editor-blue) !important; - box-shadow: 0 1px 8px 0 var(--editor-blue-shadow); - } - } - &-editor { - min-height: 10rem; - padding: .5rem; - font-size: 1rem; - color: var(--text); - width: 24rem; - - p { - margin-bottom: .5rem; - } - } - - &-active { - background-color: transparent !important; - &:hover { - background-color: #F3F4F6 !important; - } - } - - &-formats { - button:hover { - border-radius: 4px; - background-color: #F3F4F6 !important; - } - } - - &-card { - margin-bottom: 1rem; - } -} - -.ql-active .ql-stroke { - stroke: var(--editor-blue) !important; -} - -.ql-active .ql-fill { - fill: var(--editor-blue) !important; -} - -.ql-active:hover { - background-color: var(--) !important; -} - -.ql-blank::before { - color: var(--editor-grayblue) !important; - font-style: normal !important; - left: 0.5rem !important; -} - -// Quill Edit button - -.ql-html { - &-textContainer { - background: white; - } - - &-textArea { - border: 1px solid var(--border); - } - - &-buttonOk, &-buttonCancel { - border: none; - cursor: pointer; - color: var(--text); - border-radius: 6px; - transition: box-shadow .2s ease-in-out; - padding: .5rem 1rem; - - &:hover { - box-shadow: 0 1px 8px 0 var(--shadow-outer); - } - } -} -</style>