Skip to content

Commit

Permalink
MDL-75148 mod_data: Improve presets list page
Browse files Browse the repository at this point in the history
- Add a new help text.
- Add captions to table columns.
- Move action icons to action menu, and fix code to display the remove
action only for presets created by users.
- CSS improvements to fit the prototype.

In order to achive the previous points, the renderer has been improved,
to return the data and let the mustache to print it properly (instead of
returning the formatted HTML table).
  • Loading branch information
sarjona committed Aug 1, 2022
1 parent 06b86fd commit 599aca6
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 24 deletions.
57 changes: 37 additions & 20 deletions mod/data/classes/output/presets.php
Expand Up @@ -16,6 +16,8 @@

namespace mod_data\output;

use action_menu;
use action_menu_link_secondary;
use moodle_url;
use templatable;
use renderable;
Expand Down Expand Up @@ -64,54 +66,69 @@ public function __construct(int $id, array $presets, moodle_url $formactionurl,
*/
public function export_for_template(\renderer_base $output): array {

$presets = $this->get_presets();
return [
'd' => $this->id,
'formactionul' => $this->formactionurl->out(),
'presetstable' => $this->get_presets_table(),
'showmanage' => $this->manage,
'presets' => $presets,
];
}

/**
* Generates and returns the HTML for the presets table.
* Returns the presets list with the information required to display them.
*
* @return string
* @return array Presets list.
*/
private function get_presets_table(): string {
global $OUTPUT, $PAGE, $DB;

$presetstable = new \html_table();
$presetstable->align = ['center', 'left', 'left'];
$presetstable->size = ['1%', '90%', '1%'];
private function get_presets(): array {
global $OUTPUT, $PAGE;

$presets = [];
foreach ($this->presets as $preset) {
$presetname = $preset->name;
if (!empty($preset->userid)) {
// If the preset has the userid field, the full name of creator it will be added to the end of the name.
$userfieldsapi = \core_user\fields::for_name();
$namefields = $userfieldsapi->get_sql('', false, '', '', false)->selects;
$presetuser = $DB->get_record('user', array('id' => $preset->userid), 'id, ' . $namefields, MUST_EXIST);
$fields = 'id, ' . $namefields;
$presetuser = \core_user::get_user($preset->userid, $fields, MUST_EXIST);
$username = fullname($presetuser, true);
$presetname = "{$presetname} ({$username})";
}

$deleteaction = '';
$actions = [];
if ($this->manage) {
if (data_user_can_delete_preset($PAGE->context, $preset) && $preset->name != 'Image gallery') {
// Only presets saved by users can be removed (so the datapreset plugins shouldn't display the delete button).
if (!$preset->isplugin && data_user_can_delete_preset($PAGE->context, $preset)) {
$deleteactionurl = new moodle_url('/mod/data/preset.php',
['d' => $this->id, 'fullname' => "{$preset->userid}/{$preset->shortname}",
'action' => 'confirmdelete']);
$deleteaction = $OUTPUT->action_icon($deleteactionurl,
new \pix_icon('t/delete', get_string('delete')));

$actionmenu = new action_menu();
$icon = $OUTPUT->pix_icon('i/menu', get_string('actions'));
$actionmenu->set_menu_trigger($icon, 'btn btn-icon d-flex align-items-center justify-content-center');
$actionmenu->set_action_label(get_string('actions'));
$actionmenu->attributes['class'] .= ' presets-actions';

$actionmenu->add(new action_menu_link_secondary(
$deleteactionurl,
null,
get_string('delete'),
));
$actions = $actionmenu->export_for_template($OUTPUT);
}
}

$presetstable->data[] = [
\html_writer::tag('input', '', array('type' => 'radio', 'name' => 'fullname',
'value' => "{$preset->userid}/{$preset->shortname}")),
$presetname,
$deleteaction,
$presets[] = [
'id' => $this->id,
'name' => $preset->name,
'shortname' => $preset->shortname,
'fullname' => $presetname,
'userid' => $preset->userid,
'actions' => $actions,
];
}

return \html_writer::table($presetstable);
return $presets;
}
}
1 change: 1 addition & 0 deletions mod/data/lang/en/data.php
Expand Up @@ -320,6 +320,7 @@
$string['presetinfo'] = 'Saving as a preset will publish this template. Other users may be able to use it in their databases.';
$string['presetnotselected'] = 'No preset has been selected.';
$string['presets'] = 'Presets';
$string['presetshelp'] = 'Choose a preset to use as a starting point.';
$string['privacy:metadata:commentpurpose'] = 'Comments on database records';
$string['privacy:metadata:data_content'] = 'Represents one answer to one field in database activity module';
$string['privacy:metadata:data_content:fieldid'] = 'Field definition ID';
Expand Down
4 changes: 4 additions & 0 deletions mod/data/styles.css
Expand Up @@ -148,3 +148,7 @@
#page-mod-data-edit .datatagcontrol {
padding-left: 10px;
}

.preset_action_menu .dropdown-toggle::after {
display: none;
}
55 changes: 51 additions & 4 deletions mod/data/templates/presets.mustache
Expand Up @@ -19,22 +19,69 @@
Context variables required for this template:
* formactionul - The form action url.
* d - The database id.
* presetstable - The HTML output of the table with presets
* presets - List of presets containing id, name, fullname, shortname and actions.
Example context (json):
{
"formactionul": "http://www.example.com",
"d": 1,
"presetstable": "<table></table>"
"presets": [
{
"id": 1,
"name": "Image gallery",
"shortname": "imagegallery",
"fullname": "Image gallery",
"userid": 0,
"actions": []
},
{
"id": 2,
"name": "Preset saved manually",
"shortname": "Preset saved manually",
"fullname": "Preset saved manually (admin)",
"userid": 2,
"actions": []
}
]
}
}}
{{#str}}presetshelp, mod_data{{/str}}

<form method="post" action="{{formactionul}}" class="mt-4">
<input type="hidden" name="d" value="{{d}}">
<input type="hidden" name="mode" value="usepreset">
<input type="hidden" name="action" value="select">
{{{presetstable}}}
<input type="submit" name="selectpreset" value="{{#str}}usepreset, mod_data{{/str}}" class="btn btn-primary mt-2">

<table id="presets-list" class="generaltable fullwidth">
<thead>
<tr>
<th class="pl-4 border-top-0" scope="col" style="width: 3%"></th>
<th class="pl-4 border-top-0" scope="col">{{#str}} name {{/str}}</th>
<th class="pl-4 border-top-0" scope="col" style="width: 3%">{{#showmanage}}{{#str}} action {{/str}}{{/showmanage}}</th>
</tr>
</thead>
<tbody>
{{#presets}}
<tr>
<td class="p-4 border-right">
<input type="radio" name="fullname" value="{{userid}}/{{shortname}}" />
</td>
<td class="p-4">{{fullname}}</td>
<td class="p-4 preset_action_menu">
{{#actions}}
<div class="float-right">
{{>core/action_menu}}
</div>
{{/actions}}
</td>
</tr>
{{/presets}}
</tbody>
</table>

<input type="submit" name="selectpreset" value="{{#str}}usepreset, mod_data{{/str}}" class="btn btn-secondary mt-2 float-right" disabled>
</form>

{{#js}}
require(['mod_data/selectpreset'], function(selectPreset) {
selectPreset.init();
Expand Down
81 changes: 81 additions & 0 deletions mod/data/tests/behat/data_presets.feature
@@ -0,0 +1,81 @@
@mod @mod_data
Feature: Users can view and manage data presets
In order to use presets
As a user
I need to view, manage and use presets

Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| data | Mountain landscapes | n | C1 | data1 |
And the following "mod_data > presets" exist:
| database | name |
| data1 | Saved preset 1 |
| data1 | Saved preset 2 |

@javascript
Scenario: Admins can delete saved presets
Given I am on the "Mountain landscapes" "data activity" page logged in as admin
When I follow "Presets"
Then I should see "Choose a preset to use as a starting point."
And I should see "Image gallery"
And I should see "Saved preset 1"
And I should see "Saved preset 2"
# Plugin presets can't be removed.
And I should not see "Actions" in the "Image gallery" "table_row"
# The admin should be able to delete saved presets.
But I open the action menu in "Saved preset 1" "table_row"
And I should see "Delete"
And I open the action menu in "Saved preset 2" "table_row"
And I should see "Delete"

@javascript
Scenario: Teachers can see and use presets
Given the following "mod_data > fields" exist:
| database | type | name | description |
| data1 | text | Test field name | Test field description |
And I am on the "Mountain landscapes" "data activity" page logged in as teacher1
And I follow "Templates"
And I click on "Save as preset" "button"
And I set the field "Name" to "Saved preset by teacher1"
And I click on "Save" "button" in the "Save all fields and templates as preset" "dialogue"
When I follow "Presets"
Then I should see "Choose a preset to use as a starting point."
And I should see "Image gallery"
And I should see "Saved preset 1"
And I should see "Saved preset 2"
And I should see "Saved preset by teacher1"
# Plugin presets can't be removed.
And I should not see "Actions" in the "Image gallery" "table_row"
# Teachers should be able to delete their saved presets.
And I open the action menu in "Saved preset by teacher1" "table_row"
And I should see "Delete"
# Teachers can't delete the presets they haven't created.
And I should not see "Actions" in the "Saved preset 1" "table_row"
# The "Use preset" button should be enabled only when a preset is selected.
And the "Use preset" "button" should be disabled
And I click on "fullname" "radio" in the "Image gallery" "table_row"
And the "Use preset" "button" should be enabled

@javascript
Scenario: Only users with the viewalluserpresets capability can see presets created by other users
Given the following "permission override" exists:
| role | editingteacher |
| capability | mod/data:viewalluserpresets |
| permission | Prohibit |
| contextlevel | System |
| reference | |
When I am on the "Mountain landscapes" "data activity" page logged in as teacher1
And I follow "Presets"
Then I should see "Image gallery"
And I should not see "Saved preset 1"
And I should not see "Saved preset 2"

0 comments on commit 599aca6

Please sign in to comment.