mirror of
https://github.com/moodle/moodle.git
synced 2025-04-14 04:52:36 +02:00
MDL-67795 contentbank: delete content UI
This commit is contained in:
parent
58f85a6c6e
commit
45192e9a87
2
contentbank/amd/build/actions.min.js
vendored
Normal file
2
contentbank/amd/build/actions.min.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
define ("core_contentbank/actions",["jquery","core/ajax","core/notification","core/str","core/templates","core/url","core/modal_factory","core/modal_events"],function(a,b,c,d,e,f,g,h){var j={DELETE_CONTENT:"[data-action=\"deletecontent\"]"},k=function(){this.registerEvents()};k.prototype.registerEvents=function(){a(j.DELETE_CONTENT).click(function(b){b.preventDefault();var e=a(this).data("contentname"),f=a(this).data("contentid"),j=a(this).data("contextid"),k="";d.get_strings([{key:"deletecontent",component:"core_contentbank"},{key:"deletecontentconfirm",component:"core_contentbank",param:{name:e}},{key:"delete",component:"core"}]).then(function(a){var b=a[0],c=a[1];k=a[2];return g.create({title:b,body:c,type:g.types.SAVE_CANCEL,large:!0})}).done(function(a){a.setSaveButtonText(k);a.getRoot().on(h.save,function(){return i(f,j)});a.getRoot().on(h.hidden,function(){a.destroy()});a.show()}).catch(c.exception)})};function i(a,e){var g="success";b.call([{methodname:"core_contentbank_delete_content",args:{contentids:{contentid:a}}}])[0].then(function(a){if(a.result){return d.get_string("contentdeleted","core_contentbank")}g="error";return d.get_string("contentnotdeleted","core_contentbank")}).done(function(a){var b={contextid:e};if("success"==g){b.statusmsg=a}else{b.errormsg=a}window.location.href=f.relativeUrl("contentbank/index.php",b,!1)}).fail(c.exception)}return{init:function init(){return new k}}});
|
||||
//# sourceMappingURL=actions.min.js.map
|
1
contentbank/amd/build/actions.min.js.map
Normal file
1
contentbank/amd/build/actions.min.js.map
Normal file
File diff suppressed because one or more lines are too long
162
contentbank/amd/src/actions.js
Normal file
162
contentbank/amd/src/actions.js
Normal file
@ -0,0 +1,162 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Module to manage content bank actions, such as delete or rename.
|
||||
*
|
||||
* @module core_contentbank/actions
|
||||
* @package core_contentbank
|
||||
* @copyright 2020 Sara Arjona <sara@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define([
|
||||
'jquery',
|
||||
'core/ajax',
|
||||
'core/notification',
|
||||
'core/str',
|
||||
'core/templates',
|
||||
'core/url',
|
||||
'core/modal_factory',
|
||||
'core/modal_events'],
|
||||
function($, Ajax, Notification, Str, Templates, Url, ModalFactory, ModalEvents) {
|
||||
|
||||
/**
|
||||
* List of action selectors.
|
||||
*
|
||||
* @type {{DELETE_CONTENT: string}}
|
||||
*/
|
||||
var ACTIONS = {
|
||||
DELETE_CONTENT: '[data-action="deletecontent"]',
|
||||
};
|
||||
|
||||
/**
|
||||
* Actions class.
|
||||
*/
|
||||
var Actions = function() {
|
||||
this.registerEvents();
|
||||
};
|
||||
|
||||
/**
|
||||
* Register event listeners.
|
||||
*/
|
||||
Actions.prototype.registerEvents = function() {
|
||||
$(ACTIONS.DELETE_CONTENT).click(function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var contentname = $(this).data('contentname');
|
||||
var contentid = $(this).data('contentid');
|
||||
var contextid = $(this).data('contextid');
|
||||
|
||||
var strings = [
|
||||
{
|
||||
key: 'deletecontent',
|
||||
component: 'core_contentbank'
|
||||
},
|
||||
{
|
||||
key: 'deletecontentconfirm',
|
||||
component: 'core_contentbank',
|
||||
param: {
|
||||
name: contentname,
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
component: 'core'
|
||||
},
|
||||
];
|
||||
|
||||
var deleteButtonText = '';
|
||||
Str.get_strings(strings).then(function(langStrings) {
|
||||
var modalTitle = langStrings[0];
|
||||
var modalContent = langStrings[1];
|
||||
deleteButtonText = langStrings[2];
|
||||
|
||||
return ModalFactory.create({
|
||||
title: modalTitle,
|
||||
body: modalContent,
|
||||
type: ModalFactory.types.SAVE_CANCEL,
|
||||
large: true
|
||||
});
|
||||
}).done(function(modal) {
|
||||
modal.setSaveButtonText(deleteButtonText);
|
||||
modal.getRoot().on(ModalEvents.save, function() {
|
||||
// The action is now confirmed, sending an action for it.
|
||||
return deleteContent(contentid, contextid);
|
||||
});
|
||||
|
||||
// Handle hidden event.
|
||||
modal.getRoot().on(ModalEvents.hidden, function() {
|
||||
// Destroy when hidden.
|
||||
modal.destroy();
|
||||
});
|
||||
|
||||
// Show the modal.
|
||||
modal.show();
|
||||
|
||||
return;
|
||||
}).catch(Notification.exception);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete content from the content bank.
|
||||
*
|
||||
* @param {int} contentid The content to delete.
|
||||
* @param {int} contextid The contextid where the content belongs.
|
||||
*/
|
||||
function deleteContent(contentid, contextid) {
|
||||
var request = {
|
||||
methodname: 'core_contentbank_delete_content',
|
||||
args: {
|
||||
contentids: {contentid}
|
||||
}
|
||||
};
|
||||
|
||||
var requestType = 'success';
|
||||
Ajax.call([request])[0].then(function(data) {
|
||||
if (data.result) {
|
||||
return Str.get_string('contentdeleted', 'core_contentbank');
|
||||
}
|
||||
requestType = 'error';
|
||||
return Str.get_string('contentnotdeleted', 'core_contentbank');
|
||||
|
||||
}).done(function(message) {
|
||||
var params = {
|
||||
contextid: contextid
|
||||
};
|
||||
if (requestType == 'success') {
|
||||
params.statusmsg = message;
|
||||
} else {
|
||||
params.errormsg = message;
|
||||
}
|
||||
// Redirect to the main content bank page and display the message as a notification.
|
||||
window.location.href = Url.relativeUrl('contentbank/index.php', params, false);
|
||||
}).fail(Notification.exception);
|
||||
}
|
||||
|
||||
return /** @alias module:core_contentbank/actions */ {
|
||||
// Public variables and functions.
|
||||
|
||||
/**
|
||||
* Initialise the contentbank actions.
|
||||
*
|
||||
* @method init
|
||||
* @return {Actions}
|
||||
*/
|
||||
'init': function() {
|
||||
return new Actions();
|
||||
}
|
||||
};
|
||||
});
|
@ -31,6 +31,9 @@ $context = context::instance_by_id($contextid, MUST_EXIST);
|
||||
|
||||
require_capability('moodle/contentbank:access', $context);
|
||||
|
||||
$statusmsg = optional_param('statusmsg', '', PARAM_RAW);
|
||||
$errormsg = optional_param('errormsg', '', PARAM_RAW);
|
||||
|
||||
$title = get_string('contentbank');
|
||||
\core_contentbank\helper::get_page_ready($context, $title);
|
||||
if ($PAGE->course) {
|
||||
@ -74,6 +77,14 @@ if (has_capability('moodle/contentbank:upload', $context)) {
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->box_start('generalbox');
|
||||
|
||||
// If needed, display notifications.
|
||||
if ($errormsg !== '') {
|
||||
echo $OUTPUT->notification($errormsg);
|
||||
} else if ($statusmsg !== '') {
|
||||
echo $OUTPUT->notification($statusmsg, 'notifysuccess');
|
||||
}
|
||||
|
||||
// Render the contentbank contents.
|
||||
$folder = new \core_contentbank\output\bankcontent($foldercontents, $toolbar, $context);
|
||||
echo $OUTPUT->render($folder);
|
||||
|
||||
|
70
contentbank/tests/behat/delete_content.feature
Normal file
70
contentbank/tests/behat/delete_content.feature
Normal file
@ -0,0 +1,70 @@
|
||||
@core @core_contentbank @contentbank_h5p @_file_upload @javascript
|
||||
Feature: Delete H5P file from the content bank
|
||||
In order remove H5P content from the content bank
|
||||
As an admin
|
||||
I need to be able to delete any H5P content from the content bank
|
||||
|
||||
Background:
|
||||
Given I log in as "admin"
|
||||
And I follow "Manage private files..."
|
||||
And I upload "h5p/tests/fixtures/filltheblanks.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
And I click on "Content bank" "link"
|
||||
And I click on "Upload" "link"
|
||||
And I click on "Choose a file..." "button"
|
||||
And I click on "Private files" "link" in the ".fp-repo-area" "css_element"
|
||||
And I click on "filltheblanks.h5p" "link"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Save changes" "button"
|
||||
|
||||
Scenario: Admins can delete content from the content bank
|
||||
Given I click on "Content bank" "link"
|
||||
And I wait until the page is ready
|
||||
And I should see "filltheblanks.h5p"
|
||||
When I follow "filltheblanks.h5p"
|
||||
And I open the action menu in "region-main-settings-menu" "region"
|
||||
Then I should see "Delete"
|
||||
And I choose "Delete" in the open action menu
|
||||
And I should see "Are you sure you want to delete content 'filltheblanks.h5p'?"
|
||||
And I click on "Cancel" "button" in the "Delete content" "dialogue"
|
||||
And I should see "filltheblanks.h5p"
|
||||
And I open the action menu in "region-main-settings-menu" "region"
|
||||
And I choose "Delete" in the open action menu
|
||||
And I click on "Delete" "button" in the "Delete content" "dialogue"
|
||||
And I wait until the page is ready
|
||||
And I should see "The content has been deleted."
|
||||
And I should not see "filltheblanks.h5p"
|
||||
|
||||
Scenario: Users without the required capability can only delete their own content
|
||||
Given the following "permission overrides" exist:
|
||||
| capability | permission | role | contextlevel | reference |
|
||||
| moodle/contentbank:deleteanycontent | Prohibit | manager | System | |
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| manager | Max | Manager | man@example.com |
|
||||
And the following "role assigns" exist:
|
||||
| user | role | contextlevel | reference |
|
||||
| manager | manager | System | |
|
||||
And I log out
|
||||
When I log in as "manager"
|
||||
And I click on "Content bank" "link"
|
||||
And I wait until the page is ready
|
||||
And I should see "filltheblanks.h5p"
|
||||
And I follow "filltheblanks.h5p"
|
||||
Then ".header-actions-container" "css_element" should not exist
|
||||
And I click on "Private files" "link"
|
||||
And I upload "h5p/tests/fixtures/find-the-words.h5p" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
And I click on "Content bank" "link"
|
||||
And I click on "Upload" "link"
|
||||
And I click on "Choose a file..." "button"
|
||||
And I click on "Private files" "link" in the ".fp-repo-area" "css_element"
|
||||
And I click on "find-the-words.h5p" "link"
|
||||
And I click on "Select this file" "button"
|
||||
And I click on "Save changes" "button"
|
||||
And I wait until the page is ready
|
||||
And I should see "filltheblanks.h5p"
|
||||
And I should see "find-the-words.h5p"
|
||||
When I follow "find-the-words.h5p"
|
||||
And I open the action menu in "region-main-settings-menu" "region"
|
||||
Then I should see "Delete"
|
@ -27,6 +27,10 @@ require('../config.php');
|
||||
require_login();
|
||||
|
||||
$id = required_param('id', PARAM_INT);
|
||||
$deletecontent = optional_param('deletecontent', null, PARAM_INT);
|
||||
|
||||
$PAGE->requires->js_call_amd('core_contentbank/actions', 'init');
|
||||
|
||||
$record = $DB->get_record('contentbank_content', ['id' => $id], '*', MUST_EXIST);
|
||||
$context = context::instance_by_id($record->contextid, MUST_EXIST);
|
||||
require_capability('moodle/contentbank:access', $context);
|
||||
@ -52,15 +56,42 @@ $title .= ": ".$record->name;
|
||||
$PAGE->set_title($title);
|
||||
$PAGE->set_pagetype('contenbank');
|
||||
|
||||
$contenttypeclass = "\\$record->contenttype\\contenttype";
|
||||
$contenttype = new $contenttypeclass($context);
|
||||
$contentclass = "\\$record->contenttype\\content";
|
||||
$content = new $contentclass($record);
|
||||
if ($contenttype->can_delete($content)) {
|
||||
// Create the cog menu with all the secondary actions, such as delete, rename...
|
||||
$actionmenu = new action_menu();
|
||||
$actionmenu->set_alignment(action_menu::TR, action_menu::BR);
|
||||
// Add the delete content item to the menu.
|
||||
$attributes = [
|
||||
'data-action' => 'deletecontent',
|
||||
'data-contentname' => $content->get_name(),
|
||||
'data-contentid' => $content->get_id(),
|
||||
'data-contextid' => $context->id,
|
||||
];
|
||||
$actionmenu->add_secondary_action(new action_menu_link(
|
||||
new moodle_url('#'),
|
||||
new pix_icon('t/delete', get_string('delete')),
|
||||
get_string('delete'),
|
||||
false,
|
||||
$attributes
|
||||
));
|
||||
|
||||
// Add the cog menu to the header.
|
||||
$PAGE->add_header_action(html_writer::div(
|
||||
$OUTPUT->render($actionmenu),
|
||||
'd-print-none',
|
||||
['id' => 'region-main-settings-menu']
|
||||
));
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->box_start('generalbox');
|
||||
|
||||
$managerlass = "\\$record->contenttype\\contenttype";
|
||||
if (class_exists($managerlass)) {
|
||||
$manager = new $managerlass($context);
|
||||
if ($manager->can_access()) {
|
||||
echo $manager->get_view_content($record);
|
||||
}
|
||||
if ($contenttype->can_access()) {
|
||||
echo $contenttype->get_view_content($record);
|
||||
}
|
||||
|
||||
echo $OUTPUT->box_end();
|
||||
|
Loading…
x
Reference in New Issue
Block a user