From 32149e652ff1a46e057bd9e3dae2da1f3494422e Mon Sep 17 00:00:00 2001 From: Simon Detheridge Date: Tue, 9 Oct 2018 17:09:49 +0100 Subject: [PATCH] Handle 'invalid element name' error in project list ui When invalid filenames are found during project-copy, the somewhat obscure (and non-localised) 'invalid element name' error is returned. Add a special case to handle this particular error and display something more descriptive to the user. Added a modal error handler for when this error is generated by clicking the 'copy' icon in the project list, instead of using the 'more' dropdown which opens a modal copy dialog bug: overleaf/sharelatex#908 Signed-off-by: Simon Detheridge --- .../web/app/views/project/list/modals.pug | 20 ++++++++++++--- .../project-list/modal-controllers.coffee | 14 +++++++---- .../main/project-list/project-list.coffee | 25 +++++++++++++------ 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/services/web/app/views/project/list/modals.pug b/services/web/app/views/project/list/modals.pug index 50d7f8d2ef..11e8da29ea 100644 --- a/services/web/app/views/project/list/modals.pug +++ b/services/web/app/views/project/list/modals.pug @@ -98,7 +98,7 @@ script(type='text/ng-template', id='renameProjectModalTemplate') ) × h3 #{translate("rename_project")} .modal-body - .alert.alert-danger(ng-show="state.error.message") {{ state.error.message}} + .alert.alert-danger(ng-show="state.error.message") {{state.error.message}} .alert.alert-danger(ng-show="state.error && !state.error.message") #{translate("generic_something_went_wrong")} form(name="renameProjectForm", novalidate) input.form-control( @@ -127,7 +127,7 @@ script(type='text/ng-template', id='cloneProjectModalTemplate') ) × h3 #{translate("copy_project")} .modal-body - .alert.alert-danger(ng-show="state.error.message") {{ state.error.message}} + .alert.alert-danger(ng-show="state.error.message") {{state.error.message === "invalid element name" ? translate("invalid_element_name") : state.error.message}} .alert.alert-danger(ng-show="state.error && !state.error.message") #{translate("generic_something_went_wrong")} form(name="cloneProjectForm", novalidate) .form-group @@ -161,7 +161,7 @@ script(type='text/ng-template', id='newProjectModalTemplate') ) × h3 #{translate("new_project")} .modal-body - .alert.alert-danger(ng-show="state.error.message") {{ state.error.message}} + .alert.alert-danger(ng-show="state.error.message") {{state.error.message}} .alert.alert-danger(ng-show="state.error && !state.error.message") #{translate("generic_something_went_wrong")} form(novalidate, name="newProjectForm") input.form-control( @@ -262,6 +262,20 @@ script(type="text/ng-template", id="uploadProjectModalTemplate") .modal-footer button.btn.btn-default(ng-click="cancel()") #{translate("cancel")} +script(type="text/ng-template", id="showErrorModalTemplate") + .modal-header + button.close( + type="button" + data-dismiss="modal" + ng-click="cancel()" + ) × + h3 #{translate("generic_something_went_wrong")} + .modal-body + .alert.alert-danger(ng-show="error.message") {{error.message === "invalid element name" ? translate("invalid_element_name") : error.message}} + .alert.alert-danger(ng-show="error && !error.message") #{translate("generic_something_went_wrong")} + .modal-footer + button.btn.btn-default(ng-click="cancel()") #{translate("cancel")} + script(type="text/ng-template", id="userProfileModalTemplate") .modal-header button.close( diff --git a/services/web/public/coffee/main/project-list/modal-controllers.coffee b/services/web/public/coffee/main/project-list/modal-controllers.coffee index 27124e0951..3d15797940 100644 --- a/services/web/public/coffee/main/project-list/modal-controllers.coffee +++ b/services/web/public/coffee/main/project-list/modal-controllers.coffee @@ -2,9 +2,9 @@ define [ "base" ], (App) -> App.controller 'RenameProjectModalController', ($scope, $modalInstance, $timeout, project, queuedHttp) -> - $scope.inputs = + $scope.inputs = projectName: project.name - + $scope.state = inflight: false error: false @@ -35,7 +35,7 @@ define [ $modalInstance.dismiss('cancel') App.controller 'CloneProjectModalController', ($scope, $modalInstance, $timeout, project) -> - $scope.inputs = + $scope.inputs = projectName: project.name + " (Copy)" $scope.state = inflight: false @@ -66,7 +66,7 @@ define [ $modalInstance.dismiss('cancel') App.controller 'NewProjectModalController', ($scope, $modalInstance, $timeout, template) -> - $scope.inputs = + $scope.inputs = projectName: "" $scope.state = inflight: false @@ -123,7 +123,6 @@ define [ $scope.cancel = () -> $modalInstance.dismiss('cancel') - App.controller 'UploadProjectModalController', ($scope, $modalInstance, $timeout) -> $scope.cancel = () -> $modalInstance.dismiss('cancel') @@ -137,3 +136,8 @@ define [ $scope.dismiss = () -> $modalInstance.dismiss('cancel') + + App.controller 'ShowErrorModalController', ($scope, $modalInstance, error) -> + $scope.error = error + $scope.cancel = () -> + $modalInstance.dismiss('cancel') diff --git a/services/web/public/coffee/main/project-list/project-list.coffee b/services/web/public/coffee/main/project-list/project-list.coffee index 9a8d7f7a73..8bdec6f42a 100644 --- a/services/web/public/coffee/main/project-list/project-list.coffee +++ b/services/web/public/coffee/main/project-list/project-list.coffee @@ -13,7 +13,7 @@ define [ $scope.predicate = "lastUpdated" $scope.nUntagged = 0 $scope.reverse = true - $scope.searchText = + $scope.searchText = value : "" $timeout () -> @@ -37,7 +37,7 @@ define [ angular.element($window).bind "resize", () -> recalculateProjectListHeight() $scope.$apply() - + # Allow tags to be accessed on projects as well projectsById = {} for project in $scope.projects @@ -56,7 +56,7 @@ define [ tag.selected = true else tag.selected = false - + $scope.changePredicate = (newPredicate)-> if $scope.predicate == newPredicate $scope.reverse = !$scope.reverse @@ -145,7 +145,7 @@ define [ # We don't want hidden selections project.selected = false - localStorage("project_list", JSON.stringify({ + localStorage("project_list", JSON.stringify({ filter: $scope.filter, selectedTagId: selectedTag?._id })) @@ -461,7 +461,7 @@ define [ resolve: project: () -> project ) - + if storedUIOpts?.filter? if storedUIOpts.filter == "tag" and storedUIOpts.selectedTagId? markTagAsSelected(storedUIOpts.selectedTagId) @@ -505,7 +505,16 @@ define [ $scope.project.isTableActionInflight = true $scope.cloneProject($scope.project, "#{$scope.project.name} (Copy)") .then () -> $scope.project.isTableActionInflight = false - .catch () -> $scope.project.isTableActionInflight = false + .catch (response) -> + { data, status } = response + error = if status == 400 then message: data else true + modalInstance = $modal.open( + templateUrl: "showErrorModalTemplate" + controller: "ShowErrorModalController" + resolve: + error: () -> error + ) + $scope.project.isTableActionInflight = false $scope.download = (e) -> e.stopPropagation() @@ -535,11 +544,11 @@ define [ url: "/project/#{$scope.project.id}?forever=true" headers: "X-CSRF-Token": window.csrfToken - }).then () -> + }).then () -> $scope.project.isTableActionInflight = false $scope._removeProjectFromList $scope.project for tag in $scope.tags $scope._removeProjectIdsFromTagArray(tag, [ $scope.project.id ]) $scope.updateVisibleProjects() - .catch () -> + .catch () -> $scope.project.isTableActionInflight = false