MDL-53988 mod_lti: Fix followup up issues

Fix function naming
Fix param types
Fix error popping up twice with incorrect URL
Add confirm dialog when you delete a tool
Show orphaned tool proxies in list
Fix interface jumping up and down
Change to use notification stack
Change capabilities in db/services.php
Add loading animation after registering tool
Show loading animation until tools are rendered
This commit is contained in:
John Okely 2016-04-28 10:46:35 +08:00
parent 33892edf18
commit 811d9ff941
30 changed files with 842 additions and 214 deletions

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){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){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()}),a.show()})},exception:function(b){b.backtrace&&(b.lineNumber=b.backtrace[0].line,b.fileName=b.backtrace[0].file,b.fileName="..."+b.fileName.substr(b.fileName.length-20),b.stack=b.debuginfo,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"],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){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){b.backtrace&&(b.lineNumber=b.backtrace[0].line,b.fileName=b.backtrace[0].file,b.fileName="..."+b.fileName.substr(b.fileName.length-20),b.stack=b.debuginfo,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}});

View File

@ -137,7 +137,7 @@ function(Y, $, log) {
});
},
confirm: function(title, question, yesLabel, noLabel, callback) {
confirm: function(title, question, yesLabel, noLabel, yesCallback, noCallback) {
// 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 () {
@ -149,8 +149,13 @@ function(Y, $, log) {
});
modal.on('complete-yes', function() {
callback();
yesCallback();
});
if (noCallback) {
modal.on('complete-no', function() {
noCallback();
});
}
modal.show();
});
},
@ -225,7 +230,8 @@ function(Y, $, log) {
* @param {string} question
* @param {string} yesLabel
* @param {string} noLabel
* @param {function} callback
* @param {function} yesCallback
* @param {function} noCallback Optional parameter to be called if the user presses cancel.
*/
confirm: notificationModule.confirm,

View File

@ -1 +1 @@
define(["jquery","core/ajax","core/notification","core/templates","mod_lti/events","mod_lti/tool_proxy","mod_lti/tool_type","mod_lti/keys","core/str"],function(a,b,c,d,e,f,g,h,i){var j={REGISTRATION_URL:"#external-registration-url",EXTERNAL_REGISTRATION_CONTAINER:"#external-registration-page-container",EXTERNAL_REGISTRATION_TEMPLATE_CONTAINER:"#external-registration-template-container",EXTERNAL_REGISTRATION_CANCEL_BUTTON:"#cancel-external-registration",TOOL_TYPE_CAPABILITIES_CONTAINER:"#tool-type-capabilities-container",TOOL_TYPE_CAPABILITIES_TEMPLATE_CONTAINER:"#tool-type-capabilities-template-container",CAPABILITIES_AGREE_CONTAINER:".capabilities-container"},k=function(){return a(j.EXTERNAL_REGISTRATION_CONTAINER).attr("data-registration-url")},l=function(){return a(j.EXTERNAL_REGISTRATION_CANCEL_BUTTON)},m=function(){return a(j.EXTERNAL_REGISTRATION_CONTAINER)},n=function(){return a(j.EXTERNAL_REGISTRATION_TEMPLATE_CONTAINER)},o=function(){return a(j.TOOL_TYPE_CAPABILITIES_CONTAINER)},p=function(){return a(j.TOOL_TYPE_CAPABILITIES_TEMPLATE_CONTAINER)},q=function(){o().addClass("loading")},r=function(){o().removeClass("loading")},s=function(){l().addClass("loading")},t=function(){l().removeClass("loading")},u=function(){o().addClass("hidden")},v=function(){o().removeClass("hidden")},w=function(){m().addClass("hidden")},x=function(){m().removeClass("hidden")},y=function(a){var b=l();b.attr("data-tool-proxy-id",a)},z=function(){var a=l();return a.attr("data-tool-proxy-id")},A=function(){var a=l();a.removeAttr("data-tool-proxy-id")},B=function(){return z()?!0:!1},C=function(a){var c={methodname:"mod_lti_get_tool_proxy_registration_request",args:{id:a}};return b.call([c])[0]},D=function(){s();var b=a.Deferred();if(B()){var d=z();f["delete"](d).done(function(){b.resolve()}).fail(function(a){b.reject(a)})}else b.resolve();return b.done(function(){I(),t()}).fail(function(b){c.exception(b),I(),t(),i.get_strings([{key:"error",component:"moodle"},{key:"failedtodeletetoolproxy",component:"mod_lti"}]).done(function(b){var c={status:b[0],message:b[1],error:!0};a(document).trigger(e.REGISTRATION_FEEDBACK,c)}).fail(c.exception)}),b},E=function(a){var b=d.render("mod_lti/tool_proxy_registration_form",a);return b.done(function(a,b){var c=n();c.append(a),d.runTemplateJS(b),c.find("form").submit(),x()}).fail(c.exception),b},F=function(a){return g.update({id:a.id,state:g.constants.state.configured})},G=function(b){var f=a.Deferred();return d.render("mod_lti/tool_type_capabilities_agree",b).done(function(a,c){var g=p();w(),v(),d.replaceNodeContents(g,a,c);var h=g.find(j.CAPABILITIES_AGREE_CONTAINER);h.on(e.CAPABILITIES_AGREE,function(){q(),F(b).always(function(){r(),g.empty(),f.resolve()})}),h.on(e.CAPABILITIES_DECLINE,function(){g.empty(),f.resolve()})}).fail(f.reject),f.done(function(){u()}).fail(c.exception),f},H=function(){var b=a.Deferred(),c=k();return""===c?b.resolve():f.create({regurl:c}).done(function(a){var c=a.id,d=a.regurl;y(c),C(c).done(function(a){a.reg_url=d,E(a).done(function(){b.resolve()}).fail(b.fail)}).fail(b.fail)}).fail(function(c){D(),a(document).trigger(e.REGISTRATION_FEEDBACK,{status:"error",message:c.message,error:!0}),b.reject(c)}),b},I=function(){B()&&A(),w();var b=n();b.empty(),a(document).trigger(e.STOP_EXTERNAL_REGISTRATION)},J=function(){a(document).on(e.START_EXTERNAL_REGISTRATION,function(){H()});var b=l();b.click(function(a){a.preventDefault(),D()}),b.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==h.ENTER||a.keyCode==h.SPACE)&&(a.preventDefault(),D())}),window.triggerExternalRegistrationComplete=function(b){var d=a.Deferred(),f={status:b.status,message:"",error:!1};if("success"==b.status){if(i.get_strings([{key:"success",component:"moodle"},{key:"successfullycreatedtooltype",component:"mod_lti"}]).done(function(a){f.status=a[0],f.message=a[1]}).fail(c.exception),d.done(function(){I(),a(document).trigger(e.REGISTRATION_FEEDBACK,f),a(document).trigger(e.NEW_TOOL_TYPE)}).fail(c.exception),B()){var h=z();g.getFromToolProxyId(h).done(function(a){if(a&&a.length){var b=a[0];b.hascapabilitygroups?G(b).always(function(){d.resolve()}):d.resolve()}else d.resolve()}).fail(function(){d.resolve()})}}else f.message=b.error,f.error=!0,d.done(function(){D().always(function(){a(document).trigger(e.REGISTRATION_FEEDBACK,f)})}).fail(c.exception),d.resolve();return d}};return{init:function(){J()}}});
define(["jquery","core/ajax","core/notification","core/templates","mod_lti/events","mod_lti/tool_proxy","mod_lti/tool_type","mod_lti/keys","core/str"],function(a,b,c,d,e,f,g,h,i){var j={EXTERNAL_REGISTRATION_CONTAINER:"#external-registration-page-container",EXTERNAL_REGISTRATION_TEMPLATE_CONTAINER:"#external-registration-template-container",EXTERNAL_REGISTRATION_CANCEL_BUTTON:"#cancel-external-registration",TOOL_TYPE_CAPABILITIES_CONTAINER:"#tool-type-capabilities-container",TOOL_TYPE_CAPABILITIES_TEMPLATE_CONTAINER:"#tool-type-capabilities-template-container",CAPABILITIES_AGREE_CONTAINER:".capabilities-container"},k=function(){return a(j.EXTERNAL_REGISTRATION_CANCEL_BUTTON)},l=function(){return a(j.EXTERNAL_REGISTRATION_CONTAINER)},m=function(){return a(j.EXTERNAL_REGISTRATION_TEMPLATE_CONTAINER)},n=function(){return a(j.TOOL_TYPE_CAPABILITIES_CONTAINER)},o=function(){return a(j.TOOL_TYPE_CAPABILITIES_TEMPLATE_CONTAINER)},p=function(){n().addClass("loading")},q=function(){n().removeClass("loading")},r=function(){k().addClass("loading")},s=function(){k().removeClass("loading")},t=function(){n().addClass("hidden")},u=function(){n().removeClass("hidden")},v=function(){l().addClass("hidden")},w=function(){l().removeClass("hidden")},x=function(a){var b=k();b.attr("data-tool-proxy-id",a)},y=function(){var a=k();return a.attr("data-tool-proxy-id")},z=function(){var a=k();a.removeAttr("data-tool-proxy-id")},A=function(){return y()?!0:!1},B=function(){var a=k();return a.attr("data-tool-proxy-new")&&A()},C=function(){var a=k();return a.attr("data-tool-proxy-new","new")},D=function(){var a=k();return a.removeAttr("data-tool-proxy-new")},E=function(a){var c={methodname:"mod_lti_get_tool_proxy_registration_request",args:{id:a}};return b.call([c])[0]},F=function(){r();var b=a.Deferred();if(B()){var d=y();f["delete"](d).done(function(){b.resolve()}).fail(function(a){b.reject(a)})}else b.resolve();return b.done(function(){L(),s()}).fail(function(b){c.exception(b),L(),s(),i.get_strings([{key:"error",component:"moodle"},{key:"failedtodeletetoolproxy",component:"mod_lti"}]).done(function(b){var c={status:b[0],message:b[1],error:!0};a(document).trigger(e.REGISTRATION_FEEDBACK,c)}).fail(c.exception)}),b},G=function(a){var b=d.render("mod_lti/tool_proxy_registration_form",a);return b.done(function(a,b){var c=m();c.append(a),d.runTemplateJS(b),c.find("form").submit(),w()}).fail(c.exception),b},H=function(a){return g.update({id:a.id,state:g.constants.state.configured})},I=function(b){var f=a.Deferred();return d.render("mod_lti/tool_type_capabilities_agree",b).done(function(a,c){var g=o();v(),u(),d.replaceNodeContents(g,a,c);var h=g.find(j.CAPABILITIES_AGREE_CONTAINER);h.on(e.CAPABILITIES_AGREE,function(){p(),H(b).always(function(){q(),g.empty(),f.resolve()})}),h.on(e.CAPABILITIES_DECLINE,function(){g.empty(),f.resolve()})}).fail(f.reject),f.done(function(){t()}).fail(c.exception),f},J=function(b){var d=a.Deferred();return b&&""!==b?f.create({regurl:b}).done(function(a){C(),d=K(a.id)}).fail(function(b){F(),i.get_string("error","moodle").done(function(c){var d={status:c,message:b.message,error:!0};a(document).trigger(e.REGISTRATION_FEEDBACK,d)}).fail(c.exception),d.reject(b)}):d.resolve(),d},K=function(b){var c=a.Deferred();return x(b),E(b).done(function(a){G(a).done(function(){c.resolve()}).fail(c.fail)}).fail(c.fail),c},L=function(){A()&&z(),D(!1),v();var b=m();b.empty(),a(document).trigger(e.STOP_EXTERNAL_REGISTRATION)},M=function(){a(document).on(e.START_EXTERNAL_REGISTRATION,function(a,b){b&&(b.url&&J(b.url),b.proxyid&&K(b.proxyid))});var b=k();b.click(function(a){a.preventDefault(),F()}),b.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==h.ENTER||a.keyCode==h.SPACE)&&(a.preventDefault(),F())}),window.triggerExternalRegistrationComplete=function(b){var d=a.Deferred(),f={status:b.status,message:"",error:!1};if("success"==b.status){if(i.get_strings([{key:"success",component:"moodle"},{key:"successfullycreatedtooltype",component:"mod_lti"}]).done(function(a){f.status=a[0],f.message=a[1]}).fail(c.exception),d.done(function(){L(),a(document).trigger(e.REGISTRATION_FEEDBACK,f),a(document).trigger(e.NEW_TOOL_TYPE)}).fail(c.exception),B()){var h=y();g.getFromToolProxyId(h).done(function(a){if(a&&a.length){var b=a[0];b.hascapabilitygroups?I(b).always(function(){d.resolve()}):d.resolve()}else d.resolve()}).fail(function(){d.resolve()})}}else f.message=b.error,f.error=!0,d.done(function(){F().always(function(){a(document).trigger(e.REGISTRATION_FEEDBACK,f)})}).fail(c.exception),d.resolve();return d}};return{init:function(){M()}}});

View File

@ -1 +1 @@
define(["jquery","core/ajax","core/notification","core/templates","mod_lti/tool_type","mod_lti/events","mod_lti/keys"],function(a,b,c,d,e,f,g){var h={DELETE_BUTTON:".delete",NAME_ELEMENT:".name",DESCRIPTION_ELEMENT:".description",CAPABILITIES_CONTAINER:".capabilities-container",ACTIVATE_BUTTON:".tool-card-footer a.activate"},i=2e3,j=function(a){return a.find(h.DELETE_BUTTON)},k=function(a){return a.find(h.NAME_ELEMENT)},l=function(a){return a.find(h.DESCRIPTION_ELEMENT)},m=function(a){return a.find(h.ACTIVATE_BUTTON)},n=function(a){return m(a).length?!0:!1},o=function(a){return a.find(h.CAPABILITIES_CONTAINER)},p=function(a){return o(a).length?!0:!1},q=function(a){return a.attr("data-type-id")},r=function(a){a.removeClass("announcement loading success fail capabilities")},s=function(a){r(a),a.addClass("announcement loading")},t=function(a){a.removeClass("announcement loading")},u=function(b){var c=a.Deferred();return r(b),b.addClass("announcement success"),setTimeout(function(){b.removeClass("announcement success"),c.resolve()},i),c},v=function(b){var c=a.Deferred();return r(b),b.addClass("announcement fail"),setTimeout(function(){b.removeClass("announcement fail"),c.resolve()},i),c},w=function(b){var d=q(b);if(""===d)return a.Deferred().resolve();s(b);var f=e["delete"](d);return f.done(function(){t(b),u(b).done(function(){b.remove()}).fail(c.exception)}),f.fail(function(){v(b)}),f},x=function(a,b){a.attr("data-val-snapshot",b)},y=function(a){return a.attr("data-val-snapshot")},z=function(a){var b=l(a);if(!b.hasClass("loading")){var c=b.text().trim();x(b,c)}},A=function(b){var d=q(b);if(""===d)return a.Deferred().resolve();var f=l(b);if(f.hasClass("loading"))return a.Deferred().resolve();var g=f.text().trim(),h=y(f);if(h==g)return a.Deferred().resolve();f.addClass("loading");var i=e.update({id:d,description:g});return i.done(function(a){f.removeClass("loading"),f.text(a.description)}).fail(c.exception),i.fail(function(){f.removeClass("loading")}),i},B=function(a){var b=k(a);if(!b.hasClass("loading")){var c=b.text().trim();x(b,c)}},C=function(b){var c=q(b);if(""===c)return a.Deferred().resolve();var d=k(b);if(d.hasClass("loading"))return a.Deferred().resolve();var f=d.text().trim(),g=y(d);if(g==f)return a.Deferred().resolve();d.addClass("loading");var h=e.update({id:c,name:f});return h.done(function(a){d.removeClass("loading"),d.text(a.name)}),h.fail(function(){d.removeClass("loading")}),h},D=function(b){var c=q(b);if(""===c)return a.Deferred().resolve();s(b);var f=e.update({id:c,state:e.constants.state.configured});return f.done(function(c){t(b);var e=u(b),f=d.render("mod_lti/tool_card",c);a.when(f,e).then(function(a){var c=a[0],e=a[1];d.replaceNode(b,c,e)})}),f.fail(function(){t(b),v(b)}),f},E=function(a){a.addClass("announcement capabilities")},F=function(a){a.removeClass("announcement capabilities")},G=function(a){p(a)?E(a):D(a)},H=function(a){var b=j(a);b.click(function(b){b.preventDefault(),w(a)}),b.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==g.ENTER||a.keyCode==g.SPACE)&&(a.preventDefault(),b.click())});var c=l(a);c.focus(function(b){b.preventDefault(),z(a)}),c.blur(function(b){b.preventDefault(),A(a)}),c.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||a.keyCode==g.ENTER&&(a.preventDefault(),c.blur())});var d=k(a);if(d.focus(function(b){b.preventDefault(),B(a)}),d.blur(function(b){b.preventDefault(),C(a)}),d.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||a.keyCode==g.ENTER&&(a.preventDefault(),d.blur())}),n(a)){var e=m(a);e.click(function(b){b.preventDefault(),G(a)}),e.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==g.ENTER||a.keyCode==g.SPACE)&&(a.preventDefault(),e.click())})}if(p(a)){var h=o(a);h.on(f.CAPABILITIES_AGREE,function(){D(a)}),h.on(f.CAPABILITIES_DECLINE,function(){F(a)})}};return{init:function(a){H(a)}}});
define(["jquery","core/ajax","core/notification","core/templates","mod_lti/tool_type","mod_lti/events","mod_lti/keys","core/str"],function(a,b,c,d,e,f,g,h){var i={DELETE_BUTTON:".delete",NAME_ELEMENT:".name",DESCRIPTION_ELEMENT:".description",CAPABILITIES_CONTAINER:".capabilities-container",ACTIVATE_BUTTON:".tool-card-footer a.activate"},j=2e3,k=function(a){return a.find(i.DELETE_BUTTON)},l=function(a){return a.find(i.NAME_ELEMENT)},m=function(a){return a.find(i.DESCRIPTION_ELEMENT)},n=function(a){return a.find(i.ACTIVATE_BUTTON)},o=function(a){return n(a).length?!0:!1},p=function(a){return a.find(i.CAPABILITIES_CONTAINER)},q=function(a){return p(a).length?!0:!1},r=function(a){return a.attr("data-type-id")},s=function(a){a.removeClass("announcement loading success fail capabilities")},t=function(a){s(a),a.addClass("announcement loading")},u=function(a){a.removeClass("announcement loading")},v=function(b){var c=a.Deferred();return s(b),b.addClass("announcement success"),setTimeout(function(){b.removeClass("announcement success"),c.resolve()},j),c},w=function(b){var c=a.Deferred();return s(b),b.addClass("announcement fail"),setTimeout(function(){b.removeClass("announcement fail"),c.resolve()},j),c},x=function(b){var d=a.Deferred(),f=r(b);return t(b),""===f?a.Deferred().resolve():(h.get_strings([{key:"delete",component:"mod_lti"},{key:"delete_confirmation",component:"mod_lti"},{key:"delete",component:"mod_lti"},{key:"cancel",component:"core"}]).done(function(a){c.confirm(a[0],a[1],a[2],a[3],function(){e["delete"](f).done(function(){u(b),v(b).done(function(){b.remove()}).fail(c.exception).always(function(){d.resolve()})}).fail(function(a){w(b),d.reject(a)})},function(){u(b),d.resolve()})}).fail(function(a){u(b),c.exception(a),d.reject(a)}),d)},y=function(a,b){a.attr("data-val-snapshot",b)},z=function(a){return a.attr("data-val-snapshot")},A=function(a){var b=m(a);if(!b.hasClass("loading")){var c=b.text().trim();y(b,c)}},B=function(b){var d=r(b);if(""===d)return a.Deferred().resolve();var f=m(b);if(f.hasClass("loading"))return a.Deferred().resolve();var g=f.text().trim(),h=z(f);if(h==g)return a.Deferred().resolve();f.addClass("loading");var i=e.update({id:d,description:g});return i.done(function(a){f.removeClass("loading"),f.text(a.description)}).fail(c.exception),i.fail(function(){f.removeClass("loading")}),i},C=function(a){var b=l(a);if(!b.hasClass("loading")){var c=b.text().trim();y(b,c)}},D=function(b){var c=r(b);if(""===c)return a.Deferred().resolve();var d=l(b);if(d.hasClass("loading"))return a.Deferred().resolve();var f=d.text().trim(),g=z(d);if(g==f)return a.Deferred().resolve();d.addClass("loading");var h=e.update({id:c,name:f});return h.done(function(a){d.removeClass("loading"),d.text(a.name)}),h.fail(function(){d.removeClass("loading")}),h},E=function(b){var c=r(b);if(""===c)return a.Deferred().resolve();t(b);var f=e.update({id:c,state:e.constants.state.configured});return f.done(function(c){u(b);var e=v(b),f=d.render("mod_lti/tool_card",c);a.when(f,e).then(function(a){var c=a[0],e=a[1];d.replaceNode(b,c,e)})}),f.fail(function(){u(b),w(b)}),f},F=function(a){a.addClass("announcement capabilities")},G=function(a){a.removeClass("announcement capabilities")},H=function(a){q(a)?F(a):E(a)},I=function(a){var b=k(a);b.click(function(b){b.preventDefault(),x(a)}),b.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==g.ENTER||a.keyCode==g.SPACE)&&(a.preventDefault(),b.click())});var c=m(a);c.focus(function(b){b.preventDefault(),A(a)}),c.blur(function(b){b.preventDefault(),B(a)}),c.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||a.keyCode==g.ENTER&&(a.preventDefault(),c.blur())});var d=l(a);if(d.focus(function(b){b.preventDefault(),C(a)}),d.blur(function(b){b.preventDefault(),D(a)}),d.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||a.keyCode==g.ENTER&&(a.preventDefault(),d.blur())}),o(a)){var e=n(a);e.click(function(b){b.preventDefault(),H(a)}),e.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==g.ENTER||a.keyCode==g.SPACE)&&(a.preventDefault(),e.click())})}if(q(a)){var h=p(a);h.on(f.CAPABILITIES_AGREE,function(){E(a)}),h.on(f.CAPABILITIES_DECLINE,function(){G(a)})}};return{init:function(a){I(a)}}});

View File

@ -1 +1 @@
define(["jquery","core/ajax","core/notification","core/templates","mod_lti/events","mod_lti/keys","mod_lti/tool_type"],function(a,b,c,d,e,f,g){var h={REGISTRATION_FEEDBACK_CONTAINER:"#registration-feedback-container",EXTERNAL_REGISTRATION_CONTAINER:"#external-registration-container",EXTERNAL_REGISTRATION_PAGE_CONTAINER:"#external-registration-page-container",CARTRIDGE_REGISTRATION_CONTAINER:"#cartridge-registration-container",CARTRIDGE_REGISTRATION_FORM:"#cartridge-registration-form",ADD_TOOL_FORM:"#add-tool-form",TOOL_LIST_CONTAINER:"#tool-list-container",TOOL_CREATE_BUTTON:"#tool-create-button",REGISTRATION_CHOICE_CONTAINER:"#registration-choice-container",TOOL_URL:"#tool-url"},i=function(){return a(h.TOOL_CREATE_BUTTON)},j=function(){return a(h.REGISTRATION_FEEDBACK_CONTAINER)},k=function(){return a(h.TOOL_LIST_CONTAINER)},l=function(){return a(h.EXTERNAL_REGISTRATION_CONTAINER)},m=function(){return a(h.CARTRIDGE_REGISTRATION_CONTAINER)},n=function(){return a(h.REGISTRATION_CHOICE_CONTAINER)},o=function(){return a(h.TOOL_URL).val()},p=function(){l().addClass("hidden")},q=function(){m().addClass("hidden")},r=function(){n().addClass("hidden")},s=function(a){q(),r(),l().removeClass("hidden"),l().find(h.EXTERNAL_REGISTRATION_PAGE_CONTAINER).attr("data-registration-url",a),u(l())},t=function(a){p(),r(),m().removeClass("hidden"),m().find(h.CARTRIDGE_REGISTRATION_FORM).attr("data-cartridge-url",a),u(m())},u=function(a){var b=a.children().clone(!0,!0);a.empty(),a.append(b)},v=function(){y()||(p(),q(),n().removeClass("hidden"),u(n()))},w=function(){k().addClass("hidden")},x=function(){k().removeClass("hidden")},y=function(){return a.trim(j().html())},z=function(a){d.render("mod_lti/registration_feedback",a).done(function(a){p(),q(),r();var b=j();b.append(a)}).fail(c.exception)},A=function(){var a=j();a.empty(),v()},B=function(a){a.addClass("loading")},C=function(a){a.removeClass("loading")},D=function(){var a=k();B(a),g.query().done(function(b){d.render("mod_lti/tool_list",{tools:b}).done(function(b,c){a.empty(),a.append(b),d.runTemplateJS(c)}).fail(c.exception)}).fail(c.exception).always(function(){C(a)})},E=function(){var b=o();if(""===b)return a.Deferred().resolve();var d=i();B(d);var f=g.isCartridge(b);return f.always(function(){C(d)}),f.done(function(c){c.iscartridge?(a(h.TOOL_URL).val(""),a(document).trigger(e.START_CARTRIDGE_REGISTRATION,b)):(s(b),a(h.TOOL_URL).val(""),a(document).trigger(e.START_EXTERNAL_REGISTRATION),w())}),f.fail(c.exception),f},F=function(){a(document).on(e.NEW_TOOL_TYPE,function(){D()}),a(document).on(e.STOP_EXTERNAL_REGISTRATION,function(){x(),v()}),a(document).on(e.START_CARTRIDGE_REGISTRATION,function(a,b){t(b)}),a(document).on(e.STOP_CARTRIDGE_REGISTRATION,function(){m().find(h.CARTRIDGE_REGISTRATION_FORM).removeAttr("data-cartridge-url"),v()}),a(document).on(e.REGISTRATION_FEEDBACK,function(a,b){z(b)});var b=a(h.ADD_TOOL_FORM);b.submit(function(a){a.preventDefault(),E()});var c=j();c.click(function(a){a.preventDefault(),A()}),c.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==f.ENTER||a.keyCode==f.SPACE)&&(a.preventDefault(),A())})};return{init:function(){F(),D()}}});
define(["jquery","core/ajax","core/notification","core/templates","mod_lti/events","mod_lti/keys","mod_lti/tool_type","mod_lti/tool_proxy","core/str"],function(a,b,c,d,e,f,g,h,i){var j={EXTERNAL_REGISTRATION_CONTAINER:"#external-registration-container",EXTERNAL_REGISTRATION_PAGE_CONTAINER:"#external-registration-page-container",CARTRIDGE_REGISTRATION_CONTAINER:"#cartridge-registration-container",CARTRIDGE_REGISTRATION_FORM:"#cartridge-registration-form",ADD_TOOL_FORM:"#add-tool-form",TOOL_LIST_CONTAINER:"#tool-list-container",TOOL_CREATE_BUTTON:"#tool-create-button",REGISTRATION_CHOICE_CONTAINER:"#registration-choice-container",TOOL_URL:"#tool-url"},k=function(){return a(j.TOOL_CREATE_BUTTON)},l=function(){return a(j.TOOL_LIST_CONTAINER)},m=function(){return a(j.EXTERNAL_REGISTRATION_CONTAINER)},n=function(){return a(j.CARTRIDGE_REGISTRATION_CONTAINER)},o=function(){return a(j.REGISTRATION_CHOICE_CONTAINER)},p=function(){return a(j.TOOL_URL).val()},q=function(){m().addClass("hidden")},r=function(){n().addClass("hidden")},s=function(){o().addClass("hidden")},t=function(){r(),s(),m().removeClass("hidden"),v(m())},u=function(a){q(),s(),n().removeClass("hidden"),n().find(j.CARTRIDGE_REGISTRATION_FORM).attr("data-cartridge-url",a),v(n())},v=function(a){var b=a.children().clone(!0,!0);a.empty(),a.append(b)},w=function(){q(),r(),o().removeClass("hidden"),v(o())},x=function(){l().addClass("hidden")},y=function(){l().removeClass("hidden")},z=function(a){var b=a.error?"error":"success";c.addNotification({message:"<h4>"+a.status+"</h4><p>"+a.message+"</p>",type:b})},A=function(a){a.addClass("loading")},B=function(a){a.removeClass("loading")},C=function(){var b=a.Deferred(),e=l();A(e),a.when(g.query(),h.query({orphanedonly:!0})).done(function(a,c){d.render("mod_lti/tool_list",{tools:a,proxies:c}).done(function(a,c){e.empty(),e.append(a),d.runTemplateJS(c),b.resolve()}).fail(b.reject)}).fail(b.reject),b.fail(c.exception).always(function(){B(e)})},D=function(){var b=a.trim(p());if(""===b)return a.Deferred().resolve();var d=k();A(d);var f=g.isCartridge(b);return f.always(function(){B(d)}),f.done(function(c){c.iscartridge?(a(j.TOOL_URL).val(""),a(document).trigger(e.START_CARTRIDGE_REGISTRATION,b)):a(document).trigger(e.START_EXTERNAL_REGISTRATION,{url:b})}),f.fail(function(){i.get_strings([{key:"error",component:"moodle"},{key:"errorbadurl",component:"mod_lti"}]).done(function(b){a(document).trigger(e.REGISTRATION_FEEDBACK,{status:b[0],message:b[1],error:!0})}).fail(c.exception)}),f},E=function(){a(document).on(e.NEW_TOOL_TYPE,function(){C()}),a(document).on(e.START_EXTERNAL_REGISTRATION,function(){t(),a(j.TOOL_URL).val(""),x()}),a(document).on(e.STOP_EXTERNAL_REGISTRATION,function(){y(),w()}),a(document).on(e.START_CARTRIDGE_REGISTRATION,function(a,b){u(b)}),a(document).on(e.STOP_CARTRIDGE_REGISTRATION,function(){n().find(j.CARTRIDGE_REGISTRATION_FORM).removeAttr("data-cartridge-url"),w()}),a(document).on(e.REGISTRATION_FEEDBACK,function(a,b){z(b)});var b=a(j.ADD_TOOL_FORM);b.submit(function(a){a.preventDefault(),D()})};return{init:function(){E(),C()}}});

View File

@ -1 +1 @@
define(["core/ajax","core/notification"],function(a,b){return{"delete":function(c){var d={methodname:"mod_lti_delete_tool_proxy",args:{id:c}},e=a.call([d])[0];return e.fail(b.exception),e},create:function(c){var d={methodname:"mod_lti_create_tool_proxy",args:c},e=a.call([d])[0];return e.fail(b.exception),e}}});
define(["core/ajax","core/notification"],function(a,b){return{query:function(c){var d={methodname:"mod_lti_get_tool_proxies",args:c||{}},e=a.call([d])[0];return e.fail(b.exception),e},"delete":function(c){var d={methodname:"mod_lti_delete_tool_proxy",args:{id:c}},e=a.call([d])[0];return e.fail(b.exception),e},create:function(c){var d={methodname:"mod_lti_create_tool_proxy",args:c},e=a.call([d])[0];return e.fail(b.exception),e}}});

View File

@ -0,0 +1 @@
define(["jquery","core/ajax","core/notification","core/templates","mod_lti/tool_proxy","mod_lti/events","mod_lti/keys","core/str"],function(a,b,c,d,e,f,g,h){var i={DELETE_BUTTON:".delete",CAPABILITIES_CONTAINER:".capabilities-container",ACTIVATE_BUTTON:".tool-card-footer a.activate"},j=2e3,k=function(a){return a.find(i.DELETE_BUTTON)},l=function(a){return a.find(i.ACTIVATE_BUTTON)},m=function(a){return a.attr("data-proxy-id")},n=function(a){a.removeClass("announcement loading success fail capabilities")},o=function(a){n(a),a.addClass("announcement loading")},p=function(a){a.removeClass("announcement loading")},q=function(b){var c=a.Deferred();return n(b),b.addClass("announcement success"),setTimeout(function(){b.removeClass("announcement success"),c.resolve()},j),c},r=function(b){var c=a.Deferred();return n(b),b.addClass("announcement fail"),setTimeout(function(){b.removeClass("announcement fail"),c.resolve()},j),c},s=function(b){var d=a.Deferred(),f=m(b);return o(b),""===f?a.Deferred().resolve():(h.get_strings([{key:"delete",component:"mod_lti"},{key:"delete_confirmation",component:"mod_lti"},{key:"delete",component:"mod_lti"},{key:"cancel",component:"core"}]).done(function(a){c.confirm(a[0],a[1],a[2],a[3],function(){e["delete"](f).done(function(){p(b),q(b).done(function(){b.remove(),d.resolve()}).fail(c.exception)}).fail(function(a){r(b),d.reject(a)})},function(){p(b),d.resolve()})}).fail(function(a){p(b),c.exception(a),d.reject(a)}),d)},t=function(b){var c={proxyid:m(b)};a(document).trigger(f.START_EXTERNAL_REGISTRATION,c)},u=function(a){var b=k(a);b.click(function(b){b.preventDefault(),s(a)}),b.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==g.ENTER||a.keyCode==g.SPACE)&&(a.preventDefault(),b.click())});var c=l(a);c.click(function(b){b.preventDefault(),t(a)}),c.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==g.ENTER||a.keyCode==g.SPACE)&&(a.preventDefault(),c.click())})};return{init:function(a){u(a)}}});

View File

@ -1 +1 @@
define(["core/ajax","core/notification"],function(a,b){return{query:function(c){var d={methodname:"mod_lti_get_tool_types",args:c||{}},e=a.call([d])[0];return e.fail(b.exception),e},create:function(c){var d={methodname:"mod_lti_create_tool_type",args:c},e=a.call([d])[0];return e.fail(b.exception),e},update:function(c){var d={methodname:"mod_lti_update_tool_type",args:c},e=a.call([d])[0];return e.fail(b.exception),e},"delete":function(c){var d={methodname:"mod_lti_delete_tool_type",args:{id:c}},e=a.call([d])[0];return e.fail(b.exception),e},getFromToolProxyId:function(a){return this.query({toolproxyid:a})},isCartridge:function(c){var d={methodname:"mod_lti_is_cartridge",args:{url:c}},e=a.call([d])[0];return e.fail(b.exception),e},constants:{state:{configured:1,pending:2,rejected:3}}}});
define(["core/ajax","core/notification"],function(a,b){return{query:function(c){var d={methodname:"mod_lti_get_tool_types",args:c||{}},e=a.call([d])[0];return e.fail(b.exception),e},create:function(c){var d={methodname:"mod_lti_create_tool_type",args:c},e=a.call([d])[0];return e.fail(b.exception),e},update:function(c){var d={methodname:"mod_lti_update_tool_type",args:c},e=a.call([d])[0];return e.fail(b.exception),e},"delete":function(c){var d={methodname:"mod_lti_delete_tool_type",args:{id:c}},e=a.call([d])[0];return e.fail(b.exception),e},getFromToolProxyId:function(a){return this.query({toolproxyid:a})},isCartridge:function(b){var c={methodname:"mod_lti_is_cartridge",args:{url:b}},d=a.call([c])[0];return d},constants:{state:{configured:1,pending:2,rejected:3}}}});

View File

@ -34,7 +34,6 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
function($, ajax, notification, templates, ltiEvents, toolProxy, toolType, KEYS, str) {
var SELECTORS = {
REGISTRATION_URL: '#external-registration-url',
EXTERNAL_REGISTRATION_CONTAINER: '#external-registration-page-container',
EXTERNAL_REGISTRATION_TEMPLATE_CONTAINER: '#external-registration-template-container',
EXTERNAL_REGISTRATION_CANCEL_BUTTON: '#cancel-external-registration',
@ -43,17 +42,6 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
CAPABILITIES_AGREE_CONTAINER: '.capabilities-container',
};
/**
* Return the URL the user entered for the registration.
*
* @method getRegistrationURL
* @private
* @return string
*/
var getRegistrationURL = function() {
return $(SELECTORS.EXTERNAL_REGISTRATION_CONTAINER).attr('data-registration-url');
};
/**
* Return the external registration cancel button element. This button is
* the cancel button that appears while the iframe is rendered.
@ -230,6 +218,17 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
button.removeAttr('data-tool-proxy-id');
};
/**
* Returns true if a tool proxy id has been recorded.
*
* @method hasToolProxyId
* @private
* @return bool
*/
var hasToolProxyId = function() {
return getToolProxyId() ? true : false;
};
/**
* Checks if this process has created a tool proxy within
* Moodle yet.
@ -239,7 +238,32 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
* @return bool
*/
var hasCreatedToolProxy = function() {
return getToolProxyId() ? true : false;
var button = getExternalRegistrationCancelButton();
return button.attr('data-tool-proxy-new') && hasToolProxyId();
};
/**
* Records that this process has created a tool proxy.
*
* @method setProxyAsNew
* @private
* @return bool
*/
var setProxyAsNew = function() {
var button = getExternalRegistrationCancelButton();
return button.attr('data-tool-proxy-new', "new");
};
/**
* Records that this process has not created a tool proxy.
*
* @method setProxyAsOld
* @private
* @return bool
*/
var setProxyAsOld = function() {
var button = getExternalRegistrationCancelButton();
return button.removeAttr('data-tool-proxy-new');
};
/**
@ -412,53 +436,76 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
* If the tool proxy creation fails then we redirect the page section back to the home section and
* display the error, rather than rendering the external registration page.
*
* @method submitExternalRegistration
* @method createAndRegisterToolProxy
* @private
* @param url Tool registration URL to register
* @return object jQuery Deferred object
*/
var submitExternalRegistration = function() {
var createAndRegisterToolProxy = function(url) {
var promise = $.Deferred();
var url = getRegistrationURL();
if (url === "") {
if (!url || url === "") {
// No URL has been input so do nothing.
promise.resolve();
} else {
// A tool proxy needs to exists before the external page is rendered because
// A tool proxy needs to exist before the external page is rendered because
// the external page sends requests back to Moodle for information that is stored
// in the proxy.
toolProxy.create({regurl: url}).done(function(result) {
var id = result.id;
var regURL = result.regurl;
// Save the id on the DOM to cleanup later.
setToolProxyId(id);
// There is a specific set of data needed to send to the external registration page
// in a form, so let's get it from our server.
getRegistrationRequest(id).done(function(registrationRequest) {
registrationRequest.reg_url = regURL;
renderExternalRegistrationWindow(registrationRequest).done(function() {
promise.resolve();
}).fail(promise.fail);
}).fail(promise.fail);
}).fail(function(exception) {
// Clean up.
cancelRegistration();
// Let the user know what the error is.
$(document).trigger(ltiEvents.REGISTRATION_FEEDBACK, {status: 'error', message: exception.message, error: true});
promise.reject(exception);
});
toolProxy.create({regurl: url})
.done(function(result) {
// Note that it's a new proxy so we will always clean it up.
setProxyAsNew();
promise = registerProxy(result.id);
})
.fail(function(exception) {
// Clean up.
cancelRegistration();
// Let the user know what the error is.
str.get_string('error', 'moodle')
.done(function (s) {
var feedback = {
status: s,
message: exception.message,
error: true
};
$(document).trigger(ltiEvents.REGISTRATION_FEEDBACK, feedback);
})
.fail(notification.exception);
promise.reject(exception);
});
}
return promise;
};
/**
* Loads the window to register a proxy, given an ID.
*
* @method registerProxy
* @private
* @param id Proxy id to register
* @return jQuery Deferred object to fail or resolve
*/
var registerProxy = function(id) {
var promise = $.Deferred();
// Save the id on the DOM to cleanup later.
setToolProxyId(id);
// There is a specific set of data needed to send to the external registration page
// in a form, so let's get it from our server.
getRegistrationRequest(id)
.done(function(registrationRequest) {
renderExternalRegistrationWindow(registrationRequest)
.done(function() {
promise.resolve();
})
.fail(promise.fail);
})
.fail(promise.fail);
return promise;
};
/**
* Complete the registration process, clean up any left over data and
* trigger the appropriate events.
@ -467,9 +514,10 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
* @private
*/
var finishExternalRegistration = function() {
if (hasCreatedToolProxy()) {
if (hasToolProxyId()) {
clearToolProxyId();
}
setProxyAsOld(false);
hideExternalRegistrationContent();
var container = getExternalRegistrationTemplateContainer();
@ -486,9 +534,17 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
*/
var registerEventListeners = function() {
$(document).on(ltiEvents.START_EXTERNAL_REGISTRATION, function() {
submitExternalRegistration();
});
$(document).on(ltiEvents.START_EXTERNAL_REGISTRATION, function(event, data) {
if (!data) {
return;
}
if (data.url) {
createAndRegisterToolProxy(data.url);
}
if (data.proxyid) {
registerProxy(data.proxyid);
}
});
var cancelExternalRegistrationButton = getExternalRegistrationCancelButton();
cancelExternalRegistrationButton.click(function(e) {

View File

@ -26,8 +26,9 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/tool_type', 'mod_lti/events', 'mod_lti/keys'],
function($, ajax, notification, templates, toolType, ltiEvents, KEYS) {
define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/tool_type', 'mod_lti/events', 'mod_lti/keys',
'core/str'],
function($, ajax, notification, templates, toolType, ltiEvents, KEYS, str) {
var SELECTORS = {
DELETE_BUTTON: '.delete',
@ -226,23 +227,61 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/t
* @return object jQuery Deferred object
*/
var deleteType = function(element) {
var promise = $.Deferred();
var typeId = getTypeId(element);
startLoading(element);
if (typeId === "") {
return $.Deferred().resolve();
}
startLoading(element);
var promise = toolType.delete(typeId);
promise.done(function() {
stopLoading(element);
announceSuccess(element).done(function() {
element.remove();
}).fail(notification.exception);
});
promise.fail(function() { announceFailure(element); });
str.get_strings([
{
key: 'delete',
component: 'mod_lti'
},
{
key: 'delete_confirmation',
component: 'mod_lti'
},
{
key: 'delete',
component: 'mod_lti'
},
{
key: 'cancel',
component: 'core'
},
])
.done(function(strs) {
notification.confirm(strs[0], strs[1], strs[2], strs[3], function() {
toolType.delete(typeId)
.done(function() {
stopLoading(element);
announceSuccess(element)
.done(function() {
element.remove();
})
.fail(notification.exception)
.always(function() {
// Always resolve because even if the announcement fails the type was deleted.
promise.resolve();
});
})
.fail(function(error) {
announceFailure(element);
promise.reject(error);
});
}, function () {
stopLoading(element);
promise.resolve();
});
})
.fail(function(error) {
stopLoading(element);
notification.exception(error);
promise.reject(error);
});
return promise;
};

View File

@ -25,11 +25,11 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/events', 'mod_lti/keys', 'mod_lti/tool_type'],
function($, ajax, notification, templates, ltiEvents, KEYS, toolType) {
define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/events', 'mod_lti/keys', 'mod_lti/tool_type',
'mod_lti/tool_proxy', 'core/str'],
function($, ajax, notification, templates, ltiEvents, KEYS, toolType, toolProxy, str) {
var SELECTORS = {
REGISTRATION_FEEDBACK_CONTAINER: '#registration-feedback-container',
EXTERNAL_REGISTRATION_CONTAINER: '#external-registration-container',
EXTERNAL_REGISTRATION_PAGE_CONTAINER: '#external-registration-page-container',
CARTRIDGE_REGISTRATION_CONTAINER: '#cartridge-registration-container',
@ -52,17 +52,6 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
return $(SELECTORS.TOOL_CREATE_BUTTON);
};
/**
* Get the registration feedback container element.
*
* @method getRegistrationFeedbackContainer
* @private
* @return object jQuery object
*/
var getRegistrationFeedbackContainer = function() {
return $(SELECTORS.REGISTRATION_FEEDBACK_CONTAINER);
};
/**
* Get the tool list container element.
*
@ -155,11 +144,10 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
* @method showExternalRegistration
* @private
*/
var showExternalRegistration = function(url) {
var showExternalRegistration = function() {
hideCartridgeRegistration();
hideRegistrationChoices();
getExternalRegistrationContainer().removeClass('hidden');
getExternalRegistrationContainer().find(SELECTORS.EXTERNAL_REGISTRATION_PAGE_CONTAINER).attr('data-registration-url', url);
screenReaderAnnounce(getExternalRegistrationContainer());
};
@ -200,13 +188,6 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
* @private
*/
var showRegistrationChoices = function() {
if (isRegistrationFeedbackVisible()) {
// If the registration feedback is visible then we don't need
// to do anything because it will display this content when it's
// closed.
return;
}
hideExternalRegistration();
hideCartridgeRegistration();
getRegistrationChoiceContainer().removeClass('hidden');
@ -233,17 +214,6 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
getToolListContainer().removeClass('hidden');
};
/**
* Check if the registration feedback is being displayed.
*
* @method isRegistrationFeedbackVisible
* @private
* @return bool
*/
var isRegistrationFeedbackVisible = function() {
return $.trim(getRegistrationFeedbackContainer().html());
};
/**
* Display the registration feedback alert and hide the other panels.
*
@ -251,27 +221,11 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
* @private
*/
var showRegistrationFeedback = function(data) {
templates.render('mod_lti/registration_feedback', data).done(function(html) {
hideExternalRegistration();
hideCartridgeRegistration();
hideRegistrationChoices();
var container = getRegistrationFeedbackContainer();
container.append(html);
}).fail(notification.exception);
};
/**
* Hide the registration feedback alert and restore the choices panel.
*
* @method showRegistrationFeedback
* @private
*/
var clearRegistrationFeedback = function() {
var container = getRegistrationFeedbackContainer();
container.empty();
showRegistrationChoices();
var type = data.error ? 'error' : 'success';
notification.addNotification({
message: '<h4>' + data.status + '</h4><p>' + data.message + '</p>',
type: type
});
};
/**
@ -303,16 +257,29 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
* @private
*/
var reloadToolList = function() {
var promise = $.Deferred();
var container = getToolListContainer();
startLoading(container);
toolType.query().done(function(types) {
templates.render('mod_lti/tool_list', {tools: types}).done(function(html, js) {
container.empty();
container.append(html);
templates.runTemplateJS(js);
}).fail(notification.exception);
}).fail(notification.exception).always(function() { stopLoading(container); });
$.when(
toolType.query(),
toolProxy.query({'orphanedonly': true})
)
.done(function(types, proxies) {
templates.render('mod_lti/tool_list', {tools: types, proxies: proxies})
.done(function(html, js) {
container.empty();
container.append(html);
templates.runTemplateJS(js);
promise.resolve();
}).fail(promise.reject);
})
.fail(promise.reject);
promise.fail(notification.exception)
.always(function () {
stopLoading(container);
});
};
/**
@ -324,7 +291,7 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
* @return object jQuery deferred object
*/
var addTool = function() {
var url = getToolURL();
var url = $.trim(getToolURL());
if (url === "") {
return $.Deferred().resolve();
@ -342,14 +309,22 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
$(SELECTORS.TOOL_URL).val('');
$(document).trigger(ltiEvents.START_CARTRIDGE_REGISTRATION, url);
} else {
showExternalRegistration(url);
$(SELECTORS.TOOL_URL).val('');
$(document).trigger(ltiEvents.START_EXTERNAL_REGISTRATION);
hideToolList();
$(document).trigger(ltiEvents.START_EXTERNAL_REGISTRATION, {url: url});
}
});
promise.fail(notification.exception);
promise.fail(function () {
str.get_strings([{key: 'error', component: 'moodle'},
{key: 'errorbadurl', component: 'mod_lti'}])
.done(function (s) {
$(document).trigger(ltiEvents.REGISTRATION_FEEDBACK, {
status: s[0],
message: s[1],
error: true
});
})
.fail(notification.exception);
});
return promise;
};
@ -368,6 +343,12 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
reloadToolList();
});
$(document).on(ltiEvents.START_EXTERNAL_REGISTRATION, function() {
showExternalRegistration();
$(SELECTORS.TOOL_URL).val('');
hideToolList();
});
$(document).on(ltiEvents.STOP_EXTERNAL_REGISTRATION, function() {
showToolList();
showRegistrationChoices();
@ -392,19 +373,6 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/e
addTool();
});
var feedbackContainer = getRegistrationFeedbackContainer();
feedbackContainer.click(function(e) {
e.preventDefault();
clearRegistrationFeedback();
});
feedbackContainer.keypress(function(e) {
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
if (e.keyCode == KEYS.ENTER || e.keyCode == KEYS.SPACE) {
e.preventDefault();
clearRegistrationFeedback();
}
}
});
};
return /** @alias module:mod_lti/cartridge_registration_form */ {

View File

@ -25,6 +25,30 @@
*/
define(['core/ajax', 'core/notification'], function(ajax, notification) {
return /** @alias module:mod_lti/tool_proxy */ {
/**
* Get a list of tool types from Moodle for the given
* search args.
*
* See also:
* mod/lti/classes/external.php get_tool_types_parameters()
*
* @method query
* @public
* @param object Search parameters
* @return object jQuery deferred object
*/
query: function(args) {
var request = {
methodname: 'mod_lti_get_tool_proxies',
args: args || {}
};
var promise = ajax.call([request])[0];
promise.fail(notification.exception);
return promise;
},
/**
* Delete a tool proxy from Moodle.
*

View File

@ -0,0 +1,284 @@
// 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/>.
/**
* Controls all of the behaviour and interaction with a tool type card. These are
* listed on the LTI tool type management page.
*
* See template: mod_lti/tool_proxy_card
*
* @module mod_lti/tool_proxy_card_controller
* @class tool_card_controller
* @package mod_lti
* @copyright 2016 John Okely <john@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.1
*/
define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/tool_proxy', 'mod_lti/events', 'mod_lti/keys',
'core/str'],
function($, ajax, notification, templates, toolProxy, ltiEvents, KEYS, str) {
var SELECTORS = {
DELETE_BUTTON: '.delete',
CAPABILITIES_CONTAINER: '.capabilities-container',
ACTIVATE_BUTTON: '.tool-card-footer a.activate',
};
// Timeout in seconds.
var ANNOUNCEMENT_TIMEOUT = 2000;
/**
* Return the delete button element.
*
* @method getDeleteButton
* @private
* @param object jQuery object representing the tool card.
* @return object jQuery object
*/
var getDeleteButton = function(element) {
return element.find(SELECTORS.DELETE_BUTTON);
};
/**
* Return the activate button for the type.
*
* @method getActivateButton
* @private
* @param object jQuery object representing the tool card.
* @return object jQuery object
*/
var getActivateButton = function(element) {
return element.find(SELECTORS.ACTIVATE_BUTTON);
};
/**
* Get the type id.
*
* @method getTypeId
* @private
* @param object jQuery object representing the tool card.
* @return string Type ID
*/
var getTypeId = function(element) {
return element.attr('data-proxy-id');
};
/**
* Stop any announcement currently visible on the card.
*
* @method clearAllAnnouncements
* @private
* @param object jQuery object representing the tool card.
*/
var clearAllAnnouncements = function(element) {
element.removeClass('announcement loading success fail capabilities');
};
/**
* Show the loading announcement.
*
* @method startLoading
* @private
* @param object jQuery object representing the tool card.
*/
var startLoading = function(element) {
clearAllAnnouncements(element);
element.addClass('announcement loading');
};
/**
* Hide the loading announcement.
*
* @method stopLoading
* @private
* @param object jQuery object representing the tool card.
*/
var stopLoading = function(element) {
element.removeClass('announcement loading');
};
/**
* Show the success announcement. The announcement is only
* visible for 2 seconds.
*
* @method announceSuccess
* @private
* @param object jQuery object representing the tool card.
* @return object jQuery Deferred object
*/
var announceSuccess = function(element) {
var promise = $.Deferred();
clearAllAnnouncements(element);
element.addClass('announcement success');
setTimeout(function() {
element.removeClass('announcement success');
promise.resolve();
}, ANNOUNCEMENT_TIMEOUT);
return promise;
};
/**
* Show the failure announcement. The announcement is only
* visible for 2 seconds.
*
* @method announceFailure
* @private
* @param object jQuery object representing the tool card.
* @return object jQuery Deferred object
*/
var announceFailure = function(element) {
var promise = $.Deferred();
clearAllAnnouncements(element);
element.addClass('announcement fail');
setTimeout(function() {
element.removeClass('announcement fail');
promise.resolve();
}, ANNOUNCEMENT_TIMEOUT);
return promise;
};
/**
* Delete the tool type from the Moodle server. Triggers a success
* or failure announcement depending on the result.
*
* @method deleteType
* @private
* @param object jQuery object representing the tool card.
* @return object jQuery Deferred object
*/
var deleteType = function(element) {
var promise = $.Deferred();
var typeId = getTypeId(element);
startLoading(element);
if (typeId === "") {
return $.Deferred().resolve();
}
str.get_strings([
{
key: 'delete',
component: 'mod_lti'
},
{
key: 'delete_confirmation',
component: 'mod_lti'
},
{
key: 'delete',
component: 'mod_lti'
},
{
key: 'cancel',
component: 'core'
},
])
.done(function(strs) {
notification.confirm(strs[0], strs[1], strs[2], strs[3], function() {
toolProxy.delete(typeId)
.done(function() {
stopLoading(element);
announceSuccess(element)
.done(function() {
element.remove();
promise.resolve();
})
.fail(notification.exception);
})
.fail(function(error) {
announceFailure(element);
promise.reject(error);
});
}, function () {
stopLoading(element);
promise.resolve();
});
})
.fail(function(error) {
stopLoading(element);
notification.exception(error);
promise.reject(error);
});
return promise;
};
/**
* The user wishes to activate this tool so show them the capabilities that
* they need to agree to or if there are none then set the tool type's state
* to active.
*
* @method activateToolType
* @private
* @param object jQuery object representing the tool card.
*/
var activateToolType = function(element) {
var data = {proxyid: getTypeId(element)};
$(document).trigger(ltiEvents.START_EXTERNAL_REGISTRATION, data);
};
/**
* Sets up the listeners for user interaction on this tool type card.
*
* @method registerEventListeners
* @private
* @param object jQuery object representing the tool card.
*/
var registerEventListeners = function(element) {
var deleteButton = getDeleteButton(element);
deleteButton.click(function(e) {
e.preventDefault();
deleteType(element);
});
deleteButton.keypress(function(e) {
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
if (e.keyCode == KEYS.ENTER || e.keyCode == KEYS.SPACE) {
e.preventDefault();
deleteButton.click();
}
}
});
var activateButton = getActivateButton(element);
activateButton.click(function(e) {
e.preventDefault();
activateToolType(element);
});
activateButton.keypress(function(e) {
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
if (e.keyCode == KEYS.ENTER || e.keyCode == KEYS.SPACE) {
e.preventDefault();
activateButton.click();
}
}
});
};
return /** @alias module:mod_lti/tool_card_controller */ {
/**
* Initialise this module.
*
* @param object jQuery object representing the tool card.
*/
init: function(element) {
registerEventListeners(element);
}
};
});

View File

@ -137,6 +137,8 @@ define(['core/ajax', 'core/notification'], function(ajax, notification) {
/**
* Check if the given URL is a cartridge URL.
*
* The promise will fail if the URL is unreachable, so you must handle the fail result.
*
* @method isCartridge
* @public
* @param string URL
@ -152,8 +154,6 @@ define(['core/ajax', 'core/notification'], function(ajax, notification) {
var promise = ajax.call([request])[0];
promise.fail(notification.exception);
return promise;
},

View File

@ -42,12 +42,12 @@ require_once($CFG->dirroot . '/mod/lti/locallib.php');
class mod_lti_external extends external_api {
/**
* Returns description of a tool type
* Returns structure be used for returning a tool type from a web service.
*
* @return external_function_parameters
* @since Moodle 3.1
*/
private static function get_tool_type_return_parameters() {
private static function tool_type_return_structure() {
return new external_single_structure(
array(
'id' => new external_value(PARAM_INT, 'Tool type id'),
@ -90,7 +90,7 @@ class mod_lti_external extends external_api {
* @return external_function_parameters
* @since Moodle 3.1
*/
private static function get_tool_proxy_return_parameters() {
private static function tool_proxy_return_structure() {
return new external_function_parameters(
array(
'id' => new external_value(PARAM_INT, 'Tool proxy id'),
@ -113,6 +113,59 @@ class mod_lti_external extends external_api {
* Returns description of method parameters
*
* @return external_function_parameters
* @since Moodle 3.1
*/
public static function get_tool_proxies_parameters() {
return new external_function_parameters(
array(
'orphanedonly' => new external_value(PARAM_BOOL, 'Orphaned tool types only', VALUE_DEFAULT, 0)
)
);
}
/**
* Returns the tool types.
*
* @param bool $orphanedonly Retrieve only tool proxies that do not have a corresponding tool type
* @return array of tool types
* @since Moodle 3.1
* @throws moodle_exception
*/
public static function get_tool_proxies($orphanedonly) {
global $PAGE;
$params = self::validate_parameters(self::get_tool_proxies_parameters(),
array(
'orphanedonly' => $orphanedonly
));
$orphanedonly = $params['orphanedonly'];
$proxies = array();
$context = context_system::instance();
self::validate_context($context);
require_capability('moodle/site:config', $context);
$proxies = lti_get_tool_proxies($orphanedonly);
return array_map('serialise_tool_proxy', $proxies);
}
/**
* Returns description of method result value.
*
* @return external_description
* @since Moodle 3.1
*/
public static function get_tool_proxies_returns() {
return new external_multiple_structure(
self::tool_type_return_structure()
);
}
/**
* Returns description of method parameters.
*
* @return external_function_parameters
* @since Moodle 3.0
*/
public static function get_tool_launch_data_parameters() {
@ -495,7 +548,7 @@ class mod_lti_external extends external_api {
* @since Moodle 3.1
*/
public static function create_tool_proxy_returns() {
return self::get_tool_proxy_return_parameters();
return self::tool_proxy_return_structure();
}
/**
@ -545,7 +598,7 @@ class mod_lti_external extends external_api {
* @since Moodle 3.1
*/
public static function delete_tool_proxy_returns() {
return self::get_tool_proxy_return_parameters();
return self::tool_proxy_return_structure();
}
/**
@ -598,6 +651,7 @@ class mod_lti_external extends external_api {
'lti_version' => new external_value(PARAM_ALPHANUMEXT, 'LTI version'),
'reg_key' => new external_value(PARAM_TEXT, 'Tool proxy registration key'),
'reg_password' => new external_value(PARAM_TEXT, 'Tool proxy registration password'),
'reg_url' => new external_value(PARAM_TEXT, 'Tool proxy registration url'),
'tc_profile_url' => new external_value(PARAM_URL, 'Tool consumers profile URL'),
'launch_presentation_return_url' => new external_value(PARAM_URL, 'URL to redirect on registration completion'),
)
@ -657,7 +711,7 @@ class mod_lti_external extends external_api {
*/
public static function get_tool_types_returns() {
return new external_multiple_structure(
self::get_tool_type_return_parameters()
self::tool_type_return_structure()
);
}
@ -745,7 +799,7 @@ class mod_lti_external extends external_api {
* @since Moodle 3.1
*/
public static function create_tool_type_returns() {
return self::get_tool_type_return_parameters();
return self::tool_type_return_structure();
}
/**
@ -828,7 +882,7 @@ class mod_lti_external extends external_api {
* @since Moodle 3.1
*/
public static function update_tool_type_returns() {
return self::get_tool_type_return_parameters();
return self::tool_type_return_structure();
}
/**

View File

@ -56,6 +56,7 @@ class renderer extends plugin_renderer_base {
* @return string html for the page
*/
public function render_external_registration_return_page($page) {
return '';
$data = $page->export_for_template($this);
return parent::render_from_template('mod_lti/external_registration_return', $data);
}
}

View File

@ -54,12 +54,21 @@ $functions = array(
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
),
'mod_lti_get_tool_proxies' => array(
'classname' => 'mod_lti_external',
'methodname' => 'get_tool_proxies',
'description' => 'Get a list of the tool proxies',
'type' => 'read',
'capabilities' => 'moodle/site:config',
'ajax' => true
),
'mod_lti_create_tool_proxy' => array(
'classname' => 'mod_lti_external',
'methodname' => 'create_tool_proxy',
'description' => 'Create a tool proxy',
'type' => 'write',
'capabilities' => 'mod/lti:manage',
'capabilities' => 'moodle/site:config',
'ajax' => true
),
@ -68,7 +77,7 @@ $functions = array(
'methodname' => 'delete_tool_proxy',
'description' => 'Delete a tool proxy',
'type' => 'write',
'capabilities' => 'mod/lti:manage',
'capabilities' => 'moodle/site:config',
'ajax' => true
),
@ -77,7 +86,7 @@ $functions = array(
'methodname' => 'get_tool_proxy_registration_request',
'description' => 'Get a registration request for a tool proxy',
'type' => 'read',
'capabilities' => 'mod/lti:manage',
'capabilities' => 'moodle/site:config',
'ajax' => true
),
@ -86,7 +95,7 @@ $functions = array(
'methodname' => 'get_tool_types',
'description' => 'Get a list of the tool types',
'type' => 'read',
'capabilities' => 'mod/lti:manage',
'capabilities' => 'moodle/site:config',
'ajax' => true
),
@ -95,7 +104,7 @@ $functions = array(
'methodname' => 'create_tool_type',
'description' => 'Create a tool type',
'type' => 'write',
'capabilities' => 'mod/lti:manage',
'capabilities' => 'moodle/site:config',
'ajax' => true
),
@ -104,7 +113,7 @@ $functions = array(
'methodname' => 'update_tool_type',
'description' => 'Update a tool type',
'type' => 'write',
'capabilities' => 'mod/lti:manage',
'capabilities' => 'moodle/site:config',
'ajax' => true
),
@ -113,7 +122,7 @@ $functions = array(
'methodname' => 'delete_tool_type',
'description' => 'Delete a tool type',
'type' => 'write',
'capabilities' => 'mod/lti:manage',
'capabilities' => 'moodle/site:config',
'ajax' => true
),
@ -122,7 +131,7 @@ $functions = array(
'methodname' => 'is_cartridge',
'description' => 'Determine if the given url is for a cartridge',
'type' => 'read',
'capabilities' => 'mod/lti:manage',
'capabilities' => 'moodle/site:config',
'ajax' => true
),
);

View File

@ -42,7 +42,13 @@ $pageurl = new moodle_url('/mod/lti/externalregistrationreturn.php');
$PAGE->set_context($systemcontext);
$PAGE->set_url($pageurl);
$PAGE->set_pagelayout('maintenance');
echo $OUTPUT->header();
$output = $PAGE->get_renderer('mod_lti');
echo $output->header();
$params = array('message' => s($msg), 'error' => s($err), 'id' => $id, 'status' => s($status));
$page = new \mod_lti\output\external_registration_return_page();
echo $output->render($page);
$PAGE->requires->js_call_amd('mod_lti/external_registration_return', 'init', $params);
echo $OUTPUT->footer();
echo $output->footer();

View File

@ -162,6 +162,7 @@ $string['embed_no_blocks'] = 'Embed, without blocks';
$string['enableemailnotification'] = 'Send notification emails';
$string['enableemailnotification_help'] = 'If enabled, students will receive email notification when their tool submissions are graded.';
$string['enterkeyandsecret'] = 'Enter your consumer key and shared secret';
$string['errorbadurl'] = 'URL is not a valid tool URL or cartridge.';
$string['errormisconfig'] = 'Misconfigured tool. Please ask your Moodle administrator to fix the configuration of the tool.';
$string['existing_window'] = 'Existing window';
$string['extensions'] = 'LTI extension services';

View File

@ -302,6 +302,7 @@ function lti_build_registration_request($toolproxy) {
$requestparams['lti_version'] = 'LTI-2p0';
$requestparams['reg_key'] = $key;
$requestparams['reg_password'] = $secret;
$requestparams['reg_url'] = $toolproxy->regurl;
// Add the profile URL.
$profileservice = lti_get_service_by_name('profile');
@ -1623,6 +1624,30 @@ function lti_get_tool_proxy($id) {
return $toolproxy;
}
/**
* Returns lti tool proxies.
*
* @param bool $orphanedonly Only retrieves tool proxies that have no type associated with them
* @return array of basicLTI types
*/
function lti_get_tool_proxies($orphanedonly) {
global $DB;
if ($orphanedonly) {
$tools = $DB->get_records('lti_types');
$usedproxyids = array_values($DB->get_fieldset_select('lti_types', 'toolproxyid', 'toolproxyid IS NOT NULL'));
$proxies = $DB->get_records('lti_tool_proxies', null, 'state DESC, timemodified DESC');
foreach ($proxies as $key => $value) {
if (in_array($value->id, $usedproxyids)) {
unset($proxies[$key]);
}
}
return $proxies;
} else {
return $DB->get_records('lti_tool_proxies', null, 'state DESC, timemodified DESC');
}
}
/**
* Generates some of the tool proxy configuration based on the admin configuration details
*
@ -2273,6 +2298,19 @@ function get_tool_type_edit_url(stdClass $type) {
return $url->out();
}
/**
* Returns the edit url for the given tool proxy.
*
* @param stdClass $proxy The tool proxy
*
* @return string The url to edit the tool type
*/
function get_tool_proxy_edit_url(stdClass $proxy) {
$url = new moodle_url('/mod/lti/registersettings.php',
array('action' => 'update', 'id' => $proxy->id, 'sesskey' => sesskey(), 'returnto' => 'toolconfigure'));
return $url->out();
}
/**
* Returns the course url for the given tool type
*
@ -2294,7 +2332,7 @@ function get_tool_type_course_url(stdClass $type) {
*
* @param stdClass $type The tool type
*
* @return string The url to the course of the tool type
* @return string The urls of the tool type
*/
function get_tool_type_urls(stdClass $type) {
$courseurl = get_tool_type_course_url($type);
@ -2311,6 +2349,24 @@ function get_tool_type_urls(stdClass $type) {
return $urls;
}
/**
* Returns the icon and edit urls for the tool proxy.
*
* @param stdClass $proxy The tool proxy
*
* @return string The urls of the tool proxy
*/
function get_tool_proxy_urls(stdClass $proxy) {
global $OUTPUT;
$urls = array(
'icon' => $OUTPUT->pix_url('icon', 'lti')->out(),
'edit' => get_tool_proxy_edit_url($proxy),
);
return $urls;
}
/**
* Returns information on the current state of the tool type
*
@ -2432,6 +2488,34 @@ function serialise_tool_type(stdClass $type) {
);
}
/**
* Serialises this tool proxy.
*
* @param stdClass $proxy The tool proxy
*
* @return array An array of values representing this type
*/
function serialise_tool_proxy(stdClass $proxy) {
return array(
'id' => $proxy->id,
'name' => $proxy->name,
'description' => $proxy->regurl . ' You will need to activate this proxy before adding a description',
'urls' => get_tool_proxy_urls($proxy),
'state' => array(
'text' => get_string('pending', 'mod_lti'),
'pending' => true,
'configured' => false,
'rejected' => false,
'unknown' => false
),
'hascapabilitygroups' => true,
'capabilitygroups' => array(),
'courseid' => 0,
'instanceids' => array(),
'instancecount' => 0
);
}
/**
* Loads the cartridge information into the tool type, if the launch url is for a cartridge file
*

View File

@ -48,21 +48,22 @@
min-height: 800px;
}
#external-registration-container .registration-loading-container {
.loading-screen {
text-align: center;
padding: 3em;
}
#external-registration-container .registration-loading-container .loading-text, #external-registration-container .registration-loading-container .loader {
.loading-screen .loading-text {
font-size: 2em;
}
#external-registration-container .registration-loading-container .loader {
.loading-screen .loader {
margin-left: auto;
margin-right: auto;
margin-bottom: 1em;
height: 2em;
width: 2em;
font-size: 2em;
}
#registration-submit {
@ -70,7 +71,7 @@
}
#registration-form-container {
min-height: 230px;
min-height: 260px;
}
#registration-form-container .well {
@ -93,14 +94,6 @@
margin-top: 20px;
}
#registration-feedback-container {
cursor: pointer;
}
#registration-feedback-container h4 {
text-transform: capitalize;
}
#tool-type-capabilities-container .registration-loading-container {
display: none;
}
@ -325,6 +318,7 @@
.tool-card-body .description {
max-height: 100px;
word-wrap: break-word;
}
.tool-card-footer {

View File

@ -41,9 +41,9 @@
</div>
<div id="tool-type-capabilities-container" class="hidden">
<div class="registration-loading-container">
<div class="registration-loading-container loading-screen">
{{> mod_lti/loader }}
<p>{{#str}} loading, admin {{/str}}</p>
<p class="loading-text">{{#str}} loadinghelp, moodle {{/str}}</p>
</div>
<div id="tool-type-capabilities-template-container" aria-live="polite"></div>
</div>

View File

@ -15,35 +15,29 @@
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template mod_lti/registration_feedback
@template mod_lti/external_registration_return
This template provides the layout for a feedback message in the
tool configuration page.
This template provides the layout for the external tool configuration page in the
LTI module.
Classes required for JS:
* close
* alert
* alert-success
* alert-error
* none
Data attributes required for JS:
* none
Context variables required for this template:
* status
* message
Example context (json):
{
"status": "Success",
"message": "Successfully created a new tool type!"
}
*
}}
<div class="alert
{{^error}}alert-success{{/error}}
{{#error}}alert-error{{/error}}" role="alert">
<button type="button" class="close" aria-label="{{#str}} closebuttontitle, moodle {{/str}}">&times;</button>
<h4>{{status}}</h4>
{{message}}
<div id="external-registration-return-container">
<div class="registration-loading-container loading-screen">
{{> mod_lti/loader }}
<p class="loading-text">{{#str}} loadinghelp, moodle {{/str}}</p>
</div>
</div>
{{#js}}
require(['mod_lti/external_registration'], function(registration) {
registration.init();
});
{{/js}}

View File

@ -34,6 +34,7 @@
<div class="container-fluid">
<div id="main-content-container">
<div id="registration-form-container" aria-live="polite">
<div id="registration-feedback-container" aria-live="polite"></div>
<div id="registration-choice-container" class="centered-menu">
<div class="well">
<p class="lead">{{#str}} autoaddtype, mod_lti {{/str}}</p>
@ -57,7 +58,6 @@
<p><a href="{{{ managetoolsurl }}}">{{#str}} manage_tools, mod_lti {{/str}}</a><br/><a href="{{{ managetoolproxiesurl}}}">{{#str}} manage_tool_proxies, mod_lti {{/str}}</a></p>
</div>
</div>
<div id="registration-feedback-container" aria-live="polite"></div>
<div id="cartridge-registration-container" aria-live="polite" class="hidden">
{{> mod_lti/cartridge_registration_form }}
</div>

View File

@ -41,6 +41,9 @@
<div id="tool-notools-text" class="container-fluid">{{#str}} no_lti_tools, mod_lti {{/str}}</div>
{{/tools}}
<div id="tool-card-container" class="container-fluid">
{{#proxies}}
{{> mod_lti/tool_proxy_card }}
{{/proxies}}
{{#tools}}
{{> mod_lti/tool_card }}
{{/tools}}

View File

@ -0,0 +1,104 @@
{{!
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/>.
}}
{{!
@template mod_lti/tool_proxy_card
This template provides the layout for a single tool card on the tool
configuration page.
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* hascapabilitygroups
* state
** pending|configured|rejected|unknown
** text
* courseid
* urls
** course
** icon
* name
* description
* instancecount
}}
<div class="tool-card" data-proxy-id="{{id}}">
<div class="overlay-container">
<div class="img-container">
{{> mod_lti/loader }}
<div class="success-icon-container">{{#pix}} i/valid, core, {{#str}} success {{/str}}{{/pix}}</div>
<div class="fail-icon-container">{{#pix}} i/invalid, core, {{#str}} error {{/str}}{{/pix}}</div>
</div>
{{#hascapabilitygroups}}
{{> mod_lti/tool_type_capabilities_agree }}
{{/hascapabilitygroups}}
</div>
<div class="tool-card-content">
<div class="tool-card-header">
<div class="tool-card-subheader">
<div class="label
{{#state.pending}}label-info{{/state.pending}}
{{#state.configured}}label-success{{/state.configured}}
{{#state.rejected}}label-important{{/state.rejected}}
{{#state.unknown}}label-warning{{/state.unknown}}">
{{state.text}}
</div>
<div class="tool-card-actions pull-right">
{{#courseid}}
<a href="{{{urls.course}}}" title="{{#str}} courselink, mod_lti {{/str}}">{{#pix}} i/course, core, {{#str}} courselink, mod_lti {{/str}}{{/pix}}</a>
{{/courseid}}
<a class="edit" href="{{{urls.edit}}}" title="{{#str}} edit {{/str}}">{{#pix}} t/edit, core, {{#str}} edit {{/str}}{{/pix}}</a>
<a class="delete" href="#" title="{{#str}} delete {{/str}}">{{#pix}} t/delete, core, {{#str}} delete {{/str}}{{/pix}}</a>
</div>
</div>
<img class="tool-card-icon" src="{{{urls.icon}}}" alt="{{name}}"></img>
<div class="contenteditable-container">
<h4 class="name">{{name}}</h4>
<div class="overlay-container">{{> mod_lti/loader }}</div>
</div>
</div>
<div class="tool-card-body">
<div class="contenteditable-container">
<p class="description">{{description}}</p>
<div class="overlay-container">{{> mod_lti/loader }}</div>
</div>
</div>
<div class="tool-card-footer">
{{#state.pending}}
<a class="activate btn btn-success" href="#">{{#str}} activate, mod_lti {{/str}}</a>
{{/state.pending}}
{{^state.pending}}
{{#instancecount}}
<p>{{#str}} toolisbeingused, mod_lti, {{instancecount}} {{/str}}</p>
{{/instancecount}}
{{^instancecount}}
<p>{{#str}} toolisnotbeingused, mod_lti{{/str}}</p>
{{/instancecount}}
{{/state.pending}}
</div>
</div>
</div>
{{#js}}
require(['jquery', 'mod_lti/tool_proxy_card_controller'], function($, controller) {
var cardElement = $('[data-proxy-id={{id}}]');
controller.init(cardElement);
});
{{/js}}

View File

@ -31,7 +31,7 @@
}}
<div id="tool-proxy-registration-form-container">
<div class="registration-loading-container">
<div class="registration-loading-container loading-screen">
{{> mod_lti/loader }}
<p class="loading-text">{{#str}} loadinghelp, moodle {{/str}}</p>
<p id="registration-loading-failed" class="hidden">{{#str}} register_warning, mod_lti {{/str}}</p>

View File

@ -34,7 +34,7 @@ require_once($CFG->dirroot.'/mod/lti/locallib.php');
$action = optional_param('action', '', PARAM_ALPHANUMEXT);
$id = optional_param('id', '', PARAM_INT);
$tab = optional_param('tab', '', PARAM_ALPHAEXT);
$returnto = optional_param('returnto', '', PARAM_ALPHANUM);
$returnto = optional_param('returnto', '', PARAM_ALPHA);
if ($returnto == 'toolconfigure') {
$returnurl = new moodle_url($CFG->wwwroot . '/mod/lti/toolconfigure.php');

View File

@ -56,7 +56,7 @@ require_once($CFG->dirroot.'/mod/lti/locallib.php');
$action = optional_param('action', null, PARAM_ALPHANUMEXT);
$id = optional_param('id', null, PARAM_INT);
$tab = optional_param('tab', '', PARAM_ALPHAEXT);
$returnto = optional_param('returnto', '', PARAM_ALPHANUM);
$returnto = optional_param('returnto', '', PARAM_ALPHA);
if ($returnto == 'toolconfigure') {
$returnurl = new moodle_url($CFG->wwwroot . '/mod/lti/toolconfigure.php');

View File

@ -48,7 +48,7 @@
defined('MOODLE_INTERNAL') || die;
$plugin->version = 2016041800; // The current module version (Date: YYYYMMDDXX).
$plugin->version = 2016041801; // The current module version (Date: YYYYMMDDXX).
$plugin->requires = 2015111000; // Requires this Moodle version.
$plugin->component = 'mod_lti'; // Full name of the plugin (used for diagnostics).
$plugin->cron = 0;