diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditors.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditors.directive.js index edb08f1066..c852228205 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditors.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditors.directive.js @@ -206,6 +206,10 @@ removeEditor(args.editor); })); + evts.push(eventsService.on("appState.editors.closeAll", function (name, args) { + scope.editors = []; + })); + //ensure to unregister from all events! scope.$on('$destroy', function () { for (var e in evts) { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js index 726103caf9..1dd88a575b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js @@ -12,7 +12,7 @@ * Another thing this directive does is to ensure that any .control-group that contains form elements that are invalid will * be marked with the 'error' css class. This ensures that labels included in that control group are styled correctly. **/ -function valFormManager(serverValidationManager, $rootScope, $log, $timeout, notificationsService, eventsService, $routeParams, navigationService) { +function valFormManager(serverValidationManager, $rootScope, $timeout, $location, overlayService, eventsService, $routeParams, navigationService, editorService) { var SHOW_VALIDATION_CLASS_NAME = "show-validation"; var SAVING_EVENT_NAME = "formSubmitting"; @@ -104,28 +104,61 @@ function valFormManager(serverValidationManager, $rootScope, $log, $timeout, not formCtrl.$setPristine(); })); + var confirmed = false; + //This handles the 'unsaved changes' dialog which is triggered when a route is attempting to be changed but // the form has pending changes var locationEvent = $rootScope.$on('$locationChangeStart', function(event, nextLocation, currentLocation) { - if (!formCtrl.$dirty || isSavingNewItem) { + + var infiniteEditors = editorService.getEditors(); + + if (!formCtrl.$dirty && infiniteEditors.length === 0 || isSavingNewItem && infiniteEditors.length === 0) { + confirmed = true; return; } var nextPath = nextLocation.split("#")[1]; - if (nextPath) { + if (nextPath && !confirmed) { if (navigationService.isRouteChangingNavigation(currentLocation, nextLocation)) { - if (!notificationsService.hasView()) { - if (nextPath.indexOf("%253") || nextPath.indexOf("%252")) { - nextPath = decodeURIComponent(nextPath); - } - - var msg = { view: "confirmroutechange", args: { path: nextPath, listener: locationEvent } }; - notificationsService.add(msg); + if (nextPath.indexOf("%253") || nextPath.indexOf("%252")) { + nextPath = decodeURIComponent(nextPath); } + // Open discard changes overlay + var overlay = { + "title": "You have unsaved changes VALFORM", + "content": "Are you sure you want to navigate away from this page?", + "view": "default", + "submitButtonLabel": "Stay", + "closeButtonLabel": "Discard changes", + submit: function() { + overlayService.close(); + }, + close: function() { + // close all editors + editorService.closeAll(); + // allow redirection + navigationService.clearSearch(); + //we need to break the path up into path and query + var parts = nextPath.split("?"); + var query = {}; + if (parts.length > 1) { + _.each(parts[1].split("&"), function(q) { + var keyVal = q.split("="); + query[keyVal[0]] = keyVal[1]; + }); + } + $location.path(parts[0]).search(query); + overlayService.close(); + confirmed = true; + } + }; + + overlayService.open(overlay); + //prevent the route! event.preventDefault(); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js index 453785f537..eab167c2ec 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js @@ -53,7 +53,7 @@ * @methodOf umbraco.services.editorService * * @description - * Opens a media editor in infinite editing, the submit callback returns the updated content item + * Method to close the latest opened editor */ function close() { var length = editors.length; @@ -69,6 +69,26 @@ eventsService.emit("appState.editors.close", args); } + /** + * @ngdoc method + * @name umbraco.services.editorService#closeAll + * @methodOf umbraco.services.editorService + * + * @description + * Method to close all open editors + */ + function closeAll() { + + editors = []; + + var args = { + editors: editors, + editor: null + }; + + eventsService.emit("appState.editors.closeAll", args); + } + /** * @ngdoc method * @name umbraco.services.editorService#contentEditor @@ -454,6 +474,7 @@ getEditors: getEditors, open: open, close: close, + closeAll: closeAll, mediaEditor: mediaEditor, contentEditor: contentEditor, contentPicker: contentPicker, diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/default/default.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/default/default.html new file mode 100644 index 0000000000..04201dde70 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/default/default.html @@ -0,0 +1 @@ +