MDL-73495 core: Fix data attributes not being passed to individual tabs

This commit is contained in:
David Matamoros 2022-01-04 16:35:00 +01:00
parent 541d999d27
commit 5bef42d324
6 changed files with 42 additions and 28 deletions

View File

@ -1,2 +1,2 @@
define ("core/dynamic_tabs",["exports","jquery","core/templates","core/loadingicon","core/notification","core/pending","core/str","core/local/repository/dynamic_tabs","core_form/changechecker"],function(a,b,c,d,e,f,g,h,i){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=j(b);c=j(c);e=j(e);f=j(f);function j(a){return a&&a.__esModule?a:{default:a}}function k(a,b){var c=Object.keys(a);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(a);if(b)d=d.filter(function(b){return Object.getOwnPropertyDescriptor(a,b).enumerable});c.push.apply(c,d)}return c}function l(a){for(var b=1,c;b<arguments.length;b++){c=null!=arguments[b]?arguments[b]:{};if(b%2){k(Object(c),!0).forEach(function(b){m(a,b,c[b])})}else if(Object.getOwnPropertyDescriptors){Object.defineProperties(a,Object.getOwnPropertyDescriptors(c))}else{k(Object(c)).forEach(function(b){Object.defineProperty(a,b,Object.getOwnPropertyDescriptor(c,b))})}}return a}function m(a,b,c){if(b in a){Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0})}else{a[b]=c}return a}function n(a,b){return s(a)||r(a,b)||p(a,b)||o()}function o(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function p(a,b){if(!a)return;if("string"==typeof a)return q(a,b);var c=Object.prototype.toString.call(a).slice(8,-1);if("Object"===c&&a.constructor)c=a.constructor.name;if("Map"===c||"Set"===c)return Array.from(c);if("Arguments"===c||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c))return q(a,b)}function q(a,b){if(null==b||b>a.length)b=a.length;for(var c=0,d=Array(b);c<b;c++){d[c]=a[c]}return d}function r(a,b){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(a)))return;var c=[],d=!0,e=!1,f=void 0;try{for(var g=a[Symbol.iterator](),h;!(d=(h=g.next()).done);d=!0){c.push(h.value);if(b&&c.length===b)break}}catch(a){e=!0;f=a}finally{try{if(!d&&null!=g["return"])g["return"]()}finally{if(e)throw f}}return c}function s(a){if(Array.isArray(a))return a}var t={dynamicTabs:".dynamictabs",activeTab:".dynamictabs .nav-link.active",allActiveTabs:".dynamictabs .nav-link[data-toggle=\"tab\"]:not(.disabled)",tabContent:".dynamictabs .tab-pane [data-tab-content]",tabToggle:"a[data-toggle=\"tab\"]",tabPane:".dynamictabs .tab-pane",forTabName:function(a){return".dynamictabs [data-tab-content=\"".concat(a,"\"]")},forTabId:function(a){return".dynamictabs [data-toggle=\"tab\"][href=\"#".concat(a,"\"]")}},u=function(){var a=(0,b.default)(t.tabToggle);a.on("click",function(a){if(!(0,i.isAnyWatchedFormDirty)()){return}a.preventDefault();a.stopPropagation();(0,g.get_strings)([{key:"changesmade",component:"moodle"},{key:"changesmadereallygoaway",component:"moodle"},{key:"confirm",component:"moodle"}]).then(function(c){var d=n(c,3),f=d[0],g=d[1],h=d[2];return e.default.confirm(f,g,h,null,function(){(0,i.resetAllFormDirtyStates)();(0,b.default)(a.target).trigger(a.type)})}).catch(e.default.exception)});a.on("show.bs.tab",function(){var a=v();if(a){var b=document.querySelector(t.forTabName(a));b.textContent=""}}).on("shown.bs.tab",function(){var a=(0,b.default)((0,b.default)(this).attr("href"));if(1!==a.length){return}x(a.attr("id"))});if(!B()){var c=document.querySelector(t.allActiveTabs);if(c){A(c.getAttribute("aria-controls"))}else{var d=document.querySelector(t.tabPane);if(d){d.classList.add("active","show");x(d.getAttribute("id"))}}}};a.init=u;var v=function(){var a=document.querySelector(t.activeTab);return(null===a||void 0===a?void 0:a.getAttribute("aria-controls"))||null},w=function(){var a=document.querySelector(t.tabContent);return(null===a||void 0===a?void 0:a.dataset.tabContent)||null},x=function(a){var b,g,i=1<arguments.length&&arguments[1]!==void 0?arguments[1]:{};a=null!==(b=null!==(g=a)&&void 0!==g?g:v())&&void 0!==b?b:w();var j=document.querySelector(t.forTabName(a));if(!j){return}var k=new f.default("core/dynamic_tabs:loadTab:"+a),m=j.closest(t.dynamicTabs),n=l({reportid:m.dataset.reportid,id:m.dataset.id},i),o="";(0,d.addIconToContainer)(j).then(function(){return(0,h.getContent)(j.dataset.tabClass,JSON.stringify(n))}).then(function(a){o=a.javascript;return c.default.render(a.template,JSON.parse(a.content))}).then(function(a,b){return c.default.replaceNodeContents(j,a,b+o)}).then(function(){k.resolve();return null}).catch(e.default.exception)},y=function(a){return document.querySelector(t.forTabId(a))},z=function(a){return document.getElementById(a)},A=function(a){var b=y(a);if(!b){return!1}x(a);b.classList.add("active");z(a).classList.add("active","show");return!0},B=function(){var a=document.location.hash;if(a.match(/^#\w+$/g)){return A(a.replace(/^#/g,""))}return!1}});
define ("core/dynamic_tabs",["exports","jquery","core/templates","core/loadingicon","core/notification","core/pending","core/str","core/local/repository/dynamic_tabs","core_form/changechecker"],function(a,b,c,d,e,f,g,h,i){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=j(b);c=j(c);e=j(e);f=j(f);function j(a){return a&&a.__esModule?a:{default:a}}function k(a,b){var c=Object.keys(a);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(a);if(b)d=d.filter(function(b){return Object.getOwnPropertyDescriptor(a,b).enumerable});c.push.apply(c,d)}return c}function l(a){for(var b=1,c;b<arguments.length;b++){c=null!=arguments[b]?arguments[b]:{};if(b%2){k(Object(c),!0).forEach(function(b){m(a,b,c[b])})}else if(Object.getOwnPropertyDescriptors){Object.defineProperties(a,Object.getOwnPropertyDescriptors(c))}else{k(Object(c)).forEach(function(b){Object.defineProperty(a,b,Object.getOwnPropertyDescriptor(c,b))})}}return a}function m(a,b,c){if(b in a){Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0})}else{a[b]=c}return a}function n(a,b){return s(a)||r(a,b)||p(a,b)||o()}function o(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function p(a,b){if(!a)return;if("string"==typeof a)return q(a,b);var c=Object.prototype.toString.call(a).slice(8,-1);if("Object"===c&&a.constructor)c=a.constructor.name;if("Map"===c||"Set"===c)return Array.from(c);if("Arguments"===c||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c))return q(a,b)}function q(a,b){if(null==b||b>a.length)b=a.length;for(var c=0,d=Array(b);c<b;c++){d[c]=a[c]}return d}function r(a,b){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(a)))return;var c=[],d=!0,e=!1,f=void 0;try{for(var g=a[Symbol.iterator](),h;!(d=(h=g.next()).done);d=!0){c.push(h.value);if(b&&c.length===b)break}}catch(a){e=!0;f=a}finally{try{if(!d&&null!=g["return"])g["return"]()}finally{if(e)throw f}}return c}function s(a){if(Array.isArray(a))return a}var t={dynamicTabs:".dynamictabs",activeTab:".dynamictabs .nav-link.active",allActiveTabs:".dynamictabs .nav-link[data-toggle=\"tab\"]:not(.disabled)",tabContent:".dynamictabs .tab-pane [data-tab-content]",tabToggle:"a[data-toggle=\"tab\"]",tabPane:".dynamictabs .tab-pane",forTabName:function(a){return".dynamictabs [data-tab-content=\"".concat(a,"\"]")},forTabId:function(a){return".dynamictabs [data-toggle=\"tab\"][href=\"#".concat(a,"\"]")}},u=function(){var a=(0,b.default)(t.tabToggle);a.on("click",function(a){if(!(0,i.isAnyWatchedFormDirty)()){return}a.preventDefault();a.stopPropagation();(0,g.get_strings)([{key:"changesmade",component:"moodle"},{key:"changesmadereallygoaway",component:"moodle"},{key:"confirm",component:"moodle"}]).then(function(c){var d=n(c,3),f=d[0],g=d[1],h=d[2];return e.default.confirm(f,g,h,null,function(){(0,i.resetAllFormDirtyStates)();(0,b.default)(a.target).trigger(a.type)})}).catch(e.default.exception)});a.on("show.bs.tab",function(){var a=v();if(a){var b=document.querySelector(t.forTabName(a));b.textContent=""}}).on("shown.bs.tab",function(){var a=(0,b.default)((0,b.default)(this).attr("href"));if(1!==a.length){return}x(a.attr("id"))});if(!B()){var c=document.querySelector(t.allActiveTabs);if(c){A(c.getAttribute("aria-controls"))}else{var d=document.querySelector(t.tabPane);if(d){d.classList.add("active","show");x(d.getAttribute("id"))}}}};a.init=u;var v=function(){var a=document.querySelector(t.activeTab);return(null===a||void 0===a?void 0:a.getAttribute("aria-controls"))||null},w=function(){var a=document.querySelector(t.tabContent);return(null===a||void 0===a?void 0:a.dataset.tabContent)||null},x=function(a){var b,g;a=null!==(b=null!==(g=a)&&void 0!==g?g:v())&&void 0!==b?b:w();var i=document.querySelector(t.forTabName(a));if(!i){return}var j=new f.default("core/dynamic_tabs:loadTab:"+a),k="";(0,d.addIconToContainer)(i).then(function(){var a=l({},i.dataset);delete a.tabClass;delete a.tabContent;return(0,h.getContent)(i.dataset.tabClass,JSON.stringify(a))}).then(function(a){k=a.javascript;return c.default.render(a.template,JSON.parse(a.content))}).then(function(a,b){return c.default.replaceNodeContents(i,a,b+k)}).then(function(){j.resolve();return null}).catch(e.default.exception)},y=function(a){return document.querySelector(t.forTabId(a))},z=function(a){return document.getElementById(a)},A=function(a){var b=y(a);if(!b){return!1}x(a);b.classList.add("active");z(a).classList.add("active","show");return!0},B=function(){var a=document.location.hash;if(a.match(/^#\w+$/g)){return A(a.replace(/^#/g,""))}return!1}});
//# sourceMappingURL=dynamic_tabs.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -128,29 +128,24 @@ const getFirstTabName = () => {
* Loads contents of a tab using an AJAX request
*
* @param {String} tabName
* @param {Object} additionalData additional data to pass to WS
*/
const loadTab = (tabName, additionalData = {}) => {
const loadTab = (tabName) => {
// If tabName is not specified find the active tab, or if is not defined, the first available tab.
tabName = tabName ?? getActiveTabName() ?? getFirstTabName();
const tab = document.querySelector(SELECTORS.forTabName(tabName));
if (!tab) {
return;
}
const pendingPromise = new Pending('core/dynamic_tabs:loadTab:' + tabName);
const tabdata = tab.closest(SELECTORS.dynamicTabs);
const wsData = {
'reportid': tabdata.dataset.reportid,
'id': tabdata.dataset.id,
...additionalData
};
let tabjs = '';
addIconToContainer(tab)
.then(() => {
return getContent(tab.dataset.tabClass, JSON.stringify(wsData));
let tabArgs = {...tab.dataset};
delete tabArgs.tabClass;
delete tabArgs.tabContent;
return getContent(tab.dataset.tabClass, JSON.stringify(tabArgs));
})
.then((data) => {
tabjs = data.javascript;

View File

@ -31,19 +31,15 @@ use templatable;
*/
class dynamic_tabs implements templatable {
/** @var array */
protected $attributes;
/** @var base[] */
protected $tabs = [];
/**
* tabs constructor.
*
* @param array $attributes additional attributes that will be passed to the webservice
* @param base[] $tabs array of tab
*/
public function __construct(array $attributes = [], array $tabs = []) {
$this->attributes = $attributes;
public function __construct(array $tabs = []) {
foreach ($tabs as $tab) {
$this->add_tab($tab);
}
@ -66,20 +62,21 @@ class dynamic_tabs implements templatable {
*/
public function export_for_template(renderer_base $output): array {
$data = [
'dataattributes' => [],
'tabs' => []
];
foreach ($this->attributes as $name => $value) {
$data['dataattributes'][] = ['name' => $name, 'value' => $value];
}
foreach ($this->tabs as $tab) {
$dataattributes = [];
foreach ($tab->get_data() as $name => $value) {
$dataattributes[] = ['name' => $name, 'value' => $value];
}
$data['tabs'][] = [
'shortname' => $tab->get_tab_id(),
'displayname' => $tab->get_tab_label(),
'enabled' => $tab->is_available(),
'tabclass' => get_class($tab)
'tabclass' => get_class($tab),
'dataattributes' => $dataattributes,
];
}

View File

@ -83,4 +83,22 @@ abstract class base implements templatable {
* @return string
*/
abstract public function get_template(): string;
/**
* Return tab data attributes
*
* @return array
*/
public function get_data(): array {
return $this->data;
}
/**
* Add custom data to the tab data attributes
*
* @param array $data
*/
public function add_data(array $data): void {
$this->data = array_merge($this->data, $data);
}
}

View File

@ -44,7 +44,7 @@
M.util.js_pending('core_dynamic_tabs_init');
</script>
<div class="dynamictabs" {{#dataattributes}}data-{{name}}="{{value}}" {{/dataattributes}} >
<div class="dynamictabs">
{{#showtabsnavigation}}
<ul class="nav nav-tabs mb-4" id="dynamictabs-tabs" role="tablist">
{{#tabs}}
@ -58,10 +58,14 @@
{{/showtabsnavigation}}
<div class="tab-content" id="dynamictabs-content">
{{#tabs}}
<div class="tab-pane fade {{#active}}show active{{/active}}" id="{{shortname}}" role="tabpanel" aria-labelledby="{{shortname}}-tab">
<div class="container-fluid" data-tab-content="{{shortname}}" data-tab-class="{{tabclass}}">
{{{content}}}
</div>
<div class="tab-pane fade container-fluid {{#active}}show active{{/active}}"
id="{{shortname}}"
role="tabpanel"
aria-labelledby="{{shortname}}-tab"
data-tab-content="{{shortname}}"
data-tab-class="{{tabclass}}"
{{#dataattributes}}data-{{name}}="{{value}}"{{/dataattributes}}>
{{{content}}}
</div>
{{/tabs}}
</div>