From 58ec440501ee821931706fd12dbd9331b0eaca50 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Willms Date: Mon, 8 Jul 2024 15:50:03 +0200 Subject: convert oersearch to sfc, re #4302 --- app/controllers/oer/mymaterial.php | 344 ++++++++++++--------- app/views/oer/mymaterial/edit.php | 344 --------------------- lib/classes/TwilloConnector.php | 2 +- lib/models/OERMaterial.php | 3 + resources/assets/javascripts/bootstrap/dialog.js | 15 +- resources/assets/javascripts/bootstrap/oer.js | 92 ------ resources/assets/stylesheets/scss/quicksearch.scss | 44 --- resources/vue/components/OERMaterialEditor.vue | 62 ++-- resources/vue/components/Quicksearch.vue | 46 +++ resources/vue/components/StudipLevelSlider.vue | 21 +- 10 files changed, 297 insertions(+), 676 deletions(-) delete mode 100644 app/views/oer/mymaterial/edit.php diff --git a/app/controllers/oer/mymaterial.php b/app/controllers/oer/mymaterial.php index ef45722..4cc0920 100644 --- a/app/controllers/oer/mymaterial.php +++ b/app/controllers/oer/mymaterial.php @@ -9,8 +9,7 @@ class Oer_MymaterialController extends AuthenticatedController parent::before_filter($action, $args); if ( !Config::get()->OERCAMPUS_ENABLED - || - !$GLOBALS['perm']->have_perm(Config::get()->OER_PUBLIC_STATUS) + || !$GLOBALS['perm']->have_perm(Config::get()->OER_PUBLIC_STATUS) ) { throw new AccessDeniedException(); } @@ -28,176 +27,199 @@ class Oer_MymaterialController extends AuthenticatedController public function edit_action(OERMaterial $material = null) { + $this->validateMaterial($material); + PageLayout::setTitle($material->isNew() ? _('Neues Material hochladen') : _('Material bearbeiten')); - if ($material->id && !$material->isMine() && !$GLOBALS['perm']->have_perm('root')) { - throw new AccessDeniedException(); - } + + $tagsearch = new SQLSearch( + "SELECT oer_tags.name, oer_tags.name + FROM oer_tags + WHERE name LIKE :input + ORDER BY oer_tags.name", + _('Thema suchen') + ); + + $this->render_vue_app( + Studip\VueApp::create('OERMaterialEditor') + ->withProps([ + 'store-url' => $this->storeURL($material), + 'material' => [ + ...$material->toArray(), + + 'filesize' => $material->getFilePath() && file_exists($material->getFilePath()) ? filesize($material->getFilePath()) : null, + 'logoUrl' => $material->getLogoURL(), + 'tags' => array_column($material->getTopics(), 'name'), + 'users' => $material->users->map(function (OERMaterialUser $user) { + if ($user->external_contact) { + return [ + 'id' => $user->oeruser->id, + 'name' => $user->oeruser->name, + 'avatar' => $user->oeruser->avatar_url, + 'external' => true, + ]; + } + + $u = User::find($user->user_id); + return [ + 'id' => $u->user_id, + 'avatar' => Avatar::getAvatar($u->id)->getURL(Avatar::SMALL), + 'name' => $u ? $u->getFullName() : _('unbekannt'), + 'external' => false, + ]; + }), + ], + 'template' => $_SESSION['NEW_OER'] ?? null, + 'tag-search' => (string) $tagsearch, + 'licenses-enabled' => !Config::get()->getValue('OER_DISABLE_LICENSE'), + 'licenses' => License::findAndMapBySQL( + function (License $license) { + return [ + 'id' => $license->id, + 'name' => $license->name, + ]; + }, + '1 ORDER BY name' + ), + 'enable-twillo' => $this->isTwilloEnabled(), + ]) + ); + + } + + public function store_action(OERMaterial $material = null) + { + $material = $this->validateMaterial($material); + + CSRFProtection::verifyUnsafeRequest(); + $content_types = ['application/x-zip-compressed', 'application/zip', 'application/x-zip']; $tmp_folder = $GLOBALS['TMP_PATH'] . '/temp_folder_' . md5(uniqid()); - if (Request::submitted('delete') && Request::isPost()) { - CSRFProtection::verifyUnsafeRequest(); - $material->pushDataToIndexServers('delete'); - $material->delete(); - PageLayout::postSuccess(_('Das Material wurde gelöscht.')); - $this->redirect('oer/market/index'); - return; - } elseif (Request::isPost()) { - CSRFProtection::verifyUnsafeRequest(); - $was_new = $material->isNew(); - $was_on_twillo = (bool) $material['published_id_on_twillo']; - $data = Request::getArray('data'); - $material->setData($data); - if ($data['player_url'] && !$material->hasValidPreviewUrl()) { - PageLayout::postWarning(_('Die angegebene URL muss mit http(s) beginnen.')); - $material->player_url = ''; + + $was_new = $material->isNew(); + $was_on_twillo = (bool) $material->published_id_on_twillo; + $data = Request::getArray('data'); + $material->setData($data); + if ($data['player_url'] && !$material->hasValidPreviewUrl()) { + PageLayout::postWarning(_('Die angegebene URL muss mit http(s) beginnen.')); + $material->player_url = ''; + } + $material->host_id = null; + if (!empty($_FILES['file']['tmp_name'])) { + $material->content_type = get_mime_type($_FILES['file']['name']); + if (in_array($material->content_type, $content_types)) { + mkdir($tmp_folder); + \Studip\ZipArchive::extractToPath($_FILES['file']['tmp_name'], $tmp_folder); + $material->structure = $this->getFolderStructure($tmp_folder); + rmdirr($tmp_folder); + } else { + $material->structure = null; } - $material['host_id'] = null; - $material['license_identifier'] = Request::get('license', 'CC-BY-SA-4.0'); - if (!empty($_FILES['file']['tmp_name'])) { - $material['content_type'] = get_mime_type($_FILES['file']['name']); - if (in_array($material['content_type'], $content_types)) { - mkdir($tmp_folder); - \Studip\ZipArchive::extractToPath($_FILES['file']['tmp_name'], $tmp_folder); - $material['structure'] = $this->getFolderStructure($tmp_folder); - rmdirr($tmp_folder); - } else { - $material['structure'] = null; - } - $material['filename'] = $_FILES['file']['name']; - move_uploaded_file($_FILES['file']['tmp_name'], $material->getFilePath()); - } elseif (!empty($_SESSION['NEW_OER']['tmp_name'])) { - $material['content_type'] = $_SESSION['NEW_OER']['content_type'] ?: get_mime_type($_SESSION['NEW_OER']['tmp_name']); - if (in_array($material['content_type'], $content_types)) { - mkdir($tmp_folder); - \Studip\ZipArchive::extractToPath($_SESSION['NEW_OER']['tmp_name'], $tmp_folder); - $material['structure'] = $this->getFolderStructure($tmp_folder); - rmdirr($tmp_folder); - } else { - $material['structure'] = null; - } - $material['filename'] = $_SESSION['NEW_OER']['filename']; - copy($_SESSION['NEW_OER']['tmp_name'], $material->getFilePath()); + $material->filename = $_FILES['file']['name']; + move_uploaded_file($_FILES['file']['tmp_name'], $material->getFilePath()); + } elseif (!empty($_SESSION['NEW_OER']['tmp_name'])) { + $material->content_type = $_SESSION['NEW_OER']['content_type'] ?: get_mime_type($_SESSION['NEW_OER']['tmp_name']); + if (in_array($material->content_type, $content_types)) { + mkdir($tmp_folder); + \Studip\ZipArchive::extractToPath($_SESSION['NEW_OER']['tmp_name'], $tmp_folder); + $material->structure = $this->getFolderStructure($tmp_folder); + rmdirr($tmp_folder); + } else { + $material->structure = null; } + $material->filename = $_SESSION['NEW_OER']['filename']; + copy($_SESSION['NEW_OER']['tmp_name'], $material->getFilePath()); + } - if (!empty($_FILES['image']['tmp_name']) && is_array(getimagesize($_FILES['image']['tmp_name']))) { - $material['front_image_content_type'] = get_mime_type($_FILES['image']['name']); - move_uploaded_file($_FILES['image']['tmp_name'], $material->getFrontImageFilePath()); - } elseif (!empty($_SESSION['NEW_OER']['image_tmp_name'])) { - $material['front_image_content_type'] = get_mime_type($_SESSION['NEW_OER']['image_tmp_name']); - copy($_SESSION['NEW_OER']['image_tmp_name'], $material->getFrontImageFilePath()); - } - if (Request::get('delete_front_image')) { - $material['front_image_content_type'] = null; - } - if ($material->isNew() && $material['category'] === 'auto') { - $material['category'] = $material->autoDetectCategory(); - } - $material->store(); - - if ($was_new) { - OERMaterialUser::create( - [ - 'material_id' => $material->getId(), - 'user_id' => $GLOBALS['user']->id, - 'external_contact' => 0, - 'position' => 1 - ] - ); - $material->notifyFollowersAboutNewMaterial(); - } - $removed_users = Request::getArray('remove_users'); - if (!empty($removed_users)) { - foreach (Request::getArray('remove_users') as $index => $user) { - if (!$index && count($removed_users) === count($material->users)) { - continue; - } - [$external, $user_id] = array_map('trim', explode('_', $user)); - OERMaterialUser::deleteBySQL( - 'user_id = ? AND material_id = ? AND external_contact = ?', - [$user_id, $material->getId(), $external] - ); - } - } - if (Request::get('new_user')) { - [$external, $user_id] = array_map('trim', explode('_', Request::get('new_user'))); - - OERMaterialUser::create( - [ - 'material_id' => $material->getId(), - 'user_id' => $user_id, - 'external_contact' => $external, - 'position' => count($material->users) + 1 - ] - ); - } + if ( + !empty($_FILES['image']['tmp_name']) + && getimagesize($_FILES['image']['tmp_name']) !== false + ) { + $material->front_image_content_type = get_mime_type($_FILES['image']['name']); + move_uploaded_file($_FILES['image']['tmp_name'], $material->getFrontImageFilePath()); + } elseif (!empty($_SESSION['NEW_OER']['image_tmp_name'])) { + $material->front_image_content_type = get_mime_type($_SESSION['NEW_OER']['image_tmp_name']); + copy($_SESSION['NEW_OER']['image_tmp_name'], $material->getFrontImageFilePath()); + } + if (Request::get('delete_front_image')) { + $material->front_image_content_type = null; + } + if ($material->isNew() && $material->category === 'auto') { + $material->category = $material->autoDetectCategory(); + } + $material->store(); - //Topics: - $tags = Request::getArray('tags'); - if (!empty($tags)) { - foreach ($tags as $key => $tag) { - if (!trim($tag)) { - unset($tags[$key]); - } - } - } - $material->setTopics($tags); - - $material->pushDataToIndexServers(); - - if (Config::get()->OERCAMPUS_ENABLE_TWILLO && TwilloConnector::getTwilloUserID()) { - if (Request::bool('publish_on_twillo') || $_SESSION['NEW_OER']['publish_on_twillo']) { - //upload it to twillo.de - $succes_or_error = $material->uploadToTwillo($material); - if (is_string($succes_or_error)) { - PageLayout::postWarning(_('Konnte Material nicht zu twillo.de hochladen.'), [$succes_or_error]); - } - } elseif ($was_on_twillo) { - //remove it from twillo.de if able - $material->deleteFromTwillo(); - } + if ($was_new) { + OERMaterialUser::create([ + 'material_id' => $material->id, + 'user_id' => User::findCurrent()->id, + 'external_contact' => false, + 'position' => 1, + ]); + $material->notifyFollowersAboutNewMaterial(); + } + $removed_users = Request::getArray('remove_users'); + foreach (Request::getArray('remove_users') as $index => $user) { + if (!$index && count($removed_users) === count($material->users)) { + continue; } + [$external, $user_id] = array_map('trim', explode('_', $user)); + OERMaterialUser::deleteBySQL( + 'user_id = ? AND material_id = ? AND external_contact = ?', + [$user_id, $material->getId(), $external] + ); + } - unset($_SESSION['NEW_OER']); - PageLayout::postSuccess(_('Lernmaterial erfolgreich gespeichert.')); + //Topics: + $tags = Request::getArray('tags'); + $material->setTopics($tags); - if (Request::get('redirect_url')) { - if (Request::get('redirect_url') === 'files') { - $this->redirect( - URLHelper::getURL( - 'dispatch.php/course/files/index/' . Request::get('dir'), - ['cid' => Request::get('cid')] - ) + $material->pushDataToIndexServers(); + + if ($this->isTwilloEnabled()) { + if ( + Request::bool('publish_on_twillo') + || !empty($_SESSION['NEW_OER']['publish_on_twillo']) + ) { + //upload it to twillo.de + $succes_or_error = $material->uploadToTwillo(); + if (is_string($succes_or_error)) { + PageLayout::postWarning( + _('Konnte Material nicht zu twillo.de hochladen.'), + [htmlReady($succes_or_error)] ); - } else { - $this->redirect(URLHelper::getURL(Request::get('redirect_url'), [ - 'material_id' => $material->getId(), - 'url' => $this->url_for('oer/market/details/' . $material->id) - ])); } - } else { - $this->redirect('oer/market/details/' . $material->id); + } elseif ($was_on_twillo) { + //remove it from twillo.de if able + $material->deleteFromTwillo(); } + } + unset($_SESSION['NEW_OER']); + PageLayout::postSuccess(_('Lernmaterial erfolgreich gespeichert.')); + $redirect_url = Request::get('redirect_url'); + if (!$redirect_url) { + $this->redirect('oer/market/details/' . $material->id); + } elseif ($redirect_url === 'files') { + $this->redirect( + URLHelper::getURL( + 'dispatch.php/course/files/index/' . Request::get('dir'), + ['cid' => Request::get('cid')] + ) + ); + } else { + $this->redirect(URLHelper::getURL($redirect_url, [ + 'material_id' => $material->id, + 'url' => $this->url_for('oer/market/details/' . $material->id) + ])); } - if (isset($_SESSION['NEW_OER'])) { - $this->template = $_SESSION['NEW_OER']; - } - - $this->tagsearch = new SQLSearch(" - SELECT oer_tags.name, oer_tags.name - FROM oer_tags - WHERE name LIKE :input - ORDER BY oer_tags.name - ", _("Thema suchen")); } public function delete_action(OERMaterial $material) { - if ($material->id && !$material->isMine() && !$GLOBALS['perm']->have_perm('root')) { - throw new AccessDeniedException(); - } + $material = $this->validateMaterial($material); + if (Request::isPost()) { $material->pushDataToIndexServers('delete'); $material->delete(); @@ -211,13 +233,12 @@ class Oer_MymaterialController extends AuthenticatedController public function statistics_action(OERMaterial $material) { + $material = $this->validateMaterial($material); + PageLayout::setTitle(sprintf( _('Zugriffszahlen für %s'), $material->name )); - if (!$GLOBALS['perm']->have_perm('root') && !$material->isMine()) { - throw new AccessDeniedException(); - } if (Request::get("export")) { $this->counter = OERDownloadcounter::findBySQL( 'material_id = ? ORDER BY mkdate DESC', @@ -299,4 +320,19 @@ class Oer_MymaterialController extends AuthenticatedController Sidebar::Get()->addWidget($actions); } + + private function isTwilloEnabled(): bool + { + return Config::get()->getValue('OERCAMPUS_ENABLE_TWILLO') + && TwilloConnector::getTwilloUserID(); + } + + private function validateMaterial(OERMaterial $material): OERMaterial + { + if (!$material->isNew() && !$material->isMine() && !$GLOBALS['perm']->have_perm('root')) { + throw new AccessDeniedException(); + } + + return $material; + } } diff --git a/app/views/oer/mymaterial/edit.php b/app/views/oer/mymaterial/edit.php deleted file mode 100644 index 1838b75..0000000 --- a/app/views/oer/mymaterial/edit.php +++ /dev/null @@ -1,344 +0,0 @@ - - - -withProps([ - 'store-url' => $controller->edit($material), - 'material' => [ - ...$material->toArray(), - - 'filesize' => $material->getFilePath() && file_exists($material->getFilePath()) ? filesize($material->getFilePath()) : null, - 'logoUrl' => $material->getLogoURL(), - 'tags' => array_map( - fn($tag) => $tag['name'], - $material->getTopics() - ), - 'users' => $material->users->map(function (OERMaterialUser $user) { - if ($user->external_contact) { - return [ - 'id' => $user->oeruser->id, - 'name' => $user->oeruser->name, - 'avatar' => $user->oeruser->avatar_url, - 'external' => true, - ]; - } - - $u = User::find($user->user_id); - return [ - 'id' => $u->user_id, - 'avatar' => Avatar::getAvatar($u->id)->getURL(Avatar::SMALL), - 'name' => $u ? $u->getFullName() : _('unbekannt'), - 'external' => false, - ]; - }), - ], - 'template' => $template ?? null, - 'tag-search' => (string) $tagsearch, - 'licenses-enabled' => !Config::get()->getValue('OER_DISABLE_LICENSE'), - 'licenses' => License::findAndMapBySQL( - function (License $license) { - return [ - 'id' => $license->id, - 'name' => $license->name, - ]; - }, - '1 ORDER BY name' - ), - 'enable-twillo' => Config::get()->getValue('OERCAMPUS_ENABLE_TWILLO') && TwilloConnector::getTwilloUserID(), - ]) ?> - -
- -
-
- - - - - -
- -
- -
- - -
- - - - - -
- -
- - - - - - - - - - - - - - - - - isNew()) : ?> -
-

-
    "> - users as $materialuser) : ?> -
  • - - - - - - - getURL(Avatar::SMALL) ?> - - -
  • - -
  • - -
  • -
-
- - - -
- - getTopics() as $tag) { - $tags[] = $tag['name']; - } - if (!empty($template['tags'])) { - foreach ((array)$template['tags'] as $tag) { - $tags[] = $tag; - } - } - ?> - - - - - - -
- -
- - - - - -
-
-
-
-
- -
- -
-
-
- - - - - - OERCAMPUS_ENABLE_TWILLO && TwilloConnector::getTwilloUserID()) : ?> - - - -
- - OER_DISABLE_LICENSE) : ?> - isNew() - ? License::findDefault() - : $material->license; - ?> -
- - - -
- -
-
- - - - - -
- -
- isNew() ? _('Hochladen') : _('Speichern'), "save") ?> -
-
diff --git a/lib/classes/TwilloConnector.php b/lib/classes/TwilloConnector.php index 40ceff8..e7dd8b4 100644 --- a/lib/classes/TwilloConnector.php +++ b/lib/classes/TwilloConnector.php @@ -49,7 +49,7 @@ class TwilloConnector */ public static function uploadMaterial(OERMaterial $material, $user_id = null) { - $user_id || $user_id = User::findCurrent()->id; + $user_id = $user_id ?? User::findCurrent()->id; $base = new \EduSharingApiClient\EduSharingHelperBase( self::$twillo_base_url, file_get_contents($GLOBALS['STUDIP_BASE_PATH']."/config/twillo-private.key"), diff --git a/lib/models/OERMaterial.php b/lib/models/OERMaterial.php index 224c860..2048457 100644 --- a/lib/models/OERMaterial.php +++ b/lib/models/OERMaterial.php @@ -257,6 +257,9 @@ class OERMaterial extends SimpleORMap public function setTopics($tags) { + $tags = array_map('trim', $tags); + $tags = array_filter($tags); + $statement = DBManager::get()->prepare(" DELETE FROM oer_tags_material WHERE material_id = :material_id diff --git a/resources/assets/javascripts/bootstrap/dialog.js b/resources/assets/javascripts/bootstrap/dialog.js index 58d01fd..58857cb 100644 --- a/resources/assets/javascripts/bootstrap/dialog.js +++ b/resources/assets/javascripts/bootstrap/dialog.js @@ -2,7 +2,14 @@ STUDIP.domReady(function () { STUDIP.Dialog.initialize(); }); -$(document).on('click', '[data-vue-app] [data-dialog-button] .cancel.button', () => { - STUDIP.Dialog.close(); - return false; -}); +document.addEventListener( + 'click', + (event) => { + if (event.target.matches('.studip-dialog [data-vue-app] [data-dialog-button] .cancel.button')) { + STUDIP.Dialog.close(); + event.preventDefault(); + event.stopPropagation(); + } + }, + true +); diff --git a/resources/assets/javascripts/bootstrap/oer.js b/resources/assets/javascripts/bootstrap/oer.js index 3adecbc..ed472b5 100644 --- a/resources/assets/javascripts/bootstrap/oer.js +++ b/resources/assets/javascripts/bootstrap/oer.js @@ -47,95 +47,3 @@ STUDIP.domReady(() => { }); }); - -STUDIP.ready(() => { - if ($('.oercampus_editmaterial').length) { - - STUDIP.Vue.load().then(({createApp}) => { - STUDIP.OER.EditApp = createApp({ - el: '.oercampus_editmaterial', - data() { - return { - name: $('.oercampus_editmaterial input.oername').val(), - logo_url: $('.oercampus_editmaterial .logo_file').data("oldurl"), - customlogo: $('.oercampus_editmaterial .logo_file').data("customlogo"), - filename: $('.oercampus_editmaterial .file.drag-and-drop').data("filename"), - filesize: $('.oercampus_editmaterial .file.drag-and-drop').data("filesize"), - tags: $('.oercampus_editmaterial .oer_tags').data("defaulttags"), - minimumTags: 5 - }; - }, - mounted: function () { - jQuery("#difficulty_slider_edit").slider({ - range: true, - min: 1, - max: 12, - values: [jQuery("#difficulty_start").val(), jQuery("#difficulty_end").val()], - change: function (event, ui) { - jQuery("#difficulty_start").val(ui.values[0]); - jQuery("#difficulty_end").val(ui.values[1]); - } - }); - jQuery('.oercampus_editmaterial').find(':focusable').first().focus(); - }, - methods: { - editName: function () { - this.name = $('.oername').val(); - }, - editImage: function (event) { - let reader = new FileReader(); - let vue = this; - reader.addEventListener("load", function () { - vue.logo_url = reader.result; - vue.customlogo = true; - }, false); - reader.readAsDataURL( - event.target.files.length > 0 - ? event.target.files[0] - : event.dataTransfer.files[0] - ); - }, - dropImage: function (event) { - window.document.getElementById("oer_logo_uploader").files = event.dataTransfer.files; - this.editImage(event); - }, - editFile: function (event) { - this.filename = event.target.files[0].name; - this.filesize = event.target.files[0].size; - if (!this.name) { - this.name = this.filename; - $('.oername').val(this.name); - } - }, - dropFile: function (event) { - window.document.getElementById("oer_file").files = event.dataTransfer.files; - this.editFile(event); - }, - addTag: function () { - if (this.minimumTags < this.tags.length) { - this.minimumTags = this.tags.length + 1; - } else { - this.minimumTags++; - } - }, - removeTag: function (i) { - this.$delete(this.tags, i); - if ((this.minimumTags > this.tags.length) && (this.minimumTags > 5)) { - this.minimumTags--; - } - } - }, - computed: { - displayTags () { - const result = this.tags.concat([]); - while (result.length < this.minimumTags) { - result.push(''); - } - return result; - } - }, - components: { Quicksearch } - }); - }); - } -}); diff --git a/resources/assets/stylesheets/scss/quicksearch.scss b/resources/assets/stylesheets/scss/quicksearch.scss index ef6c372..6687450 100644 --- a/resources/assets/stylesheets/scss/quicksearch.scss +++ b/resources/assets/stylesheets/scss/quicksearch.scss @@ -89,47 +89,3 @@ div.quicksearch_frame { background-position: center center; } } - -.quicksearch_container { - display: inline-flex; - flex-direction: row-reverse; - width: 100%; - - .dropdownmenu { - max-width: 0; - max-height: 0; - overflow: visible; - position: relative; - top: 31px; - z-index: 99999; - - .autocomplete__results { - list-style-type: none; - padding: 1px; - border: 1px solid var(--light-gray-color-40); - background-color: var(--white); - max-height: 275px; - width: 600px; - overflow-x: auto; - overflow-y: hidden; - - > li { - padding: 5px; - cursor: pointer; - display: flex; - align-items: flex-start; - - &:hover, &.autocomplete__result--selected { - background-color: var(--base-color); - color: var(--white); - } - - img { - max-width: 40px; - max-height: 40px; - margin-right: 5px; - } - } - } - } -} diff --git a/resources/vue/components/OERMaterialEditor.vue b/resources/vue/components/OERMaterialEditor.vue index 88b9232..1ad1f86 100644 --- a/resources/vue/components/OERMaterialEditor.vue +++ b/resources/vue/components/OERMaterialEditor.vue @@ -6,7 +6,7 @@ data-secure enctype="multipart/form-data" > - +

{{ $gettext('Themen (am besten mindestens 5)') }}

@@ -196,9 +196,12 @@ @@ -206,10 +209,25 @@ import Quicksearch from "./Quicksearch.vue"; import StudipIcon from "./StudipIcon.vue"; import StudipLevelSlider from "./StudipLevelSlider.vue"; +import Vue from "vue"; + +let mounted = false; export default { name: "OERMaterialEditor", components: {StudipLevelSlider, StudipIcon, Quicksearch }, + directives: { + ['focus-on-create']: { + bind(el) { + if (mounted) { + Vue.nextTick(() => el.querySelector('input')?.focus()); + } + } + } + }, + mounted () { + mounted = true; + }, props: { material: { type: Object, @@ -287,11 +305,6 @@ export default { return this.template?.image_tmp_name?.length > 0 || this.material.front_image_content_type?.length > 0; }, - displayTags () { - return this.material.tags.concat( - Array(this.minimumTags).fill('') - ).slice(0, this.minimumTags); - }, logoUrl() { return this.template?.image_tmp_name ? STUDIP.URLHelper.getURL('dispatch.php/oer/mymaterial/show_tmp_image') : this.material.logoUrl; }, @@ -299,9 +312,6 @@ export default { return STUDIP.URLHelper; } }, - mounted() { - jQuery('.oercampus_editmaterial').find(':focusable').first().focus(); - }, methods: { editImage(event) { let reader = new FileReader(); @@ -336,12 +346,13 @@ export default { this.tags.push(''); }, removeTag(i) { - this.$delete(this.tags, i); - if ( - this.minimumTags > this.tags.length - && this.minimumTags > 5 - ) { - this.minimumTags--; + this.tags = this.tags.filter((element, index) => index !== i); + } + }, + watch: { + tags(current) { + if (current.length === 0) { + this.tags.push(''); } } } @@ -383,14 +394,5 @@ export default { .oer_tags_container { margin-top: 10px; } - - .level_labels { - display: flex; - justify-content: space-between; - font-size: 0.8em; - color: var(--black); - margin-top: 20px; - } - } diff --git a/resources/vue/components/Quicksearch.vue b/resources/vue/components/Quicksearch.vue index 0f37ae0..cdfdeb0 100644 --- a/resources/vue/components/Quicksearch.vue +++ b/resources/vue/components/Quicksearch.vue @@ -181,3 +181,49 @@ export default { } } + diff --git a/resources/vue/components/StudipLevelSlider.vue b/resources/vue/components/StudipLevelSlider.vue index a1b91e0..ee362e6 100644 --- a/resources/vue/components/StudipLevelSlider.vue +++ b/resources/vue/components/StudipLevelSlider.vue @@ -1,11 +1,16 @@