diff --git a/src/Umbraco.Core/Constants-PropertyEditors.cs b/src/Umbraco.Core/Constants-PropertyEditors.cs index 063bb7b27f..203c27fc2d 100644 --- a/src/Umbraco.Core/Constants-PropertyEditors.cs +++ b/src/Umbraco.Core/Constants-PropertyEditors.cs @@ -197,6 +197,11 @@ namespace Umbraco.Core /// public const string MemberPickerAlias = "Umbraco.MemberPicker"; + /// + /// Alias for the Member Group Picker datatype. + /// + public const string MemberGroupPickerAlias = "Umbraco.MemberGroupPicker"; + /// /// Guid for the Multi-Node Tree Picker datatype /// diff --git a/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js b/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js index 842f6ff7c3..c937d30ae7 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js @@ -373,6 +373,25 @@ angular.module('umbraco.services') options.show = true; return openDialog(options); }, + + /** + * @ngdoc method + * @name umbraco.services.dialogService#memberGroupPicker + * @methodOf umbraco.services.dialogService + * + * @description + * Opens a member group picker in a modal, the callback returns a object representing the selected member + * @param {Object} options member group picker dialog options object + * @param {$scope} options.scope dialog scope + * @param {$scope} options.multiPicker should the tree pick one or multiple members before returning + * @param {Function} options.callback callback function + * @returns {Object} modal object + */ + memberGroupPicker: function (options) { + options.template = 'views/common/dialogs/memberGroupPicker.html'; + options.show = true; + return openDialog(options); + }, /** * @ngdoc method diff --git a/src/Umbraco.Web.UI.Client/src/common/services/user.service.js b/src/Umbraco.Web.UI.Client/src/common/services/user.service.js index 1808d30660..06cc7289b3 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/user.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/user.service.js @@ -1,5 +1,5 @@ angular.module('umbraco.services') -.factory('userService', function ($rootScope, $q, $location, $log, securityRetryQueue, authResource, dialogService, $timeout) { +.factory('userService', function ($rootScope, $q, $location, $log, securityRetryQueue, authResource, dialogService, $timeout, angularHelper) { var currentUser = null; var lastUserId = null; @@ -60,8 +60,8 @@ angular.module('umbraco.services') this will continually count down their current remaining seconds every 2 seconds until there are no more seconds remaining. */ - function countdownUserTimeout() { - $timeout(function () { + function countdownUserTimeout() { + $timeout(function() { if (currentUser) { //countdown by 2 seconds since that is how long our timer is for. currentUser.remainingAuthSeconds -= 2; @@ -90,12 +90,17 @@ angular.module('umbraco.services') countdownUserTimeout(); } else { - + //we are either timed out or very close to timing out so we need to show the login dialog. - userAuthExpired(); + //NOTE: the safeApply because our timeout is set to not run digests (performance reasons) + angularHelper.safeApply($rootScope, function() { + userAuthExpired(); + }); + } - } - }, 2000);//every 2 seconds + } + }, 2000, //every 2 seconds + false); //false = do NOT execute a digest for every iteration } /** Called to update the current user's timeout */ diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.controller.js index ab7fa18867..78258427d2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.controller.js @@ -10,7 +10,7 @@ * signs the user in */ var d = new Date(); - var weekday = new Array("Super Sunday", "Manic Monday", "Tremendous Tuesday", "Wonderfull Wednesday", "Thunder Thursday", "Friendly Friday", "Shiny Saturday"); + var weekday = new Array("Super Sunday", "Manic Monday", "Tremendous Tuesday", "Wonderful Wednesday", "Thunder Thursday", "Friendly Friday", "Shiny Saturday"); $scope.today = weekday[d.getDay()]; $scope.errorMsg = ""; @@ -56,4 +56,4 @@ } }); }; -}); \ No newline at end of file +}); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.controller.js new file mode 100644 index 0000000000..d7d85a4142 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.controller.js @@ -0,0 +1,55 @@ +//used for the member picker dialog +angular.module("umbraco").controller("Umbraco.Dialogs.MemberGroupPickerController", + function($scope, eventsService, entityResource, searchService, $log) { + var dialogOptions = $scope.$parent.dialogOptions; + $scope.dialogTreeEventHandler = $({}); + $scope.results = []; + + /** Method used for selecting a node */ + function select(text, id, entity) { + + + $scope.showSearch = false; + $scope.results = []; + $scope.term = ""; + $scope.oldTerm = undefined; + + if (dialogOptions.multiPicker) { + $scope.select(id); + } + else { + $scope.submit(id); + + } + } + + + $scope.dialogTreeEventHandler.bind("treeNodeSelect", function(ev, args) { + args.event.preventDefault(); + args.event.stopPropagation(); + + + eventsService.publish("Umbraco.Dialogs.MemberGroupPickerController.Select", args).then(function(a) { + + //This is a tree node, so we don't have an entity to pass in, it will need to be looked up + //from the server in this method. + select(a.node.name, a.node.id); + + if (dialogOptions && dialogOptions.multipicker) { + + var c = $(a.event.target.parentElement); + if (!a.node.selected) { + a.node.selected = true; + c.find("i.umb-tree-icon").hide() + .after(""); + } + else { + a.node.selected = false; + c.find(".temporary").remove(); + c.find("i.umb-tree-icon").show(); + } + } + }); + + }); + }); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.html new file mode 100644 index 0000000000..6a8a0e3551 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.html @@ -0,0 +1,37 @@ +
+ + + + +
\ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js index ceac0f36f4..877ad7d351 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js @@ -1,5 +1,5 @@ angular.module("umbraco") - .controller("Umbraco.Dialogs.UserController", function ($scope, $location, userService, historyService) { + .controller("Umbraco.Dialogs.UserController", function ($scope, $location, $timeout, userService, historyService) { $scope.user = userService.getCurrentUser(); $scope.history = historyService.current; @@ -13,5 +13,17 @@ angular.module("umbraco") $scope.gotoHistory = function (link) { $location.path(link); $scope.hide(); - }; -}); \ No newline at end of file + }; + + //Manually update the remaining timeout seconds + function updateTimeout() { + $timeout(function () { + $scope.user = userService.getCurrentUser(); + //manually execute the digest against this scope only + $scope.$digest(); + updateTimeout(); //keep going (recurse) + }, 1000, false); // 1 second, do NOT execute a global digest + } + updateTimeout(); + + }); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/default/StartupDashboardVideos.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/default/StartupDashboardVideos.html index 9e72ea5f01..2135c37859 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/default/StartupDashboardVideos.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/default/StartupDashboardVideos.html @@ -3,7 +3,7 @@

To get you started: