Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

My course overview improvements: Difference between revisions

From MoodleDocs
No edit summary
No edit summary
Line 17: Line 17:
== Requirements ==
== Requirements ==


A user viewing the "My course overview" block will need to be able to see:
=== 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.


=== Todos ===
* Mustache templates:
A list of tasks from activities with the following attributes:
** 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)


* A unique identifier for the todo, the context id, component, area and itemid.
=== Todo API ===
* The name of the thing this relates to (default to the activity full name)
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 link to the thing that this relates to (defaults to the view.php of the module)
* The course this thing relates to (required)
* An icon (default to activity icon)
* A start date and time (optional)
* An end date and time (optional) - current prototype shows this - maybe it's not needed
* A count of items (e.g. 4 unread posts)
* Name of the task ("Submit assignment")
* Action when clicked (optional)
* Action only available from-to (optional date)
* Display/order date (either the start or end date)


The action stuff (name of the action, url, count of items, availability) could be generated at run time, per module, based on the event details since it can change based on permissions etc.
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.  


This list needs to be able to be ordered and paginated by course, date, and original course order of the items themselves.
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.


The items in this list must obey the rules for module visibility. If the user cannot see the module they cannot see the task.
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.


====To clarify with UX team====
* 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


* How many items to display in "Next 7 days"? Is there a limit, or we always show all of the items?
=== Chart.js ===
* 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?
* Add a new chart type (pie chart) to Moodle's chart API for use in the templates above
* 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.


===Progress===
=== 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.


We need a way to determine a users course progress.
* 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


Course completion:
=== Calendar Block ===
For courses using completion this will be the % completed activities.
* 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


No course completion:
=== Course Completion Tracking ===
For courses without course completion - we still need to show the progression percentage, and need to find a way to compute one.
* 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


=== Courses tab ===
=== 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
** A list has been started here https://docs.google.com/document/d/1qfl2MEzdZcNlT2rvBSsIgWhRZsloRnsb2m5TALFn_C8/edit
* 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.


The course end date must have an effect on the students access/permissions in the course. Currently, students can still access the course and complete activities.
=== 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.


====To clarify with UX team====
== 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?
* Are the courses paginated? Is there a "More" button to load more courses?
* 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.
* 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?
* Are all the three tabs (in progress, upcoming, completed) always shown, even if they are empty?
=== Specification ===
Make functions to get the data.
Print the data
Remove obsolete code
Deprecate print_overview API
Todos API
==== Progress API ====
The current progression needs to be stored somewhere to performance. Caching may lead to losing the data on upgrade whereas the data is not stale yet. Being notified of changes can easily be known if the course is using the completion API. If not, we'll have to think of something...
==== Todos API ====
* Identify todos each core activity will provide
* Identify actions which may affect the status of the current todos (editing module, submitting assignment, changing dates, ...) for each module
Todos could be stored in a gigantic table, possible with another table containing user overrides not to have to create an entry per todo per user per module. Or, query each module each time for the current user, and cache the result. Or, something else.
Invalidating the cache of list of todos has to be considered, we may want to edit/delete a task once the user has taken action on it.
The name is "Todo".
We've decided that we're going to use the existing calendar event stuff to track what the user needs to know about.
Stuff we need to do:
* Make sure we're creating calendar events in every module that requires an action from the user
* Make the calendar API more robust
* Check that the calendar API shows the appropriate events for the user, e.g. if one user has permission to see an assignment and another doesn't then does the event show up for both users?
* Make sure there are proper indexes on the events table
* Add a display/order by date field to the events table
* Build a display API on top of the event data for the "todos" to display them on the course overview block

Revision as of 01:18, 13 December 2016

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
Discussion https://tracker.moodle.org/browse/UX-8
Assignee HQ Projects Team


Summary

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).

Requirements

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

Chart.js

  • 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.

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?