Implemented custom user-tops and did somestyling in the courses list
This commit is contained in:
parent
29c8dd9aa4
commit
737da8c051
2
amd/build/studyplan-editor-components.min.js
vendored
2
amd/build/studyplan-editor-components.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -3821,14 +3821,15 @@ export default {
|
|||
template: `
|
||||
<li class="t-coursecat-list-item">
|
||||
<span v-if="hasDetails" v-b-toggle="'coursecat-'+value.id">
|
||||
<i class="when-closed fa fa-caret-right"></i>
|
||||
<i class="when-open fa fa-caret-down"></i>
|
||||
<i class="when-closed fa fa-caret-right t-caret"></i>
|
||||
<i class="when-open fa fa-caret-down t-caret"></i>
|
||||
<span class="t-coursecat-heading">
|
||||
<i class="t-coursecat-list-item fa fa-tasks"></i>
|
||||
{{ value.category.name }}
|
||||
</span>
|
||||
</span>
|
||||
<span v-else>
|
||||
<i class="when-closed fa t-caret" style="visibility: hidden"></i>
|
||||
<span class="t-coursecat-heading">
|
||||
<i class="t-coursecat-list-item fa fa-tasks"></i>
|
||||
{{ value.category.name }}
|
||||
|
|
|
@ -48,6 +48,87 @@ class courseservice extends \external_api {
|
|||
const CAP_VIEW = "local/treestudyplan:viewuserreports";
|
||||
|
||||
|
||||
/**
|
||||
* Get the topmost categories for the specicied user.
|
||||
* Most of the work is offloaded to an SQL query in the interest of speed, but moodle functions are used to double check access permissions.
|
||||
* @param int $userid Id of the user
|
||||
* @return array of core_course_category
|
||||
*/
|
||||
public static function user_tops($userid) {
|
||||
global $DB;
|
||||
$tops = [];
|
||||
|
||||
/*
|
||||
SELECT UNIQUE ctx.* FROM mdl_context AS ctx
|
||||
INNER JOIN mdl_role_assignments AS ra ON ra.contextid = ctx.id
|
||||
INNER JOIN mdl_role_capabilities AS rc ON ra.roleid = rc.roleid
|
||||
LEFT JOIN mdl_course_categories AS cat ON ctx.instanceid = cat.id
|
||||
WHERE ( ctx.contextlevel = 40 OR ctx.contextlevel = 10 )
|
||||
AND ra.userid = 58 AND rc.capability = 'moodle/category:viewcourselist'
|
||||
ORDER BY ctx.depth ASC, cat.sortorder ASC;
|
||||
*/
|
||||
$capability = 'moodle/category:viewcourselist';
|
||||
|
||||
$sql = "SELECT UNIQUE ctx.* FROM {context} AS ctx
|
||||
INNER JOIN {role_assignments} AS ra ON ra.contextid = ctx.id
|
||||
INNER JOIN {role_capabilities} AS rc ON ra.roleid = rc.roleid
|
||||
LEFT JOIN {course_categories} AS cat ON ctx.instanceid = cat.id
|
||||
WHERE ( ctx.contextlevel = :ctxl_coursecat OR ctx.contextlevel = :ctxl_system )
|
||||
AND ra.userid = :userid AND rc.capability = :capability
|
||||
ORDER BY ctx.depth ASC, cat.sortorder ASC";
|
||||
|
||||
// Use recordset to handle the eventuality of a really big and complex moodle setup.
|
||||
$recordset = $DB->get_recordset_sql($sql, ["userid" => $userid, "capability" => $capability,
|
||||
"ctxl_coursecat" => \CONTEXT_COURSECAT, "ctxl_system" => \CONTEXT_SYSTEM,]);
|
||||
|
||||
$contextids = [];
|
||||
foreach ($recordset as $r) {
|
||||
// Get the paths as an array.
|
||||
$parents = explode("/",$r->path);
|
||||
// Strip the first item, since it is an empty one.
|
||||
array_shift($parents);
|
||||
// Strip the last item, since it refers to self.
|
||||
array_pop($parents);
|
||||
// Figure out if any of the remaining parent contexts are already contexts with permission.
|
||||
$intersect = array_intersect($contextids,$parents);
|
||||
if (count($intersect) == 0) {
|
||||
// Double check permissions according to the moodle capability system.
|
||||
$ctx = \context::instance_by_id($r->id);
|
||||
if (has_capability($capability,$ctx,$userid)) {
|
||||
// Get the actual category object.
|
||||
if ($r->contextlevel == \CONTEXT_SYSTEM) {
|
||||
// The user can view all (non-hidden) categories, so add all categories of depth = 1;
|
||||
$tops = []; // Reset the array, just in case.
|
||||
$rs = $DB->get_recordset("course_categories",["depth" => 1],'sortorder');
|
||||
foreach( $rs as $rcat) {
|
||||
// Get the category, and double check if the category is visible to the current user.
|
||||
// Just in case it is a hidden category and the user does not have the viewhidden permission.
|
||||
$cat = \core_course_category::get($rcat->id, \IGNORE_MISSING, false, $userid);
|
||||
if ($cat !== null) {
|
||||
// Register the category.
|
||||
array_push($tops,$cat);
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
break; // Stop the loop immediately so the list of visible depth 2 categories is returned.
|
||||
} else { // Can only be \CONTEXT_COURSECAT according to the SQL query.
|
||||
// Get the category, and double check if the category is visible to the current user.
|
||||
// Just in case it is a hidden category and the user does not have the viewhidden permission.
|
||||
$cat = \core_course_category::get($r->instanceid, \IGNORE_MISSING, false, $userid);
|
||||
if ($cat !== null) {
|
||||
// Register the context id in the list now, since we know the category is really visible.
|
||||
array_push($contextids,$r->id);
|
||||
// Register the category.
|
||||
array_push($tops,$cat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$recordset->close();
|
||||
return $tops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return value description for map_categories function
|
||||
*/
|
||||
|
@ -93,7 +174,7 @@ class courseservice extends \external_api {
|
|||
* @return array
|
||||
*/
|
||||
public static function map_categories($rootid = 0) {
|
||||
global $CFG, $DB;
|
||||
global $USER;
|
||||
|
||||
$root = \core_course_category::get($rootid,\MUST_EXIST,true);
|
||||
|
||||
|
@ -101,15 +182,12 @@ class courseservice extends \external_api {
|
|||
|
||||
if ($root->id == 0) {
|
||||
// On the system level, determine the user's topmost allowed catecories.
|
||||
$usertop = \core_course_category::user_top();
|
||||
if ($usertop->id == 0) {
|
||||
// Top category..
|
||||
$children = $root->get_children(); // Returns a list of çore_course_category, let it overwrite $children.
|
||||
} else {
|
||||
$children = [$usertop];
|
||||
}
|
||||
// This uses a custom function, since moodle's "core_course_category::user_top()" is somewhat deficient.
|
||||
$children = self::user_tops($USER->id);
|
||||
} else if ($root->is_uservisible()) {
|
||||
$children = [$root];
|
||||
} else {
|
||||
return []; // Category not user visible.
|
||||
}
|
||||
|
||||
$list = [];
|
||||
|
|
|
@ -121,7 +121,6 @@ class studyplanservice extends \external_api {
|
|||
$studyplan = studyplan::find_by_id($id);
|
||||
webservicehelper::require_capabilities([self::CAP_EDIT, self::CAP_VIEW], $studyplan->context());
|
||||
$model = $studyplan->editor_model();
|
||||
debug::dump($model);
|
||||
return $model;
|
||||
} else {
|
||||
return null;
|
||||
|
|
|
@ -264,6 +264,22 @@
|
|||
stroke-opacity: 0.5;
|
||||
stroke-dasharray: 4 4;
|
||||
}
|
||||
.path-local-treestudyplan ul.t-coursecat-list,
|
||||
.path-local-treestudyplan ul.t-course-list,
|
||||
.features-treestudyplan ul.t-coursecat-list,
|
||||
.features-treestudyplan ul.t-course-list {
|
||||
padding-left: 1em;
|
||||
}
|
||||
.path-local-treestudyplan ul.t-coursecat-list ul.t-coursecat-list,
|
||||
.path-local-treestudyplan ul.t-coursecat-list ul.t-course-list,
|
||||
.path-local-treestudyplan ul.t-course-list ul.t-coursecat-list,
|
||||
.path-local-treestudyplan ul.t-course-list ul.t-course-list,
|
||||
.features-treestudyplan ul.t-coursecat-list ul.t-coursecat-list,
|
||||
.features-treestudyplan ul.t-coursecat-list ul.t-course-list,
|
||||
.features-treestudyplan ul.t-course-list ul.t-coursecat-list,
|
||||
.features-treestudyplan ul.t-course-list ul.t-course-list {
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
.path-local-treestudyplan ul.t-item-module-children,
|
||||
.path-local-treestudyplan ul.t-coursecat-list li,
|
||||
.path-local-treestudyplan ul.t-course-list li,
|
||||
|
@ -293,6 +309,26 @@
|
|||
max-width: 24px;
|
||||
max-height: 24px;
|
||||
}
|
||||
.path-local-treestudyplan li.t-coursecat-list-item i.t-caret,
|
||||
.features-treestudyplan li.t-coursecat-list-item i.t-caret {
|
||||
width: 9px;
|
||||
}
|
||||
.path-local-treestudyplan li.t-coursecat-list-item,
|
||||
.path-local-treestudyplan li.t-course-list-item .draggable-course,
|
||||
.features-treestudyplan li.t-coursecat-list-item,
|
||||
.features-treestudyplan li.t-course-list-item .draggable-course {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.path-local-treestudyplan li.t-coursecat-list-item:hover,
|
||||
.path-local-treestudyplan li.t-course-list-item .draggable-course:hover,
|
||||
.features-treestudyplan li.t-coursecat-list-item:hover,
|
||||
.features-treestudyplan li.t-course-list-item .draggable-course:hover {
|
||||
text-overflow: clip;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
}
|
||||
.path-local-treestudyplan i.t-coursecat-list-item,
|
||||
.features-treestudyplan i.t-coursecat-list-item {
|
||||
color: var(--coursecat-list);
|
||||
|
|
|
@ -169,6 +169,16 @@
|
|||
stroke-dasharray: 4 4;
|
||||
}
|
||||
|
||||
ul.t-coursecat-list,
|
||||
ul.t-course-list {
|
||||
padding-left: 1em;
|
||||
|
||||
ul.t-coursecat-list,
|
||||
ul.t-course-list {
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
ul.t-item-module-children,
|
||||
ul.t-coursecat-list li,
|
||||
ul.t-course-list li {
|
||||
|
@ -195,6 +205,26 @@
|
|||
max-height: 24px;
|
||||
}
|
||||
|
||||
li.t-coursecat-list-item {
|
||||
i.t-caret {
|
||||
width: 9px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
li.t-coursecat-list-item, li.t-course-list-item .draggable-course {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:hover {
|
||||
text-overflow: clip;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
i.t-coursecat-list-item {
|
||||
color: var(--coursecat-list);
|
||||
}
|
||||
|
|
36
styles.css
36
styles.css
|
@ -264,6 +264,22 @@
|
|||
stroke-opacity: 0.5;
|
||||
stroke-dasharray: 4 4;
|
||||
}
|
||||
.path-local-treestudyplan ul.t-coursecat-list,
|
||||
.path-local-treestudyplan ul.t-course-list,
|
||||
.features-treestudyplan ul.t-coursecat-list,
|
||||
.features-treestudyplan ul.t-course-list {
|
||||
padding-left: 1em;
|
||||
}
|
||||
.path-local-treestudyplan ul.t-coursecat-list ul.t-coursecat-list,
|
||||
.path-local-treestudyplan ul.t-coursecat-list ul.t-course-list,
|
||||
.path-local-treestudyplan ul.t-course-list ul.t-coursecat-list,
|
||||
.path-local-treestudyplan ul.t-course-list ul.t-course-list,
|
||||
.features-treestudyplan ul.t-coursecat-list ul.t-coursecat-list,
|
||||
.features-treestudyplan ul.t-coursecat-list ul.t-course-list,
|
||||
.features-treestudyplan ul.t-course-list ul.t-coursecat-list,
|
||||
.features-treestudyplan ul.t-course-list ul.t-course-list {
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
.path-local-treestudyplan ul.t-item-module-children,
|
||||
.path-local-treestudyplan ul.t-coursecat-list li,
|
||||
.path-local-treestudyplan ul.t-course-list li,
|
||||
|
@ -293,6 +309,26 @@
|
|||
max-width: 24px;
|
||||
max-height: 24px;
|
||||
}
|
||||
.path-local-treestudyplan li.t-coursecat-list-item i.t-caret,
|
||||
.features-treestudyplan li.t-coursecat-list-item i.t-caret {
|
||||
width: 9px;
|
||||
}
|
||||
.path-local-treestudyplan li.t-coursecat-list-item,
|
||||
.path-local-treestudyplan li.t-course-list-item .draggable-course,
|
||||
.features-treestudyplan li.t-coursecat-list-item,
|
||||
.features-treestudyplan li.t-course-list-item .draggable-course {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.path-local-treestudyplan li.t-coursecat-list-item:hover,
|
||||
.path-local-treestudyplan li.t-course-list-item .draggable-course:hover,
|
||||
.features-treestudyplan li.t-coursecat-list-item:hover,
|
||||
.features-treestudyplan li.t-course-list-item .draggable-course:hover {
|
||||
text-overflow: clip;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
}
|
||||
.path-local-treestudyplan i.t-coursecat-list-item,
|
||||
.features-treestudyplan i.t-coursecat-list-item {
|
||||
color: var(--coursecat-list);
|
||||
|
|
Loading…
Reference in New Issue
Block a user