Commit e82b2ed8 authored by victor's avatar victor 🙇
Browse files

Merge branch 'MDL-72565-integration' of https://github.com/roland04/moodle

parents e1c9c7b0 68eb55b8
......@@ -48,6 +48,11 @@ $string['audiencedeleted'] = 'Deleted audience \'{$a}\'';
$string['audiencemultiselectpostfix'] = '{$a->elements} plus {$a->morecount} more';
$string['audiencenotsaved'] = 'Audience not saved';
$string['audiencesaved'] = 'Audience saved';
$string['cardview'] = 'Card view';
$string['cardview_help'] = 'Card view allows you to define the layout of your report when viewed on narrow devices. Columns will collapse beyond the limit set here, with a toggle to expand the card to view all report data.';
$string['cardviewfirstcolumntitle'] = 'First column title';
$string['cardviewsettingssaved'] = 'Card view settings saved';
$string['cardviewvisiblecolumns'] = 'Columns visible';
$string['columnadded'] = 'Added column \'{$a}\'';
$string['columnaggregated'] = 'Aggregated column \'{$a}\'';
$string['columndeleted'] = 'Deleted column \'{$a}\'';
......
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="lib/db" VERSION="20211011" COMMENT="XMLDB file for core Moodle tables"
<XMLDB PATH="lib/db" VERSION="20211106" COMMENT="XMLDB file for core Moodle tables"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
>
......@@ -4387,6 +4387,7 @@
<FIELD NAME="source" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="type" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="conditiondata" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="settingsdata" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="component" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="area" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
......
......@@ -3130,5 +3130,20 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2021110800.02);
}
if ($oldversion < 2021110800.03) {
// Define field settingsdata to be added to reportbuilder_report.
$table = new xmldb_table('reportbuilder_report');
$field = new xmldb_field('settingsdata', XMLDB_TYPE_TEXT, null, null, null, null, null, 'conditiondata');
// Conditionally launch add field settingsdata.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Main savepoint reached.
upgrade_main_savepoint(true, 2021110800.03);
}
return true;
}
......@@ -87,6 +87,9 @@ class flexible_table {
/** @var string[] Columns that are expected to contain a users fullname. */
protected $userfullnamecolumns = ['fullname'];
/** @var array[] Attributes for each column */
private $columnsattributes = [];
/**
* @var bool Whether or not to store table properties in the user_preferences table.
*/
......@@ -426,6 +429,16 @@ class flexible_table {
}
}
/**
* Sets the given $attributes to $this->columnsattributes.
* Column attributes will be added to every cell in the column.
*
* @param array[] $attributes e.g. ['c0_firstname' => ['data-foo' => 'bar']]
*/
public function set_columnsattributes(array $attributes): void {
$this->columnsattributes = $attributes;
}
/**
* Sets all columns' $propertys to the given $value in $this->column_style.
* @param int $property
......@@ -454,12 +467,14 @@ class flexible_table {
$this->columns = array();
$this->column_style = array();
$this->column_class = array();
$this->columnsattributes = [];
$colnum = 0;
foreach ($columns as $column) {
$this->columns[$column] = $colnum++;
$this->column_style[$column] = array();
$this->column_class[$column] = '';
$this->columnsattributes[$column] = [];
$this->column_suppress[$column] = false;
}
}
......@@ -1101,34 +1116,7 @@ class flexible_table {
array('class' => 'tabledivider')), array('colspan' => $colcount));
} else {
$colbyindex = array_flip($this->columns);
foreach ($row as $index => $data) {
$column = $colbyindex[$index];
$attributes = [
'class' => "cell c{$index}" . $this->column_class[$column],
'id' => "{$rowid}_c{$index}",
'style' => $this->make_styles_string($this->column_style[$column]),
];
$celltype = 'td';
if ($this->headercolumn && $column == $this->headercolumn) {
$celltype = 'th';
$attributes['scope'] = 'row';
}
if (empty($this->prefs['collapse'][$column])) {
if ($this->column_suppress[$column] && $suppress_lastrow !== NULL && $suppress_lastrow[$index] === $data) {
$content = '&nbsp;';
} else {
$content = $data;
}
} else {
$content = '&nbsp;';
}
$html .= html_writer::tag($celltype, $content, $attributes);
}
$html .= $this->get_row_cells_html($rowid, $row, $suppress_lastrow);
}
$html .= html_writer::end_tag('tr');
......@@ -1141,6 +1129,49 @@ class flexible_table {
return $html;
}
/**
* Generate html code for the row cells.
*
* @param string $rowid
* @param array $row
* @param array|null $suppresslastrow
* @return string
*/
public function get_row_cells_html(string $rowid, array $row, ?array $suppresslastrow): string {
$html = '';
$colbyindex = array_flip($this->columns);
foreach ($row as $index => $data) {
$column = $colbyindex[$index];
$attributes = [
'class' => "cell c{$index}" . $this->column_class[$column],
'id' => "{$rowid}_c{$index}",
'style' => $this->make_styles_string($this->column_style[$column]),
];
$celltype = 'td';
if ($this->headercolumn && $column == $this->headercolumn) {
$celltype = 'th';
$attributes['scope'] = 'row';
}
$attributes += $this->columnsattributes[$column] ?? [];
if (empty($this->prefs['collapse'][$column])) {
if ($this->column_suppress[$column] && $suppresslastrow !== null && $suppresslastrow[$index] === $data) {
$content = '&nbsp;';
} else {
$content = $data;
}
} else {
$content = '&nbsp;';
}
$html .= html_writer::tag($celltype, $content, $attributes);
}
return $html;
}
/**
* This function is not part of the public api.
*/
......
......@@ -2,6 +2,9 @@ This files describes API changes in core libraries and APIs,
information provided here is intended especially for developers.
=== 4.0 ===
* New method flexible_table::set_columnsattributes() has been introduced to add column attributes applied in every cell.
* New method flexible_table::get_row_cells_html() has been introduced, extracted from flexible_table::get_row_html
so it can be overriden individually.
* Since Boxnet has been remove from core then boxnet_client() class has been removed from core too.
* New navigation classes to mimic the new navigation project. The existing navigation callbacks are still available and
will be called. The following behaviour will be the new standard for nodes added via callbacks:
......
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
......@@ -32,6 +32,7 @@ import {init as columnsEditorInit} from 'core_reportbuilder/local/editor/columns
import {init as conditionsEditorInit} from 'core_reportbuilder/local/editor/conditions';
import {init as filtersEditorInit} from 'core_reportbuilder/local/editor/filters';
import {init as sortingEditorInit} from 'core_reportbuilder/local/editor/sorting';
import {init as cardviewEditorInit} from 'core_reportbuilder/local/editor/card_view';
import {getReport} from 'core_reportbuilder/local/repository/reports';
let initialized = false;
......@@ -44,6 +45,7 @@ export const init = () => {
conditionsEditorInit(initialized);
filtersEditorInit(initialized);
sortingEditorInit(initialized);
cardviewEditorInit(initialized);
// Ensure we only add our listeners once (can be called multiple times by mustache template).
if (initialized) {
......
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder card view editor
*
* @module core_reportbuilder/local/editor/card_view
* @copyright 2021 Mikel Martín <mikel@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
"use strict";
import DynamicForm from 'core_form/dynamicform';
import {add as addToast} from 'core/toast';
import {get_string as getString} from "core/str";
import {subscribe as subscribe} from 'core/pubsub';
import Notification from 'core/notification';
import * as reportEvents from 'core_reportbuilder/local/events';
import * as reportSelectors from 'core_reportbuilder/local/selectors';
let cardViewForm = null;
/**
* Initialise card view form, must be called on each init because the form container is re-created when switching editor modes
*/
const initCardViewForm = () => {
const cardViewFormContainer = document.querySelector(reportSelectors.regions.settingsCardView);
if (!cardViewFormContainer) {
return;
}
cardViewForm = new DynamicForm(cardViewFormContainer, '\\core_reportbuilder\\form\\card_view');
cardViewForm.addEventListener(cardViewForm.events.FORM_SUBMITTED, (event) => {
event.preventDefault();
getString('cardviewsettingssaved', 'core_reportbuilder')
.then(addToast)
.catch(Notification.exception);
});
};
/**
* Initialise module
*
* @param {Boolean} initialized Ensure we only add our listeners once
*/
export const init = (initialized) => {
initCardViewForm();
if (initialized) {
return;
}
// Update form each time a column is added or removed to the custom report.
subscribe(reportEvents.publish.reportColumnsUpdated, () => {
const reportElement = document.querySelector(reportSelectors.regions.report);
cardViewForm.load({reportid: reportElement.dataset.reportId});
});
};
......@@ -63,6 +63,9 @@ const initConditionsForm = () => {
// Handle dynamic conditions form.
const reportElement = document.querySelector(reportSelectors.regions.report);
const conditionFormContainer = reportElement.querySelector(reportSelectors.regions.settingsConditions);
if (!conditionFormContainer) {
return;
}
const conditionForm = new DynamicForm(conditionFormContainer, '\\core_reportbuilder\\form\\condition');
// Submit report conditions.
......
......@@ -52,6 +52,7 @@ const SELECTORS = {
audienceEmptyMessage: '[data-region=no-instances-message]',
audienceDescription: '[data-region=audience-description]',
audienceNotSavedLabel: '[data-region=audience-not-saved]',
settingsCardView: '[data-region="settings-cardview"]',
},
actions: {
reportActionPopup: '[data-action="report-action-popup"]',
......@@ -71,6 +72,7 @@ const SELECTORS = {
audienceAdd: '[data-action="add-audience"]',
audienceEdit: '[data-action="edit-audience"]',
audienceDelete: '[data-action="delete-audience"]',
toggleCardView: '[data-action="toggle-card"]',
},
};
......
......@@ -26,6 +26,13 @@ import * as reportSelectors from 'core_reportbuilder/local/selectors';
import {setPageNumber, refreshTableContent} from 'core_table/dynamic';
import * as tableSelectors from 'core_table/local/dynamic/selectors';
const CLASSES = {
COLLAPSED: 'collapsed',
EXPANDED: 'show',
ICONUP: 'fa-angle-up',
ICONDOWN: 'fa-angle-down'
};
let initialized = false;
/**
......@@ -65,5 +72,26 @@ export const init = () => {
window.openpopup(event, popupAction.jsfunctionargs);
});
// Listen for card view toggle events.
document.addEventListener('click', (event) => {
const toggleCard = event.target.closest(reportSelectors.actions.toggleCardView);
if (toggleCard) {
const tableCard = toggleCard.closest('tr');
const toggleIcon = toggleCard.querySelector('i');
event.preventDefault();
if (toggleCard.classList.contains(CLASSES.COLLAPSED)) {
tableCard.classList.add(CLASSES.EXPANDED);
toggleIcon.classList.replace(CLASSES.ICONDOWN, CLASSES.ICONUP);
toggleCard.classList.remove(CLASSES.COLLAPSED);
toggleCard.setAttribute('aria-expanded', "true");
} else {
tableCard.classList.remove(CLASSES.EXPANDED);
toggleIcon.classList.replace(CLASSES.ICONUP, CLASSES.ICONDOWN);
toggleCard.classList.add(CLASSES.COLLAPSED);
toggleCard.removeAttribute('aria-expanded');
}
}
});
initialized = true;
};
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment