MDL-63996 core/tags: Pending JS for all tag code

This commit is contained in:
Andrew Nicols
2019-12-18 12:02:40 +08:00
parent dd8f4b46d4
commit 1c127290cf
4 changed files with 209 additions and 108 deletions
+1 -1
View File
@@ -1 +1 @@
define(["core/yui","jquery","core/log"],function(a,b,c){var d={types:{success:"core/notification_success",info:"core/notification_info",warning:"core/notification_warning",error:"core/notification_error"},fieldName:"user-notifications",fetchNotifications:function(){require(["core/ajax"],function(a){var b=a.call([{methodname:"core_fetch_notifications",args:{contextid:d.contextid}}]);b[0].done(d.addNotifications)})},addNotifications:function(a){a||(a=[]),b.each(a,function(a,b){d.renderNotification(b.template,b.variables)})},setupTargetRegion:function(){var a=b("#"+d.fieldName);if(a.length)return!1;var c=b("<span>").attr("id",d.fieldName);return a=b("#region-main"),a.length?a.prepend(c):(a=b('[role="main"]'),a.length?a.prepend(c):(a=b("body"),a.prepend(c)))},addNotification:function(a){var c=d.types.error;return a=b.extend({closebutton:!0,announce:!0,type:"error"},a),a.template?(c=a.template,delete a.template):a.type&&("undefined"!=typeof d.types[a.type]&&(c=d.types[a.type]),delete a.type),d.renderNotification(c,a)},renderNotification:function(a,e){return"undefined"!=typeof e.message&&e.message?void require(["core/templates"],function(c){c.render(a,e).done(function(a,e){b("#"+d.fieldName).prepend(a),c.runTemplateJS(e)}).fail(d.exception)}):void c.debug("Notification received without content. Skipping.")},alert:function(b,c,d){a.use("moodle-core-notification-alert",function(){var a=new M.core.alert({title:b,message:c,yesLabel:d});a.show()})},confirm:function(b,c,d,e,f,g){a.use("moodle-core-notification-confirm",function(){var a=new M.core.confirm({title:b,question:c,yesLabel:d,noLabel:e});a.on("complete-yes",function(){f()}),g&&a.on("complete-no",function(){g()}),a.show()})},exception:function(b){if("undefined"==typeof b.stack&&(b.stack=""),b.debuginfo&&(b.stack+=b.debuginfo+"\n"),!b.backtrace&&b.stacktrace&&(b.backtrace=b.stacktrace),b.backtrace){b.stack+=b.backtrace;var c=b.backtrace.match(/line ([^ ]*) of/),d=b.backtrace.match(/ of ([^:]*): /);c&&c[1]&&(b.lineNumber=c[1]),d&&d[1]&&(b.fileName=d[1],b.fileName.length>30&&(b.fileName="..."+b.fileName.substr(b.fileName.length-27)))}"undefined"==typeof b.name&&b.errorcode&&(b.name=b.errorcode),a.use("moodle-core-notification-exception",function(){var a=new M.core.exception(b);a.show()})}};return{init:function(a,b){d.contextid=a,d.setupTargetRegion(),d.addNotifications(b),d.fetchNotifications()},fetchNotifications:d.fetchNotifications,addNotification:d.addNotification,alert:d.alert,confirm:d.confirm,exception:d.exception}});
define(["core/yui","jquery","core/log","core/pending"],function(a,b,c,d){var e={types:{success:"core/notification_success",info:"core/notification_info",warning:"core/notification_warning",error:"core/notification_error"},fieldName:"user-notifications",fetchNotifications:function(){var a=new d("core/notification:fetchNotifications");require(["core/ajax"],function(b){var c=b.call([{methodname:"core_fetch_notifications",args:{contextid:e.contextid}}]);c[0].then(e.addNotifications).always(a.resolve)})},addNotifications:function(a){var c=new d("core/notification:addNotifications");a||(a=[]),b.each(a,function(a,b){e.renderNotification(b.template,b.variables)}),c.resolve()},setupTargetRegion:function(){var a=b("#"+e.fieldName);if(a.length)return!1;var c=b("<span>").attr("id",e.fieldName);return a=b("#region-main"),a.length?a.prepend(c):(a=b('[role="main"]'),a.length?a.prepend(c):(a=b("body"),a.prepend(c)))},addNotification:function(a){var c=new d("core/notification:addNotifications"),f=e.types.error;return a=b.extend({closebutton:!0,announce:!0,type:"error"},a),a.template?(f=a.template,delete a.template):a.type&&("undefined"!=typeof e.types[a.type]&&(f=e.types[a.type]),delete a.type),c.resolve(),e.renderNotification(f,a)},renderNotification:function(a,f){if("undefined"==typeof f.message||!f.message)return void c.debug("Notification received without content. Skipping.");var g=new d("core/notification:renderNotification");require(["core/templates"],function(c){c.render(a,f).then(function(a,d){b("#"+e.fieldName).prepend(a),c.runTemplateJS(d)}).always(g.resolve)["catch"](e.exception)})},alert:function(b,c,e){var f=new d("core/notification:alert");a.use("moodle-core-notification-alert",function(){var a=new M.core.alert({title:b,message:c,yesLabel:e});a.show(),f.resolve()})},confirm:function(b,c,e,f,g,h){var i=new d("core/notification:confirm");a.use("moodle-core-notification-confirm",function(){var a=new M.core.confirm({title:b,question:c,yesLabel:e,noLabel:f});a.on("complete-yes",function(){g()}),h&&a.on("complete-no",function(){h()}),a.show(),i.resolve()})},exception:function(b){var c=new d("core/notification:addNotifications");if("undefined"==typeof b.stack&&(b.stack=""),b.debuginfo&&(b.stack+=b.debuginfo+"\n"),!b.backtrace&&b.stacktrace&&(b.backtrace=b.stacktrace),b.backtrace){b.stack+=b.backtrace;var e=b.backtrace.match(/line ([^ ]*) of/),f=b.backtrace.match(/ of ([^:]*): /);e&&e[1]&&(b.lineNumber=e[1]),f&&f[1]&&(b.fileName=f[1],b.fileName.length>30&&(b.fileName="..."+b.fileName.substr(b.fileName.length-27)))}"undefined"==typeof b.name&&b.errorcode&&(b.name=b.errorcode),a.use("moodle-core-notification-exception",function(){var a=new M.core.exception(b);a.show(),c.resolve()})}};return{init:function(a,b){e.contextid=a,e.setupTargetRegion(),e.addNotifications(b),e.fetchNotifications()},fetchNotifications:e.fetchNotifications,addNotification:e.addNotification,alert:e.alert,confirm:e.confirm,exception:e.exception}});
+1 -1
View File
File diff suppressed because one or more lines are too long
+43 -14
View File
@@ -26,8 +26,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 2.9
*/
define(['core/yui', 'jquery', 'core/log'],
function(Y, $, log) {
define(['core/yui', 'jquery', 'core/log', 'core/pending'],
function(Y, $, log, Pending) {
var notificationModule = {
types: {
'success': 'core/notification_success',
@@ -39,6 +39,8 @@ function(Y, $, log) {
fieldName: 'user-notifications',
fetchNotifications: function() {
var pendingPromise = new Pending('core/notification:fetchNotifications');
require(['core/ajax'], function(ajax) {
var promises = ajax.call([{
methodname: 'core_fetch_notifications',
@@ -47,13 +49,17 @@ function(Y, $, log) {
}
}]);
// This currently fails when not logged in.
// eslint-disable-next-line promise/catch-or-return
promises[0]
.done(notificationModule.addNotifications)
;
.then(notificationModule.addNotifications)
.always(pendingPromise.resolve);
});
},
addNotifications: function(notifications) {
var pendingPromise = new Pending('core/notification:addNotifications');
if (!notifications) {
notifications = [];
}
@@ -61,6 +67,8 @@ function(Y, $, log) {
$.each(notifications, function(i, notification) {
notificationModule.renderNotification(notification.template, notification.variables);
});
pendingPromise.resolve();
},
setupTargetRegion: function() {
@@ -86,13 +94,15 @@ function(Y, $, log) {
},
addNotification: function(notification) {
var pendingPromise = new Pending('core/notification:addNotifications');
var template = notificationModule.types.error;
notification = $.extend({
closebutton: true,
announce: true,
type: 'error'
}, notification);
closebutton: true,
announce: true,
type: 'error'
}, notification);
if (notification.template) {
template = notification.template;
@@ -104,6 +114,8 @@ function(Y, $, log) {
delete notification.type;
}
pendingPromise.resolve();
return notificationModule.renderNotification(template, notification);
},
@@ -112,18 +124,25 @@ function(Y, $, log) {
log.debug('Notification received without content. Skipping.');
return;
}
var pendingPromise = new Pending('core/notification:renderNotification');
require(['core/templates'], function(templates) {
templates.render(template, variables)
.done(function(html, js) {
$('#' + notificationModule.fieldName).prepend(html);
templates.runTemplateJS(js);
})
.fail(notificationModule.exception)
;
.then(function(html, js) {
$('#' + notificationModule.fieldName).prepend(html);
templates.runTemplateJS(js);
return;
})
.always(pendingPromise.resolve)
.catch(notificationModule.exception);
});
},
alert: function(title, message, yesLabel) {
var pendingPromise = new Pending('core/notification:alert');
// Here we are wrapping YUI. This allows us to start transitioning, but
// wait for a good alternative without having inconsistent dialogues.
Y.use('moodle-core-notification-alert', function() {
@@ -134,10 +153,14 @@ function(Y, $, log) {
});
alert.show();
pendingPromise.resolve();
});
},
confirm: function(title, question, yesLabel, noLabel, yesCallback, noCallback) {
var pendingPromise = new Pending('core/notification:confirm');
// Here we are wrapping YUI. This allows us to start transitioning, but
// wait for a good alternative without having inconsistent dialogues.
Y.use('moodle-core-notification-confirm', function() {
@@ -157,10 +180,14 @@ function(Y, $, log) {
});
}
modal.show();
pendingPromise.resolve();
});
},
exception: function(ex) {
var pendingPromise = new Pending('core/notification:addNotifications');
// Fudge some parameters.
if (typeof ex.stack == 'undefined') {
ex.stack = '';
@@ -193,6 +220,8 @@ function(Y, $, log) {
var modal = new M.core.exception(ex);
modal.show();
pendingPromise.resolve();
});
}
};
+164 -92
View File
@@ -22,8 +22,25 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.0
*/
define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str', 'core/modal_factory', 'core/modal_events'],
function($, ajax, templates, notification, str, ModalFactory, ModalEvents) {
define([
'jquery',
'core/ajax',
'core/templates',
'core/notification',
'core/str',
'core/modal_factory',
'core/modal_events',
'core/pending',
], function(
$,
ajax,
templates,
notification,
str,
ModalFactory,
ModalEvents,
Pending
) {
return /** @alias module:core/tag */ {
/**
@@ -34,27 +51,31 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
initTagindexPage: function() {
// Click handler for changing tag type.
$('body').delegate('.tagarea[data-ta] a[data-quickload=1]', 'click', function(e) {
var pendingPromise = new Pending('core/tag:initTagindexPage');
e.preventDefault();
var target = $(this),
query = target[0].search.replace(/^\?/, ''),
tagarea = target.closest('.tagarea[data-ta]'),
args = query.split('&').reduce(function(s, c) {
var target = $(this);
var query = target[0].search.replace(/^\?/, '');
var tagarea = target.closest('.tagarea[data-ta]');
var args = query.split('&').reduce(function(s, c) {
var t = c.split('=');
s[t[0]] = decodeURIComponent(t[1]);
return s;
}, {});
var promises = ajax.call([{
ajax.call([{
methodname: 'core_tag_get_tagindex',
args: {tagindex: args}
}], true);
$.when.apply($, promises)
.done(function(data) {
templates.render('core_tag/index', data).done(function(html) {
tagarea.replaceWith(html);
});
});
}])[0]
.then(function(data) {
return templates.render('core_tag/index', data);
})
.then(function(html, js) {
templates.replaceNode(tagarea, html, js);
return;
})
.always(pendingPromise.resolve)
.catch(notification.exception);
});
},
@@ -64,17 +85,29 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
* @method initManagePage
*/
initManagePage: function() {
// Set cell 'time modified' to 'now' when any of the element is updated in this row.
$('body').on('updated', '[data-inplaceeditable]', function(e) {
str.get_string('selecttag', 'core_tag', e.ajaxreturn.value)
.then(function(s) {
return $('label[for="tagselect' + e.ajaxreturn.itemid + '"]').html(s);
})
.fail(notification.exception);
str.get_string('now').done(function(s) {
$(e.target).closest('tr').find('td.col-timemodified').html(s);
});
var pendingPromise = new Pending('core/tag:initManagePage');
str.get_strings([
{
key: 'selecttag',
component: 'core_tag',
},
{
key: 'now',
component: 'core',
},
])
.then(function(result) {
$('label[for="tagselect' + e.ajaxreturn.itemid + '"]').html(result[0]);
$(e.target).closest('tr').find('td.col-timemodified').html(result[1]);
return;
})
.always(pendingPromise.resolve)
.catch(notification.exception);
if (e.ajaxreturn.itemtype === 'tagflag') {
var row = $(e.target).closest('tr');
if (e.ajaxreturn.value === '0') {
@@ -87,60 +120,76 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
// Confirmation for single tag delete link.
$('.tag-management-table').delegate('a.tagdelete', 'click', function(e) {
var pendingPromise = new Pending('core/tag:tagdelete');
e.preventDefault();
var href = $(this).attr('href');
str.get_strings([
{key: 'delete'},
{key: 'confirmdeletetag', component: 'tag'},
{key: 'yes'},
{key: 'no'},
]).done(function(s) {
notification.confirm(s[0], s[1], s[2], s[3], function() {
window.location.href = href;
});
}
);
{key: 'delete', component: 'core'},
{key: 'confirmdeletetag', component: 'tag'},
{key: 'yes', component: 'core'},
{key: 'no', component: 'core'},
])
.then(function(s) {
return notification.confirm(s[0], s[1], s[2], s[3], function() {
window.location.href = href;
});
})
.always(pendingPromise.resolve)
.catch(notification.exception);
});
// Confirmation for bulk tag delete button.
$("#tag-management-delete").click(function(e) {
var form = $(this).closest('form').get(0),
cnt = $(form).find("input[type=checkbox]:checked").length;
var form = $(this).closest('form').get(0);
var cnt = $(form).find("input[type=checkbox]:checked").length;
if (!cnt) {
return;
}
var pendingPromise = new Pending('core/tag:tag-management-delete');
var tempElement = $("<input type='hidden'/>").attr('name', this.name);
e.preventDefault();
str.get_strings([
{key: 'delete'},
{key: 'confirmdeletetags', component: 'tag'},
{key: 'yes'},
{key: 'no'},
]).done(function(s) {
notification.confirm(s[0], s[1], s[2], s[3], function() {
tempElement.appendTo(form);
form.submit();
});
}
);
{key: 'delete', component: 'core'},
{key: 'confirmdeletetags', component: 'tag'},
{key: 'yes', component: 'core'},
{key: 'no', component: 'core'},
])
.then(function(s) {
return notification.confirm(s[0], s[1], s[2], s[3], function() {
tempElement.appendTo(form);
form.submit();
});
})
.always(pendingPromise.resolve)
.catch(notification.exception);
});
// Confirmation for bulk tag combine button.
$("#tag-management-combine").click(function(e) {
var pendingPromise = new Pending('core/tag:tag-management-combine');
e.preventDefault();
var form = $(this).closest('form').get(0),
tags = $(form).find("input[type=checkbox]:checked");
var form = $(this).closest('form').get(0);
var tags = $(form).find("input[type=checkbox]:checked");
if (tags.length <= 1) {
str.get_strings([
{key: 'combineselected', component: 'tag'},
{key: 'selectmultipletags', component: 'tag'},
{key: 'ok'},
]).done(function(s) {
notification.alert(s[0], s[1], s[2]);
}
);
])
.then(function(s) {
return notification.alert(s[0], s[1], s[2]);
})
.always(pendingPromise.resolve)
.catch(notification.exception);
return;
}
var tempElement = $("<input type='hidden'/>").attr('name', this.name);
var saveButtonText = '';
var tagOptions = [];
@@ -155,8 +204,9 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
str.get_strings([
{key: 'combineselected', component: 'tag'},
{key: 'continue'}
]).then(function(langStrings) {
{key: 'continue', component: 'core'}
])
.then(function(langStrings) {
var modalTitle = langStrings[0];
saveButtonText = langStrings[1];
var templateContext = {
@@ -167,9 +217,14 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
body: templates.render('core_tag/combine_tags', templateContext),
type: ModalFactory.types.SAVE_CANCEL
});
}).then(function(modal) {
})
.then(function(modal) {
modal.setSaveButtonText(saveButtonText);
return modal;
})
.then(function(modal) {
// Handle save event.
modal.getRoot().on(ModalEvents.save, function(e) {
e.preventDefault();
@@ -196,7 +251,9 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
return;
}).catch(notification.exception);
})
.always(pendingPromise.resolve)
.catch(notification.exception);
});
// When user changes tag name to some name that already exists suggest to combine the tags.
@@ -205,43 +262,41 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
var newvalue = e.newvalue; // The value that user tried to udpated the element to.
var tagid = $(e.target).attr('data-itemid');
if (exception.errorcode === 'namesalreadybeeingused') {
var pendingPromise = new Pending('core/tag:updatefailed');
e.preventDefault(); // This will prevent default error dialogue.
str.get_strings([
{key: 'nameuseddocombine', component: 'tag'},
{key: 'yes'},
{key: 'cancel'},
]).done(function(s) {
notification.confirm(e.message, s[0], s[1], s[2], function() {
])
.then(function(s) {
return notification.confirm(e.message, s[0], s[1], s[2], function() {
window.location.href = window.location.href + "&newname=" + encodeURIComponent(newvalue) +
"&tagid=" + encodeURIComponent(tagid) +
'&action=renamecombine&sesskey=' + M.cfg.sesskey;
});
});
})
.always(pendingPromise.resolve)
.catch(notification.exception);
}
});
// Form for adding standard tags.
$('body').on('click', 'a[data-action=addstandardtag]', function(e) {
var pendingPromise = new Pending('core/tag:addstandardtag');
e.preventDefault();
var saveButtonText = '';
str.get_strings([
{key: 'addotags', component: 'tag'},
{key: 'continue'}
]).then(function(langStrings) {
var modalTitle = langStrings[0];
saveButtonText = langStrings[1];
var templateContext = {
return ModalFactory.create({
title: str.get_string('addotags', 'tag'),
body: templates.render('core_tag/add_tags', {
actionurl: window.location.href,
sesskey: M.cfg.sesskey
};
return ModalFactory.create({
title: modalTitle,
body: templates.render('core_tag/add_tags', templateContext),
type: ModalFactory.types.SAVE_CANCEL
});
}).then(function(modal) {
modal.setSaveButtonText(saveButtonText);
}),
type: ModalFactory.types.SAVE_CANCEL
})
.then(function(modal) {
modal.setSaveButtonText(str.get_string('continue', 'core'));
// Handle save event.
modal.getRoot().on(ModalEvents.save, function(e) {
@@ -285,7 +340,9 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
return;
}).catch(notification.exception);
})
.always(pendingPromise.resolve)
.catch(notification.exception);
});
},
@@ -296,6 +353,8 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
*/
initManageCollectionsPage: function() {
$('body').on('updated', '[data-inplaceeditable]', function(e) {
var pendingPromise = new Pending('core/tag:initManageCollectionsPage-updated');
var ajaxreturn = e.ajaxreturn,
areaid, collid, isenabled;
if (ajaxreturn.component === 'core_tag' && ajaxreturn.itemtype === 'tagareaenable') {
@@ -319,9 +378,13 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
$(".tag-collections-table ul[data-collectionid=" + collid + "] li[data-areaid=" + areaid + "]").show();
}
}
pendingPromise.resolve();
});
$('body').on('click', '.addtagcoll > a', function(e) {
var pendingPromise = new Pending('core/tag:initManageCollectionsPage-addtagcoll');
e.preventDefault();
var keys = [
{
@@ -329,13 +392,15 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
component: 'tag'
},
{
key: 'create'
key: 'create',
component: 'core'
}
];
var href = $(this).attr('data-url');
var saveButtonText = '';
str.get_strings(keys).then(function(langStrings) {
str.get_strings(keys)
.then(function(langStrings) {
var modalTitle = langStrings[0];
saveButtonText = langStrings[1];
var templateContext = {
@@ -347,7 +412,8 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
body: templates.render('core_tag/add_tag_collection', templateContext),
type: ModalFactory.types.SAVE_CANCEL
});
}).then(function(modal) {
})
.then(function(modal) {
modal.setSaveButtonText(saveButtonText);
// Handle save event.
@@ -388,25 +454,31 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
modal.show();
return;
return modal;
}).catch(notification.exception);
})
.always(pendingPromise.resolve)
.catch(notification.exception);
});
$('body').on('click', '.tag-collections-table .action_delete', function(e) {
var pendingPromise = new Pending('core/tag:initManageCollectionsPage-action_delete');
e.preventDefault();
var href = $(this).attr('data-url') + '&sesskey=' + M.cfg.sesskey;
str.get_strings([
{key: 'delete'},
{key: 'suredeletecoll', component: 'tag', param: $(this).attr('data-collname')},
{key: 'yes'},
{key: 'no'},
]).done(function(s) {
notification.confirm(s[0], s[1], s[2], s[3], function() {
window.location.href = href;
});
}
);
{key: 'delete'},
{key: 'suredeletecoll', component: 'tag', param: $(this).attr('data-collname')},
{key: 'yes'},
{key: 'no'},
])
.then(function(s) {
return notification.confirm(s[0], s[1], s[2], s[3], function() {
window.location.href = href;
});
})
.always(pendingPromise.resolve)
.catch(notification.exception);
});
}
};