MDL-75148 mod_data: Improve presets list page

- 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).
This commit is contained in:
Sara Arjona
2022-08-01 12:08:16 +02:00
parent 06b86fdfc3
commit 599aca679b
5 changed files with 174 additions and 24 deletions
+37 -20
View File
@@ -16,6 +16,8 @@
namespace mod_data\output;
use action_menu;
use action_menu_link_secondary;
use moodle_url;
use templatable;
use renderable;
@@ -64,54 +66,69 @@ class presets implements templatable, renderable {
*/
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
View File
@@ -320,6 +320,7 @@ $string['portfolionotfile'] = 'Export to a portfolio rather than a file (csv and
$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';
+4
View File
@@ -148,3 +148,7 @@
#page-mod-data-edit .datatagcontrol {
padding-left: 10px;
}
.preset_action_menu .dropdown-toggle::after {
display: none;
}
+51 -4
View File
@@ -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();
+81
View File
@@ -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"