This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch csp
in repository https://gitbox.apache.org/repos/asf/openmeetings.git


The following commit(s) were added to refs/heads/csp by this push:
     new 3ca1ca6  [OPENMEETINGS-2165] upload dialog is converted
3ca1ca6 is described below

commit 3ca1ca6e7d95e0094286995cd74cd9a295b8f0a8
Author: Maxim Solodovnik <[email protected]>
AuthorDate: Fri Feb 14 16:19:43 2020 +0700

    [OPENMEETINGS-2165] upload dialog is converted
---
 .../apache/openmeetings/backup/BackupExport.java   | 108 ++++++------
 .../apache/openmeetings/backup/BackupImport.java   |  24 ++-
 .../java/org/apache/openmeetings/cli/Admin.java    |   2 +-
 .../openmeetings/web/admin/AdminActionsPanel.java  |   2 +-
 .../openmeetings/web/admin/backup/BackupPanel.html |   5 +-
 .../openmeetings/web/admin/backup/BackupPanel.java | 192 ++++++++++++---------
 .../web/admin/connection/ConnectionsPanel.java     |   8 +-
 .../openmeetings/web/admin/email/EmailForm.java    |   2 +-
 .../web/admin/groups/GroupUsersPanel.java          |   5 +-
 .../openmeetings/web/admin/labels/LangPanel.html   |   1 -
 .../openmeetings/web/admin/labels/LangPanel.java   |   6 +-
 .../openmeetings/web/admin/oauth/OAuthForm.java    |   4 +-
 .../openmeetings/web/admin/rooms/RoomForm.java     |   8 +-
 .../openmeetings/web/common/FormActionsPanel.java  |   2 +-
 .../apache/openmeetings/web/common/MainPanel.java  |   2 +-
 .../web/common/UploadableImagePanel.java           |   3 +-
 .../common/confirmation/ConfirmableAjaxBorder.java |  19 ++
 .../openmeetings/web/room/sidebar/RoomSidebar.java |   2 +-
 .../web/room/sidebar/UploadDialog.html             |  11 +-
 .../web/room/sidebar/UploadDialog.java             | 156 ++++++-----------
 .../web/user/calendar/CalendarDialog.java          |   2 +-
 .../openmeetings/web/user/chat/ChatToolbar.java    |   2 +-
 .../dashboard/admin/AdminCleanupInfoDialog.java    |   2 +-
 .../web/user/profile/InvitationDetails.java        |   2 +-
 .../web/user/profile/MessagesContactsPanel.java    |   6 +-
 .../web/util/CallbackFunctionHelper.java           |  20 ---
 .../apache/openmeetings/web/util/ThreadHelper.java |  48 ++++++
 .../src/main/webapp/css/raw-general.css            |   5 -
 .../org/apache/openmeetings/backup/TestBackup.java |   2 +-
 29 files changed, 342 insertions(+), 309 deletions(-)

diff --git 
a/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupExport.java
 
b/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupExport.java
index fcc9348..14172ac 100644
--- 
a/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupExport.java
+++ 
b/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupExport.java
@@ -162,24 +162,42 @@ public class BackupExport {
                         */
                        writeList(ser, zos, "version.xml", "version", 
Arrays.asList(BackupVersion.get()));
                        progressHolder.setProgress(2);
-                       exportGroups(zos, progressHolder);
-                       exportUsers(zos, progressHolder);
-                       exportRoom(zos, progressHolder);
-                       exportRoomGroup(zos, progressHolder);
-                       exportRoomFile(zos, progressHolder);
-                       exportCalendar(zos, progressHolder);
-                       exportAppointment(zos, progressHolder);
-                       exportMeetingMember(zos, progressHolder);
-                       exportLdap(zos, progressHolder, ser);
-                       exportOauth(zos, progressHolder);
-                       exportPrivateMsg(zos, progressHolder);
-                       exportPrivateMsgFolder(zos, progressHolder, ser);
-                       exportContacts(zos, progressHolder);
-                       exportFile(zos, progressHolder);
-                       exportRecording(zos, progressHolder);
-                       exportPoll(zos, progressHolder);
-                       exportConfig(zos, progressHolder);
-                       exportChat(zos, progressHolder);
+                       exportGroups(zos);
+                       progressHolder.setProgress(5);
+                       exportUsers(zos);
+                       progressHolder.setProgress(10);
+                       exportRoom(zos);
+                       progressHolder.setProgress(15);
+                       exportRoomGroup(zos);
+                       progressHolder.setProgress(17);
+                       exportRoomFile(zos);
+                       progressHolder.setProgress(17);
+                       exportCalendar(zos);
+                       progressHolder.setProgress(22);
+                       exportAppointment(zos);
+                       progressHolder.setProgress(25);
+                       exportMeetingMember(zos);
+                       progressHolder.setProgress(30);
+                       exportLdap(zos, ser);
+                       progressHolder.setProgress(35);
+                       exportOauth(zos);
+                       progressHolder.setProgress(45);
+                       exportPrivateMsg(zos);
+                       progressHolder.setProgress(50);
+                       exportPrivateMsgFolder(zos, ser);
+                       progressHolder.setProgress(55);
+                       exportContacts(zos);
+                       progressHolder.setProgress(60);
+                       exportFile(zos);
+                       progressHolder.setProgress(65);
+                       exportRecording(zos);
+                       progressHolder.setProgress(70);
+                       exportPoll(zos);
+                       progressHolder.setProgress(75);
+                       exportConfig(zos);
+                       progressHolder.setProgress(80);
+                       exportChat(zos);
+                       progressHolder.setProgress(85);
 
                        if (includeFiles) {
                                exportFiles(progressHolder, zos);
@@ -229,20 +247,19 @@ public class BackupExport {
        /*
         * ##################### Backup  Groups
         */
-       private void exportGroups(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportGroups(ZipOutputStream zos) throws Exception {
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
                Serializer ser = new Persister(strategy);
                List<Group> list = groupDao.get(0, Integer.MAX_VALUE);
                bindDate(registry, list);
                writeList(ser, zos, "organizations.xml", "organisations", list);
-               progressHolder.setProgress(5);
        }
 
        /*
         * ##################### Backup Users
         */
-       private void exportUsers(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportUsers(ZipOutputStream zos) throws Exception {
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
                Serializer ser = new Persister(strategy);
@@ -253,13 +270,12 @@ public class BackupExport {
                bindDate(registry, list);
 
                writeList(ser, zos, "users.xml", "users", list);
-               progressHolder.setProgress(10);
        }
 
        /*
         * ##################### Backup Room
         */
-       private void exportRoom(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportRoom(ZipOutputStream zos) throws Exception {
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
                Serializer serializer = new Persister(strategy);
@@ -269,13 +285,12 @@ public class BackupExport {
                List<Room> list = roomDao.get();
                bindDate(registry, list);
                writeList(serializer, zos, "rooms.xml", "rooms", list);
-               progressHolder.setProgress(15);
        }
 
        /*
         * ##################### Backup Room Groups
         */
-       private void exportRoomGroup(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportRoomGroup(ZipOutputStream zos) throws Exception {
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
                Serializer serializer = new Persister(strategy);
@@ -284,13 +299,12 @@ public class BackupExport {
                registry.bind(Room.class, RoomConverter.class);
 
                writeList(serializer, zos, "rooms_organisation.xml", 
"room_organisations", roomDao.getGroups());
-               progressHolder.setProgress(17);
        }
 
        /*
         * ##################### Backup Room Files
         */
-       private void exportRoomFile(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportRoomFile(ZipOutputStream zos) throws Exception {
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
                Serializer serializer = new Persister(strategy);
@@ -299,13 +313,12 @@ public class BackupExport {
                registry.bind(Recording.class, BaseFileItemConverter.class);
 
                writeList(serializer, zos, "roomFiles.xml", "RoomFiles", 
roomDao.getFiles());
-               progressHolder.setProgress(17);
        }
 
        /*
         * ##################### Backup Calendars
         */
-       private void exportCalendar(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportCalendar(ZipOutputStream zos) throws Exception {
                List<OmCalendar> list = calendarDao.get();
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
@@ -314,13 +327,12 @@ public class BackupExport {
                bindDate(registry, list);
 
                writeList(serializer, zos, "calendars.xml", "calendars", list);
-               progressHolder.setProgress(22);
        }
 
        /*
         * ##################### Backup Appointments
         */
-       private void exportAppointment(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportAppointment(ZipOutputStream zos) throws Exception {
                List<Appointment> list = appointmentDao.get();
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
@@ -332,13 +344,12 @@ public class BackupExport {
                bindDate(registry, list);
 
                writeList(serializer, zos, "appointements.xml", "appointments", 
list);
-               progressHolder.setProgress(25);
        }
 
        /*
         * ##################### Backup Meeting Members
         */
-       private void exportMeetingMember(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportMeetingMember(ZipOutputStream zos) throws Exception {
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
                Serializer serializer = new Persister(strategy);
@@ -348,38 +359,35 @@ public class BackupExport {
 
                writeList(serializer, zos, "meetingmembers.xml",
                                "meetingmembers", 
meetingMemberDao.getMeetingMembers());
-               progressHolder.setProgress(30);
        }
 
        /*
         * ##################### LDAP Configs
         */
-       private void exportLdap(ZipOutputStream zos, ProgressHolder 
progressHolder, Serializer ser) throws Exception {
+       private void exportLdap(ZipOutputStream zos, Serializer ser) throws 
Exception {
                List<LdapConfig> ldapList = ldapConfigDao.get();
                if (!ldapList.isEmpty()) {
                        ldapList.remove(0);
                }
                writeList(ser, zos, "ldapconfigs.xml", "ldapconfigs", ldapList);
-               progressHolder.setProgress(35);
        }
 
        /*
         * ##################### OAuth2 servers
         */
-       private void exportOauth(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportOauth(ZipOutputStream zos) throws Exception {
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
                Serializer serializer = new Persister(strategy);
                List<OAuthServer> list = auth2Dao.get(0, Integer.MAX_VALUE);
                bindDate(registry, list);
                writeList(serializer, zos, "oauth2servers.xml", 
"oauth2servers", list);
-               progressHolder.setProgress(45);
        }
 
        /*
         * ##################### Private Messages
         */
-       private void exportPrivateMsg(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportPrivateMsg(ZipOutputStream zos) throws Exception {
                List<PrivateMessage> list = privateMessageDao.get(0, 
Integer.MAX_VALUE);
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
@@ -389,22 +397,20 @@ public class BackupExport {
                registry.bind(Room.class, RoomConverter.class);
                bindDate(registry, list, PrivateMessage::getInserted);
                writeList(serializer, zos, "privateMessages.xml", 
"privatemessages", list);
-               progressHolder.setProgress(50);
        }
 
        /*
         * ##################### Private Message Folders
         */
-       private void exportPrivateMsgFolder(ZipOutputStream zos, ProgressHolder 
progressHolder, Serializer ser) throws Exception {
+       private void exportPrivateMsgFolder(ZipOutputStream zos, Serializer 
ser) throws Exception {
                writeList(ser, zos, "privateMessageFolder.xml",
                                "privatemessagefolders", 
privateMessageFolderDao.get(0, Integer.MAX_VALUE));
-               progressHolder.setProgress(55);
        }
 
        /*
         * ##################### User Contacts
         */
-       private void exportContacts(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportContacts(ZipOutputStream zos) throws Exception {
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
                Serializer serializer = new Persister(strategy);
@@ -412,13 +418,12 @@ public class BackupExport {
                registry.bind(User.class, UserConverter.class);
 
                writeList(serializer, zos, "userContacts.xml", "usercontacts", 
userContactDao.get());
-               progressHolder.setProgress(60);
        }
 
        /*
         * ##################### File-Explorer
         */
-       private void exportFile(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportFile(ZipOutputStream zos) throws Exception {
                List<FileItem> list = fileItemDao.get();
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
@@ -426,13 +431,12 @@ public class BackupExport {
 
                bindDate(registry, list);
                writeList(serializer, zos, "fileExplorerItems.xml", 
"fileExplorerItems", list);
-               progressHolder.setProgress(65);
        }
 
        /*
         * ##################### Recordings
         */
-       private void exportRecording(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportRecording(ZipOutputStream zos) throws Exception {
                List<Recording> list = recordingDao.get();
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
@@ -440,13 +444,12 @@ public class BackupExport {
 
                bindDate(registry, list);
                writeList(serializer, zos, "flvRecordings.xml", 
"flvrecordings", list);
-               progressHolder.setProgress(70);
        }
 
        /*
         * ##################### Polls
         */
-       private void exportPoll(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportPoll(ZipOutputStream zos) throws Exception {
                List<RoomPoll> list = pollManager.get();
                Registry registry = new Registry();
                Strategy strategy = new RegistryStrategy(registry);
@@ -457,24 +460,22 @@ public class BackupExport {
                registry.bind(RoomPoll.Type.class, PollTypeConverter.class);
                bindDate(registry, list, RoomPoll::getCreated);
                writeList(serializer, zos, "roompolls.xml", "roompolls", list);
-               progressHolder.setProgress(75);
        }
 
        /*
         * ##################### Config
         */
-       private void exportConfig(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportConfig(ZipOutputStream zos) throws Exception {
                List<Configuration> list = configurationDao.get(0, 
Integer.MAX_VALUE);
                Serializer serializer = getConfigSerializer(list);
 
                writeList(serializer, zos, "configs.xml", "configs", list);
-               progressHolder.setProgress(80);
        }
 
        /*
         * ##################### Chat
         */
-       private void exportChat(ZipOutputStream zos, ProgressHolder 
progressHolder) throws Exception {
+       private void exportChat(ZipOutputStream zos) throws Exception {
                List<ChatMessage> list = chatDao.get(0, Integer.MAX_VALUE);
                Registry registry = new Registry();
                registry.bind(User.class, UserConverter.class);
@@ -484,7 +485,6 @@ public class BackupExport {
 
                bindDate(registry, list, ChatMessage::getSent);
                writeList(serializer, zos, "chat_messages.xml", 
"chat_messages", list);
-               progressHolder.setProgress(85);
        }
 
        private static Serializer getConfigSerializer(List<Configuration> list) 
throws Exception {
diff --git 
a/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java
 
b/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java
index 3883f85..fe14b5b 100644
--- 
a/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java
+++ 
b/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java
@@ -363,7 +363,8 @@ public class BackupImport {
                return f;
        }
 
-       public void performImport(InputStream is) throws Exception {
+       public void performImport(InputStream is, ProgressHolder 
progressHolder) throws Exception {
+               progressHolder.setProgress(0);
                userMap.clear();
                groupMap.clear();
                calendarMap.clear();
@@ -387,30 +388,50 @@ public class BackupImport {
                registry.bind(Date.class, DateConverter.class);
 
                BackupVersion ver = getVersion(simpleSerializer, f);
+               progressHolder.setProgress(2);
                importConfigs(f);
+               progressHolder.setProgress(7);
                importGroups(f, simpleSerializer);
+               progressHolder.setProgress(12);
                importLdap(f, simpleSerializer);
+               progressHolder.setProgress(17);
                importOauth(f, simpleSerializer);
+               progressHolder.setProgress(22);
                importUsers(f);
+               progressHolder.setProgress(27);
                importRooms(f);
+               progressHolder.setProgress(32);
                importRoomGroups(f);
+               progressHolder.setProgress(37);
                importChat(f);
+               progressHolder.setProgress(42);
                importCalendars(f);
+               progressHolder.setProgress(47);
                importAppointments(f);
+               progressHolder.setProgress(52);
                importMeetingMembers(f);
+               progressHolder.setProgress(57);
                importRecordings(f);
+               progressHolder.setProgress(62);
                importPrivateMsgFolders(f, simpleSerializer);
+               progressHolder.setProgress(67);
                importContacts(f);
+               progressHolder.setProgress(72);
                importPrivateMsgs(f);
+               progressHolder.setProgress(77);
                List<FileItem> files = importFiles(f);
+               progressHolder.setProgress(82);
                importPolls(f);
+               progressHolder.setProgress(87);
                importRoomFiles(f);
+               progressHolder.setProgress(92);
 
                log.info("Room files import complete, starting copy of files 
and folders");
                /*
                 * ##################### Import real files and folders
                 */
                importFolders(f);
+               progressHolder.setProgress(97);
 
                if (ver.compareTo(BackupVersion.get("4.0.0")) < 0) {
                        for (BaseFileItem bfi : files) {
@@ -434,6 +455,7 @@ public class BackupImport {
                log.info("File explorer item import complete, clearing temp 
files");
 
                FileUtils.deleteDirectory(f);
+               progressHolder.setProgress(100);
        }
 
        private static BackupVersion getVersion(Serializer ser, File f) {
diff --git 
a/openmeetings-install/src/main/java/org/apache/openmeetings/cli/Admin.java 
b/openmeetings-install/src/main/java/org/apache/openmeetings/cli/Admin.java
index 42f9f61..281a6ff 100644
--- a/openmeetings-install/src/main/java/org/apache/openmeetings/cli/Admin.java
+++ b/openmeetings-install/src/main/java/org/apache/openmeetings/cli/Admin.java
@@ -553,7 +553,7 @@ public class Admin {
        private void processRestore(File backup) throws Exception {
                try (InputStream is = new FileInputStream(backup)) {
                        BackupImport importCtrl = 
getApplicationContext().getBean(BackupImport.class);
-                       importCtrl.performImport(is);
+                       importCtrl.performImport(is, new ProgressHolder());
                }
        }
 
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminActionsPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminActionsPanel.java
index 5c36a26..3fc63da 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminActionsPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminActionsPanel.java
@@ -18,7 +18,7 @@
  */
 package org.apache.openmeetings.web.admin;
 
-import static 
org.apache.openmeetings.web.util.CallbackFunctionHelper.newOkCancelDangerConfirm;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelDangerConfirm;
 
 import org.apache.openmeetings.web.common.FormActionsPanel;
 import org.apache.wicket.ajax.AjaxRequestTarget;
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/backup/BackupPanel.html
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/backup/BackupPanel.html
index d78d23c..f66e437 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/backup/BackupPanel.html
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/backup/BackupPanel.html
@@ -35,14 +35,13 @@
                                </div>
                        </div>
                        <div class="formelement">
-                               <span wicket:id="progress"></span>
-                               <div wicket:id="dprogress"></div>
+                               <div class="m-3" wicket:id="progress"></div>
                        </div>
                        <div class="formelement">
                                <!-- Perform Download -->
                                <button wicket:id="download"></button>
                                <!-- Perform Upload -->
-                               <button class="fileinput fileinput-new d-inline 
m-0 btn btn-file btn-outline-primary" data-provides="fileinput">
+                               <button class="fileinput fileinput-new d-inline 
m-0 btn btn-file btn-outline-primary" data-provides="fileinput" 
wicket:id="upload">
                                        <wicket:message key="1536"/>
                                        <input class="uploadFileField" 
wicket:id="fileInput" type="file"/>
                                </button>
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/backup/BackupPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/backup/BackupPanel.java
index 63de964..4dc1b3b 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/backup/BackupPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/backup/BackupPanel.java
@@ -25,7 +25,9 @@ import java.io.File;
 import java.nio.file.Path;
 import java.text.DecimalFormat;
 import java.time.Duration;
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 
 import org.apache.openmeetings.backup.BackupExport;
 import org.apache.openmeetings.backup.BackupImport;
@@ -33,17 +35,20 @@ import org.apache.openmeetings.backup.ProgressHolder;
 import org.apache.openmeetings.util.CalendarPatterns;
 import org.apache.openmeetings.util.OmFileHelper;
 import org.apache.openmeetings.web.admin.AdminBasePanel;
+import org.apache.openmeetings.web.util.ThreadHelper;
 import org.apache.openmeetings.web.util.upload.BootstrapFileUploadBehavior;
-import org.apache.wicket.ajax.AbstractAjaxTimerBehavior;
+import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior;
+import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
 import org.apache.wicket.extensions.ajax.AjaxDownloadBehavior;
-import 
org.apache.wicket.extensions.ajax.markup.html.form.upload.UploadProgressBar;
+import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.CheckBox;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.upload.FileUpload;
 import org.apache.wicket.markup.html.form.upload.FileUploadField;
+import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.request.resource.IResource;
@@ -53,11 +58,11 @@ import org.apache.wicket.util.lang.Bytes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.googlecode.wicket.jquery.ui.widget.progressbar.ProgressBar;
-
 import 
de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxButton;
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import 
de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.components.progress.UpdatableProgressBar;
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.utilities.BackgroundColorBehavior;
 /**
  * Panel component to manage Backup Import/Export
  *
@@ -83,13 +88,33 @@ public class BackupPanel extends AdminBasePanel {
        private class BackupForm extends Form<Void> {
                private static final long serialVersionUID = 1L;
                private final Model<Boolean> includeFilesInBackup = 
Model.of(true);
-               private FileUploadField fileUploadField;
-               private AbstractAjaxTimerBehavior timer;
-               private ProgressBar progressBar;
+               private final FileUploadField fileUploadField = new 
FileUploadField("fileInput", new IModel<List<FileUpload>>() {
+                       private static final long serialVersionUID = 1L;
+
+                       @Override
+                       public void setObject(List<FileUpload> object) {
+                               //no-op
+                       }
+
+                       @Override
+                       public List<FileUpload> getObject() {
+                               return new ArrayList<>();
+                       }
+               }) {
+                       private static final long serialVersionUID = 1L;
+
+                       @Override
+                       protected boolean forceCloseStreamsOnDetach() {
+                               return false;
+                       }
+               };
+               private UpdatableProgressBar progressBar;
                private File backupFile;
                private Throwable th = null;
-               private boolean started = false;
-               private ProgressHolder progressHolder;
+               private boolean modeDownload = false;
+               private final ProgressHolder progressHolder = new 
ProgressHolder();
+               private BootstrapAjaxButton download;
+               private final WebMarkupContainer upload = new 
WebMarkupContainer("upload");
 
                public BackupForm(String id) {
                        super(id);
@@ -105,16 +130,13 @@ public class BackupPanel extends AdminBasePanel {
                        DecimalFormat formatter = new DecimalFormat("#,###.00");
                        add(new Label("MaxUploadSize", 
formatter.format(megaBytes)));
 
-                       // Add one file input field
-                       fileUploadField = new FileUploadField("fileInput");
-
                        add(new CheckBox("includeFilesInBackup", 
includeFilesInBackup));
 
                        // Set maximum size controlled by configuration
                        setMaxSize(Bytes.bytes(maxBytes));
 
                        // Add a component to download a file without page 
refresh
-                       final AjaxDownloadBehavior download = new 
AjaxDownloadBehavior(new IResource() {
+                       final AjaxDownloadBehavior downloader = new 
AjaxDownloadBehavior(new IResource() {
                                private static final long serialVersionUID = 1L;
 
                                @Override
@@ -131,25 +153,24 @@ public class BackupPanel extends AdminBasePanel {
                                        }.respond(attributes);
                                }
                        });
-                       add(download);
+                       add(downloader);
                        // add an download button
-                       add(new BootstrapAjaxButton("download", new 
ResourceModel("1066"), this, Buttons.Type.Outline_Primary) {
+                       add(download = new BootstrapAjaxButton("download", new 
ResourceModel("1066"), this, Buttons.Type.Outline_Primary) {
                                private static final long serialVersionUID = 1L;
 
                                @Override
                                protected void onSubmit(AjaxRequestTarget 
target) {
+                                       modeDownload = true;
                                        String dateString = "backup_" + 
CalendarPatterns.getTimeForStreamId(new Date());
                                        backupFile = new 
File(OmFileHelper.getUploadBackupDir(), dateString + ".zip");
-                                       th = null;
-                                       started = true;
-                                       progressHolder = new ProgressHolder();
-
-                                       timer.restart(target);
-                                       new Thread(new 
BackupProcess(backupExport, includeFilesInBackup.getObject())
-                                               , "Openmeetings - " + 
dateString).start();
-
-                                       // repaint the feedback panel so that 
it is hidden
-                                       target.add(feedback, 
progressBar.setVisible(true));
+                                       startWithProgress(() -> {
+                                               try {
+                                                       
backupExport.performExport(backupFile, includeFilesInBackup.getObject(), 
progressHolder);
+                                               } catch (Exception e) {
+                                                       log.error("Exception on 
panel backup download ", e);
+                                                       th = e;
+                                               }
+                                       }, dateString, target);
                                }
 
                                @Override
@@ -158,51 +179,63 @@ public class BackupPanel extends AdminBasePanel {
                                        target.add(feedback);
                                }
                        });
-                       add(timer = new 
AbstractAjaxTimerBehavior(Duration.ofSeconds(1)) {
+                       add(progressBar = new UpdatableProgressBar("progress", 
new Model<>(0), BackgroundColorBehavior.Color.Info, true) {
                                private static final long serialVersionUID = 1L;
 
                                @Override
-                               protected void onTimer(AjaxRequestTarget 
target) {
-                                       if (!started) {
-                                               timer.stop(target);
-                                               return;
-                                       }
+                               protected IModel<Integer> newValue() {
+                                       return 
Model.of(progressHolder.getProgress());
+                               }
+
+                               @Override
+                               protected void 
onPostProcessTarget(IPartialPageRequestHandler target) {
                                        if (th != null) {
-                                               timer.stop(target);
-                                               progressBar.setVisible(false);
+                                               stop(target);
                                                feedback.error(th.getMessage());
-                                               target.add(feedback);
-                                       } else {
-                                               
progressBar.setModelObject(progressHolder.getProgress());
-                                               progressBar.refresh(target);
+                                               onComplete(target);
                                        }
+                                       super.onPostProcessTarget(target);
                                }
-                       });
-                       add((progressBar = new ProgressBar("dprogress", new 
Model<>(0)) {
-                               private static final long serialVersionUID = 1L;
 
                                @Override
-                               protected void onComplete(AjaxRequestTarget 
target) {
-                                       timer.stop(target);
-                                       
target.add(progressBar.setVisible(false));
-
-                                       download.initiate(target);
+                               protected void 
onComplete(IPartialPageRequestHandler target) {
+                                       progressBar.setVisible(false);
+                                       target.add(feedback);
+                                       updateButtons(target, true);
+                                       if (modeDownload) {
+                                               downloader.initiate(target);
+                                       }
+                                       super.onComplete(target);
                                }
-                       
}).setVisible(false).setOutputMarkupPlaceholderTag(true));
-                       add(fileUploadField.add(new 
AjaxFormSubmitBehavior(this, "change") {
+                       });
+                       
progressBar.updateInterval(Duration.ofSeconds(1)).stop(null).striped(false).setVisible(false).setOutputMarkupPlaceholderTag(true);
+                       upload.add(fileUploadField.add(new 
AjaxFormSubmitBehavior(this, "change") {
                                private static final long serialVersionUID = 1L;
 
                                @Override
                                protected void onSubmit(AjaxRequestTarget 
target) {
                                        FileUpload upload = 
fileUploadField.getFileUpload();
+                                       modeDownload = false;
                                        try {
-                                               if (upload == null || 
upload.getInputStream() == null) {
-                                                       feedback.error("File is 
empty");
-                                                       target.add(feedback);
-                                                       return;
-                                               }
-                                               
backupImport.performImport(upload.getInputStream());
-                                               
feedback.success(getString("387") + " - " + getString("54"));
+                                               startWithProgress(() -> {
+                                                       try {
+                                                               if (upload == 
null || upload.getInputStream() == null) {
+                                                                       
feedback.error("File is empty");
+                                                                       
target.add(feedback);
+                                                                       return;
+                                                               }
+                                                               
backupImport.performImport(upload.getInputStream(), progressHolder);
+                                                               
feedback.success(getString("387") + " - " + getString("54"));
+                                                       } catch (Exception e) {
+                                                               
log.error("Exception on panel backup download ", e);
+                                                               th = e;
+                                                       } finally {
+                                                               if (upload != 
null) {
+                                                                       
upload.closeStreams();
+                                                                       
upload.delete();
+                                                               }
+                                                       }
+                                               }, "Restore", target);
                                        } catch (Exception e) {
                                                log.error("Exception on panel 
backup upload ", e);
                                                feedback.error(e);
@@ -217,48 +250,45 @@ public class BackupPanel extends AdminBasePanel {
                                        target.add(feedback);
                                }
                        }));
-                       add(new Label("cmdLineDesc", 
getString("1505")).setEscapeModelStrings(false).setRenderBodyOnly(true));
+                       add(upload.setOutputMarkupId(true), new 
Label("cmdLineDesc", 
getString("1505")).setEscapeModelStrings(false).setRenderBodyOnly(true));
                        super.onInitialize();
                }
 
-               @Override
-               protected void onDetach() {
-                       includeFilesInBackup.detach();
-                       super.onDetach();
+               private void updateButtons(IPartialPageRequestHandler target, 
boolean enabled) {
+                       download.setEnabled(enabled);
+                       upload.add(enabled ? 
AttributeModifier.remove("disabled") : AttributeModifier.append("disabled", 
"disabled"));
+                       fileUploadField.setEnabled(enabled);
+                       target.add(download, upload);
                }
 
-               private class BackupProcess implements Runnable {
-                       private BackupExport backup;
-                       private boolean includeFiles;
+               private void startWithProgress(Runnable r, String label, 
AjaxRequestTarget target) {
+                       th = null;
+                       progressHolder.setProgress(0);
 
-                       public BackupProcess(BackupExport backup, boolean 
includeFiles) {
-                               this.backup = backup;
-                               this.includeFiles = includeFiles;
-                               th = null;
-                       }
+                       ThreadHelper.startRunnable(r, "Openmeetings - " + 
label);
 
-                       @Override
-                       public void run() {
-                               try {
-                                       backup.performExport(backupFile, 
includeFiles, progressHolder);
-                               } catch (Exception e) {
-                                       log.error("Exception on panel backup 
download ", e);
-                                       th = e;
-                               }
-                       }
+                       // repaint the feedback panel so that it is hidden
+                       updateButtons(target, false);
+                       target.add(feedback, 
progressBar.restart(target).setModelObject(0).setVisible(true));
+               }
+
+               @Override
+               protected void onDetach() {
+                       includeFilesInBackup.detach();
+                       super.onDetach();
                }
        }
 
        public BackupPanel(String id) {
                super(id);
+       }
 
+       @Override
+       protected void onInitialize() {
+               super.onInitialize();
                add(feedback.setOutputMarkupId(true));
 
-               BackupForm backupForm = new BackupForm("backupUpload");
-
-               backupForm.add(new UploadProgressBar("progress", backupForm, 
backupForm.fileUploadField));
-
-               add(backupForm);
+               add(new BackupForm("backupUpload"));
                add(BootstrapFileUploadBehavior.INSTANCE);
        }
 }
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
index b3576ea..3650099 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
@@ -19,7 +19,7 @@
 package org.apache.openmeetings.web.admin.connection;
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.ATTR_CLASS;
-import static 
org.apache.openmeetings.web.util.CallbackFunctionHelper.newOkCancelConfirmCfg;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelConfirm;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
@@ -34,7 +34,6 @@ import org.apache.openmeetings.web.admin.AdminBasePanel;
 import org.apache.openmeetings.web.admin.SearchableDataView;
 import org.apache.openmeetings.web.app.ClientManager;
 import org.apache.openmeetings.web.common.PagedEntityListPanel;
-import org.apache.openmeetings.web.common.confirmation.ConfirmationBehavior;
 import org.apache.openmeetings.web.data.SearchableDataProvider;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.ajax.AjaxEventBehavior;
@@ -98,9 +97,6 @@ public class ConnectionsPanel extends AdminBasePanel {
                                        private static final long 
serialVersionUID = 1L;
                                        {
                                                setSize(Buttons.Size.Small);
-                                               add(new 
ConfirmationBehavior(/*TODO 
https://github.com/l0rdn1kk0n/wicket-bootstrap/issues/845 ".om-kick-btn", 
*/newOkCancelConfirmCfg(container, getString("605"))
-                                                               
.withSingleton(true)
-                                                               ));
                                        }
 
                                        @Override
@@ -108,7 +104,7 @@ public class ConnectionsPanel extends AdminBasePanel {
                                                cm.invalidate(c.getUserId(), 
c.getSessionId());
                                                target.add(container, 
details.setVisible(false));
                                        }
-                               });
+                               }.add(newOkCancelConfirm(this, 
getString("605"))));
                                item.add(new AjaxEventBehavior(EVT_CLICK) {
                                        private static final long 
serialVersionUID = 1L;
 
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/email/EmailForm.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/email/EmailForm.java
index 48c6509..cfbdb03 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/email/EmailForm.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/email/EmailForm.java
@@ -18,7 +18,7 @@
  */
 package org.apache.openmeetings.web.admin.email;
 
-import static 
org.apache.openmeetings.web.util.CallbackFunctionHelper.newOkCancelDangerConfirm;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelDangerConfirm;
 
 import org.apache.openmeetings.db.dao.basic.MailMessageDao;
 import org.apache.openmeetings.db.entity.basic.MailMessage;
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/groups/GroupUsersPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/groups/GroupUsersPanel.java
index 8f5c39c..fe55167 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/groups/GroupUsersPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/groups/GroupUsersPanel.java
@@ -18,6 +18,8 @@
  */
 package org.apache.openmeetings.web.admin.groups;
 
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelDangerConfirm;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -29,7 +31,6 @@ import org.apache.openmeetings.web.admin.SearchableDataView;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.PagedEntityListPanel;
 import org.apache.openmeetings.web.data.SearchableDataProvider;
-import org.apache.openmeetings.web.util.CallbackFunctionHelper;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
 import org.apache.wicket.markup.html.basic.Label;
@@ -92,7 +93,7 @@ public class GroupUsersPanel extends Panel {
                                        }
                                };
                                del.setIconType(FontAwesome5IconType.times_s)
-                                               
.add(CallbackFunctionHelper.newOkCancelDangerConfirm(this, getString("833")));
+                                               
.add(newOkCancelDangerConfirm(this, getString("833")));
                                item.add(del);
                                item.add(new BootstrapBadge("new", new 
ResourceModel("lbl.new"), 
BadgeBehavior.Type.Warning).setVisible((grpUser.getId() == null)));
                        }
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/labels/LangPanel.html
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/labels/LangPanel.html
index 7197bfd..3096f3a 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/labels/LangPanel.html
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/labels/LangPanel.html
@@ -38,7 +38,6 @@
                                                <wicket:message key="387"/>
                                                <input type="file" 
accept="text/xml" wicket:id="fileInput"/>
                                        </button>
-                                       <span 
wicket:id="progress">[progressbar]</span>
                                </div>
                        </div>
                </form>
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/labels/LangPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/labels/LangPanel.java
index cdb6f5e..8c4791d 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/labels/LangPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/labels/LangPanel.java
@@ -20,6 +20,7 @@ package org.apache.openmeetings.web.admin.labels;
 
 import static java.time.Duration.ZERO;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.ATTR_CLASS;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelDangerConfirm;
 import static org.apache.wicket.request.resource.ContentDisposition.ATTACHMENT;
 
 import java.io.IOException;
@@ -39,7 +40,6 @@ import 
org.apache.openmeetings.web.common.PagedEntityListPanel;
 import org.apache.openmeetings.web.data.DataViewContainer;
 import org.apache.openmeetings.web.data.OmOrderByBorder;
 import org.apache.openmeetings.web.data.SearchableDataProvider;
-import org.apache.openmeetings.web.util.CallbackFunctionHelper;
 import org.apache.openmeetings.web.util.upload.BootstrapFileUploadBehavior;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.ajax.AjaxEventBehavior;
@@ -47,7 +47,6 @@ import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.extensions.ajax.AjaxDownloadBehavior;
-import 
org.apache.wicket.extensions.ajax.markup.html.form.upload.UploadProgressBar;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.upload.FileUpload;
@@ -151,7 +150,6 @@ public class LangPanel extends AdminBasePanel {
                add(navigator);
                langForm = new LangForm("langForm", listContainer, this);
                langForm.add(fileUploadField);
-               langForm.add(new UploadProgressBar("progress", langForm, 
fileUploadField));
                fileUploadField.add(new AjaxFormSubmitBehavior(langForm, 
"change") {
                        private static final long serialVersionUID = 1L;
 
@@ -249,7 +247,7 @@ public class LangPanel extends AdminBasePanel {
                        }
                };
                langForm.add(delLngBtn.setIconType(FontAwesome5IconType.times_s)
-                               
.add(CallbackFunctionHelper.newOkCancelDangerConfirm(this, getString("833"))));
+                               .add(newOkCancelDangerConfirm(this, 
getString("833"))));
                super.onInitialize();
        }
 
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/oauth/OAuthForm.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/oauth/OAuthForm.java
index 844d9e5..d1e3728 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/oauth/OAuthForm.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/oauth/OAuthForm.java
@@ -19,6 +19,7 @@
 package org.apache.openmeetings.web.admin.oauth;
 
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelDangerConfirm;
 import static org.apache.openmeetings.web.pages.auth.SignInPage.getRedirectUri;
 
 import java.util.AbstractMap.SimpleEntry;
@@ -32,7 +33,6 @@ import org.apache.openmeetings.db.entity.server.OAuthServer;
 import org.apache.openmeetings.db.entity.server.OAuthServer.RequestInfoMethod;
 import org.apache.openmeetings.db.entity.server.OAuthServer.RequestTokenMethod;
 import org.apache.openmeetings.web.admin.AdminBaseForm;
-import org.apache.openmeetings.web.util.CallbackFunctionHelper;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.WebMarkupContainer;
@@ -80,7 +80,7 @@ public class OAuthForm extends AdminBaseForm<OAuthServer> {
                                }
                        };
                        del.setIconType(FontAwesome5IconType.times_s)
-                                       
.add(CallbackFunctionHelper.newOkCancelDangerConfirm(this, getString("833")));
+                                       .add(newOkCancelDangerConfirm(this, 
getString("833")));
                        item.add(new Label("key", Model.of(entry.getKey())))
                                .add(new Label("value", 
Model.of(entry.getValue())))
                                .add(del);
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
index 5e1a0eb..db27b57 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
@@ -23,6 +23,7 @@ import static 
org.apache.openmeetings.web.admin.AdminUserChoiceProvider.PAGE_SIZ
 import static org.apache.openmeetings.web.app.Application.kickUser;
 import static org.apache.openmeetings.web.app.WebSession.getRights;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelDangerConfirm;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -48,7 +49,6 @@ import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.web.admin.AdminBaseForm;
 import org.apache.openmeetings.web.admin.AdminUserChoiceProvider;
 import org.apache.openmeetings.web.app.ClientManager;
-import org.apache.openmeetings.web.util.CallbackFunctionHelper;
 import org.apache.openmeetings.web.util.RestrictiveChoiceProvider;
 import org.apache.openmeetings.web.util.RoomTypeDropDown;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -110,7 +110,7 @@ public class RoomForm extends AdminBaseForm<Room> {
                                }
                        };
                        del.setIconType(FontAwesome5IconType.times_s)
-                                       
.add(CallbackFunctionHelper.newOkCancelDangerConfirm(this, getString("833")));
+                                       .add(newOkCancelDangerConfirm(this, 
getString("833")));
                        item.add(new Label("clientId", "" + c.getUserId()))
                                .add(new Label("clientLogin", "" + 
c.getUser().getLogin()))
                                .add(del);
@@ -318,7 +318,7 @@ public class RoomForm extends AdminBaseForm<Room> {
                                        }
                                };
                                del.setIconType(FontAwesome5IconType.times_s)
-                                               
.add(CallbackFunctionHelper.newOkCancelDangerConfirm(this, getString("833")));
+                                               
.add(newOkCancelDangerConfirm(this, getString("833")));
                                item.add(new CheckBox("superModerator", new 
PropertyModel<Boolean>(moderator, "superModerator")))
                                        .add(new Label("userId", 
String.valueOf(moderator.getUser().getId())))
                                        .add(name)
@@ -404,7 +404,7 @@ public class RoomForm extends AdminBaseForm<Room> {
                                        }
                                };
                                del.setIconType(FontAwesome5IconType.times_s)
-                                               
.add(CallbackFunctionHelper.newOkCancelDangerConfirm(this, getString("833")));
+                                               
.add(newOkCancelDangerConfirm(this, getString("833")));
                                item.add(new Label("name", new 
PropertyModel<>(rf.getFile(), "name")))
                                        .add(new Label("wbIdx", new 
PropertyModel<>(rf, "wbIdx")))
                                        .add(del);
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/FormActionsPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/FormActionsPanel.java
index 56a7783..48e268d 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/FormActionsPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/FormActionsPanel.java
@@ -18,7 +18,7 @@
  */
 package org.apache.openmeetings.web.common;
 
-import static 
org.apache.openmeetings.web.util.CallbackFunctionHelper.newOkCancelDangerConfirm;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelDangerConfirm;
 
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
index 427114a..6a0d079 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
@@ -24,9 +24,9 @@ import static 
org.apache.openmeetings.util.OpenmeetingsVariables.ATTR_CLASS;
 import static 
org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_MYROOMS_ENABLED;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.PARAM_USER_ID;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelConfirm;
 import static 
org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getParam;
-import static 
org.apache.openmeetings.web.util.CallbackFunctionHelper.newOkCancelConfirm;
 import static org.apache.openmeetings.web.util.OmUrlFragment.CHILD_ID;
 import static org.apache.openmeetings.web.util.OmUrlFragment.PROFILE_EDIT;
 import static org.apache.openmeetings.web.util.OmUrlFragment.PROFILE_MESSAGES;
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/UploadableImagePanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/UploadableImagePanel.java
index 7fdd0de..36bb7e8 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/UploadableImagePanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/UploadableImagePanel.java
@@ -19,7 +19,7 @@
 package org.apache.openmeetings.web.common;
 
 import static 
org.apache.openmeetings.util.OpenmeetingsVariables.getMaxUploadSize;
-import static 
org.apache.openmeetings.web.util.CallbackFunctionHelper.newOkCancelConfirm;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelConfirm;
 
 import java.io.File;
 import java.util.Optional;
@@ -35,7 +35,6 @@ import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.upload.FileUpload;
 import org.apache.wicket.markup.html.form.upload.FileUploadField;
-import org.apache.wicket.markup.html.panel.EmptyPanel;
 import org.apache.wicket.model.util.ListModel;
 import org.apache.wicket.util.lang.Bytes;
 import org.slf4j.Logger;
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/confirmation/ConfirmableAjaxBorder.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/confirmation/ConfirmableAjaxBorder.java
index dab2c01..a5039c3 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/confirmation/ConfirmableAjaxBorder.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/confirmation/ConfirmableAjaxBorder.java
@@ -20,6 +20,7 @@ package org.apache.openmeetings.web.common.confirmation;
 
 import static org.apache.openmeetings.web.common.BasePanel.EVT_CLICK;
 
+import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxEventBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
@@ -114,4 +115,22 @@ public abstract class ConfirmableAjaxBorder extends Border 
{
                title.detach();
                message.detach();
        }
+
+       public static ConfirmationBehavior newOkCancelDangerConfirm(Component 
c, String title) {
+               return new ConfirmationBehavior(newOkCancelConfirmCfg(c, title)
+                               .withBtnOkClass("btn btn-sm btn-danger")
+                               .withBtnOkIconClass("fas 
fa-exclamation-triangle")
+                               );
+       }
+
+       public static ConfirmationBehavior newOkCancelConfirm(Component c, 
String title) {
+               return new ConfirmationBehavior(newOkCancelConfirmCfg(c, 
title));
+       }
+
+       public static ConfirmationConfig newOkCancelConfirmCfg(Component c, 
String title) {
+               return new ConfirmationConfig()
+                               .withBtnCancelLabel(c.getString("lbl.cancel"))
+                               .withBtnOkLabel(c.getString("54"))
+                               .withTitle(title);
+       }
 }
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
index 34e4321..b2d9b56 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
@@ -221,7 +221,7 @@ public class RoomSidebar extends Panel {
        }
 
        public void showUpload(IPartialPageRequestHandler handler) {
-               upload.open(handler);
+               upload.show(handler);
        }
 
        public void setFilesActive(IPartialPageRequestHandler handler) {
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.html
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.html
index aeeea96..181cf1d 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.html
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.html
@@ -20,18 +20,17 @@
 -->
 <!DOCTYPE html>
 <html xmlns:wicket="http://wicket.apache.org";>
-<wicket:panel>
+<wicket:extend>
        <form wicket:id="form">
                <div class="mb-4"><wicket:message key="594"/></div>
-               <div class="fileinput fileinput-new m-0" 
data-provides="fileinput">
+               <div class="fileinput fileinput-new d-inline m-0" 
data-provides="fileinput">
                        <div class="fileinput-filename d-block"></div>
-                       <span class="btn btn-file">
+                       <span class="btn btn-file btn-outline-primary">
                                <span><wicket:message key="596"/></span>
                                <input type="file" multiple="multiple" 
wicket:id="file"/>
                        </span>
                </div>
                <div wicket:id="feedback" class="error"></div>
-               <span wicket:id="progress">[progressbar]</span>
                <div class="mt-3">
                        <input wicket:id="to-wb" type="checkbox"/><label 
wicket:for="to-wb"><wicket:message key="1312"/></label>
                        <div class="ml-3" wicket:id="clean-block">
@@ -39,9 +38,9 @@
                        </div>
                </div>
        </form>
-       <div wicket:id="convProgress"></div>
+       <div wicket:id="progress"></div>
        <form wicket:id="name-form">
                <input type="hidden" wicket:id="name"/>
        </form>
-</wicket:panel>
+</wicket:extend>
 </html>
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.java
index eecc5b4..8ca54c4 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.java
@@ -23,7 +23,6 @@ import static 
org.apache.openmeetings.web.app.WebSession.getUserId;
 
 import java.time.Duration;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
 import java.util.function.DoubleConsumer;
@@ -34,17 +33,13 @@ import org.apache.openmeetings.db.entity.file.BaseFileItem;
 import org.apache.openmeetings.db.entity.file.FileItem;
 import org.apache.openmeetings.util.process.ProcessResult;
 import org.apache.openmeetings.util.process.ProcessResultList;
-import org.apache.openmeetings.web.app.Application;
-import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.room.RoomPanel;
+import org.apache.openmeetings.web.util.ThreadHelper;
 import org.apache.openmeetings.web.util.upload.BootstrapFileUploadBehavior;
-import org.apache.wicket.ThreadContext;
-import org.apache.wicket.ajax.AbstractAjaxTimerBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior;
 import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
-import 
org.apache.wicket.extensions.ajax.markup.html.form.upload.UploadProgressBar;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.JavaScriptHeaderItem;
 import org.apache.wicket.markup.head.PriorityHeaderItem;
@@ -56,7 +51,7 @@ import org.apache.wicket.markup.html.form.upload.FileUpload;
 import org.apache.wicket.markup.html.form.upload.FileUploadField;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
-import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 import org.apache.wicket.util.lang.Bytes;
@@ -64,13 +59,15 @@ import org.apache.wicket.util.string.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
-import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
-import com.googlecode.wicket.jquery.ui.widget.progressbar.ProgressBar;
-
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 import 
de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.components.progress.UpdatableProgressBar;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.dialog.ModalCloseButton;
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.utilities.BackgroundColorBehavior;
+import 
de.agilecoders.wicket.extensions.markup.html.bootstrap.spinner.SpinnerAjaxButton;
 
-public class UploadDialog extends AbstractFormDialog<String> {
+public class UploadDialog extends Modal<String> {
        private static final long serialVersionUID = 1L;
        private static final Logger log = 
LoggerFactory.getLogger(UploadDialog.class);
        private final NotificationPanel feedback = new 
NotificationPanel("feedback");
@@ -87,8 +84,7 @@ public class UploadDialog extends AbstractFormDialog<String> {
                        return true;
                }
        };
-       private DialogButton upload;
-       private DialogButton cancel;
+       private SpinnerAjaxButton upload;
        private final FileUploadField uploadField = new FileUploadField("file", 
new IModel<List<FileUpload>>() {
                private static final long serialVersionUID = 1L;
 
@@ -121,52 +117,40 @@ public class UploadDialog extends 
AbstractFormDialog<String> {
        @SpringBean
        private FileItemLogDao fileLogDao;
 
-       private final AbstractAjaxTimerBehavior timer = new 
AbstractAjaxTimerBehavior(Duration.ofSeconds(1)) {
+       private final UpdatableProgressBar progressBar = new 
UpdatableProgressBar("progress", new Model<>(0), 
BackgroundColorBehavior.Color.Info, true) {
                private static final long serialVersionUID = 1L;
 
                @Override
-               protected void onTimer(AjaxRequestTarget target) {
-                       if (progress == null) {
-                               timer.stop(target);
-                               return;
-                       }
-                       if (progress.intValue() == 100) {
-                               timer.stop(target);
-                               target.add(progressBar.setVisible(false));
-                               room.getSidebar().updateFiles(target);
-                               if (form.hasError()) {
-                                       setTitle(target, 
getString("upload.dlg.choose.title"));
-                                       target.add(form.setVisible(true));
-                                       onError(target, null);
-                               } else {
-                                       close(target, null);
-                               }
-                       } else {
-                               progressBar.setModelObject(progress);
-                               progressBar.refresh(target);
-                       }
+               protected IModel<Integer> newValue() {
+                       return Model.of(progress);
                }
-       };
-       private final ProgressBar progressBar = new ProgressBar("convProgress", 
new Model<>(0)) {
-               private static final long serialVersionUID = 1L;
 
                @Override
-               protected void onComplete(AjaxRequestTarget target) {
-                       timer.stop(target);
+               protected void onComplete(IPartialPageRequestHandler target) {
                        progressBar.setVisible(false);
+                       room.getSidebar().updateFiles(target);
+                       if (form.hasError()) {
+                               target.add(form.setVisible(true));
+                               target.add(feedback);
+                       } else {
+                               close(target);
+                       }
                        target.add(progressBar);
                }
        };
-       private Integer progress;
+       private int progress = 0;
 
        public UploadDialog(String id, RoomPanel room, RoomFilePanel roomFiles) 
{
-               super(id, "");
+               super(id);
                this.roomFiles = roomFiles;
                this.room = room;
        }
 
        @Override
        protected void onInitialize() {
+               header(new ResourceModel("upload.dlg.choose.title"));
+               setBackdrop(Backdrop.STATIC);
+
                
add(form.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
                toWb.add(new OnChangeAjaxBehavior() {
                        private static final long serialVersionUID = 1L;
@@ -190,88 +174,52 @@ public class UploadDialog extends 
AbstractFormDialog<String> {
                        @Override
                        protected void onSubmit(AjaxRequestTarget target) {
                                if 
(!Strings.isEmpty(getComponent().getDefaultModelObjectAsString())) {
-                                       upload.setEnabled(true, target);
+                                       target.add(upload.setEnabled(true));
                                }
                        }
                }).setOutputMarkupId(true);
-               form.add(new UploadProgressBar("progress", form, uploadField));
 
                add(nameForm.add(fileName.setOutputMarkupId(true)));
                add(BootstrapFileUploadBehavior.INSTANCE);
-               getTitle().setObject(getString("upload.dlg.choose.title"));
-               upload = new DialogButton("upload", getString("593"), false) {
+               addButton(upload = new SpinnerAjaxButton("button", new 
ResourceModel("593"), form, Buttons.Type.Outline_Primary) {
                        private static final long serialVersionUID = 1L;
 
                        @Override
-                       public boolean isIndicating() {
-                               return true;
+                       protected void onError(AjaxRequestTarget target) {
+                               target.add(feedback);
                        }
-               };
-               cancel = new DialogButton("close", getString("85"));
-
-               
add(progressBar.setOutputMarkupPlaceholderTag(true).setVisible(false));
-               add(timer);
-               super.onInitialize();
-       }
 
-       @Override
-       public void onClick(AjaxRequestTarget target, DialogButton button) {
-               if (button == null || button.match("close")) {
-                       super.onClick(target, button);
-               }
-       }
+                       @Override
+                       protected void onSubmit(AjaxRequestTarget target) {
+                               List<FileUpload> ful = 
uploadField.getFileUploads();
+                               if (ful != null) {
 
-       @Override
-       protected List<DialogButton> getButtons() {
-               return Arrays.asList(upload, cancel);
-       }
+                                       progress = 0;
+                                       progressBar.restart(target);
+                                       target.add(
+                                                       
progressBar.setModelObject(progress).setVisible(true)
+                                                       , form.setVisible(false)
+                                                       , 
upload.setEnabled(false));
 
-       @Override
-       public DialogButton getSubmitButton() {
-               return upload;
-       }
+                                       
ThreadHelper.startRunnable(UploadDialog.this::convertAll);
+                               }
+                       }
+               });
+               upload.setEnabled(false);
+               addButton(new ModalCloseButton(new 
ResourceModel("85")).type(Buttons.Type.Outline_Secondary));
 
-       @Override
-       public Form<?> getForm() {
-               return form;
+               
progressBar.updateInterval(Duration.ofSeconds(1)).stop(null).striped(false);
+               
add(progressBar.setOutputMarkupPlaceholderTag(true).setVisible(false));
+               super.onInitialize();
        }
 
        @Override
-       protected void onOpen(IPartialPageRequestHandler handler) {
-               setTitle(handler, getString("upload.dlg.choose.title"));
-               super.onOpen(handler);
-               upload.setEnabled(true, handler);
+       public Modal<String> show(IPartialPageRequestHandler handler) {
+               handler.add(upload.setEnabled(true));
                uploadField.setModelObject(new ArrayList<>());
                handler.add(form.setVisible(true), fileName);
                handler.appendJavaScript(String.format("bindUpload('%s', 
'%s');", form.getMarkupId(), fileName.getMarkupId()));
-       }
-
-       @Override
-       protected void onError(AjaxRequestTarget target, DialogButton btn) {
-               target.add(feedback);
-       }
-
-       @Override
-       protected void onSubmit(AjaxRequestTarget target, DialogButton btn) {
-               List<FileUpload> ful = uploadField.getFileUploads();
-               if (ful != null) {
-
-                       progress = 0;
-                       timer.restart(target);
-                       setTitle(target, getString("upload.dlg.convert.title"));
-                       
target.add(progressBar.setModelObject(progress).setVisible(true), 
form.setVisible(false));
-
-                       final Application app = Application.get();
-                       final WebSession session = WebSession.get();
-                       final RequestCycle rc = RequestCycle.get();
-                       new Thread(() -> {
-                               ThreadContext.setApplication(app);
-                               ThreadContext.setSession(session);
-                               ThreadContext.setRequestCycle(rc);
-                               convertAll();
-                               ThreadContext.detach();
-                       }).start();
-               }
+               return super.show(handler);
        }
 
        @Override
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarDialog.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarDialog.java
index 78350d7..7e60bcc 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarDialog.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarDialog.java
@@ -19,7 +19,7 @@
 package org.apache.openmeetings.web.user.calendar;
 
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
-import static 
org.apache.openmeetings.web.util.CallbackFunctionHelper.newOkCancelDangerConfirm;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelDangerConfirm;
 
 import java.util.List;
 
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatToolbar.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatToolbar.java
index 7b8e6a2..7858308 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatToolbar.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/ChatToolbar.java
@@ -26,8 +26,8 @@ import static 
org.apache.openmeetings.web.app.WebSession.getDateFormat;
 import static org.apache.openmeetings.web.app.WebSession.getRights;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 import static org.apache.openmeetings.web.common.BasePanel.EVT_CLICK;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelDangerConfirm;
 import static org.apache.openmeetings.web.room.RoomPanel.isModerator;
-import static 
org.apache.openmeetings.web.util.CallbackFunctionHelper.newOkCancelDangerConfirm;
 
 import java.util.List;
 
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/dashboard/admin/AdminCleanupInfoDialog.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/dashboard/admin/AdminCleanupInfoDialog.java
index 86824a3..c305a4d 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/dashboard/admin/AdminCleanupInfoDialog.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/dashboard/admin/AdminCleanupInfoDialog.java
@@ -26,7 +26,7 @@ import static 
org.apache.openmeetings.cli.CleanupHelper.getRecUnit;
 import static org.apache.openmeetings.util.OmFileHelper.getHumanSize;
 import static org.apache.openmeetings.util.OmFileHelper.getStreamsDir;
 import static org.apache.openmeetings.util.OmFileHelper.getUploadDir;
-import static 
org.apache.openmeetings.web.util.CallbackFunctionHelper.newOkCancelDangerConfirm;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelDangerConfirm;
 
 import org.apache.openmeetings.cli.CleanupEntityUnit;
 import org.apache.openmeetings.cli.CleanupUnit;
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/InvitationDetails.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/InvitationDetails.java
index f71a50c..6d31180 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/InvitationDetails.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/InvitationDetails.java
@@ -20,7 +20,7 @@ package org.apache.openmeetings.web.user.profile;
 
 import static org.apache.openmeetings.db.util.FormatHelper.formatUser;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
-import static 
org.apache.openmeetings.web.util.CallbackFunctionHelper.newOkCancelDangerConfirm;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelDangerConfirm;
 
 import java.util.Date;
 
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.java
index 5bf1975..e5c7e0f 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/profile/MessagesContactsPanel.java
@@ -24,6 +24,7 @@ import static 
org.apache.openmeetings.db.entity.user.PrivateMessage.TRASH_FOLDER
 import static org.apache.openmeetings.util.OpenmeetingsVariables.ATTR_CLASS;
 import static org.apache.openmeetings.web.app.WebSession.getDateFormat;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
+import static 
org.apache.openmeetings.web.common.confirmation.ConfirmableAjaxBorder.newOkCancelDangerConfirm;
 import static 
org.apache.openmeetings.web.util.CallbackFunctionHelper.addOnClick;
 
 import java.util.ArrayList;
@@ -53,7 +54,6 @@ import org.apache.openmeetings.web.data.OmOrderByBorder;
 import org.apache.openmeetings.web.data.SearchableDataProvider;
 import org.apache.openmeetings.web.user.MessageDialog;
 import org.apache.openmeetings.web.user.rooms.RoomEnterBehavior;
-import org.apache.openmeetings.web.util.CallbackFunctionHelper;
 import org.apache.openmeetings.web.util.ContactsHelper;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
@@ -232,7 +232,7 @@ public class MessagesContactsPanel extends UserBasePanel {
                                        }
                                };
                                del.setIconType(FontAwesome5IconType.times_s)
-                                               
.add(CallbackFunctionHelper.newOkCancelDangerConfirm(this, getString("833")));
+                                               
.add(newOkCancelDangerConfirm(this, getString("833")));
                                item.add(del);
                                item.add(new AjaxEventBehavior(EVT_CLICK) {
                                        private static final long 
serialVersionUID = 1L;
@@ -499,7 +499,7 @@ public class MessagesContactsPanel extends UserBasePanel {
                                        }
                                };
                                del.setIconType(FontAwesome5IconType.times_s)
-                                               
.add(CallbackFunctionHelper.newOkCancelDangerConfirm(this, getString("833")));
+                                               
.add(newOkCancelDangerConfirm(this, getString("833")));
                                item.add(del.setVisible(!uc.isPending()));
                        }
                };
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/CallbackFunctionHelper.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/CallbackFunctionHelper.java
index cca93f8..c9d1808 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/CallbackFunctionHelper.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/CallbackFunctionHelper.java
@@ -20,8 +20,6 @@ import static java.util.UUID.randomUUID;
 
 import java.io.Serializable;
 
-import org.apache.openmeetings.web.common.confirmation.ConfirmationBehavior;
-import org.apache.openmeetings.web.common.confirmation.ConfirmationConfig;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
@@ -64,22 +62,4 @@ public class CallbackFunctionHelper {
        public static AttributeModifier addOnClick(Serializable handler) {
                return AttributeModifier.replace("onclick", handler);
        }
-
-       public static ConfirmationConfig newOkCancelConfirmCfg(Component c, 
String title) {
-               return new ConfirmationConfig()
-                               .withBtnCancelLabel(c.getString("lbl.cancel"))
-                               .withBtnOkLabel(c.getString("54"))
-                               .withTitle(title);
-       }
-
-       public static ConfirmationBehavior newOkCancelConfirm(Component c, 
String title) {
-               return new ConfirmationBehavior(newOkCancelConfirmCfg(c, 
title));
-       }
-
-       public static ConfirmationBehavior newOkCancelDangerConfirm(Component 
c, String title) {
-               return new ConfirmationBehavior(newOkCancelConfirmCfg(c, title)
-                               .withBtnOkClass("btn btn-sm btn-danger")
-                               .withBtnOkIconClass("fas 
fa-exclamation-triangle")
-                               );
-       }
 }
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ThreadHelper.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ThreadHelper.java
new file mode 100644
index 0000000..6415838
--- /dev/null
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/ThreadHelper.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openmeetings.web.util;
+
+import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.app.WebSession;
+import org.apache.wicket.ThreadContext;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.util.string.Strings;
+
+public class ThreadHelper {
+       private ThreadHelper() {}
+
+       public static void startRunnable(Runnable r) {
+               startRunnable(r, null);
+       }
+
+       public static void startRunnable(Runnable r, String name) {
+               final Application app = Application.get();
+               final WebSession session = WebSession.get();
+               final RequestCycle rc = RequestCycle.get();
+               Thread t = new Thread(() -> {
+                       ThreadContext.setApplication(app);
+                       ThreadContext.setSession(session);
+                       ThreadContext.setRequestCycle(rc);
+                       r.run();
+                       ThreadContext.detach();
+               });
+               if (!Strings.isEmpty(name)) {
+                       t.setName(name);
+               }
+               t.start();
+       }
+}
diff --git a/openmeetings-web/src/main/webapp/css/raw-general.css 
b/openmeetings-web/src/main/webapp/css/raw-general.css
index df4f6ad..dc0d250 100644
--- a/openmeetings-web/src/main/webapp/css/raw-general.css
+++ b/openmeetings-web/src/main/webapp/css/raw-general.css
@@ -286,11 +286,6 @@ html, body {
        margin-left: 10px;
        padding-left: 10px;
 }
-.ui-progressbar div {
-       text-align: center;
-       padding-top: 7px;
-       font-weight: bold;
-}
 table.messages {
        width: 100%;
        min-height: 500px;
diff --git 
a/openmeetings-web/src/test/java/org/apache/openmeetings/backup/TestBackup.java 
b/openmeetings-web/src/test/java/org/apache/openmeetings/backup/TestBackup.java
index a9c6ba6..80057b1 100644
--- 
a/openmeetings-web/src/test/java/org/apache/openmeetings/backup/TestBackup.java
+++ 
b/openmeetings-web/src/test/java/org/apache/openmeetings/backup/TestBackup.java
@@ -94,7 +94,7 @@ public class TestBackup extends AbstractJUnitDefaults {
                        String name = backup.getName();
                        log.debug("Import of backup file : '" + name + "' is 
started ...");
                        try (InputStream is = new FileInputStream(backup)) {
-                               backupController.performImport(is);
+                               backupController.performImport(is, new 
ProgressHolder());
                                long newGroupCount = groupDao.count();
                                long newUserCount = userDao.count();
                                long newRoomCount = roomDao.count();

Reply via email to