commit
9556f9d86f
@ -0,0 +1,154 @@ |
||||
<template> |
||||
<q-form> |
||||
<TinyEditor |
||||
id="introText" |
||||
v-model="item.introText" |
||||
required |
||||
:init="{ |
||||
skin_url: '/build/libs/tinymce/skins/ui/oxide', |
||||
content_css: '/build/libs/tinymce/skins/content/default/content.css', |
||||
branding: false, |
||||
relative_urls: false, |
||||
height: 500, |
||||
toolbar_mode: 'sliding', |
||||
file_picker_callback : browser, |
||||
autosave_ask_before_unload: true, |
||||
plugins: [ |
||||
'fullpage advlist autolink lists link image charmap print preview anchor', |
||||
'searchreplace visualblocks code fullscreen', |
||||
'insertdatetime media table paste wordcount emoticons ' + extraPlugins |
||||
], |
||||
toolbar: 'undo redo | bold italic underline strikethrough | insertfile image media template link | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | forecolor backcolor removeformat | pagebreak | charmap emoticons | fullscreen preview save print | code codesample | ltr rtl | ' + extraPlugins, |
||||
} |
||||
" |
||||
/> |
||||
<!-- For extra content--> |
||||
<slot></slot> |
||||
</q-form> |
||||
</template> |
||||
|
||||
<script> |
||||
import useVuelidate from '@vuelidate/core'; |
||||
import { required } from '@vuelidate/validators'; |
||||
import {ref} from "vue"; |
||||
import isEmpty from "lodash/isEmpty"; |
||||
|
||||
export default { |
||||
name: 'ToolIntroForm', |
||||
setup () { |
||||
const config = ref([]); |
||||
const extraPlugins = ref(''); |
||||
|
||||
if (!isEmpty(window.config)) { |
||||
config.value = window.config; |
||||
if (config.value['editor.translate_html']) { |
||||
extraPlugins.value = 'translatehtml'; |
||||
} |
||||
} |
||||
|
||||
return { v$: useVuelidate(), extraPlugins } |
||||
}, |
||||
props: { |
||||
values: { |
||||
type: Object, |
||||
required: true |
||||
}, |
||||
errors: { |
||||
type: Object, |
||||
default: () => {} |
||||
}, |
||||
initialValues: { |
||||
type: Object, |
||||
default: () => {} |
||||
}, |
||||
}, |
||||
data() { |
||||
return { |
||||
introText: null, |
||||
parentResourceNodeId: null, |
||||
resourceNode: null, |
||||
}; |
||||
}, |
||||
computed: { |
||||
item() { |
||||
return this.initialValues || this.values; |
||||
}, |
||||
violations() { |
||||
return this.errors || {}; |
||||
} |
||||
}, |
||||
methods: { |
||||
browser (callback, value, meta) { |
||||
//const route = useRoute(); |
||||
let nodeId = this.$route.params['node']; |
||||
let folderParams = this.$route.query; |
||||
let url = this.$router.resolve({ name: 'DocumentForHtmlEditor', params: { id: nodeId }, query: folderParams }) |
||||
url = url.fullPath; |
||||
console.log(url); |
||||
|
||||
if (meta.filetype === 'image') { |
||||
url = url + "&type=images"; |
||||
} else { |
||||
url = url + "&type=files"; |
||||
} |
||||
|
||||
console.log(url); |
||||
|
||||
window.addEventListener('message', function (event) { |
||||
var data = event.data; |
||||
if (data.url) { |
||||
url = data.url; |
||||
console.log(meta); // {filetype: "image", fieldname: "src"} |
||||
callback(url); |
||||
} |
||||
}); |
||||
|
||||
|
||||
tinymce.activeEditor.windowManager.openUrl({ |
||||
url: url,// use an absolute path! |
||||
title: 'file manager', |
||||
/*width: 900, |
||||
height: 450, |
||||
resizable: 'yes'*/ |
||||
}, { |
||||
oninsert: function (file, fm) { |
||||
var url, reg, info; |
||||
|
||||
// URL normalization |
||||
url = fm.convAbsUrl(file.url); |
||||
|
||||
// Make file info |
||||
info = file.name + ' (' + fm.formatSize(file.size) + ')'; |
||||
|
||||
// Provide file and text for the link dialog |
||||
if (meta.filetype === 'file') { |
||||
callback(url, {text: info, title: info}); |
||||
} |
||||
|
||||
// Provide image and alt text for the image dialog |
||||
if (meta.filetype === 'image') { |
||||
callback(url, {alt: info}); |
||||
} |
||||
|
||||
// Provide alternative source and posted for the media dialog |
||||
if (meta.filetype === 'media') { |
||||
callback(url); |
||||
} |
||||
} |
||||
}); |
||||
return false; |
||||
}, |
||||
}, |
||||
validations: { |
||||
item: { |
||||
introText: { |
||||
//required, |
||||
}, |
||||
parentResourceNodeId: { |
||||
}, |
||||
resourceNode:{ |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
@ -0,0 +1,9 @@ |
||||
<template> |
||||
<router-view></router-view> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'ToolIntroLayout' |
||||
} |
||||
</script> |
||||
@ -0,0 +1,25 @@ |
||||
export default { |
||||
path: '/resources/ctoolintro/', |
||||
meta: { requiresAuth: true, showBreadcrumb: true }, |
||||
name: 'ctoolintro', |
||||
component: () => import('../components/ctoolintro/Layout.vue'), |
||||
redirect: { name: 'ToolIntroList' }, |
||||
children: [ |
||||
{ |
||||
name: 'ToolIntroCreate', |
||||
path: 'new/:courseTool', |
||||
component: () => import('../views/ctoolintro/Create.vue') |
||||
}, |
||||
{ |
||||
name: 'ToolIntroUpdate', |
||||
//path: ':id/edit',
|
||||
path: 'edit', |
||||
component: () => import('../views/ctoolintro/Update.vue') |
||||
}, |
||||
{ |
||||
name: 'ToolIntroShow', |
||||
path: '', |
||||
component: () => import('../views/ctoolintro/Show.vue') |
||||
} |
||||
] |
||||
}; |
||||
@ -0,0 +1,3 @@ |
||||
import makeService from './api'; |
||||
|
||||
export default makeService('c_tool_intros'); |
||||
@ -0,0 +1,97 @@ |
||||
<template> |
||||
<Toolbar |
||||
:handle-submit="onSendForm" |
||||
/> |
||||
|
||||
<ToolIntroForm |
||||
ref="createForm" |
||||
:values="item" |
||||
:errors="violations" |
||||
/> |
||||
<Loading :visible="isLoading" /> |
||||
</template> |
||||
|
||||
<script> |
||||
import {mapActions, mapGetters, useStore} from 'vuex'; |
||||
import { createHelpers } from 'vuex-map-fields'; |
||||
import ToolIntroForm from '../../components/ctoolintro/Form.vue'; |
||||
import Loading from '../../components/Loading.vue'; |
||||
import Toolbar from '../../components/Toolbar.vue'; |
||||
import CreateMixin from '../../mixins/CreateMixin'; |
||||
import {computed, onMounted, reactive, ref, toRefs} from "vue"; |
||||
import useVuelidate from "@vuelidate/core"; |
||||
import {useRoute, useRouter} from "vue-router"; |
||||
import isEmpty from "lodash/isEmpty"; |
||||
import {RESOURCE_LINK_PUBLISHED} from "../../components/resource_links/visibility.js"; |
||||
import axios from 'axios' |
||||
import { ENTRYPOINT } from '../../config/entrypoint' |
||||
import useNotification from "../../components/Notification"; |
||||
import {useI18n} from "vue-i18n"; |
||||
const servicePrefix = 'ctoolintro'; |
||||
|
||||
const { mapFields } = createHelpers({ |
||||
getterType: 'ctoolintro/getField', |
||||
mutationType: 'ctoolintro/updateField' |
||||
}); |
||||
|
||||
export default { |
||||
name: 'ToolIntroCreate', |
||||
servicePrefix, |
||||
mixins: [CreateMixin], |
||||
components: { |
||||
Loading, |
||||
Toolbar, |
||||
ToolIntroForm |
||||
}, |
||||
setup() { |
||||
const users = ref([]); |
||||
const isLoadingSelect = ref(false); |
||||
const item = ref({}); |
||||
const route = useRoute(); |
||||
const router = useRouter(); |
||||
const {showNotification} = useNotification(); |
||||
const { t } = useI18n(); |
||||
|
||||
let id = route.params.id; |
||||
if (isEmpty(id)) { |
||||
id = route.query.id; |
||||
} |
||||
|
||||
let toolId = route.params.courseTool; |
||||
|
||||
// Get the current intro text. |
||||
axios.get(ENTRYPOINT + 'c_tool_intros/' + toolId).then(response => { |
||||
let data = response.data; |
||||
item.value['introText'] = data.introText; |
||||
}).catch(function (error) { |
||||
console.log(error); |
||||
}); |
||||
|
||||
item.value['parentResourceNodeId'] = Number(route.query.parentResourceNodeId); |
||||
item.value['courseTool'] = '/api/c_tools/'+toolId; |
||||
|
||||
item.value['resourceLinkList'] = [{ |
||||
sid: route.query.sid, |
||||
cid: route.query.cid, |
||||
visibility: RESOURCE_LINK_PUBLISHED, // visible by default |
||||
}]; |
||||
|
||||
function onCreated(item) { |
||||
showNotification(t('Updated')); |
||||
router.go(-1); |
||||
} |
||||
|
||||
return {v$: useVuelidate(), users, isLoadingSelect, item, onCreated}; |
||||
}, |
||||
computed: { |
||||
...mapFields(['error', 'isLoading', 'created', 'violations']), |
||||
...mapGetters({ |
||||
'isAuthenticated': 'security/isAuthenticated', |
||||
'currentUser': 'security/getUser', |
||||
}), |
||||
}, |
||||
methods: { |
||||
...mapActions('ctoolintro', ['create', 'createWithFormData']) |
||||
} |
||||
}; |
||||
</script> |
||||
@ -0,0 +1,118 @@ |
||||
<template> |
||||
<div> |
||||
<Toolbar |
||||
:handle-delete="del" |
||||
:handle-list="list" |
||||
> |
||||
<template slot="left"> |
||||
<v-toolbar-title v-if="item">{{ |
||||
`${$options.servicePrefix} ${item['@id']}` |
||||
}}</v-toolbar-title> |
||||
</template> |
||||
</Toolbar> |
||||
<br /> |
||||
<div v-if="item" class="table-course-show"> |
||||
<v-simple-table> |
||||
<template slot="default"> |
||||
<thead> |
||||
<tr> |
||||
<th>Field</th> |
||||
<th>Value</th> |
||||
<th>Field</th> |
||||
<th>Value</th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<tr> |
||||
<td><strong>{{ $t('title') }}</strong></td> |
||||
<td> |
||||
{{ item['title'] }} |
||||
</td> |
||||
|
||||
<td><strong>{{ $t('code') }}</strong></td> |
||||
<td> |
||||
{{ item['code'] }} |
||||
</td> |
||||
</tr> |
||||
|
||||
<tr> |
||||
<td><strong>{{ $t('courseLanguage') }}</strong></td> |
||||
<td> |
||||
{{ item['courseLanguage'] }} |
||||
</td> |
||||
|
||||
<td><strong>{{ $t('category') }}</strong></td> |
||||
<td> |
||||
<div v-if="item['category']"> |
||||
{{ item['category'].name }} |
||||
</div> |
||||
<div v-else> |
||||
- |
||||
</div> |
||||
|
||||
</td> |
||||
</tr> |
||||
|
||||
<tr> |
||||
<td><strong>{{ $t('visibility') }}</strong></td> |
||||
<td> |
||||
{{ $n(item['visibility']) }} </td> |
||||
|
||||
<td><strong>{{ $t('departmentName') }}</strong></td> |
||||
<td> |
||||
{{ item['departmentName'] }} |
||||
</td> |
||||
</tr> |
||||
|
||||
<tr> |
||||
<td><strong>{{ $t('departmentUrl') }}</strong></td> |
||||
<td> |
||||
{{ item['departmentUrl'] }} |
||||
</td> |
||||
|
||||
<td><strong>{{ $t('expirationDate') }}</strong></td> |
||||
<td> |
||||
{{ formatDateTime(item['expirationDate'], 'long') }} </td> |
||||
</tr> |
||||
|
||||
</tbody> |
||||
</template> |
||||
</v-simple-table> |
||||
</div> |
||||
<Loading :visible="isLoading" /> |
||||
|
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { mapActions, mapGetters } from 'vuex'; |
||||
import { mapFields } from 'vuex-map-fields'; |
||||
import Loading from '../../components/Loading.vue'; |
||||
import ShowMixin from '../../mixins/ShowMixin'; |
||||
import Toolbar from '../../components/Toolbar.vue'; |
||||
|
||||
const servicePrefix = 'ctoolintro'; |
||||
|
||||
export default { |
||||
name: 'ToolIntroShow', |
||||
servicePrefix, |
||||
components: { |
||||
Loading, |
||||
Toolbar |
||||
}, |
||||
mixins: [ShowMixin], |
||||
computed: { |
||||
...mapFields('ctoolintro', { |
||||
isLoading: 'isLoading' |
||||
}), |
||||
...mapGetters('ctoolintro', ['find']) |
||||
}, |
||||
methods: { |
||||
...mapActions('ctoolintro', { |
||||
deleteItem: 'del', |
||||
reset: 'resetShow', |
||||
retrieve: 'load' |
||||
}) |
||||
} |
||||
}; |
||||
</script> |
||||
@ -0,0 +1,76 @@ |
||||
<template> |
||||
<Toolbar |
||||
:handle-submit="onSendForm" |
||||
/> |
||||
|
||||
<ToolIntroForm |
||||
ref="updateForm" |
||||
v-if="item" |
||||
:values="item" |
||||
:errors="violations" |
||||
/> |
||||
<Loading :visible="isLoading || deleteLoading" /> |
||||
|
||||
</template> |
||||
|
||||
<script> |
||||
import { mapActions, mapGetters } from 'vuex'; |
||||
import { mapFields } from 'vuex-map-fields'; |
||||
import ToolIntroForm from '../../components/ctoolintro/Form.vue'; |
||||
import Loading from '../../components/Loading.vue'; |
||||
import Toolbar from '../../components/Toolbar.vue'; |
||||
import UpdateMixin from '../../mixins/UpdateMixin'; |
||||
import useNotification from "../../components/Notification"; |
||||
import {useI18n} from "vue-i18n"; |
||||
import {useRouter} from "vue-router"; |
||||
import {watch} from "vue"; |
||||
|
||||
const servicePrefix = 'ctoolintro'; |
||||
|
||||
export default { |
||||
name: 'ToolIntroUpdate', |
||||
servicePrefix, |
||||
mixins: [UpdateMixin], |
||||
components: { |
||||
Loading, |
||||
Toolbar, |
||||
ToolIntroForm |
||||
}, |
||||
setup() { |
||||
const {showNotification} = useNotification(); |
||||
const { t } = useI18n(); |
||||
const router = useRouter(); |
||||
|
||||
/*function updated(val) { |
||||
showNotification(t('Updated')); |
||||
router.go(-1); |
||||
}*/ |
||||
//return {updated}; |
||||
return; |
||||
}, |
||||
computed: { |
||||
...mapFields('ctoolintro', { |
||||
deleteLoading: 'isLoading', |
||||
isLoading: 'isLoading', |
||||
error: 'error', |
||||
updated: 'updated', |
||||
violations: 'violations' |
||||
}), |
||||
...mapGetters('ctoolintro', ['find']), |
||||
...mapGetters({ |
||||
'isCurrentTeacher': 'security/isCurrentTeacher', |
||||
}), |
||||
}, |
||||
methods: { |
||||
...mapActions('ctoolintro', { |
||||
createReset: 'resetCreate', |
||||
deleteItem: 'del', |
||||
delReset: 'resetDelete', |
||||
retrieve: 'load', |
||||
update: 'update', |
||||
updateWithFormData: 'updateWithFormData', |
||||
updateReset: 'resetUpdate' |
||||
}) |
||||
} |
||||
}; |
||||
</script> |
||||
@ -0,0 +1,39 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Tool; |
||||
|
||||
use Chamilo\CourseBundle\Entity\CToolIntro; |
||||
|
||||
class ToolIntro extends AbstractTool implements ToolInterface |
||||
{ |
||||
public function getName(): string |
||||
{ |
||||
return 'tool_intro'; |
||||
} |
||||
|
||||
public function getIcon(): string |
||||
{ |
||||
return 'mdi-certificate'; |
||||
} |
||||
|
||||
public function getLink(): string |
||||
{ |
||||
return '/resources/ctoolintro'; |
||||
} |
||||
|
||||
public function getCategory(): string |
||||
{ |
||||
return 'tool'; |
||||
} |
||||
|
||||
public function getResourceTypes(): ?array |
||||
{ |
||||
return [ |
||||
'tool_intro' => CToolIntro::class, |
||||
]; |
||||
} |
||||
} |
||||
Loading…
Reference in new issue