Temp8 validation fixing (#2699)
* Showing notifications if any for any response with status 400 >= x < 500. * fixes valFormManager * Updates logic for the valpropertymsg.directive to simplify it and so that it doesn't need to query the DOM which was causing issues with timing. * commits package-lock * fixes some issues with the securityinterceptor, properly nests promises in contentEditingHelper, fixes errors occuring when not handling promise rejections due to validation problems, * another unhandled potential validation problem * Merge branch 'temp-U4-7757' of https://github.com/lars-erik/Umbraco-CMS into lars-erik-temp-U4-7757 # Conflicts: # src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js * cleans up the interceptor objects and puts them in appropriate modules and files, centralizes the logic to show notifications so that only happens in one place. * Fixes more places where notifications were manually shown. * Fixes validation with the variant publishing overlay and html descrepencies
This commit is contained in:
@@ -79,7 +79,7 @@ var sources = {
|
||||
filters: { files: ["src/common/filters/**/*.js"], out: "umbraco.filters.js" },
|
||||
resources: { files: ["src/common/resources/**/*.js"], out: "umbraco.resources.js" },
|
||||
services: { files: ["src/common/services/**/*.js"], out: "umbraco.services.js" },
|
||||
security: { files: ["src/common/security/**/*.js"], out: "umbraco.security.js" }
|
||||
security: { files: ["src/common/interceptors/**/*.js"], out: "umbraco.interceptors.js" }
|
||||
},
|
||||
|
||||
//selectors for copying all views into the build
|
||||
@@ -406,4 +406,4 @@ gulp.task('test:e2e', function() {
|
||||
keepalive: true
|
||||
})
|
||||
.start();
|
||||
});
|
||||
});
|
||||
|
||||
5699
src/Umbraco.Web.UI.Client/package-lock.json
generated
5699
src/Umbraco.Web.UI.Client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ LazyLoad.js([
|
||||
'../js/app.js',
|
||||
'../js/umbraco.resources.js',
|
||||
'../js/umbraco.services.js',
|
||||
'../js/umbraco.security.js',
|
||||
'../js/umbraco.interceptors.js',
|
||||
'../ServerVariables',
|
||||
'../lib/signalr/jquery.signalR.js',
|
||||
'/umbraco/BackOffice/signalr/hubs',
|
||||
|
||||
@@ -286,7 +286,7 @@
|
||||
contentResource.unPublish($scope.content.id, culture)
|
||||
.then(function (data) {
|
||||
|
||||
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
@@ -301,7 +301,6 @@
|
||||
$scope.page.buttonGroupState = "success";
|
||||
|
||||
}, function (err) {
|
||||
formHelper.showNotifications(err.data);
|
||||
$scope.page.buttonGroupState = 'error';
|
||||
});
|
||||
}
|
||||
@@ -367,12 +366,12 @@
|
||||
}
|
||||
}
|
||||
else {
|
||||
return performSave({ saveMethod: contentResource.publish, action: "publish" });
|
||||
return performSave({ saveMethod: contentResource.publish, action: "publish" }).catch(angular.noop);;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.save = function () {
|
||||
return performSave({ saveMethod: $scope.saveMethod(), action: "save" });
|
||||
return performSave({ saveMethod: $scope.saveMethod(), action: "save" }).catch(angular.noop);
|
||||
};
|
||||
|
||||
$scope.preview = function (content) {
|
||||
@@ -396,7 +395,7 @@
|
||||
else {
|
||||
$scope.save().then(function (data) {
|
||||
previewWindow.location.href = redirect;
|
||||
});
|
||||
}).catch(angular.noop);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ angular.module("umbraco.directives.html")
|
||||
labelFor: "@",
|
||||
required: "@?"
|
||||
},
|
||||
require: '?^form',
|
||||
require: '?^^form',
|
||||
transclude: true,
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
|
||||
@@ -15,7 +15,7 @@ var _umbPropertyEditor = function (umbPropEditorHelper) {
|
||||
preview: "@"
|
||||
},
|
||||
|
||||
require: "^form",
|
||||
require: "^^form",
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
templateUrl: 'views/components/property/umb-property-editor.html',
|
||||
@@ -37,4 +37,4 @@ var _umbPropertyEditor = function (umbPropEditorHelper) {
|
||||
};
|
||||
};
|
||||
|
||||
angular.module("umbraco.directives").directive('umbPropertyEditor', _umbPropertyEditor);
|
||||
angular.module("umbraco.directives").directive('umbPropertyEditor', _umbPropertyEditor);
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
}
|
||||
|
||||
var directive = {
|
||||
require: "^form",
|
||||
require: "^^form",
|
||||
restrict: 'A',
|
||||
link: link
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
angular.module('umbraco.directives.validation')
|
||||
.directive('valCompare',function () {
|
||||
return {
|
||||
require: ["ngModel", "^form"],
|
||||
require: ["ngModel", "^^form"],
|
||||
link: function (scope, elem, attrs, ctrls) {
|
||||
|
||||
var ctrl = ctrls[0];
|
||||
@@ -23,4 +23,4 @@ angular.module('umbraco.directives.validation')
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
* 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) {
|
||||
|
||||
var SHOW_VALIDATION_CLASS_NAME = "show-validation";
|
||||
var SAVING_EVENT_NAME = "formSubmitting";
|
||||
var SAVED_EVENT_NAME = "formSubmitted";
|
||||
|
||||
return {
|
||||
require: "form",
|
||||
restrict: "A",
|
||||
@@ -39,14 +44,22 @@ function valFormManager(serverValidationManager, $rootScope, $log, $timeout, not
|
||||
},
|
||||
link: function (scope, element, attr, formCtrl) {
|
||||
|
||||
|
||||
/*
|
||||
FIXME: This is commented out because it caused this error
|
||||
http://uixdk.com/angular/docs/error/ng/cpws
|
||||
resulting in an endless digest loop for all editors
|
||||
|
||||
//watch the list of validation errors to notify the application of any validation changes
|
||||
scope.$watch(function () {
|
||||
return formCtrl.$error;
|
||||
//the validators are in the $error collection: https://docs.angularjs.org/api/ng/type/form.FormController#$error
|
||||
//since each key is the validator name (i.e. 'required') we can't just watch the number of keys, we need to watch
|
||||
//the sum of the items inside of each key
|
||||
|
||||
//get the lengths of each array for each key in the $error collection
|
||||
var validatorLengths = _.map(formCtrl.$error, function (val, key) {
|
||||
return val.length;
|
||||
});
|
||||
//sum up all numbers in the resulting array
|
||||
var sum = _.reduce(validatorLengths, function (memo, num) {
|
||||
return memo + num;
|
||||
}, 0);
|
||||
//this is the value we watch to notify of any validation changes on the form
|
||||
return sum;
|
||||
}, function (e) {
|
||||
scope.$broadcast("valStatusChanged", { form: formCtrl });
|
||||
|
||||
@@ -58,11 +71,7 @@ function valFormManager(serverValidationManager, $rootScope, $log, $timeout, not
|
||||
var noInError = element.find(".control-group .ng-valid").closest(".control-group").not(inError);
|
||||
noInError.removeClass("error");
|
||||
|
||||
}, true);
|
||||
|
||||
var className = attr.valShowValidation ? attr.valShowValidation : "show-validation";
|
||||
var savingEventName = attr.savingEvent ? attr.savingEvent : "formSubmitting";
|
||||
var savedEvent = attr.savedEvent ? attr.savingEvent : "formSubmitted";
|
||||
});
|
||||
|
||||
//This tracks if the user is currently saving a new item, we use this to determine
|
||||
// if we should display the warning dialog that they are leaving the page - if a new item
|
||||
@@ -72,23 +81,23 @@ function valFormManager(serverValidationManager, $rootScope, $log, $timeout, not
|
||||
|
||||
//we should show validation if there are any msgs in the server validation collection
|
||||
if (serverValidationManager.items.length > 0) {
|
||||
element.addClass(className);
|
||||
element.addClass(SHOW_VALIDATION_CLASS_NAME);
|
||||
}
|
||||
|
||||
var unsubscribe = [];
|
||||
|
||||
//listen for the forms saving event
|
||||
unsubscribe.push(scope.$on(savingEventName, function(ev, args) {
|
||||
element.addClass(className);
|
||||
unsubscribe.push(scope.$on(SAVING_EVENT_NAME, function(ev, args) {
|
||||
element.addClass(SHOW_VALIDATION_CLASS_NAME);
|
||||
|
||||
//set the flag so we can check to see if we should display the error.
|
||||
isSavingNewItem = $routeParams.create;
|
||||
}));
|
||||
|
||||
//listen for the forms saved event
|
||||
unsubscribe.push(scope.$on(savedEvent, function(ev, args) {
|
||||
unsubscribe.push(scope.$on(SAVED_EVENT_NAME, function(ev, args) {
|
||||
//remove validation class
|
||||
element.removeClass(className);
|
||||
element.removeClass(SHOW_VALIDATION_CLASS_NAME);
|
||||
|
||||
//clear form state as at this point we retrieve new data from the server
|
||||
//and all validation will have cleared at this point
|
||||
@@ -133,8 +142,8 @@ function valFormManager(serverValidationManager, $rootScope, $log, $timeout, not
|
||||
$timeout(function(){
|
||||
formCtrl.$setPristine();
|
||||
}, 1000);
|
||||
*/
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.directives.validation').directive("valFormManager", valFormManager);
|
||||
angular.module('umbraco.directives.validation').directive("valFormManager", valFormManager);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @description This directive is used to control the display of the property level validation message.
|
||||
* We will listen for server side validation changes
|
||||
* and when an error is detected for this property we'll show the error message.
|
||||
* In order for this directive to work, the valStatusChanged directive must be placed on the containing form.
|
||||
* In order for this directive to work, the valFormManager directive must be placed on the containing form.
|
||||
**/
|
||||
function valPropertyMsg(serverValidationManager) {
|
||||
|
||||
@@ -15,16 +15,18 @@ function valPropertyMsg(serverValidationManager) {
|
||||
scope: {
|
||||
property: "="
|
||||
},
|
||||
require: "^form", //require that this directive is contained within an ngForm
|
||||
replace: true, //replace the element with the template
|
||||
restrict: "E", //restrict to element
|
||||
require: ['^^form', '^^valFormManager'],
|
||||
replace: true,
|
||||
restrict: "E",
|
||||
template: "<div ng-show=\"errorMsg != ''\" class='alert alert-error property-error' >{{errorMsg}}</div>",
|
||||
|
||||
/**
|
||||
Our directive requries a reference to a form controller
|
||||
which gets passed in to this parameter
|
||||
*/
|
||||
link: function (scope, element, attrs, formCtrl) {
|
||||
link: function (scope, element, attrs, ctrl) {
|
||||
|
||||
//the property form controller api
|
||||
var formCtrl = ctrl[0];
|
||||
|
||||
//the valFormManager controller api
|
||||
var valFormManager = ctrl[1];
|
||||
|
||||
var watcher = null;
|
||||
|
||||
@@ -39,10 +41,12 @@ function valPropertyMsg(serverValidationManager) {
|
||||
return err.errorMsg;
|
||||
}
|
||||
else {
|
||||
//TODO: localize
|
||||
return scope.property.propertyErrorMessage ? scope.property.propertyErrorMessage : "Property has errors";
|
||||
}
|
||||
|
||||
}
|
||||
//TODO: localize
|
||||
return "Property has errors";
|
||||
}
|
||||
|
||||
@@ -98,18 +102,19 @@ function valPropertyMsg(serverValidationManager) {
|
||||
|
||||
var unsubscribe = [];
|
||||
|
||||
//listen for form error changes
|
||||
unsubscribe.push(scope.$on("valStatusChanged", function(evt, args) {
|
||||
if (args.form.$invalid) {
|
||||
|
||||
//listen for form validation changes.
|
||||
//The alternative is to add a watch to formCtrl.$invalid but that would lead to many more watches then
|
||||
// subscribing to this single watch.
|
||||
valFormManager.onValidationStatusChanged(function (evt, args) {
|
||||
if (formCtrl.$invalid) {
|
||||
//first we need to check if the valPropertyMsg validity is invalid
|
||||
if (formCtrl.$error.valPropertyMsg && formCtrl.$error.valPropertyMsg.length > 0) {
|
||||
//since we already have an error we'll just return since this means we've already set the
|
||||
// hasError and errorMsg properties which occurs below in the serverValidationManager.subscribe
|
||||
return;
|
||||
}
|
||||
else if (element.closest(".umb-control-group").find(".ng-invalid").length > 0) {
|
||||
//check if it's one of the properties that is invalid in the current content property
|
||||
//if there are any errors in the current property form that are not valPropertyMsg
|
||||
else if (_.without(_.keys(formCtrl.$error), "valPropertyMsg").length > 0) {
|
||||
hasError = true;
|
||||
//update the validation message if we don't already have one assigned.
|
||||
if (showValidation && scope.errorMsg === "") {
|
||||
@@ -125,7 +130,7 @@ function valPropertyMsg(serverValidationManager) {
|
||||
hasError = false;
|
||||
scope.errorMsg = "";
|
||||
}
|
||||
}, true));
|
||||
});
|
||||
|
||||
//listen for the forms saving event
|
||||
unsubscribe.push(scope.$on("formSubmitting", function(ev, args) {
|
||||
@@ -193,4 +198,4 @@ function valPropertyMsg(serverValidationManager) {
|
||||
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.directives.validation').directive("valPropertyMsg", valPropertyMsg);
|
||||
angular.module('umbraco.directives.validation').directive("valPropertyMsg", valPropertyMsg);
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:valServerField
|
||||
* @restrict A
|
||||
* @description This directive is used to associate a content field (not user defined) with a server-side validation response
|
||||
* @description This directive is used to associate a field with a server-side validation response
|
||||
* so that the validators in angular are updated based on server-side feedback.
|
||||
* (For validation of user defined content properties on content/media/members, the valServer directive is used)
|
||||
**/
|
||||
function valServerField(serverValidationManager) {
|
||||
return {
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
}
|
||||
|
||||
var directive = {
|
||||
require: ['?^form', '?^valFormManager'],
|
||||
require: ['?^^form', '?^^valFormManager'],
|
||||
restrict: "A",
|
||||
link: link
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
**/
|
||||
function valTab() {
|
||||
return {
|
||||
require: ['^form', '^valFormManager'],
|
||||
require: ['^^form', '^^valFormManager'],
|
||||
restrict: "A",
|
||||
link: function (scope, element, attr, ctrs) {
|
||||
|
||||
@@ -35,4 +35,4 @@ function valTab() {
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.directives.validation').directive("valTab", valTab);
|
||||
angular.module('umbraco.directives.validation').directive("valTab", valTab);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
function valToggleMsg(serverValidationManager) {
|
||||
return {
|
||||
require: "^form",
|
||||
require: "^^form",
|
||||
restrict: "A",
|
||||
|
||||
/**
|
||||
@@ -87,4 +87,4 @@ function valToggleMsg(serverValidationManager) {
|
||||
* @requires formController
|
||||
* @description This directive will show/hide an error based on: is the value + the given validator invalid? AND, has the form been submitted ?
|
||||
**/
|
||||
angular.module('umbraco.directives.validation').directive("valToggleMsg", valToggleMsg);
|
||||
angular.module('umbraco.directives.validation').directive("valToggleMsg", valToggleMsg);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
angular.module('umbraco.interceptors', [])
|
||||
// We have to add the interceptor to the queue as a string because the interceptor depends upon service instances that are not available in the config block.
|
||||
.config(['$httpProvider', function($httpProvider) {
|
||||
$httpProvider.defaults.xsrfHeaderName = 'X-UMB-XSRF-TOKEN';
|
||||
$httpProvider.defaults.xsrfCookieName = 'UMB-XSRF-TOKEN';
|
||||
|
||||
$httpProvider.interceptors.push('securityInterceptor');
|
||||
$httpProvider.interceptors.push('debugRequestInterceptor');
|
||||
}]);
|
||||
@@ -0,0 +1,25 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Used to set debug headers on all requests where necessary
|
||||
* @param {any} $q
|
||||
* @param {any} urlHelper
|
||||
*/
|
||||
function debugRequestInterceptor($q, urlHelper) {
|
||||
return {
|
||||
//dealing with requests:
|
||||
'request': function(config) {
|
||||
var queryStrings = urlHelper.getQueryStringParams();
|
||||
if (queryStrings.umbDebug === "true" || queryStrings.umbdebug === "true") {
|
||||
config.headers["X-UMB-DEBUG"] = "true";
|
||||
}
|
||||
return config;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
angular.module('umbraco.interceptors').factory('debugRequestInterceptor', debugRequestInterceptor);
|
||||
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,11 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/** Used to filter the request interceptor */
|
||||
function requestInterceptorFilter() {
|
||||
return ["www.gravatar.com"];
|
||||
}
|
||||
|
||||
angular.module('umbraco.interceptors').value('requestInterceptorFilter', requestInterceptorFilter);
|
||||
|
||||
})();
|
||||
@@ -1,9 +1,19 @@
|
||||
angular.module('umbraco.security.interceptor')
|
||||
// This http interceptor listens for authentication successes and failures
|
||||
.factory('securityInterceptor', ['$injector', 'securityRetryQueue', 'notificationsService', 'eventsService', 'requestInterceptorFilter', function ($injector, queue, notifications, eventsService, requestInterceptorFilter) {
|
||||
return {
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
'response': function(response) {
|
||||
/**
|
||||
* This http interceptor listens for authentication successes and failures
|
||||
* @param {any} $q
|
||||
* @param {any} $injector
|
||||
* @param {any} requestRetryQueue
|
||||
* @param {any} notificationsService
|
||||
* @param {any} eventsService
|
||||
* @param {any} requestInterceptorFilter
|
||||
*/
|
||||
function securityInterceptor($q, $injector, requestRetryQueue, notificationsService, eventsService, requestInterceptorFilter) {
|
||||
return {
|
||||
|
||||
'response': function (response) {
|
||||
// Intercept successful requests
|
||||
//Here we'll check if our custom header is in the response which indicates how many seconds the user's session has before it
|
||||
//expires. Then we'll update the user in the user service accordingly.
|
||||
@@ -14,7 +24,7 @@ angular.module('umbraco.security.interceptor')
|
||||
var userService = $injector.get('userService');
|
||||
userService.setUserTimeout(headers["x-umb-user-seconds"]);
|
||||
}
|
||||
|
||||
|
||||
//this checks if the user's values have changed, in which case we need to update the user details throughout
|
||||
//the back office similar to how we do when a user logs in
|
||||
if (headers["x-umb-user-modified"]) {
|
||||
@@ -23,8 +33,8 @@ angular.module('umbraco.security.interceptor')
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
'responseError': function(rejection) {
|
||||
|
||||
'responseError': function (rejection) {
|
||||
|
||||
// Intercept failed requests
|
||||
// Make sure we have the configuration of the request (don't we always?)
|
||||
@@ -36,13 +46,13 @@ angular.module('umbraco.security.interceptor')
|
||||
//Here we'll check if we should ignore the error (either based on the original header set or the request configuration)
|
||||
if (headers["x-umb-ignore-error"] === "ignore" || config.umbIgnoreErrors === true || (angular.isArray(config.umbIgnoreStatus) && config.umbIgnoreStatus.indexOf(rejection.status) !== -1)) {
|
||||
//exit/ignore
|
||||
return promise;
|
||||
return $q.reject(rejection);
|
||||
}
|
||||
var filtered = _.find(requestInterceptorFilter(), function (val) {
|
||||
return config.url.indexOf(val) > 0;
|
||||
});
|
||||
if (filtered) {
|
||||
return promise;
|
||||
return $q.reject(rejection);
|
||||
}
|
||||
|
||||
//A 401 means that the user is not logged in
|
||||
@@ -51,11 +61,11 @@ angular.module('umbraco.security.interceptor')
|
||||
var userService = $injector.get('userService'); // see above
|
||||
|
||||
//Associate the user name with the retry to ensure we retry for the right user
|
||||
promise = userService.getCurrentUser()
|
||||
return userService.getCurrentUser()
|
||||
.then(function (user) {
|
||||
var userName = user ? user.name : null;
|
||||
//The request bounced because it was not authorized - add a new request to the retry queue
|
||||
return queue.pushRetryFn('unauthorized-server', userName, function retryRequest() {
|
||||
return requestRetryQueue.pushRetryFn('unauthorized-server', userName, function retryRequest() {
|
||||
// We must use $injector to get the $http service to prevent circular dependency
|
||||
return $injector.get('$http')(rejection.config);
|
||||
});
|
||||
@@ -74,9 +84,9 @@ angular.module('umbraco.security.interceptor')
|
||||
errMsg += "<br/> with data: <br/><i>" + angular.toJson(rejection.config.data) + "</i><br/>Contact your administrator for information.";
|
||||
}
|
||||
|
||||
notifications.error(
|
||||
notificationsService.error(
|
||||
"Request error",
|
||||
errMsg);
|
||||
errMsg);
|
||||
|
||||
}
|
||||
else if (rejection.status === 403) {
|
||||
@@ -94,35 +104,15 @@ angular.module('umbraco.security.interceptor')
|
||||
msg += "<br/> with data: <br/><i>" + angular.toJson(rejection.config.data) + "</i><br/>Contact your administrator for information.";
|
||||
}
|
||||
|
||||
notifications.error("Authorization error", msg);
|
||||
notificationsService.error("Authorization error", msg);
|
||||
}
|
||||
|
||||
return $q.reject(rejection);
|
||||
}
|
||||
};
|
||||
}])
|
||||
//used to set headers on all requests where necessary
|
||||
.factory('umbracoRequestInterceptor', function ($q, urlHelper) {
|
||||
return {
|
||||
//dealing with requests:
|
||||
'request': function (config) {
|
||||
var queryStrings = urlHelper.getQueryStringParams();
|
||||
if (queryStrings.umbDebug === "true" || queryStrings.umbdebug === "true") {
|
||||
config.headers["X-UMB-DEBUG"] = "true";
|
||||
}
|
||||
return config;
|
||||
}
|
||||
};
|
||||
})
|
||||
.value('requestInterceptorFilter', function () {
|
||||
return ["www.gravatar.com"];
|
||||
})
|
||||
}
|
||||
|
||||
// We have to add the interceptor to the queue as a string because the interceptor depends upon service instances that are not available in the config block.
|
||||
.config(['$httpProvider', function ($httpProvider) {
|
||||
$httpProvider.defaults.xsrfHeaderName = 'X-UMB-XSRF-TOKEN';
|
||||
$httpProvider.defaults.xsrfCookieName = 'UMB-XSRF-TOKEN';
|
||||
angular.module('umbraco.interceptors').factory('securityInterceptor', securityInterceptor);
|
||||
|
||||
$httpProvider.interceptors.push('securityInterceptor');
|
||||
$httpProvider.interceptors.push('umbracoRequestInterceptor');
|
||||
}]);
|
||||
|
||||
})();
|
||||
@@ -1,4 +0,0 @@
|
||||
//TODO: This is silly and unecessary to have a separate module for this
|
||||
angular.module('umbraco.security.retryQueue', []);
|
||||
angular.module('umbraco.security.interceptor', ['umbraco.security.retryQueue']);
|
||||
angular.module('umbraco.security', ['umbraco.security.retryQueue', 'umbraco.security.interceptor']);
|
||||
@@ -1,90 +0,0 @@
|
||||
//TODO: This is silly and unecessary to have a separate module for this
|
||||
angular.module('umbraco.security.retryQueue', [])
|
||||
|
||||
// This is a generic retry queue for security failures. Each item is expected to expose two functions: retry and cancel.
|
||||
.factory('securityRetryQueue', ['$q', '$log', function ($q, $log) {
|
||||
|
||||
var retryQueue = [];
|
||||
var retryUser = null;
|
||||
|
||||
var service = {
|
||||
// The security service puts its own handler in here!
|
||||
onItemAddedCallbacks: [],
|
||||
|
||||
hasMore: function() {
|
||||
return retryQueue.length > 0;
|
||||
},
|
||||
push: function(retryItem) {
|
||||
retryQueue.push(retryItem);
|
||||
// Call all the onItemAdded callbacks
|
||||
angular.forEach(service.onItemAddedCallbacks, function(cb) {
|
||||
try {
|
||||
cb(retryItem);
|
||||
} catch(e) {
|
||||
$log.error('securityRetryQueue.push(retryItem): callback threw an error' + e);
|
||||
}
|
||||
});
|
||||
},
|
||||
pushRetryFn: function(reason, userName, retryFn) {
|
||||
// The reason parameter is optional
|
||||
if ( arguments.length === 2) {
|
||||
retryFn = userName;
|
||||
userName = reason;
|
||||
reason = undefined;
|
||||
}
|
||||
|
||||
if ((retryUser && retryUser !== userName) || userName === null) {
|
||||
throw new Error('invalid user');
|
||||
}
|
||||
|
||||
retryUser = userName;
|
||||
|
||||
// The deferred object that will be resolved or rejected by calling retry or cancel
|
||||
var deferred = $q.defer();
|
||||
var retryItem = {
|
||||
reason: reason,
|
||||
retry: function() {
|
||||
// Wrap the result of the retryFn into a promise if it is not already
|
||||
$q.when(retryFn()).then(function(value) {
|
||||
// If it was successful then resolve our deferred
|
||||
deferred.resolve(value);
|
||||
}, function(value) {
|
||||
// Othewise reject it
|
||||
deferred.reject(value);
|
||||
});
|
||||
},
|
||||
cancel: function() {
|
||||
// Give up on retrying and reject our deferred
|
||||
deferred.reject();
|
||||
}
|
||||
};
|
||||
service.push(retryItem);
|
||||
return deferred.promise;
|
||||
},
|
||||
retryReason: function() {
|
||||
return service.hasMore() && retryQueue[0].reason;
|
||||
},
|
||||
cancelAll: function() {
|
||||
while(service.hasMore()) {
|
||||
retryQueue.shift().cancel();
|
||||
}
|
||||
retryUser = null;
|
||||
},
|
||||
retryAll: function (userName) {
|
||||
|
||||
if (retryUser == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (retryUser !== userName) {
|
||||
service.cancelAll();
|
||||
return;
|
||||
}
|
||||
|
||||
while(service.hasMore()) {
|
||||
retryQueue.shift().retry();
|
||||
}
|
||||
}
|
||||
};
|
||||
return service;
|
||||
}]);
|
||||
@@ -1 +1 @@
|
||||
angular.module("umbraco.services", ["umbraco.security", "umbraco.resources"]);
|
||||
angular.module("umbraco.services", ["umbraco.interceptors", "umbraco.resources"]);
|
||||
|
||||
@@ -54,7 +54,7 @@ function angularHelper($log, $q) {
|
||||
* This checks if a digest/apply is already occuring, if not it will force an apply call
|
||||
*/
|
||||
safeApply: function (scope, fn) {
|
||||
if (scope.$$phase || scope.$root.$$phase) {
|
||||
if (scope.$$phase || (scope.$root && scope.$root.$$phase)) {
|
||||
if (angular.isFunction(fn)) {
|
||||
fn();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
|
||||
return {
|
||||
|
||||
/** Used by the content editor and mini content editor to perform saving operations */
|
||||
//TODO: Make this a more helpful/reusable method for other form operations! we can simplify this form most forms
|
||||
//TODO: Make this a more helpful/reusable method for other form operations! we can simplify this form most forms
|
||||
// = this is already done in the formhelper service
|
||||
contentEditorPerformSave: function (args) {
|
||||
if (!angular.isObject(args)) {
|
||||
throw "args must be an object";
|
||||
@@ -59,7 +60,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
|
||||
return args.saveMethod(args.content, $routeParams.create, fileManager.getFiles())
|
||||
.then(function (data) {
|
||||
|
||||
formHelper.resetForm({ scope: args.scope, notifications: data.notifications });
|
||||
formHelper.resetForm({ scope: args.scope });
|
||||
|
||||
self.handleSuccessfulSave({
|
||||
scope: args.scope,
|
||||
@@ -71,7 +72,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
|
||||
});
|
||||
|
||||
args.scope.busy = false;
|
||||
return $q.when(data);
|
||||
return $q.resolve(data);
|
||||
|
||||
}, function (err) {
|
||||
self.handleSaveError({
|
||||
@@ -81,12 +82,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
|
||||
rebindCallback.apply(self, [args.content, err.data]);
|
||||
}
|
||||
});
|
||||
//show any notifications
|
||||
if (angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
|
||||
args.scope.busy = false;
|
||||
return $q.reject(err);
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* A utility class used to streamline how forms are developed, to ensure that validation is check and displayed consistently and to ensure that the correct events
|
||||
* fire when they need to.
|
||||
*/
|
||||
function formHelper(angularHelper, serverValidationManager, $timeout, notificationsService, dialogService, localizationService) {
|
||||
function formHelper(angularHelper, serverValidationManager, $timeout, notificationsService, dialogService) {
|
||||
return {
|
||||
|
||||
/**
|
||||
@@ -64,8 +64,7 @@ function formHelper(angularHelper, serverValidationManager, $timeout, notificati
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* Called by controllers when a form has been successfully submitted. the correct events execute
|
||||
* and that the notifications are displayed if there are any.
|
||||
* Called by controllers when a form has been successfully submitted, this ensures the correct events are raised.
|
||||
*
|
||||
* @param {object} args An object containing arguments for form submission
|
||||
*/
|
||||
@@ -77,8 +76,6 @@ function formHelper(angularHelper, serverValidationManager, $timeout, notificati
|
||||
throw "args.scope cannot be null";
|
||||
}
|
||||
|
||||
this.showNotifications(args);
|
||||
|
||||
args.scope.$broadcast("formSubmitted", { scope: args.scope });
|
||||
},
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A service normally used to recover from session expiry
|
||||
* @param {any} $q
|
||||
* @param {any} $log
|
||||
*/
|
||||
function requestRetryQueue($q, $log) {
|
||||
|
||||
var retryQueue = [];
|
||||
var retryUser = null;
|
||||
|
||||
var service = {
|
||||
// The security service puts its own handler in here!
|
||||
onItemAddedCallbacks: [],
|
||||
|
||||
hasMore: function () {
|
||||
return retryQueue.length > 0;
|
||||
},
|
||||
push: function (retryItem) {
|
||||
retryQueue.push(retryItem);
|
||||
// Call all the onItemAdded callbacks
|
||||
angular.forEach(service.onItemAddedCallbacks, function (cb) {
|
||||
try {
|
||||
cb(retryItem);
|
||||
} catch (e) {
|
||||
$log.error('requestRetryQueue.push(retryItem): callback threw an error' + e);
|
||||
}
|
||||
});
|
||||
},
|
||||
pushRetryFn: function (reason, userName, retryFn) {
|
||||
// The reason parameter is optional
|
||||
if (arguments.length === 2) {
|
||||
retryFn = userName;
|
||||
userName = reason;
|
||||
reason = undefined;
|
||||
}
|
||||
|
||||
if ((retryUser && retryUser !== userName) || userName === null) {
|
||||
throw new Error('invalid user');
|
||||
}
|
||||
|
||||
retryUser = userName;
|
||||
|
||||
// The deferred object that will be resolved or rejected by calling retry or cancel
|
||||
var deferred = $q.defer();
|
||||
var retryItem = {
|
||||
reason: reason,
|
||||
retry: function () {
|
||||
// Wrap the result of the retryFn into a promise if it is not already
|
||||
$q.when(retryFn()).then(function (value) {
|
||||
// If it was successful then resolve our deferred
|
||||
deferred.resolve(value);
|
||||
}, function (value) {
|
||||
// Othewise reject it
|
||||
deferred.reject(value);
|
||||
});
|
||||
},
|
||||
cancel: function () {
|
||||
// Give up on retrying and reject our deferred
|
||||
deferred.reject();
|
||||
}
|
||||
};
|
||||
service.push(retryItem);
|
||||
return deferred.promise;
|
||||
},
|
||||
retryReason: function () {
|
||||
return service.hasMore() && retryQueue[0].reason;
|
||||
},
|
||||
cancelAll: function () {
|
||||
while (service.hasMore()) {
|
||||
retryQueue.shift().cancel();
|
||||
}
|
||||
retryUser = null;
|
||||
},
|
||||
retryAll: function (userName) {
|
||||
|
||||
if (retryUser == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (retryUser !== userName) {
|
||||
service.cancelAll();
|
||||
return;
|
||||
}
|
||||
|
||||
while (service.hasMore()) {
|
||||
retryQueue.shift().retry();
|
||||
}
|
||||
}
|
||||
};
|
||||
return service;
|
||||
|
||||
}
|
||||
angular.module('umbraco.services').factory('requestRetryQueue', requestRetryQueue);
|
||||
})();
|
||||
@@ -3,7 +3,8 @@
|
||||
* @name umbraco.services.umbRequestHelper
|
||||
* @description A helper object used for sending requests to the server
|
||||
**/
|
||||
function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogService, notificationsService, eventsService) {
|
||||
function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogService, notificationsService, eventsService, formHelper) {
|
||||
|
||||
return {
|
||||
|
||||
/**
|
||||
@@ -24,7 +25,7 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
if (!virtualPath.startsWith("~/")) {
|
||||
throw "The path " + virtualPath + " is not a virtual path";
|
||||
}
|
||||
if (!Umbraco.Sys.ServerVariables.application.applicationPath) {
|
||||
if (!Umbraco.Sys.ServerVariables.application.applicationPath) {
|
||||
throw "No applicationPath defined in Umbraco.ServerVariables.application.applicationPath";
|
||||
}
|
||||
return Umbraco.Sys.ServerVariables.application.applicationPath + virtualPath.trimStart("~/");
|
||||
@@ -42,7 +43,7 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
* @param {Array} queryStrings An array of key/value pairs
|
||||
*/
|
||||
dictionaryToQueryString: function (queryStrings) {
|
||||
|
||||
|
||||
if (angular.isArray(queryStrings)) {
|
||||
return _.map(queryStrings, function (item) {
|
||||
var key = null;
|
||||
@@ -63,7 +64,7 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
//this allows for a normal object to be passed in (ie. a dictionary)
|
||||
return decodeURIComponent($.param(queryStrings));
|
||||
}
|
||||
|
||||
|
||||
throw "The queryString parameter is not an array or object of key value pairs";
|
||||
},
|
||||
|
||||
@@ -116,12 +117,10 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
* The error callback must return an object containing: {errorMsg: errorMessage, data: originalData, status: status }
|
||||
*/
|
||||
resourcePromise: function (httpPromise, opts) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
|
||||
/** The default success callback used if one is not supplied in the opts */
|
||||
function defaultSuccess(data, status, headers, config) {
|
||||
//when it's successful, just return the data
|
||||
console.log("succes promise", data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -141,13 +140,15 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
error: ((!opts || !opts.error) ? defaultError : opts.error)
|
||||
};
|
||||
|
||||
httpPromise.then(function (response) {
|
||||
return httpPromise.then(function (response) {
|
||||
|
||||
//invoke the callback
|
||||
var result = callbacks.success.apply(this, [response.data, response.status, response.headers, response.config]);
|
||||
|
||||
formHelper.showNotifications(response.data);
|
||||
|
||||
//when it's successful, just return the data
|
||||
deferred.resolve(result);
|
||||
return $q.resolve(result);
|
||||
|
||||
}, function (response) {
|
||||
|
||||
@@ -169,24 +170,23 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
//show a simple error notification
|
||||
notificationsService.error("Server error", "Contact administrator, see log for full details.<br/><i>" + result.errorMsg + "</i>");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
formHelper.showNotifications(result.data);
|
||||
}
|
||||
|
||||
//return an error object including the error message for UI
|
||||
deferred.reject({
|
||||
return $q.reject({
|
||||
errorMsg: result.errorMsg,
|
||||
data: result.data,
|
||||
status: result.status
|
||||
});
|
||||
|
||||
|
||||
})
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
|
||||
},
|
||||
|
||||
/** Used for saving media/content specifically */
|
||||
/** Used for saving content/media/members specifically */
|
||||
postSaveContent: function (args) {
|
||||
|
||||
if (!args.restApiUrl) {
|
||||
@@ -204,10 +204,7 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
if (!args.dataFormatter) {
|
||||
throw "args.dataFormatter is a required argument";
|
||||
}
|
||||
|
||||
|
||||
var deferred = $q.defer();
|
||||
|
||||
|
||||
//save the active tab id so we can set it when the data is returned.
|
||||
var activeTab = _.find(args.content.tabs, function (item) {
|
||||
return item.active;
|
||||
@@ -215,9 +212,10 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
var activeTabIndex = (activeTab === undefined ? 0 : _.indexOf(args.content.tabs, activeTab));
|
||||
|
||||
//save the data
|
||||
this.postMultiPartRequest(
|
||||
return this.postMultiPartRequest(
|
||||
args.restApiUrl,
|
||||
{ key: "contentItem", value: args.dataFormatter(args.content, args.action) },
|
||||
//data transform callback:
|
||||
function (data, formData) {
|
||||
//now add all of the assigned files
|
||||
for (var f in args.files) {
|
||||
@@ -225,64 +223,63 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
// so we know which property it belongs to on the server side
|
||||
formData.append("file_" + args.files[f].alias, args.files[f].file);
|
||||
}
|
||||
|
||||
},
|
||||
function (data, status, headers, config) {
|
||||
}).then(function (response) {
|
||||
//success callback
|
||||
|
||||
//reset the tabs and set the active one
|
||||
if(data.tabs && data.tabs.length > 0) {
|
||||
_.each(data.tabs, function (item) {
|
||||
if (response.data.tabs && response.data.tabs.length > 0) {
|
||||
_.each(response.data.tabs, function (item) {
|
||||
item.active = false;
|
||||
});
|
||||
data.tabs[activeTabIndex].active = true;
|
||||
response.data.tabs[activeTabIndex].active = true;
|
||||
}
|
||||
|
||||
formHelper.showNotifications(response.data);
|
||||
|
||||
//the data returned is the up-to-date data so the UI will refresh
|
||||
deferred.resolve(data);
|
||||
},
|
||||
function (data, status, headers, config) {
|
||||
return $q.resolve(response.data);
|
||||
}, function (response) {
|
||||
//failure callback
|
||||
|
||||
//when there's a 500 (unhandled) error show a YSOD overlay if debugging is enabled.
|
||||
if (status >= 500 && status < 600) {
|
||||
if (response.status >= 500 && response.status < 600) {
|
||||
|
||||
//This is a bit of a hack to check if the error is due to a file being uploaded that is too large,
|
||||
// we have to just check for the existence of a string value but currently that is the best way to
|
||||
// do this since it's very hacky/difficult to catch this on the server
|
||||
if (typeof data !== "undefined" && typeof data.indexOf === "function" && data.indexOf("Maximum request length exceeded") >= 0) {
|
||||
if (typeof response.data !== "undefined" && typeof response.data.indexOf === "function" && response.data.indexOf("Maximum request length exceeded") >= 0) {
|
||||
notificationsService.error("Server error", "The uploaded file was too large, check with your site administrator to adjust the maximum size allowed");
|
||||
}
|
||||
}
|
||||
else if (Umbraco.Sys.ServerVariables["isDebuggingEnabled"] === true) {
|
||||
//show a ysod dialog
|
||||
eventsService.emit('app.ysod',
|
||||
{
|
||||
errorMsg: 'An error occured',
|
||||
data: data
|
||||
data: response.data
|
||||
});
|
||||
}
|
||||
else {
|
||||
//show a simple error notification
|
||||
notificationsService.error("Server error", "Contact administrator, see log for full details.<br/><i>" + data.ExceptionMessage + "</i>");
|
||||
notificationsService.error("Server error", "Contact administrator, see log for full details.<br/><i>" + response.data.ExceptionMessage + "</i>");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
formHelper.showNotifications(response.data);
|
||||
}
|
||||
|
||||
//return an error object including the error message for UI
|
||||
deferred.reject({
|
||||
return $q.reject({
|
||||
errorMsg: 'An error occurred',
|
||||
data: data,
|
||||
status: status
|
||||
data: response.data,
|
||||
status: response.status
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/** Posts a multi-part mime request to the server */
|
||||
postMultiPartRequest: function (url, jsonData, transformCallback, successCallback, failureCallback) {
|
||||
postMultiPartRequest: function (url, jsonData, transformCallback) {
|
||||
|
||||
//validate input, jsonData can be an array of key/value pairs or just one key/value pair.
|
||||
if (!jsonData) { throw "jsonData cannot be null"; }
|
||||
@@ -293,9 +290,8 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
});
|
||||
}
|
||||
else if (!jsonData.key || !jsonData.value) { throw "jsonData object must have both a key and a value property"; }
|
||||
|
||||
|
||||
$http({
|
||||
|
||||
return $http({
|
||||
method: 'POST',
|
||||
url: url,
|
||||
//IMPORTANT!!! You might think this should be set to 'multipart/form-data' but this is not true because when we are sending up files
|
||||
@@ -303,11 +299,11 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
// and setting the Content-type manually will not set this boundary parameter. For whatever reason, setting the Content-type to 'undefined'
|
||||
// will force the request to automatically populate the headers properly including the boundary parameter.
|
||||
headers: { 'Content-Type': undefined },
|
||||
transformRequest: function (data) {
|
||||
transformRequest: function(data) {
|
||||
var formData = new FormData();
|
||||
//add the json data
|
||||
if (angular.isArray(data)) {
|
||||
_.each(data, function (item) {
|
||||
_.each(data, function(item) {
|
||||
formData.append(item.key, !angular.isString(item.value) ? angular.toJson(item.value) : item.value);
|
||||
});
|
||||
}
|
||||
@@ -323,16 +319,10 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
return formData;
|
||||
},
|
||||
data: jsonData
|
||||
}).
|
||||
then(function (response) {
|
||||
if (successCallback) {
|
||||
successCallback.apply(this, [response.data, response.status, response.headers, response.config]);
|
||||
}
|
||||
}).
|
||||
catch(function (response) {
|
||||
if (failureCallback) {
|
||||
failureCallback.apply(this, [response.data, response.status, response.headers, response.config]);
|
||||
}
|
||||
}).then(function(response) {
|
||||
return $q.resolve(response);
|
||||
}, function(response) {
|
||||
return $q.reject(response);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -343,17 +333,15 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
*/
|
||||
downloadFile : function (httpPath) {
|
||||
|
||||
var deferred = $q.defer();
|
||||
|
||||
// Use an arraybuffer
|
||||
$http.get(httpPath, { responseType: 'arraybuffer' })
|
||||
.success(function (data, status, headers) {
|
||||
|
||||
return $http.get(httpPath, { responseType: 'arraybuffer' })
|
||||
.then(function (response) {
|
||||
|
||||
var octetStreamMime = 'application/octet-stream';
|
||||
var success = false;
|
||||
|
||||
// Get the headers
|
||||
headers = headers();
|
||||
var headers = response.headers();
|
||||
|
||||
// Get the filename from the x-filename header or default to "download.bin"
|
||||
var filename = headers['x-filename'] || 'download.bin';
|
||||
@@ -363,8 +351,7 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
|
||||
try {
|
||||
// Try using msSaveBlob if supported
|
||||
console.log("Trying saveBlob method ...");
|
||||
var blob = new Blob([data], { type: contentType });
|
||||
var blob = new Blob([response.data], { type: contentType });
|
||||
if (navigator.msSaveBlob)
|
||||
navigator.msSaveBlob(blob, filename);
|
||||
else {
|
||||
@@ -373,7 +360,6 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
if (saveBlob === undefined) throw "Not supported";
|
||||
saveBlob(blob, filename);
|
||||
}
|
||||
console.log("saveBlob succeeded");
|
||||
success = true;
|
||||
} catch (ex) {
|
||||
console.log("saveBlob method failed with the following exception:");
|
||||
@@ -390,8 +376,7 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
// Try to simulate a click
|
||||
try {
|
||||
// Prepare a blob URL
|
||||
console.log("Trying download link method with simulated click ...");
|
||||
var blob = new Blob([data], { type: contentType });
|
||||
var blob = new Blob([response.data], { type: contentType });
|
||||
var url = urlCreator.createObjectURL(blob);
|
||||
link.setAttribute('href', url);
|
||||
|
||||
@@ -402,7 +387,6 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
var event = document.createEvent('MouseEvents');
|
||||
event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||
link.dispatchEvent(event);
|
||||
console.log("Download link method with simulated click succeeded");
|
||||
success = true;
|
||||
|
||||
} catch (ex) {
|
||||
@@ -416,11 +400,9 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
try {
|
||||
// Prepare a blob URL
|
||||
// Use application/octet-stream when using window.location to force download
|
||||
console.log("Trying download link method with window.location ...");
|
||||
var blob = new Blob([data], { type: octetStreamMime });
|
||||
var blob = new Blob([response.data], { type: octetStreamMime });
|
||||
var url = urlCreator.createObjectURL(blob);
|
||||
window.location = url;
|
||||
console.log("Download link method with window.location succeeded");
|
||||
success = true;
|
||||
} catch (ex) {
|
||||
console.log("Download link method with window.location failed with the following exception:");
|
||||
@@ -433,23 +415,19 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
|
||||
if (!success) {
|
||||
// Fallback to window.open method
|
||||
console.log("No methods worked for saving the arraybuffer, using last resort window.open");
|
||||
window.open(httpPath, '_blank', '');
|
||||
}
|
||||
|
||||
deferred.resolve();
|
||||
})
|
||||
.error(function (data, status) {
|
||||
console.log("Request failed with status: " + status);
|
||||
return $q.resolve();
|
||||
|
||||
deferred.reject({
|
||||
}, function (response) {
|
||||
|
||||
return $q.reject({
|
||||
errorMsg: "An error occurred downloading the file",
|
||||
data: data,
|
||||
status: status
|
||||
data: response.data,
|
||||
status: response.status
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular.module('umbraco.services')
|
||||
.factory('userService', function ($rootScope, eventsService, $q, $location, $log, securityRetryQueue, authResource, dialogService, $timeout, angularHelper, $http) {
|
||||
.factory('userService', function ($rootScope, eventsService, $q, $location, $log, requestRetryQueue, authResource, dialogService, $timeout, angularHelper, $http) {
|
||||
|
||||
var currentUser = null;
|
||||
var lastUserId = null;
|
||||
@@ -32,10 +32,10 @@ angular.module('umbraco.services')
|
||||
loginDialog = null;
|
||||
|
||||
if (success) {
|
||||
securityRetryQueue.retryAll(currentUser.name);
|
||||
requestRetryQueue.retryAll(currentUser.name);
|
||||
}
|
||||
else {
|
||||
securityRetryQueue.cancelAll();
|
||||
requestRetryQueue.cancelAll();
|
||||
$location.path('/');
|
||||
}
|
||||
}
|
||||
@@ -172,8 +172,8 @@ angular.module('umbraco.services')
|
||||
}
|
||||
|
||||
// Register a handler for when an item is added to the retry queue
|
||||
securityRetryQueue.onItemAddedCallbacks.push(function (retryItem) {
|
||||
if (securityRetryQueue.hasMore()) {
|
||||
requestRetryQueue.onItemAddedCallbacks.push(function (retryItem) {
|
||||
if (requestRetryQueue.hasMore()) {
|
||||
userAuthExpired();
|
||||
}
|
||||
});
|
||||
@@ -260,10 +260,10 @@ angular.module('umbraco.services')
|
||||
}
|
||||
|
||||
setCurrentUser(data);
|
||||
|
||||
|
||||
return $q.when(currentUser);
|
||||
}, function () {
|
||||
//it failed, so they are not logged in
|
||||
//it failed, so they are not logged in
|
||||
return $q.reject(currentUser);
|
||||
});
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ LazyLoad.js(
|
||||
'js/umbraco.filters.js',
|
||||
'js/umbraco.resources.js',
|
||||
'js/umbraco.services.js',
|
||||
'js/umbraco.security.js',
|
||||
'js/umbraco.interceptors.js',
|
||||
'js/umbraco.controllers.js',
|
||||
'js/routes.js',
|
||||
'js/init.js'
|
||||
@@ -46,4 +46,4 @@ LazyLoad.js(
|
||||
angular.bootstrap(document, ['umbraco']);
|
||||
});
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
.then(function (data) {
|
||||
|
||||
//success
|
||||
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
$scope.invitedUserPasswordModel.buttonState = "success";
|
||||
//set the user and set them as logged in
|
||||
$scope.invitedUser = data;
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
<div class="umb-list umb-list--condensed" ng-if="!vm.loading">
|
||||
|
||||
<div class="umb-list-item" ng-repeat="variant in vm.variants | filter:vm.dirtyVariantFilter">
|
||||
<div class="umb-list-item" ng-repeat="variant in vm.variants | filter:vm.dirtyVariantFilter track by variant.compositeId">
|
||||
<ng-form name="publishVariantSelectorForm">
|
||||
<label class="flex" for="{{variant.htmlId}}">
|
||||
<div class="flex">
|
||||
<input id="{{variant.htmlId}}"
|
||||
name="publishVariantSelector"
|
||||
type="checkbox"
|
||||
@@ -22,14 +22,16 @@
|
||||
style="margin-right: 8px;"
|
||||
val-server-field="{{variant.htmlId}}" />
|
||||
<div>
|
||||
<div ng-class="{'bold': variant.published}" style="margin-bottom: 2px;">{{ variant.language.name }}</div>
|
||||
<div class="umb-permission__description" ng-if="!variant.validationError && variant.isEdited && variant.state === 'Published'"><localize key="content_publishedPendingChanges"></localize></div>
|
||||
<div class="umb-permission__description" ng-if="!variant.validationError && variant.isEdited && variant.state === 'Unpublished'"><localize key="content_unpublishedPendingChanges"></localize></div>
|
||||
<div class="umb-permission__description" ng-if="!variant.validationError && variant.isEdited === false">{{ variant.state }}</div>
|
||||
|
||||
<label for="{{variant.htmlId}}">
|
||||
<span ng-class="{'bold': variant.published}" style="margin-bottom: 2px;">{{ variant.language.name }}</span>
|
||||
</label>
|
||||
<div class="umb-permission__description" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && variant.isEdited && variant.state === 'Published'"><localize key="content_publishedPendingChanges"></localize></div>
|
||||
<div class="umb-permission__description" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && variant.isEdited && variant.state === 'Unpublished'"><localize key="content_unpublishedPendingChanges"></localize></div>
|
||||
<div class="umb-permission__description" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && variant.isEdited === false">{{ variant.state }}</div>
|
||||
<div class="umb-permission__description" style="color: #F02E28;" val-msg-for="publishVariantSelector" val-toggle-msg="valServerField"></div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</ng-form>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
@@ -147,7 +147,7 @@ angular.module("umbraco")
|
||||
$scope.changePasswordModel.value.generatedPassword = data.value;
|
||||
}
|
||||
|
||||
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
|
||||
$scope.changePasswordButtonState = "success";
|
||||
$timeout(function() {
|
||||
|
||||
@@ -100,13 +100,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.CopyController",
|
||||
}, function (err) {
|
||||
$scope.success = false;
|
||||
$scope.error = err;
|
||||
$scope.busy = false;
|
||||
//show any notifications
|
||||
if (angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
$scope.busy = false;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
contentResource.createBlueprintFromContent($scope.currentNode.id, $scope.message.name)
|
||||
.then(function(data) {
|
||||
|
||||
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
|
||||
navigationService.hideMenu();
|
||||
},
|
||||
|
||||
@@ -54,12 +54,6 @@ function ContentDeleteController($scope, contentResource, treeService, navigatio
|
||||
if (err.status && err.status >= 500) {
|
||||
dialogService.ysodDialog(err);
|
||||
}
|
||||
|
||||
if (err.data && angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -20,14 +20,7 @@ function ContentEmptyRecycleBinController($scope, contentResource, treeService,
|
||||
|
||||
$scope.busy = false;
|
||||
$scope.currentNode.loading = false;
|
||||
|
||||
//show any notifications
|
||||
if (angular.isArray(result.notifications)) {
|
||||
for (var i = 0; i < result.notifications.length; i++) {
|
||||
notificationsService.showNotification(result.notifications[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
treeService.removeChildNodes($scope.currentNode);
|
||||
navigationService.hideMenu();
|
||||
|
||||
|
||||
@@ -102,12 +102,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.MoveController",
|
||||
$scope.success = false;
|
||||
$scope.error = err;
|
||||
$scope.busy = false;
|
||||
//show any notifications
|
||||
if (angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ function DataTypeEditController($scope, $routeParams, $location, appState, navig
|
||||
dataTypeResource.save($scope.content, $scope.preValues, $routeParams.create)
|
||||
.then(function(data) {
|
||||
|
||||
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
|
||||
@@ -51,12 +51,7 @@ angular.module("umbraco")
|
||||
$scope.success = false;
|
||||
$scope.error = err;
|
||||
$scope.busy = false;
|
||||
//show any notifications
|
||||
if (angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -46,12 +46,7 @@ angular.module("umbraco")
|
||||
$scope.success = false;
|
||||
$scope.error = err;
|
||||
$scope.busy = false;
|
||||
//show any notifications
|
||||
if (angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -40,9 +40,7 @@ function DocumentTypesCreateController($scope, $location, navigationService, con
|
||||
activate: true
|
||||
});
|
||||
|
||||
formHelper.resetForm({
|
||||
scope: $scope
|
||||
});
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
|
||||
var section = appState.getSectionState("currentSection");
|
||||
|
||||
@@ -50,12 +48,6 @@ function DocumentTypesCreateController($scope, $location, navigationService, con
|
||||
|
||||
$scope.error = err;
|
||||
|
||||
//show any notifications
|
||||
if (angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -51,12 +51,7 @@ angular.module("umbraco")
|
||||
$scope.success = false;
|
||||
$scope.error = err;
|
||||
$scope.busy = false;
|
||||
//show any notifications
|
||||
if (angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
angular.module("umbraco")
|
||||
.controller("Umbraco.Editors.ContentTypeContainers.RenameController",
|
||||
[
|
||||
"$scope",
|
||||
"$injector",
|
||||
"navigationService",
|
||||
"notificationsService",
|
||||
"localizationService",
|
||||
function (scope, injector, navigationService, notificationsService, localizationService) {
|
||||
function(scope, injector, navigationService, notificationsService, localizationService) {
|
||||
var notificationHeader;
|
||||
|
||||
function reportSuccessAndClose(treeName) {
|
||||
@@ -25,7 +19,7 @@
|
||||
localizationService.localize(
|
||||
"renamecontainer_folderWasRenamed",
|
||||
[scope.currentNode.name, scope.model.folderName])
|
||||
.then(function (msg) {
|
||||
.then(function(msg) {
|
||||
notificationsService.showNotification({
|
||||
type: 0,
|
||||
header: notificationHeader,
|
||||
@@ -37,27 +31,21 @@
|
||||
}
|
||||
|
||||
localizationService.localize("renamecontainer_renamed")
|
||||
.then(function (s) { notificationHeader = s; });
|
||||
.then(function(s) { notificationHeader = s; });
|
||||
|
||||
scope.model = {
|
||||
folderName: scope.currentNode.name
|
||||
}
|
||||
|
||||
scope.renameContainer = function (resourceKey, treeName) {
|
||||
scope.renameContainer = function(resourceKey, treeName) {
|
||||
var resource = injector.get(resourceKey);
|
||||
|
||||
resource.renameContainer(scope.currentNode.id, scope.model.folderName)
|
||||
.then(function () {
|
||||
.then(function() {
|
||||
reportSuccessAndClose(treeName);
|
||||
}, function (err) {
|
||||
}, function(err) {
|
||||
scope.error = err;
|
||||
|
||||
if (angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]);
|
||||
);
|
||||
|
||||
@@ -85,9 +85,7 @@
|
||||
|
||||
languageResource.save(vm.language).then(function (lang) {
|
||||
|
||||
formHelper.resetForm({
|
||||
scope: $scope
|
||||
});
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
|
||||
vm.language = lang;
|
||||
vm.page.saveButtonState = "success";
|
||||
@@ -108,12 +106,6 @@
|
||||
|
||||
formHelper.handleError(err);
|
||||
|
||||
//show any notifications
|
||||
if (angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -70,12 +70,6 @@
|
||||
}, function (err) {
|
||||
language.deleteButtonState = "error";
|
||||
|
||||
//show any notifications
|
||||
if (angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -56,11 +56,6 @@ function MediaDeleteController($scope, mediaResource, treeService, navigationSer
|
||||
dialogService.ysodDialog(err);
|
||||
}
|
||||
|
||||
if (err.data && angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ function mediaEditController($scope, $routeParams, appState, mediaResource, enti
|
||||
mediaResource.save($scope.content, create, fileManager.getFiles())
|
||||
.then(function(data) {
|
||||
|
||||
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
@@ -226,13 +226,6 @@ function mediaEditController($scope, $routeParams, appState, mediaResource, enti
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data)
|
||||
});
|
||||
|
||||
//show any notifications
|
||||
if (angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
|
||||
editorState.set($scope.content);
|
||||
$scope.busy = false;
|
||||
$scope.page.saveButtonState = "error";
|
||||
|
||||
@@ -21,13 +21,6 @@ function MediaEmptyRecycleBinController($scope, mediaResource, treeService, navi
|
||||
$scope.busy = false;
|
||||
$scope.currentNode.loading = false;
|
||||
|
||||
//show any notifications
|
||||
if (angular.isArray(result.notifications)) {
|
||||
for (var i = 0; i < result.notifications.length; i++) {
|
||||
notificationsService.showNotification(result.notifications[i]);
|
||||
}
|
||||
}
|
||||
|
||||
treeService.removeChildNodes($scope.currentNode);
|
||||
navigationService.hideMenu();
|
||||
|
||||
|
||||
@@ -46,12 +46,7 @@ angular.module("umbraco")
|
||||
$scope.success = false;
|
||||
$scope.error = err;
|
||||
$scope.busy = false;
|
||||
//show any notifications
|
||||
if (angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -52,12 +52,7 @@ angular.module("umbraco")
|
||||
$scope.success = false;
|
||||
$scope.error = err;
|
||||
$scope.busy = false;
|
||||
//show any notifications
|
||||
if (angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ function MemberEditController($scope, $routeParams, $location, $q, $window, appS
|
||||
memberResource.save($scope.content, $routeParams.create, fileManager.getFiles())
|
||||
.then(function(data) {
|
||||
|
||||
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
|
||||
@@ -67,7 +67,7 @@ function MemberGroupsEditController($scope, $routeParams, appState, navigationSe
|
||||
memberGroupResource.save($scope.content, $scope.preValues, $routeParams.create)
|
||||
.then(function (data) {
|
||||
|
||||
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
|
||||
@@ -45,18 +45,14 @@
|
||||
activate: true
|
||||
});
|
||||
|
||||
formHelper.resetForm({
|
||||
scope: $scope
|
||||
});
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
|
||||
var section = appState.getSectionState("currentSection");
|
||||
|
||||
}, function (err) {
|
||||
|
||||
vm.createFolderError = err;
|
||||
|
||||
//show any notifications
|
||||
formHelper.showNotifications(err.data);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,11 +71,7 @@
|
||||
if($routeParams.create && $routeParams.nomacro !== "true") {
|
||||
macroResource.createPartialViewMacroWithFile(saved.virtualPath, saved.name).then(function(created) {
|
||||
completeSave(saved);
|
||||
}, function(err) {
|
||||
//show any notifications
|
||||
formHelper.showNotifications(err.data);
|
||||
|
||||
});
|
||||
}, angular.noop);
|
||||
} else {
|
||||
completeSave(saved);
|
||||
}
|
||||
|
||||
@@ -55,17 +55,13 @@
|
||||
activate: true
|
||||
});
|
||||
|
||||
formHelper.resetForm({
|
||||
scope: $scope
|
||||
});
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
|
||||
var section = appState.getSectionState("currentSection");
|
||||
|
||||
}, function(err) {
|
||||
|
||||
vm.createFolderError = err;
|
||||
|
||||
formHelper.showNotifications(err.data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,12 +216,8 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific
|
||||
if (reload === true) {
|
||||
$scope.reloadView($scope.contentId, true);
|
||||
}
|
||||
|
||||
if (err.data && angular.isArray(err.data.notifications)) {
|
||||
for (var i = 0; i < err.data.notifications.length; i++) {
|
||||
notificationsService.showNotification(err.data.notifications[i]);
|
||||
}
|
||||
} else if (successMsg) {
|
||||
|
||||
if (successMsg) {
|
||||
localizationService.localize("bulk_done")
|
||||
.then(function(v) {
|
||||
notificationsService.success(v, successMsg);
|
||||
|
||||
@@ -39,16 +39,13 @@
|
||||
activate: true
|
||||
});
|
||||
|
||||
formHelper.resetForm({
|
||||
scope: $scope
|
||||
});
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
|
||||
var section = appState.getSectionState("currentSection");
|
||||
|
||||
}, function(err) {
|
||||
|
||||
vm.createFolderError = err;
|
||||
formHelper.showNotifications(err.data);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -138,11 +138,8 @@
|
||||
//if the user saved, then try to execute all extended save options
|
||||
extendedSave(saved).then(function(result) {
|
||||
//if all is good, then reset the form
|
||||
formHelper.resetForm({ scope: $scope, notifications: saved.notifications });
|
||||
}, function(err) {
|
||||
//otherwise show the notifications for the user being saved
|
||||
formHelper.showNotifications(saved);
|
||||
});
|
||||
formHelper.resetForm({ scope: $scope });
|
||||
}, angular.noop);
|
||||
|
||||
vm.user = _.omit(saved, "navigation");
|
||||
//restore
|
||||
@@ -162,10 +159,7 @@
|
||||
redirectOnFailure: false,
|
||||
err: err
|
||||
});
|
||||
//show any notifications
|
||||
if (err.data) {
|
||||
formHelper.showNotifications(err.data);
|
||||
}
|
||||
|
||||
vm.page.saveButtonState = "error";
|
||||
});
|
||||
}
|
||||
@@ -319,10 +313,10 @@
|
||||
vm.user.userState = 1;
|
||||
setUserDisplayState();
|
||||
vm.disableUserButtonState = "success";
|
||||
formHelper.showNotifications(data);
|
||||
|
||||
}, function (error) {
|
||||
vm.disableUserButtonState = "error";
|
||||
formHelper.showNotifications(error.data);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -332,10 +326,8 @@
|
||||
vm.user.userState = 0;
|
||||
setUserDisplayState();
|
||||
vm.enableUserButtonState = "success";
|
||||
formHelper.showNotifications(data);
|
||||
}, function (error) {
|
||||
vm.enableUserButtonState = "error";
|
||||
formHelper.showNotifications(error.data);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -345,10 +337,8 @@
|
||||
vm.user.userState = 0;
|
||||
setUserDisplayState();
|
||||
vm.unlockUserButtonState = "success";
|
||||
formHelper.showNotifications(data);
|
||||
}, function (error) {
|
||||
vm.unlockUserButtonState = "error";
|
||||
formHelper.showNotifications(error.data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -96,10 +96,7 @@
|
||||
userGroupsResource.deleteUserGroups(vm.selection).then(function (data) {
|
||||
clearSelection();
|
||||
onInit();
|
||||
formHelper.showNotifications(data);
|
||||
}, function(error) {
|
||||
formHelper.showNotifications(error.data);
|
||||
});
|
||||
}, angular.noop);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -250,14 +250,11 @@
|
||||
// show the correct badges
|
||||
setUserDisplayState(vm.users);
|
||||
|
||||
formHelper.showNotifications(data);
|
||||
|
||||
vm.disableUserButtonState = "init";
|
||||
clearSelection();
|
||||
|
||||
}, function (error) {
|
||||
vm.disableUserButtonState = "error";
|
||||
formHelper.showNotifications(error.data);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -273,13 +270,10 @@
|
||||
});
|
||||
// show the correct badges
|
||||
setUserDisplayState(vm.users);
|
||||
// show notification
|
||||
formHelper.showNotifications(data);
|
||||
vm.enableUserButtonState = "init";
|
||||
clearSelection();
|
||||
}, function (error) {
|
||||
vm.enableUserButtonState = "error";
|
||||
formHelper.showNotifications(error.data);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -295,13 +289,10 @@
|
||||
});
|
||||
// show the correct badges
|
||||
setUserDisplayState(vm.users);
|
||||
// show notification
|
||||
formHelper.showNotifications(data);
|
||||
vm.unlockUserButtonState = "init";
|
||||
clearSelection();
|
||||
}, function (error) {
|
||||
vm.unlockUserButtonState = "error";
|
||||
formHelper.showNotifications(error.data);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -334,11 +325,8 @@
|
||||
vm.selectedBulkUserGroups = [];
|
||||
vm.userGroupPicker.show = false;
|
||||
vm.userGroupPicker = null;
|
||||
formHelper.showNotifications(data);
|
||||
clearSelection();
|
||||
}, function (error) {
|
||||
formHelper.showNotifications(error.data);
|
||||
});
|
||||
}, angular.noop);
|
||||
},
|
||||
close: function (oldModel) {
|
||||
vm.selectedBulkUserGroups = [];
|
||||
|
||||
@@ -4,11 +4,11 @@ var app = angular.module('umbraco', [
|
||||
'umbraco.resources',
|
||||
'umbraco.services',
|
||||
'umbraco.mocks',
|
||||
'umbraco.security',
|
||||
'umbraco.interceptors',
|
||||
'ngCookies',
|
||||
'LocalStorageModule'
|
||||
]);
|
||||
|
||||
/* For Angular 1.2: we need to load in Routing separately
|
||||
'ngRoute'
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
'js/umbraco.directives.js',
|
||||
'js/umbraco.filters.js',
|
||||
'js/umbraco.services.js',
|
||||
'js/umbraco.security.js',
|
||||
'js/umbraco.interceptors.js',
|
||||
'js/umbraco.controllers.js',
|
||||
'js/routes.js',
|
||||
'js/init.js'
|
||||
|
||||
Reference in New Issue
Block a user