Chamilo is a learning management system focused on ease of use and accessibility
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
chamilo-lms/assets/vue/components/basecomponents/BaseTinyEditor.vue

161 lines
4.5 KiB

<template>
<div class="base-tiny-editor">
<label v-if="title" :for="editorId">{{ title }}</label>
<TinyEditor
:id="editorId"
:model-value="modelValue"
:init="editorConfig"
:required="required"
@update:model-value="updateValue"
@input="updateValue"
/>
<p v-if="helpText" class="help-text">{{ helpText }}</p>
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue'
import TinyEditor from '@tinymce/tinymce-vue'
import { useRoute, useRouter } from "vue-router"
import { useCidReqStore } from "../../store/cidReq"
import { storeToRefs } from "pinia"
import { useStore } from "vuex"
const props = defineProps({
editorId: String,
modelValue: String,
required: Boolean,
editorConfig: Object,
title: String,
helpText: String,
mode: { type: String, default: 'personal_files' },
useFileManager: { type: Boolean, default: false }
})
const emit = defineEmits(['update:modelValue'])
const router = useRouter()
const route = useRoute()
const parentResourceNodeId = ref(0)
const store = useStore()
const user = computed(() => store.getters["security/getUser"])
// Set the parent node ID based on the user's resource node ID or route parameter
parentResourceNodeId.value = user.value.resourceNode["id"]
if (route.params.node) {
parentResourceNodeId.value = Number(route.params.node)
}
const updateValue = (value) => {
emit('update:modelValue', value)
}
const defaultEditorConfig = {
skin_url: '/build/libs/tinymce/skins/ui/oxide',
content_css: '/build/libs/tinymce/skins/content/default/content.css',
branding: false,
relative_urls: false,
height: 280,
toolbar_mode: 'sliding',
autosave_ask_before_unload: true,
plugins: [
'advlist autolink lists link image charmap print preview anchor',
'searchreplace visualblocks code fullscreen',
'insertdatetime media table paste wordcount emoticons',
],
toolbar: 'undo redo | bold italic underline strikethrough | ...',
file_picker_callback: filePickerCallback
}
const editorConfig = computed(() => ({
...defaultEditorConfig,
...props.editorConfig
}))
function filePickerCallback(callback, value, meta) {
if (!props.useFileManager) {
const input = document.createElement('input');
input.setAttribute('type', 'file');
input.style.display = 'none';
input.onchange = () => {
const file = input.files[0];
const title = file.name;
const comment = '';
const fileType = 'file';
const resourceLinkList = [];
const formData = new FormData();
formData.append('uploadFile', file);
formData.append('title', title);
formData.append('comment', comment);
formData.append('parentResourceNodeId', parentResourceNodeId.value);
formData.append('filetype', fileType);
formData.append('resourceLinkList', resourceLinkList);
fetch('/file-manager/upload-image', {
method: 'POST',
body: formData,
})
.then(response => response.json())
.then(data => {
if (data.location) {
callback(data.location);
} else {
console.error('Failed to upload file');
}
})
.catch(error => console.error('Error uploading file:', error))
.finally(() => document.body.removeChild(input));
};
document.body.appendChild(input);
input.click();
return
}
let url;
if (props.mode === 'personal_files') {
url = '/resources/filemanager/personal_list/1477'
} else if (props.mode === 'documents') {
const cidReqStore = useCidReqStore();
const { course, session } = storeToRefs(cidReqStore);
let nodeId = course.value && course.value.resourceNode ? course.value.resourceNode.id : null;
if (!nodeId) {
console.error('Resource node ID is not available.');
return;
}
let folderParams = Object.entries(route.query).map(([key, value]) => `${key}=${value}`).join('&');
url = router.resolve({ name: "DocumentForHtmlEditor", params: { id: nodeId }, query: route.query }).href;
}
if (meta.filetype === 'image') {
url += "&type=images";
} else {
url += "&type=files";
}
window.addEventListener("message", function (event) {
var data = event.data;
if (data.url) {
url = data.url;
callback(url);
}
});
tinymce.activeEditor.windowManager.openUrl({
url: url,
title: "File manager",
onMessage: (api, message) => {
if (message.mceAction === 'fileSelected') {
const fileUrl = message.content;
callback(fileUrl);
api.close();
}
}
});
}
</script>