diff --git a/bbb-lti/grails-app/assets/javascripts/bootstrap-confirmation.min.js b/bbb-lti/grails-app/assets/javascripts/bootstrap-confirmation.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..2119d183629ccab7c08231ac9ee94158e19d03d4
--- /dev/null
+++ b/bbb-lti/grails-app/assets/javascripts/bootstrap-confirmation.min.js
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap Confirmation 2.3.1
+ * Copyright 2013 Nimit Suwannagate <ethaizone@hotmail.com>
+ * Copyright 2014-2016 Damien "Mistic" Sorel <contact@git.strangeplanet.fr>
+ * Licensed under the Apache License, Version 2.0
+ */
+!function($){"use strict";function a(a){for(var b=window,c=a.split("."),d=c.pop(),e=0,f=c.length;e<f;e++)b=b[c[e]];return function(){b[d].call(this)}}if(!$.fn.popover)throw new Error("Confirmation requires popover.js");var b=function(a,b){b.trigger="click",this.init(a,b)};b.VERSION="2.3.1",b.DEFAULTS=$.extend({},$.fn.popover.Constructor.DEFAULTS,{placement:"top",title:"Are you sure?",popout:!1,singleton:!1,copyAttributes:"href target",buttons:null,onConfirm:$.noop,onCancel:$.noop,btnOkClass:"btn-xs btn-primary",btnOkIcon:"glyphicon glyphicon-ok",btnOkLabel:"Yes",btnCancelClass:"btn-xs btn-default",btnCancelIcon:"glyphicon glyphicon-remove",btnCancelLabel:"No",template:'<div class="popover confirmation"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"><p class="confirmation-content"></p><div class="confirmation-buttons text-center"><div class="btn-group"><a class="btn" data-apply="confirmation"></a><a class="btn" data-dismiss="confirmation"></a></div></div></div></div>'}),b.prototype=$.extend({},$.fn.popover.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.init=function(a,b){$.fn.popover.Constructor.prototype.init.call(this,"confirmation",a,b),this.options._isDelegate=!1,b.selector?this.options._selector=this._options._selector=b._root_selector+" "+b.selector:b._selector?(this.options._selector=b._selector,this.options._isDelegate=!0):this.options._selector=b._root_selector;var c=this;this.options.selector||(this.options._attributes={},this.options.copyAttributes?"string"==typeof this.options.copyAttributes&&(this.options.copyAttributes=this.options.copyAttributes.split(" ")):this.options.copyAttributes=[],this.options.copyAttributes.forEach(function(a){this.options._attributes[a]=this.$element.attr(a)},this),this.$element.on(this.options.trigger,function(a,b){b||(a.preventDefault(),a.stopPropagation(),a.stopImmediatePropagation())}),this.$element.on("show.bs.confirmation",function(a){c.options.singleton&&$(c.options._selector).not($(this)).filter(function(){return void 0!==$(this).data("bs.confirmation")}).confirmation("hide")})),this.options._isDelegate||(this.eventBody=!1,this.uid=this.$element[0].id||this.getUID("group_"),this.$element.on("shown.bs.confirmation",function(a){c.options.popout&&!c.eventBody&&(c.eventBody=$("body").on("click.bs.confirmation."+c.uid,function(a){$(c.options._selector).is(a.target)||($(c.options._selector).filter(function(){return void 0!==$(this).data("bs.confirmation")}).confirmation("hide"),$("body").off("click.bs."+c.uid),c.eventBody=!1)}))}))},b.prototype.setContent=function(){var a=this,b=this.tip(),c=this.getTitle(),d=this.getContent();if(b.find(".popover-title")[this.options.html?"html":"text"](c),b.find(".confirmation-content").toggle(!!d).children().detach().end()[this.options.html?"string"==typeof d?"html":"append":"text"](d),b.on("click",function(a){a.stopPropagation()}),this.options.buttons){var e=b.find(".confirmation-buttons .btn-group").empty();this.options.buttons.forEach(function(b){e.append($("<a></a>").addClass(b["class"]).html(b.label).prepend($("<i></i>").addClass(b.icon)," ").one("click",function(){b.onClick&&b.onClick.call(a.$element),b.cancel?(a.getOnCancel.call(a).call(a.$element),a.$element.trigger("canceled.bs.confirmation")):(a.getOnConfirm.call(a).call(a.$element),a.$element.trigger("confirmed.bs.confirmation")),a.$element.confirmation("hide")}))},this)}else b.find('[data-apply="confirmation"]').addClass(this.options.btnOkClass).html(this.options.btnOkLabel).attr(this.options._attributes).prepend($("<i></i>").addClass(this.options.btnOkIcon)," ").off("click").one("click",function(){a.getOnConfirm.call(a).call(a.$element),a.$element.trigger("confirmed.bs.confirmation"),a.$element.trigger(a.options.trigger,[!0]),a.$element.confirmation("hide")}),b.find('[data-dismiss="confirmation"]').addClass(this.options.btnCancelClass).html(this.options.btnCancelLabel).prepend($("<i></i>").addClass(this.options.btnCancelIcon)," ").off("click").one("click",function(){a.getOnCancel.call(a).call(a.$element),a.inState&&(a.inState.click=!1),a.$element.trigger("canceled.bs.confirmation"),a.$element.confirmation("hide")});b.removeClass("fade top bottom left right in"),b.find(".popover-title").html()||b.find(".popover-title").hide()},b.prototype.getOnConfirm=function(){return this.$element.attr("data-on-confirm")?a(this.$element.attr("data-on-confirm")):this.options.onConfirm},b.prototype.getOnCancel=function(){return this.$element.attr("data-on-cancel")?a(this.$element.attr("data-on-cancel")):this.options.onCancel};var c=$.fn.confirmation;$.fn.confirmation=function(a){var c="object"==typeof a&&a||{};return c._root_selector=this.selector,this.each(function(){var d=$(this),e=d.data("bs.confirmation");(e||"destroy"!=a)&&(e||d.data("bs.confirmation",e=new b(this,c)),"string"==typeof a&&(e[a](),"hide"==a&&e.inState&&(e.inState.click=!1)))})},$.fn.confirmation.Constructor=b,$.fn.confirmation.noConflict=function(){return $.fn.confirmation=c,this}}(jQuery);
\ No newline at end of file
diff --git a/bbb-lti/grails-app/assets/javascripts/tool.js b/bbb-lti/grails-app/assets/javascripts/tool.js
index c32dc0635cc3e048793f7c6568e9b21143692bb9..4f9da332264fd75ad2c5147bf6a547088e1af0b8 100644
--- a/bbb-lti/grails-app/assets/javascripts/tool.js
+++ b/bbb-lti/grails-app/assets/javascripts/tool.js
@@ -18,29 +18,23 @@
 $(document).ready( function () {
 	if (typeof jQuery !== 'undefined') {
 		(function($) {
-			$('#spinner').ajaxStart(function() {
-				$(this).fadeIn();
-			}).ajaxStop(function() {
-				$(this).fadeOut();
+			$('[data-toggle="confirmation"]').confirmation({popout: true});
+			$('#recordings').dataTable({
+				columnDefs: [ {
+					targets: 3,
+					render: $.fn.dataTable.render.moment('X', 'LLL', locale)
+				} ],
+				sPaginationType : "full_numbers",
+				"columns": [
+					null,
+					null,
+					null,
+					null,
+					null,
+					{ "width": "160px" }
+				],
+				"order": [[ 3, "desc" ]]
 			});
 		})(jQuery);
-		
-		$('#recordings').dataTable({
-			columnDefs: [ {
-				targets: 3,
-				render: $.fn.dataTable.render.moment('X', 'LLL', locale)
-			} ],
-			sPaginationType : "full_numbers",
-			"columns": [
-				null,
-				null,
-				null,
-				null,
-				null,
-				{ "width": "160px" }
-			],
-			"order": [[ 3, "desc" ]]
-		});
-		
 	}
 });
diff --git a/bbb-lti/grails-app/conf/BuildConfig.groovy b/bbb-lti/grails-app/conf/BuildConfig.groovy
index b5de2927746e542e8a773c9d89c8e530e072c09e..0bf647fec3f6cb2567a104182888511ffe2e6c43 100644
--- a/bbb-lti/grails-app/conf/BuildConfig.groovy
+++ b/bbb-lti/grails-app/conf/BuildConfig.groovy
@@ -84,6 +84,6 @@ grails.project.dependency.resolution = {
         // plugins needed at runtime but not for compilation
         runtime ":database-migration:1.4.0"
         runtime ":jquery:1.11.1"
-        runtime ':twitter-bootstrap:3.3.4'
+        runtime ':twitter-bootstrap:3.3.5'
     }
 }
diff --git a/bbb-lti/grails-app/i18n/messages.properties b/bbb-lti/grails-app/i18n/messages.properties
index 34f14873a4935ab2d5d83248bd96fa39d19bd06b..a9a014740524315d68b6ab5d1e78b046d2f031de 100644
--- a/bbb-lti/grails-app/i18n/messages.properties
+++ b/bbb-lti/grails-app/i18n/messages.properties
@@ -29,15 +29,18 @@ tool.view.join=Join Meeting
 tool.view.recording=Recording
 tool.view.recording.format.presentation=presentation
 tool.view.recording.format.video=video
+tool.view.recording.delete.confirmation=Are you sure to permanently delete this recording?
+tool.view.recording.delete.confirmation.warning=Warning
+tool.view.recording.delete.confirmation.yes=Yes
+tool.view.recording.delete.confirmation.no=No
+tool.view.recording.publish=Publish
+tool.view.recording.unpublish=Unpublish
+tool.view.recording.delete=Delete
 tool.view.activity=Activity
 tool.view.description=Description
 tool.view.date=Date
 tool.view.duration=Duration
 tool.view.actions=Actions
-tool.view.publishRecording=Publish
-tool.view.unpublishRecording=Unpublish
-tool.view.deleteRecording=Delete
-tool.view.deleteRecordingConfirmation=Are you sure to permanently delete this recording?
 tool.view.dateFormat=E, MMM dd, yyyy HH:mm:ss Z
 
 tool.error.general=Connection could not be established.
\ No newline at end of file
diff --git a/bbb-lti/grails-app/i18n/messages_es.properties b/bbb-lti/grails-app/i18n/messages_es.properties
index d45063b6cd4184d328c63e67dd56f66b760345c1..7e0eedbf335ba1e69dffed503faf3e860a44f3e0 100644
--- a/bbb-lti/grails-app/i18n/messages_es.properties
+++ b/bbb-lti/grails-app/i18n/messages_es.properties
@@ -27,15 +27,21 @@ tool.view.join=Ingresar a la sesi&#243;n
 tool.view.recording=Grabaci&#243;n
 tool.view.recording.format.presentation=presentaci&#243;n
 tool.view.recording.format.video=video
+tool.view.recording.delete.confirmation=Esta seguro de borrar permanentemente esta grabaci&#243;n?
+tool.view.recording.delete.confirmation.warning=Advertencia
+tool.view.recording.delete.confirmation.yes=Si
+tool.view.recording.delete.confirmation.no=No
+tool.view.recording.publish=Mostrar
+tool.view.recording.unpublish=Esconder
+tool.view.recording.delete=Borrar
+tool.view.recording.confirmation.warning=
+tool.view.recording.confirmation.yes=Si
+tool.view.recording.confirmation.no=No
 tool.view.activity=Actividad
 tool.view.description=Descripci&#243;n
 tool.view.date=Fecha
 tool.view.duration=Duraci&#243;n
 tool.view.actions=Acciones
-tool.view.publishRecording=Mostrar
-tool.view.unpublishRecording=Esconder
-tool.view.deleteRecording=Borrar
-tool.view.deleteRecordingConfirmation=Esta seguro de borrar permanentemente esta grabaci&#243;n?
 tool.view.dateFormat=E, MMM dd, yyyy HH:mm:ss Z
 
 tool.error.general=No pudo estableserce la conexi&#243;n.
\ No newline at end of file
diff --git a/bbb-lti/grails-app/i18n/messages_fr.properties b/bbb-lti/grails-app/i18n/messages_fr.properties
index 29c72517ab63a44edaaf7d056cc6babf2bf3a852..70c9fd7fbda9b803d3c1ecbda3db82b568235148 100644
--- a/bbb-lti/grails-app/i18n/messages_fr.properties
+++ b/bbb-lti/grails-app/i18n/messages_fr.properties
@@ -25,15 +25,18 @@ tool.view.join=Saisie de la r&#233;union
 tool.view.recording=Enregistrement
 tool.view.recording.format.presentation=presentation
 tool.view.recording.format.video=video
+tool.view.recording.delete.confirmation=Veillez &#224; supprimer d&#233;finitivement cet enregistrement?
+tool.view.recording.delete.confirmation.warning=Attention
+tool.view.recording.delete.confirmation.yes=Oui
+tool.view.recording.delete.confirmation.no=Non
+tool.view.recording.publish=Publier
+tool.view.recording.unpublish=D&#233;publier
+tool.view.recording.delete=Supprimer
 tool.view.activity=Activit&#233;
 tool.view.description=Description
 tool.view.date=Date
 tool.view.duration=Dur&#233;e
 tool.view.actions=Actions
-tool.view.publishRecording=Publier
-tool.view.unpublishRecording=D&#233;publier
-tool.view.deleteRecording=Supprimer
-tool.view.deleteRecordingConfirmation=Veillez &#224; supprimer d&#233;finitivement cet enregistrement?
 tool.view.dateFormat=E, MMM dd, yyyy HH:mm:ss Z
 
 tool.error.general=Pas possible &#233;tablir la connection.
\ No newline at end of file
diff --git a/bbb-lti/grails-app/views/tool/index.gsp b/bbb-lti/grails-app/views/tool/index.gsp
index 5222623ac812a5aba7b2ba3e186dc4d0fd5a0707..348ded651cd73f17e7871e74c7aca64fce0a9c95 100644
--- a/bbb-lti/grails-app/views/tool/index.gsp
+++ b/bbb-lti/grails-app/views/tool/index.gsp
@@ -11,6 +11,7 @@
         <asset:javascript src="dataTables.plugin.datetime.js"/>
         <asset:javascript src="moment-with-locales.min.js"/>
         <asset:javascript src="bootstrap.js"/>
+        <asset:javascript src="bootstrap-confirmation.min.js"/>
         <asset:javascript src="tool.js"/>
     </head>
     <body>
@@ -35,9 +36,11 @@
                 <g:if test="${ismoderator || r.published == 'true'}">  
                 <tr class="r0 lastrow">
                     <td class="cell c0" style="text-align:center;">
+                    <g:if test="${r.published == 'true'}">
                     <g:each in="${r.playback}" var="p">
                         <a title="<g:message code="tool.view.recording.format.${p.type}" />" target="_new" href="${p.url}"><g:message code="tool.view.recording.format.${p.type}" /></a>&#32;
                     </g:each>
+                    </g:if>
                     </td>
                     <td class="cell c1" style="text-align:center;">${r.name}</td>
                     <td class="cell c2" style="text-align:center;">${r.metadata.contextactivitydescription}</td>
@@ -46,12 +49,20 @@
                     <g:if test="${ismoderator}">
                     <td class="cell c5 lastcol" style="text-align:center;">
                       <g:if test="${r.published == 'true'}">
-                      <button class="btn btn-default btn-sm glyphicon glyphicon-eye-close" name="unpublish_recording" type="submit" value="${r.recordID}" onClick="window.location='${createLink(controller:'tool',action:'publish',id: '0')}?bbb_recording_published=${r.published}&bbb_recording_id=${r.recordID}'; return false;"></button>
+                      <a title="<g:message code="tool.view.recording.unpublish" />" class="btn btn-default btn-sm glyphicon glyphicon-eye-close" name="unpublish_recording" type="submit" value="${r.recordID}" href="${createLink(controller:'tool',action:'publish',id: '0')}?bbb_recording_published=${r.published}&bbb_recording_id=${r.recordID}"></a>
                       </g:if>
                       <g:else>
-                      <button class="btn btn-default btn-sm glyphicon glyphicon-eye-open" name="publish_recording" type="submit" value="${r.recordID}" onClick="window.location='${createLink(controller:'tool',action:'publish',id: '0')}?bbb_recording_published=${r.published}&bbb_recording_id=${r.recordID}'; return false;"></button>
+                      <a title="<g:message code="tool.view.recording.publish" />" class="btn btn-default btn-sm glyphicon glyphicon-eye-open" name="publish_recording" type="submit" value="${r.recordID}" href="${createLink(controller:'tool',action:'publish',id: '0')}?bbb_recording_published=${r.published}&bbb_recording_id=${r.recordID}"></a>
                       </g:else>
-                      <button class="btn btn-danger btn-sm glyphicon glyphicon-trash" name="delete_recording" type="submit" value="${r.recordID}" onClick="if(confirm('<g:message code="tool.view.deleteRecordingConfirmation" />')) window.location='${createLink(controller:'tool',action:'delete',id: '0')}?bbb_recording_id=${r.recordID}'; return false;"></button>
+                      <a title="<g:message code="tool.view.recording.delete" />" class="btn btn-danger btn-sm glyphicon glyphicon-trash" name="delete_recording" value="${r.recordID}"
+                        data-toggle="confirmation"
+                        data-title="<g:message code="tool.view.recording.delete.confirmation.warning" />"
+                        data-content="<g:message code="tool.view.recording.delete.confirmation" />"
+                        data-btn-ok-label="<g:message code="tool.view.recording.delete.confirmation.yes" />"
+                        data-btn-cancel-label="<g:message code="tool.view.recording.delete.confirmation.no" />"
+                        data-placement="left"
+                        href="${createLink(controller:'tool',action:'delete',id: '0')}?bbb_recording_id=${r.recordID}">
+                      </a>
                     </td>
                     </g:if>
                 </tr>