Call the SimpleUploadAdapter plugin of the decoupled CKEditor 5 in React - ckeditor5

I have tried to use the decoupled ckeditor 5 in react. It works when I did not call any plugins. I tried many ways to call the SimpleUploadAdapter plugin, but it didn't work.
This is my code base, please give me an example to call it.
import { CKEditor } from "#ckeditor/ckeditor5-react";
import DecoupledEditor from "#ckeditor/ckeditor5-build-decoupled-document";
const editorConfiguration = {
toolbar: {
items: [
'heading',
'|',
'bold', 'italic', 'link',
'|',
'alignment:left', 'alignment:center', 'alignment:right', 'alignment:justify',
'|',
'bulletedList', 'numberedList',
'|',
'indent', 'outdent',
'|',
'imageUpload', 'insertTable', 'mediaEmbed',
'|',
'undo', 'redo'
],
shouldNotGroupWhenFull: true,
},
};
function App() {
return (
<div className="App">
<CKEditor
onReady={ editor => {
editor.ui.getEditableElement().parentElement.insertBefore(
editor.ui.view.toolbar.element,
editor.ui.getEditableElement()
);
this.editor = editor;
} }
onError={ ( error, { willEditorRestart } ) => {
if ( willEditorRestart ) {
this.editor.ui.view.toolbar.element.remove();
}
} }
onChange={ ( event, editor ) => console.log( { event, editor } ) }
editor={ DecoupledEditor }
data="<p>Hello from CKEditor 5's decoupled editor!</p>"
config={editorConfiguration}
/>
</div>
);
}
export default App;
DecoupledEditor.builtinPlugins.map( plugin => plugin.pluginName ) cannot found the SimpleUploadAdapter plugin
import SimpleUploadAdapter from '#ckeditor/ckeditor5-upload/src/adapters/simpleuploadadapter'; shows Uncaught CKEditorError: ckeditor-duplicated-modules
use custom-online-builder, install it to project/ckeditor5 directory, then import to project/src/App.js
import { Editor, EditorWatchdog } from '../ckeditor5/src/ckeditor';
import { CKEditor } from "#ckeditor/ckeditor5-react";
function App() {
return (
<div className="App">
<CKEditor
...
editor={ Editor }
...
/>
</div>
);
}
Then, the console shows Error: You attempted to import ../ckeditor5/src/ckeditor which falls outside of the project src/ directory. Relative imports outside of src/ are not supported. You can either move it inside src/, or add a symlink to it from project's node_modules/.

Related

vue-i18n: language dependent view

I use vue-i18n in my application.
Now I would like to add an "About" view with a lot text and links.
I think it would be better maintainable to have several language dependent views than adding several {{ $t(...)}} in one view about.vue.
I thought about something like adding language ISO code to the view name:
.../about.en.vue
.../about.de.vue
.../about.es.vue
What would be the best way to combine and integrate with vue-i18n? Probably there is a different way?
You can use a dynamic component to achieve this:
<template>
<component :is="localizedAbout" />
</template>
<script>
import AboutEn from '../about.en.vue';
import AboutEs from '../about.es.vue';
import AboutDe from '../about.de.vue';
export default {
components: {
AboutEn,
AboutEs,
AboutDe,
},
computed: {
localizedAbout() {
switch (this.$i18n.locale) {
case 'en':
return AboutEn;
case 'es':
return AboutEs;
case 'de':
return AboutDe;
default:
return '';
}
},
},
}
</script>
After doing some other stuff, I was today able to solve this issue by using dynamic imports:
<template>
<b-container class="about">
<component :is="langComponent" />
</b-container>
</template>
<script>
export default {
name: 'AboutView',
data () {
return {
langComponent: null
}
},
mounted () {
this.$watch(
'$i18n.locale',
(newLocale, oldLocale) => {
if (newLocale === oldLocale) {
return
}
this.setLangAbout()
},
{
immediate: true
}
)
},
methods: {
setLangAbout () {
try {
import('#/components/about/About.' + this.$i18n.locale + '.vue').then(module => {
this.langComponent = module.default
})
} catch (err) {
console.log(err)
import('#/components/about/About.en.vue').then(module => {
this.langComponent = module.default
})
}
}
}
}
</script>
Thanks #Pochwar for your initial answer. Based on this I have done some more researched.
Following links helped me to solve this problem:
How does Dynamic Import in webpack works when used with an expression?
Comment at Error: Cannot find module with dynamic import

Uncaught CKEditorError: ckeditor-duplicated-modules in Vuejs3

I'm trying to install ckeditor. In console getting this error Here is my package.json file. In ckeditor5 module getting same error when I import font plugin.Now I'm trying to install all plugins manually.
<template>
<div id="app">
<ckeditor :editor="editor" v-model="editorData" :config="editorConfig"></ckeditor>
</div>
<script>
// ⚠️ NOTE: We don't use #ckeditor/ckeditor5-build-classic any more!
// Since we're building CKEditor from source, we use the source version of ClassicEditor.
// import ClassicEditor from '#ckeditor/ckeditor5-editor-classic/src/classiceditor';
import ClassicEditor from '#ckeditor/ckeditor5-editor-classic/src/classiceditor';
import EssentialsPlugin from '#ckeditor/ckeditor5-essentials/src/essentials';
import BoldPlugin from '#ckeditor/ckeditor5-basic-styles/src/bold';
import ItalicPlugin from '#ckeditor/ckeditor5-basic-styles/src/italic';
import LinkPlugin from '#ckeditor/ckeditor5-link/src/link';
import ParagraphPlugin from '#ckeditor/ckeditor5-paragraph/src/paragraph';
export default {
name: 'app',
data() {
return {
editor: ClassicEditor,
editorData: '<p>Content of the editor.</p>',
editorConfig: {
plugins: [
EssentialsPlugin,
BoldPlugin,
ItalicPlugin,
LinkPlugin,
ParagraphPlugin
],
toolbar: {
items: [
'bold',
'italic',
'link',
'undo',
'redo'
]
}
}
};
}
};

vue bootstrap toaster instantly vanishing / hiding itself

In my Vue Bootstrap (v2.21.2) Web-App i want to use Toasts to present some errors to the user. Those errors are produced by the REST-API-client. In my vb-components i catch those errors and call a function which itself uses https://bootstrap-vue.org/docs/components/toast#toasts-on-demand this.$bvToast.toast() to dynamically create and show the error-message.
As expected the toast is created but will instantly hide itself again. I tried disabling the auto-hide property and play around with the timeout which had no effect. Since i am calling this function in some sub-components i also tried calling this.$root.$bvToaster.toast() but the toasts are still only showing for some 100 microseconds or so.
The relevant (reduced) code-extracts of my project:
App.vue:
<template>
<div id="app">
<Navbar #viewChanged="view = $event;" />
<Pki v-if="view == 'pki'" />
</div>
</template>
<script>
import Navbar from "./components/Navbar.vue";
import Pki from './components/Certificates'
export default {
data() {
return {
view: null
}
},
name: "FooBar",
components: {
Navbar,
Pki
},
};
</script>
Certificates.vue:
<template>
<!-- ... -->
</template>
<script>
// ...
mounted() {
this.getCertificates();
},
methods: {
alert(title, content, variant = 'danger') {
this.$bvToast.toast(content, {
title: title,
toaster: 'b-toaster-bottom-right',
variant: variant,
solid: true,
appendToast: true,
autoHideDelay: 10000
});
},
getCertificates() {
axios.get("/v1/pki/certificates")
.then((response) => {
// ...
});
})
.catch((error) => {
this.alert('API Error', 'failed to fetch certificate list (' + error.message + ')');
console.log('getCertificates(): HTTP ERROR ' + error.response.status + ' (' + error.response.data + ')');
});
}
}
</script>
If you are using bootstrap 5 just add this css
.toast:not(.show) {
display: block;
}
I think you don't have the appropriate version of the bootstrap css.
e.g 4.5.3 bootstrap css
and after load the vue bootstrap
Had the same issue, and this solved it

Importing Node Packages in Vue without Composition API?

I've been trying for a while to learn how to use external Node Packages, but I keep getting frustrated.
I am currently trying to implement TinyMCE. I've installed the required packages and the example instructs me to do the following:
<script>
import Editor from '#tinymce/tinymce-vue'
export default {
name: 'app',
components: {
'editor': Editor
}
}
</script>
This is a pretty common pattern that I can never get to work, I'm guessing because I don't use the composition API. When I try to do something like this:
import Editor from '#tinymce/tinymce-vue'
const messageForm = workdesk.component('message-form', {
template: "#message-form",
delimiters: ["[[", "]]"],
props: ['project'],
components: {
'editor': Editor
},
data() {
return {
contacts: baseData.contacts,
proposed: {},
}
},
methods: {
}
})
it tells me Uncaught SyntaxError: Cannot use import statement outside a module
Does this mean that I need to learn Composition API to start using these external packages? Or am I doing something else wrong?
You do not need the Composition API in order to use TinyMCE. You can try something like this:
<template>
<Editor v-model="text" :init="editorConfig" />
</template>
<script>
// we must import TinyMCE locally, or tinymce-vue will try to load it from TinyCloud and complain about a missing API key
import 'tinymce/tinymce';
// Default icons are required for TinyMCE 5.3 or above
import 'tinymce/icons/default';
// A theme is also required
import 'tinymce/themes/silver';
// Any plugins you want to use has to be imported
import 'tinymce/plugins/advlist';
import 'tinymce/plugins/autolink';
import 'tinymce/plugins/lists';
import 'tinymce/plugins/link';
import 'tinymce/plugins/image';
import 'tinymce/plugins/charmap';
import 'tinymce/plugins/anchor';
import 'tinymce/plugins/searchreplace';
import 'tinymce/plugins/visualblocks';
import 'tinymce/plugins/code';
import 'tinymce/plugins/insertdatetime';
import 'tinymce/plugins/imagetools';
import 'tinymce/plugins/media';
import 'tinymce/plugins/table';
import 'tinymce/plugins/paste';
import 'tinymce/plugins/help';
import 'tinymce/plugins/wordcount';
import 'tinymce/plugins/spellchecker';
import 'tinymce/plugins/hr';
import 'tinymce/plugins/contextmenu';
import Editor from '#tinymce/tinymce-vue';
export default
{
name: 'RichEditor',
components:
{
Editor,
},
props:
{
value:
{
type: String,
default: ''
},
height:
{
type: [String, Number],
default: 400
}
},
data()
{
return {
text: this.value,
};
},
computed:
{
editorConfig()
{
return {
height: this.height,
content_css: process.env.BASE_URL + 'tinymce_skin/content/default/content.css',
skin_url: process.env.BASE_URL + 'tinymce_skin/ui/oxide',
menubar: 'file edit view insert format tools table tc help',
toolbar: 'undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist checklist | forecolor backcolor casechange formatpainter removeformat | pagebreak | charmap emoticons | insertfile image media pageembed template link anchor codesample',
quickbars_selection_toolbar: 'bold italic | quicklink h2 h3 blockquote quickimage quicktable',
toolbar_mode: 'sliding',
contextmenu: 'link image imagetools table',
plugins:
[
'advlist autolink lists link image charmap anchor',
'searchreplace visualblocks code imagetools hr',
'insertdatetime media table paste code help wordcount'
],
image_advtab: true,
};
},
},
watch:
{
text(newVal)
{
this.$emit('input', newVal);
}
}
};
</script>
and also in vue.config.js
module.exports =
{
chainWebpack: config =>
{
// TinyMCE - copy skins from node_modules/tinymce to the /public folder
config.plugins.has('copy') && config.plugin('copy')
.tap(([pathConfigs]) =>
{
//const to = pathConfigs[0].to;
pathConfigs[0].force = true; // so the original `/public` folder keeps priority
// add other locations.
pathConfigs.unshift({
context: './node_modules/tinymce/skins',
from: './**/*',
to: './tinymce_skin',
});
return [pathConfigs];
});
return config;
},
}

StencilJS Click method not getting called

while trying the example code from stenciljs doc - https://stenciljs.com/docs/templating-jsx, I'am facing one issue. The click event handler is not getting triggered at all.
import { Component, h } from '#stencil/core';
#Component({
tag: 'my-component',
shadow: true
})
export class MyComponent {
handleClick(event: UIEvent) {
alert('Received the button click!');
}
render() {
return (
<button onClick={ (event: UIEvent) => this.handleClick(event)}>Click Me!</button>
);
}
}
--index.html code--
<my-component></my-component>
You can try to use Polyfills in case that your Browser has issues with ES6 syntax e.g.
npm run build --es5