My course overview improvements

Revision as of 01:22, 13 December 2016 by Ryan Wyllie (talk | contribs)

Jump to: navigation, search

This page will detail the technical specification for the improvements to the My course overview block.

Improvements to my course overview block.
Project state Starting
Tracker issue MDL-55611
Assignee HQ Projects Team


The new design for the UI for the course overview block requires the ability for Moodle to efficiently query plugins for a list of "date based" tasks for the current user.

The existing "mod print_overview" callbacks do not have sufficient functionality (no separation of fields, inefficient, incomplete, no relation to completion API, inconsistently implemented across modules) so we will have to build a new API (and deprecate mod_xx_print_overview).


Course Overview Block

The course overview block will communicate exclusively with the Todo API and will present the Todo's as described in UX-8. We need to remove the old code used to render the course overview block and have it use the new APIs.

  • Mustache templates:
    • General template for the block (wrapping template)
      • Timeline view
        • Sort by dates (wrapping template)
          • Template for displaying single todo (rendered in list)
        • Sort by courses (wrapping template)
          • Single course section, includes list of todos similar to "sort by dates" (can maybe re-use the template for a single todo here)
    • Courses view
      • Single template can probably be re-used for "in progress", "upcoming" and "completed" views, just rendered with different data
      • As above, single template for a course
  • Javascript
    • Add a module to interact with the Todo API (no bespoke ajax requests everywhere please)
    • Module for the course overview block that handles the high level interaction (changing between timeline and courses views etc)
    • Module for timeline view (maybe even have separate modules for "sort by dates" and "sort by courses"?). Handles requesting the data and rendering the templates etc.
      • Module needs to handle paginated results (view more button being clicked)
    • Module for courses view that handles requesting the data and rendering the templates
      • Module needs to handle paginated results (view more button being clicked)
    • Use the new pie chart we add
  • CSS: Style each of the templates (try to re-use the Bootstrap classes to keep this minimal)
    • Style Boost theme
    • Style bootstrap base theme (e.g. clean)
    • Add responsive styling (need to ask the UX team for some mock ups of smaller resolutions)
  • Accessibility: Add the appropriate aria attributes to each of the templates above to make the block accessible by a screen reader (more work than it seems)
  • Update blocks/course_overview/block_course_overview.php "get_content" to render a template via the renderer (need to add a new function)
  • Remove the existing functions being used to render the course overview (including functions in the renderer and lib.php)
  • Add behat tests for the interface that covers each permutation of the view (timeline, sort by dates, courses, courseview etc)

Todo API

This will be a new API in core to represent the concept of "todos" in Moodle, i.e. the list of items displayed in the course overview block. A todo is made up of a calendar event and an associated action for the user.

The appropriate action will need to be calculated on a per user basis, per event, and per module because of complex permission problems. E.g. a user may have an event for an assignment that they no longer have permission to view or they may have an event for an assignment that can't be started until after another module has been completed etc.

Given the intensity of some of these calculations we'll need to look into aggressively caching results and maybe even avoid doing the calculations per request.

Since we're leveraging the existing calendar events for the static data we may not need to actually persist the todos anywhere other than caching.

  • Add a todo class (pretty please can we have an actual class rather than just stdClass)
    • Some properties of the class:
      • unique id (context id, component, area and item id?)
      • name - the name of the thing the todo relates to (e.g. activity name)
      • url - the url of the thing the todo relates to (e.g. view.php of the module)
      • user id - the id of the user this todo belong to
      • course id - the course if that the todo relates to
      • icon url - the icon for the todo (default to the module icon)
      • start date (optional) - when the todo starts
      • end date (optional) - when the todo must be actioned by
      • item count - how many associated items there are (e.g. 4 unread posts)
      • action name - display name of the todo (e.g. "submit assignment")
      • action url - url of the todo action (e.g. link to the assignment submission page)
      • action start date - a date after which the todo can be actioned (only display the action url after this date)
  • Add an API class to provide access to todos (get todos for a user, get todos for a user grouped by course etc).
    • Retrieval of todos needs to suppose pagination (and pagination with filters, e.g. first 10 todos in the next 7 days, second 10 todos in the next 7 days).
  • Add a data access layer that abstracts away all of the SQL so that we don't have that logic everywhere (ideally).
    • The API class would benefit from this.
    • It can also hide the fact that we're piggy backing on the calendar events, just in case we want to change that in the future.
    • It can also handle all of the caching
    • Support pagination as above
  • Add a standard interface for plugins to implement which will perform the required calculations and permission checks to generate the correct action based on the given user and event(s).
    • The core todo API can't (and shouldn't) know every place that will want to create a todo, so we need to provide a standard way for each plugin to register itself as something that will create a todo and an interface for them to do the data manipulation required.
  • Add an external API class.
    • This class shouldn't contain any business logic (that all lives in the API class).
    • It needs to do is call into the API class to get the appropriate todos and then create the correct renderables from the todo.
    • All functions should be accessible via ajax. This is the class that the course overview block (and mobile app) will use.
  • Add some renderables for the todo
    • The todos should probably just be renderable / template-able themselves
    • These will be used by the external API class.
  • Improve performance using caching (this will be trial and error with the performance testing)
  • Write unit tests for all new API functions and external API functions


  • Add a new chart type (pie chart) to Moodle's chart API for use in the templates above

Calendar Event API

We'll be using the existing calendar events as the basis for the "todos". The current calendar event data structure contains most of the data that we'll need so we'll leverage that rather than create duplicate data. The API will need to be extended in order to support the more complex data requests we'll need.

  • Add a display/order by date field to the calendar event table to allow us to do the date sorting (e.g. get me all events in the next 7 days) without having to do the start date + duration calculation
  • Add indexes to the event table if they are missing
    • display/order by date
    • course id
    • user id
  • Add functions to the calendar event API to retrieve groups of events for a given user(s)
    • currently it seems the API only loads one at a time so you need to do direct SQL in the calling code
    • API should probably handle grouping of results, e.g. events for a user would be the distinct set of any course level events + group event override + user event override, where each has higher precedence than the last in the result set
    • API needs to support order by new date field
    • API needs to support limit and offset
  • Add unit tests for new API functions

Calendar Block

  • Make sure all of the todos are showing up in the calendar for the user
    • Note: we *should* get this for free since we are simply creating calendar events

Course Completion Tracking

  • Develop a way to track completion on for all courses
    • This needs to take into account all activities within the course, even ones that don't have any completion tracking enabled
  • Add an API to query the completion status of a course that implements the agreed approach
  • Do we need to persist the course progress somewhere or can it be calculated at run time?
    • Assess performance of both options
  • If we need to persist the completion then we need to add hooks into all places that can alter the completion value and update the persistence so that the data is always accurate

General Moodle stuff

  • Remove all uses of the "print_overview" callback thingo we're using through Moodle for modules to add stuff to the course overview block
  • Find all of the places in Moodle that need to generate create a todo and have them create appropriate calendar events
  • Find all of the places that may affect the status of a calendar event and update the event to make sure it is accurate (eg. editing a module, submitting an assignment, changing course dates etc)
  • Add an implementation of the callback interface thingo to each module that will be creating a todo
    • This implementation will take a calendar event and the user and do all of the appropriate checks to see if the user should see the todo, etc
    • It will then create the appropriate todo from the calendar event and add all of the action stuff.

General Testing

  • We need to do some performance testing on the overview with a site that has thousands of events and hundreds of courses to ensure that everything renders in a timely manner.

Proof Of Concept Code

I've knocked together a little proof of concept type branch that does a skeleton implementation of some of this stuff. You can find it here

Please review it and add any comments or what ever.

Questions for the UX team

  • How many items to display in "Next 7 days"? Is there a limit, or we always show all of the items?
  • In the prototype 6c (the one that we are supposed to develop from) the todo disappears from the list when it is actioned. Is this the correct behaviour? What happens to the corresponding event in the calendar? Does that also get removed?
  • What do we show when a todo is only available for a certain duration? E.g. chat where it's open for only 3 days. Only having the end date seems weird in that case.
  • Is the list of courses paginated in the courses view? Is there a "More" button to load more courses?
  • What happens with courses which do not have a start date, and end date? Will they show in "In progress" for as long as I am enrolled in them? Note that if I unenrol from the course, I will lose access to it.
  • Are all the three tabs (in progress, upcoming, completed) always shown, even if they are empty?