mirror of
https://github.com/moodle/moodle.git
synced 2025-04-15 21:45:37 +02:00
MDL-68796 core_contentbank: Store view preferences
includes privacy export, privacy unit test
This commit is contained in:
parent
68fd8d8bdf
commit
c393d8185a
2
contentbank/amd/build/sort.min.js
vendored
2
contentbank/amd/build/sort.min.js
vendored
@ -1,2 +1,2 @@
|
||||
define ("core_contentbank/sort",["exports","core_contentbank/selectors","core/str","core/prefetch"],function(a,b,c,d){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=e(b);d=e(d);function e(a){return a&&a.__esModule?a:{default:a}}var f=function(){var a=document.querySelector(b.default.regions.contentbank);d.default.prefetchStrings("contentbank",["sortbyx","sortbyxreverse","contentname","lastmodified","size","type"]);g(a)};a.init=f;var g=function(a){var c=document.querySelector(b.default.regions.filearea),d=c.querySelectorAll(b.default.elements.listitem),e=a.querySelector(b.default.actions.viewgrid),f=a.querySelector(b.default.actions.viewlist);e.addEventListener("click",function(){a.classList.remove("view-list");a.classList.add("view-grid");e.classList.add("active");f.classList.remove("active")});f.addEventListener("click",function(){a.classList.remove("view-grid");a.classList.add("view-list");f.classList.add("active");e.classList.remove("active")});var g=a.querySelector(b.default.actions.sortname);g.addEventListener("click",function(){var b=h(a,g);j(c,d,"data-file",b)});var i=a.querySelector(b.default.actions.sortdate);i.addEventListener("click",function(){var b=h(a,i);j(c,d,"data-timemodified",b)});var k=a.querySelector(b.default.actions.sortsize);k.addEventListener("click",function(){var b=h(a,k);j(c,d,"data-bytes",b)});var l=a.querySelector(b.default.actions.sorttype);l.addEventListener("click",function(){var b=h(a,l);j(c,d,"data-type",b)})},h=function(a,c){var d=a.querySelectorAll(b.default.elements.sortbutton);d.forEach(function(a){if(a!==c){a.classList.remove("dir-asc");a.classList.remove("dir-desc");a.classList.add("dir-none");i(a,!1)}});var e=!0;if(c.classList.contains("dir-none")){c.classList.remove("dir-none");c.classList.add("dir-asc")}else if(c.classList.contains("dir-asc")){c.classList.remove("dir-asc");c.classList.add("dir-desc");e=!1}else if(c.classList.contains("dir-desc")){c.classList.remove("dir-desc");c.classList.add("dir-asc")}i(c,e);return e},i=function(a,b){var d=b?"sortbyxreverse":"sortbyx";return(0,c.get_string)(a.dataset.string,"contentbank").then(function(a){return(0,c.get_string)(d,"core",a)}).then(function(b){a.setAttribute("title",b);return b}).catch()},j=function(a,b,c,d){var e=[].slice.call(b).sort(function(e,a){var b=e.getAttribute(c),f=a.getAttribute(c);if(!isNaN(b)){b=parseInt(b);f=parseInt(f)}if(d){return b>f?1:-1}else{return b<f?1:-1}});e.forEach(function(b){return a.appendChild(b)})}});
|
||||
define ("core_contentbank/sort",["exports","./selectors","core/str","core/prefetch","core/ajax","core/notification"],function(a,b,c,d,e,f){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=g(b);d=g(d);e=g(e);f=g(f);function g(a){return a&&a.__esModule?a:{default:a}}var h=function(){var a=document.querySelector(b.default.regions.contentbank);d.default.prefetchStrings("contentbank",["sortbyx","sortbyxreverse","contentname","lastmodified","size","type"]);i(a)};a.init=h;var i=function(a){var c=document.querySelector(b.default.regions.filearea),d=c.querySelectorAll(b.default.elements.listitem),e=a.querySelector(b.default.actions.viewgrid),f=a.querySelector(b.default.actions.viewlist);e.addEventListener("click",function(){a.classList.remove("view-list");a.classList.add("view-grid");e.classList.add("active");f.classList.remove("active");j(!1)});f.addEventListener("click",function(){a.classList.remove("view-grid");a.classList.add("view-list");f.classList.add("active");e.classList.remove("active");j(!0)});var g=a.querySelector(b.default.actions.sortname);g.addEventListener("click",function(){var b=k(a,g);m(c,d,"data-file",b)});var h=a.querySelector(b.default.actions.sortdate);h.addEventListener("click",function(){var b=k(a,h);m(c,d,"data-timemodified",b)});var i=a.querySelector(b.default.actions.sortsize);i.addEventListener("click",function(){var b=k(a,i);m(c,d,"data-bytes",b)});var l=a.querySelector(b.default.actions.sorttype);l.addEventListener("click",function(){var b=k(a,l);m(c,d,"data-type",b)})},j=function(a){if(!1===a){a=null}var b={methodname:"core_user_update_user_preferences",args:{preferences:[{type:"core_contentbank_view_list",value:a}]}};return e.default.call([b])[0].catch(f.default.exception)},k=function(a,c){var d=a.querySelectorAll(b.default.elements.sortbutton);d.forEach(function(a){if(a!==c){a.classList.remove("dir-asc");a.classList.remove("dir-desc");a.classList.add("dir-none");l(a,!1)}});var e=!0;if(c.classList.contains("dir-none")){c.classList.remove("dir-none");c.classList.add("dir-asc")}else if(c.classList.contains("dir-asc")){c.classList.remove("dir-asc");c.classList.add("dir-desc");e=!1}else if(c.classList.contains("dir-desc")){c.classList.remove("dir-desc");c.classList.add("dir-asc")}l(c,e);return e},l=function(a,b){var d=b?"sortbyxreverse":"sortbyx";return(0,c.get_string)(a.dataset.string,"contentbank").then(function(a){return(0,c.get_string)(d,"core",a)}).then(function(b){a.setAttribute("title",b);return b}).catch()},m=function(a,b,c,d){var e=[].slice.call(b).sort(function(e,a){var b=e.getAttribute(c),f=a.getAttribute(c);if(!isNaN(b)){b=parseInt(b);f=parseInt(f)}if(d){return b>f?1:-1}else{return b<f?1:-1}});e.forEach(function(b){return a.appendChild(b)})}});
|
||||
//# sourceMappingURL=sort.min.js.map
|
||||
|
File diff suppressed because one or more lines are too long
@ -22,9 +22,11 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import selectors from 'core_contentbank/selectors';
|
||||
import selectors from './selectors';
|
||||
import {get_string as getString} from 'core/str';
|
||||
import Prefetch from 'core/prefetch';
|
||||
import Ajax from 'core/ajax';
|
||||
import Notification from 'core/notification';
|
||||
|
||||
/**
|
||||
* Set up the contentbank views.
|
||||
@ -59,6 +61,7 @@ const registerListenerEvents = (contentBank) => {
|
||||
contentBank.classList.add('view-grid');
|
||||
viewGrid.classList.add('active');
|
||||
viewList.classList.remove('active');
|
||||
setViewListPreference(false);
|
||||
});
|
||||
|
||||
viewList.addEventListener('click', () => {
|
||||
@ -66,6 +69,7 @@ const registerListenerEvents = (contentBank) => {
|
||||
contentBank.classList.add('view-list');
|
||||
viewList.classList.add('active');
|
||||
viewGrid.classList.remove('active');
|
||||
setViewListPreference(true);
|
||||
});
|
||||
|
||||
// Sort by file name alphabetical
|
||||
@ -97,6 +101,35 @@ const registerListenerEvents = (contentBank) => {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the contentbank user preference in list view
|
||||
*
|
||||
* @param {Bool} viewList view ContentBank as list.
|
||||
* @return {Promise} Repository promise.
|
||||
*/
|
||||
const setViewListPreference = function(viewList) {
|
||||
|
||||
// If the given status is not hidden, the preference has to be deleted with a null value.
|
||||
if (viewList === false) {
|
||||
viewList = null;
|
||||
}
|
||||
|
||||
const request = {
|
||||
methodname: 'core_user_update_user_preferences',
|
||||
args: {
|
||||
preferences: [
|
||||
{
|
||||
type: 'core_contentbank_view_list',
|
||||
value: viewList
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
return Ajax.call([request])[0].catch(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the sort button view.
|
||||
*
|
||||
|
@ -97,6 +97,7 @@ class bankcontent implements renderable, templatable {
|
||||
'type' => $mimetype
|
||||
);
|
||||
}
|
||||
$data->viewlist = get_user_preferences('core_contentbank_view_list');
|
||||
$data->contents = $contentdata;
|
||||
$data->tools = $this->toolbar;
|
||||
return $data;
|
||||
|
@ -44,7 +44,8 @@ use context_course;
|
||||
class provider implements
|
||||
\core_privacy\local\metadata\provider,
|
||||
\core_privacy\local\request\core_userlist_provider,
|
||||
\core_privacy\local\request\plugin\provider {
|
||||
\core_privacy\local\request\plugin\provider,
|
||||
\core_privacy\local\request\user_preference_provider {
|
||||
|
||||
/**
|
||||
* Returns meta data about this system.
|
||||
@ -65,6 +66,26 @@ class provider implements
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export all user preferences for the contentbank
|
||||
*
|
||||
* @param int $userid The userid of the user whose data is to be exported.
|
||||
*/
|
||||
public static function export_user_preferences(int $userid) {
|
||||
$preference = get_user_preferences('core_contentbank_view_list', null, $userid);
|
||||
if (isset($preference)) {
|
||||
writer::export_user_preference(
|
||||
'core_contentbank',
|
||||
'core_contentbank_view_list',
|
||||
$preference,
|
||||
get_string('privacy:request:preference:set', 'core_contentbank', (object) [
|
||||
'name' => 'core_contentbank_view_list',
|
||||
'value' => $preference,
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of contexts that contain user information for the specified user.
|
||||
*
|
||||
|
39
contentbank/lib.php
Normal file
39
contentbank/lib.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Library functions for contentbank
|
||||
*
|
||||
* @package core_contentbank
|
||||
* @copyright 2020 Bas Brands
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the current user preferences that are available
|
||||
*
|
||||
* @return Array preferences configuration
|
||||
*/
|
||||
function core_contentbank_user_preferences() {
|
||||
return [
|
||||
'core_contentbank_view_list' => [
|
||||
'choices' => array(0, 1),
|
||||
'type' => PARAM_INT,
|
||||
'null' => NULL_NOT_ALLOWED,
|
||||
'default' => 'none'
|
||||
],
|
||||
];
|
||||
}
|
@ -48,7 +48,8 @@
|
||||
}
|
||||
|
||||
}}
|
||||
<div class="content-bank-container view-grid" data-region="contentbank">
|
||||
<div class="content-bank-container {{#viewlist}}view-list{{/viewlist}} {{^viewlist}}view-grid{{/viewlist}}"
|
||||
data-region="contentbank">
|
||||
<div class="d-flex justify-content-between flex-column flex-sm-row">
|
||||
<div class="cb-search-container mb-2">
|
||||
{{>core_contentbank/bankcontent/search}}
|
||||
|
@ -38,12 +38,12 @@
|
||||
{{#pix}} {{{ icon }}} {{/pix}} {{{ name }}}
|
||||
</a>
|
||||
{{/tools}}
|
||||
<button class="icon-no-margin btn btn-secondary active ml-2"
|
||||
<button class="icon-no-margin btn btn-secondary {{^viewlist}}active{{/viewlist}} ml-2"
|
||||
title="{{#str}} displayicons, contentbank {{/str}}"
|
||||
data-action="viewgrid">
|
||||
{{#pix}}a/view_icon_active, core, {{#str}} displayicons, contentbank {{/str}} {{/pix}}
|
||||
</button>
|
||||
<button class="icon-no-margin btn btn-secondary"
|
||||
<button class="icon-no-margin btn btn-secondary {{#viewlist}}active{{/viewlist}}"
|
||||
title="{{#str}} displaydetails, contentbank {{/str}}"
|
||||
data-action="viewlist">
|
||||
{{#pix}}t/viewdetails, core, {{#str}} displaydetails, contentbank {{/str}} {{/pix}}
|
||||
|
28
contentbank/tests/behat/view_preferences.feature
Normal file
28
contentbank/tests/behat/view_preferences.feature
Normal file
@ -0,0 +1,28 @@
|
||||
@core @core_contentbank @contentbank_h5p @javascript
|
||||
Feature: Store the content bank view preference
|
||||
In order to consistantly view the content bank in icons or details view
|
||||
As an admin
|
||||
I need to be able to store my view preference
|
||||
|
||||
Background:
|
||||
Given the following "contentbank content" exist:
|
||||
| contextlevel | reference | contenttype | user | contentname |
|
||||
| System | | contenttype_h5p | admin | filltheblanks.h5p |
|
||||
| System | | contenttype_h5p | admin | mathsbook.h5p |
|
||||
|
||||
Scenario: Admins can order content in the content bank
|
||||
Given I log in as "admin"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And I add the "Navigation" block if not present
|
||||
And I expand "Site pages" node
|
||||
And I click on "Content bank" "link"
|
||||
When I click on "Display contentbank with file details" "button"
|
||||
And I should see "Last modified"
|
||||
And I follow "filltheblanks.h5p"
|
||||
And I click on "Content bank" "link"
|
||||
And I should see "Last modified"
|
||||
And I click on "Display contentbank with icons" "button"
|
||||
And I follow "filltheblanks.h5p"
|
||||
And I click on "Content bank" "link"
|
||||
And I should not see "Last modified"
|
@ -29,6 +29,7 @@ use stdClass;
|
||||
use context_system;
|
||||
use context_coursecat;
|
||||
use context_course;
|
||||
use context_user;
|
||||
use core_contentbank\privacy\provider;
|
||||
use core_privacy\local\request\approved_contextlist;
|
||||
use core_privacy\local\request\writer;
|
||||
@ -361,4 +362,50 @@ class core_contentbank_privacy_testcase extends provider_testcase {
|
||||
|
||||
return $scenario;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that export_user_preferences returns no data if the user has not visited any content bank.
|
||||
*/
|
||||
public function test_export_user_preferences_no_pref() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$managerroleid = $DB->get_field('role', 'id', ['shortname' => 'manager']);
|
||||
$this->getDataGenerator()->role_assign($managerroleid, $user->id);
|
||||
|
||||
provider::export_user_preferences($user->id);
|
||||
$writer = writer::with_context(context_system::instance());
|
||||
$this->assertFalse($writer->has_any_data());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for provider::test_export_user_preferences().
|
||||
*/
|
||||
public function test_export_user_preferences() {
|
||||
global $DB;
|
||||
|
||||
// Test setup.
|
||||
$this->resetAfterTest(true);
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
|
||||
set_user_preference('core_contentbank_view_list', 1);
|
||||
// Test the user preferences export contains 1 user preference record for the User.
|
||||
provider::export_user_preferences($user->id);
|
||||
$contextuser = context_user::instance($user->id);
|
||||
$writer = writer::with_context($contextuser);
|
||||
$this->assertTrue($writer->has_any_data());
|
||||
|
||||
$prefs = $writer->get_user_preferences('core_contentbank');
|
||||
$this->assertCount(1, (array) $prefs);
|
||||
$this->assertEquals(1, $prefs->core_contentbank_view_list->value);
|
||||
$this->assertEquals(
|
||||
get_string('privacy:request:preference:set', 'core_contentbank', (object) [
|
||||
'name' => 'core_contentbank_view_list',
|
||||
'value' => $prefs->core_contentbank_view_list->value,
|
||||
]),
|
||||
$prefs->core_contentbank_view_list->description
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ $string['privacy:metadata:content:usercreated'] = 'The user has created the cont
|
||||
$string['privacy:metadata:content:usermodified'] = 'The last user who modified the content.';
|
||||
$string['privacy:metadata:contentbankcontent'] = 'Stores the content of the content bank.';
|
||||
$string['privacy:metadata:userid'] = 'The ID of the user creating or modifying content bank content.';
|
||||
$string['privacy:request:preference:set'] = 'The value of the setting \'{$a->name}\' was \'{$a->value}\'';
|
||||
$string['rename'] = 'Rename';
|
||||
$string['renamecontent'] = 'Rename content';
|
||||
$string['searchcontentbankbyname'] = 'Search for content by name';
|
||||
|
@ -997,7 +997,7 @@ class core_user {
|
||||
// Core components that may want to define their preferences.
|
||||
// List of core components implementing callback is hardcoded here for performance reasons.
|
||||
// TODO MDL-58184 cache list of core components implementing a function.
|
||||
$corecomponents = ['core_message', 'core_calendar'];
|
||||
$corecomponents = ['core_message', 'core_calendar', 'core_contentbank'];
|
||||
foreach ($corecomponents as $component) {
|
||||
if (($pluginpreferences = component_callback($component, 'user_preferences')) && is_array($pluginpreferences)) {
|
||||
$preferences += $pluginpreferences;
|
||||
|
Loading…
x
Reference in New Issue
Block a user