diff --git a/static/js/dist/app/users.min.js b/static/js/dist/app/users.min.js
index b8f93106..f1b7666d 100644
--- a/static/js/dist/app/users.min.js
+++ b/static/js/dist/app/users.min.js
@@ -1 +1 @@
-let users=[];const save=id=>{if($("#password").val()!==$("#confirm_password").val()){modalError("Passwords must match.");return}let user={username:$("#username").val(),password:$("#password").val(),role:$("#role").val(),password_change_required:$("#force_password_change_checkbox").prop("checked"),account_locked:$("#account_locked_checkbox").prop("checked")};if(id!=-1){user.id=id;api.userId.put(user).success(data=>{successFlash("User "+escapeHtml(user.username)+" updated successfully!");load();dismiss();$("#modal").modal("hide")}).error(data=>{modalError(data.responseJSON.message)})}else{api.users.post(user).success(data=>{successFlash("User "+escapeHtml(user.username)+" registered successfully!");load();dismiss();$("#modal").modal("hide")}).error(data=>{modalError(data.responseJSON.message)})}};const dismiss=()=>{$("#username").val("");$("#password").val("");$("#confirm_password").val("");$("#role").val("");$("#force_password_change_checkbox").prop("checked",true);$("#account_locked_checkbox").prop("checked",false);$("#modal\\.flashes").empty()};const edit=id=>{$("#username").attr("disabled",false);$("#modalSubmit").unbind("click").click(()=>{save(id)});$("#role").select2();if(id==-1){$("#userModalLabel").text("New User");$("#role").val("user");$("#role").trigger("change")}else{$("#userModalLabel").text("Edit User");api.userId.get(id).success(user=>{$("#username").val(user.username);$("#role").val(user.role.slug);$("#role").trigger("change");$("#force_password_change_checkbox").prop("checked",user.password_change_required);$("#account_locked_checkbox").prop("checked",user.account_locked);if(user.username=="admin"){$("#username").attr("disabled",true)}}).error(function(){errorFlash("Error fetching user")})}};const deleteUser=id=>{var user=users.find(x=>x.id==id);if(!user){return}if(user.username=="admin"){Swal.fire({title:"Unable to Delete User",text:"The user account "+escapeHtml(user.username)+" cannot be deleted.",type:"info"});return}Swal.fire({title:"Are you sure?",text:"This will delete the account for "+escapeHtml(user.username)+" as well as all of the objects they have created.\n\nThis can't be undone!",type:"warning",animation:false,showCancelButton:true,confirmButtonText:"Delete",confirmButtonColor:"#428bca",reverseButtons:true,allowOutsideClick:false,preConfirm:function(){return new Promise((resolve,reject)=>{api.userId.delete(id).success(msg=>{resolve()}).error(data=>{reject(data.responseJSON.message)})}).catch(error=>{Swal.showValidationMessage(error)})}}).then(function(result){if(result.value){Swal.fire("User Deleted!","The user account for "+escapeHtml(user.username)+" and all associated objects have been deleted!","success")}$('button:contains("OK")').on("click",function(){location.reload()})})};const impersonate=id=>{var user=users.find(x=>x.id==id);if(!user){return}Swal.fire({title:"Are you sure?",html:"You will be logged out of your account and logged in as "+escapeHtml(user.username)+"",type:"warning",animation:false,showCancelButton:true,confirmButtonText:"Swap User",confirmButtonColor:"#428bca",reverseButtons:true,allowOutsideClick:false}).then(result=>{if(result.value){fetch("/impersonate",{method:"post",body:"username="+user.username+"&csrf_token="+encodeURIComponent(csrf_token),headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then(response=>{if(response.status==200){Swal.fire({title:"Success!",html:"Successfully changed to user "+escapeHtml(user.username)+".",type:"success",showCancelButton:false,confirmButtonText:"Home",allowOutsideClick:false}).then(result=>{if(result.value){window.location.href="/"}})}else{Swal.fire({title:"Error!",type:"error",html:"Failed to change to user "+escapeHtml(user.username)+".",showCancelButton:false})}})}})};const load=()=>{$("#userTable").hide();$("#loading").show();api.users.get().success(us=>{users=us;$("#loading").hide();$("#userTable").show();let userTable=$("#userTable").DataTable({destroy:true,columnDefs:[{orderable:false,targets:"no-sort"}]});userTable.clear();userRows=[];$.each(users,(i,user)=>{lastlogin="Never";if(user.last_login!="0001-01-01T00:00:00Z"){lastlogin=moment(user.last_login).format("MMMM Do YYYY, h:mm:ss a")}userRows.push([escapeHtml(user.username),escapeHtml(user.role.name),lastlogin,"
"])});userTable.rows.add(userRows).draw()}).error(()=>{errorFlash("Error fetching users")})};$(document).ready(function(){load();$("#modal").on("hide.bs.modal",function(){dismiss()});$.fn.select2.defaults.set("width","100%");$.fn.select2.defaults.set("dropdownParent",$("#role-select"));$.fn.select2.defaults.set("theme","bootstrap");$.fn.select2.defaults.set("sorter",function(data){return data.sort(function(a,b){if(a.text.toLowerCase()>b.text.toLowerCase()){return 1}if(a.text.toLowerCase(){if($("#password").val()!==$("#confirm_password").val()){modalError("Passwords must match.");return}let user={username:$("#username").val(),password:$("#password").val(),role:$("#role").val(),password_change_required:$("#force_password_change_checkbox").prop("checked"),account_locked:$("#account_locked_checkbox").prop("checked")};if(id!=-1){user.id=id;api.userId.put(user).success(data=>{successFlash("User "+escapeHtml(user.username)+" updated successfully!");load();dismiss();$("#modal").modal("hide")}).error(data=>{modalError(data.responseJSON.message)})}else{api.users.post(user).success(data=>{successFlash("User "+escapeHtml(user.username)+" registered successfully!");load();dismiss();$("#modal").modal("hide")}).error(data=>{modalError(data.responseJSON.message)})}};const dismiss=()=>{$("#username").val("");$("#password").val("");$("#confirm_password").val("");$("#role").val("");$("#force_password_change_checkbox").prop("checked",true);$("#account_locked_checkbox").prop("checked",false);$("#modal\\.flashes").empty()};const edit=id=>{$("#username").attr("disabled",false);$("#modalSubmit").unbind("click").click(()=>{save(id)});$("#role").select2();if(id==-1){$("#userModalLabel").text("New User");$("#role").val("user");$("#role").trigger("change")}else{$("#userModalLabel").text("Edit User");api.userId.get(id).success(user=>{$("#username").val(user.username);$("#role").val(user.role.slug);$("#role").trigger("change");$("#force_password_change_checkbox").prop("checked",user.password_change_required);$("#account_locked_checkbox").prop("checked",user.account_locked);if(user.username=="admin"){$("#username").attr("disabled",true)}}).error(function(){errorFlash("Error fetching user")})}};const deleteUser=id=>{var user=users.find(x=>x.id==id);if(!user){return}if(user.username=="admin"){Swal.fire({title:"Unable to Delete User",text:"The user account "+escapeHtml(user.username)+" cannot be deleted.",type:"info"});return}Swal.fire({title:"Are you sure?",text:"This will delete the account for "+escapeHtml(user.username)+" as well as all of the objects they have created.\n\nThis can't be undone!",type:"warning",animation:false,showCancelButton:true,confirmButtonText:"Delete",confirmButtonColor:"#428bca",reverseButtons:true,allowOutsideClick:false,preConfirm:function(){return new Promise((resolve,reject)=>{api.userId.delete(id).success(msg=>{resolve()}).error(data=>{reject(data.responseJSON.message)})}).catch(error=>{Swal.showValidationMessage(error)})}}).then(function(result){if(result.value){Swal.fire("User Deleted!","The user account for "+escapeHtml(user.username)+" and all associated objects have been deleted!","success")}$('button:contains("OK")').on("click",function(){location.reload()})})};const impersonate=id=>{var user=users.find(x=>x.id==id);if(!user){return}Swal.fire({title:"Are you sure?",html:"You will be logged out of your account and logged in as "+escapeHtml(user.username)+"",type:"warning",animation:false,showCancelButton:true,confirmButtonText:"Swap User",confirmButtonColor:"#428bca",reverseButtons:true,allowOutsideClick:false}).then(result=>{if(result.value){fetch("/impersonate",{method:"post",body:"username="+user.username+"&csrf_token="+encodeURIComponent(csrf_token),headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then(response=>{if(response.status==200){Swal.fire({title:"Success!",html:"Successfully changed to user "+escapeHtml(user.username)+".",type:"success",showCancelButton:false,confirmButtonText:"Home",allowOutsideClick:false}).then(result=>{if(result.value){window.location.href="/"}})}else{Swal.fire({title:"Error!",type:"error",html:"Failed to change to user "+escapeHtml(user.username)+".",showCancelButton:false})}})}})};const load=()=>{$("#userTable").hide();$("#loading").show();api.users.get().success(us=>{users=us;$("#loading").hide();$("#userTable").show();let userTable=$("#userTable").DataTable({destroy:true,columnDefs:[{orderable:false,targets:"no-sort"}]});userTable.clear();userRows=[];$.each(users,(i,user)=>{lastlogin="";if(user.last_login!="0001-01-01T00:00:00Z"){lastlogin=moment(user.last_login).format("MMMM Do YYYY, h:mm:ss a")}userRows.push([escapeHtml(user.username),escapeHtml(user.role.name),lastlogin,"