Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0
This commit is contained in:
@@ -197,6 +197,11 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string MemberPickerAlias = "Umbraco.MemberPicker";
|
||||
|
||||
/// <summary>
|
||||
/// Alias for the Member Group Picker datatype.
|
||||
/// </summary>
|
||||
public const string MemberGroupPickerAlias = "Umbraco.MemberGroupPicker";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Multi-Node Tree Picker datatype
|
||||
/// </summary>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 @@
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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("<i class='icon umb-tree-icon sprTree icon-check blue temporary'></i>");
|
||||
}
|
||||
else {
|
||||
a.node.selected = false;
|
||||
c.find(".temporary").remove();
|
||||
c.find("i.umb-tree-icon").show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
<div class="umb-panel" ng-controller="Umbraco.Dialogs.MemberGroupPickerController">
|
||||
|
||||
<div class="umb-panel-body with-footer">
|
||||
|
||||
|
||||
<div ng-hide="showSearch">
|
||||
<umb-tree
|
||||
section="member"
|
||||
treealias="memberGroup"
|
||||
cachekey="membergrouppickerDialog"
|
||||
showheader="false"
|
||||
showoptions="false"
|
||||
isdialog="true"
|
||||
eventhandler="dialogTreeEventHandler">
|
||||
</umb-tree>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-panel-footer" >
|
||||
<div class="umb-el-wrap umb-panel-buttons">
|
||||
<div class="btn-toolbar umb-btn-toolbar pull-right">
|
||||
|
||||
<a href ng-click="close()" class="btn btn-link">
|
||||
<localize key="general_cancel">Cancel</localize>
|
||||
</a>
|
||||
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
ng-show="multipicker"
|
||||
ng-click="submit(dialogData)">
|
||||
<localize key="buttons_select">Select</localize>({{dialogData.selection.length}})
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -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();
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
//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();
|
||||
|
||||
});
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<h4>To get you started:</h4>
|
||||
<div class="row-fluid"
|
||||
ng-init="init('http://umbraco.tv/videos/implementor/rss')"
|
||||
ng-init="init('http://umbraco.tv/videos/implementor/chapterrss?sort=no')"
|
||||
ng-controller="Umbraco.Dashboard.StartupVideosController">
|
||||
|
||||
<ul class="thumbnails" >
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<h4>To get you started:</h4>
|
||||
<div class="row-fluid"
|
||||
ng-init="init('http://umbraco.tv/videos/developer/rss')"
|
||||
ng-init="init('http://umbraco.tv/videos/developer/chapterrss?sort=no')"
|
||||
ng-controller="Umbraco.Dashboard.StartupVideosController">
|
||||
|
||||
<ul class="thumbnails" >
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<h4>To get you started:</h4>
|
||||
<div class="row-fluid"
|
||||
ng-init="init('http://umbraco.tv/videos/implementor/rss')"
|
||||
ng-init="init('http://umbraco.tv/videos/implementor/chapterrss?sort=no')"
|
||||
ng-controller="Umbraco.Dashboard.StartupVideosController">
|
||||
|
||||
<ul class="thumbnails" >
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<h4>To get you started:</h4>
|
||||
<div class="row-fluid"
|
||||
ng-init="init('http://umbraco.tv/videos/developer/rss')"
|
||||
ng-init="init('http://umbraco.tv/videos/implementor/chapterrss?sort=no')"
|
||||
ng-controller="Umbraco.Dashboard.StartupVideosController">
|
||||
|
||||
<ul class="thumbnails" >
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
//this controller simply tells the dialogs service to open a memberPicker window
|
||||
//with a specified callback, this callback will receive an object with a selection on it
|
||||
angular.module('umbraco')
|
||||
.controller("Umbraco.PropertyEditors.MemberGroupPickerController",
|
||||
|
||||
function($scope, dialogService, entityResource, $log, iconHelper){
|
||||
$scope.renderModel = [];
|
||||
$scope.ids = $scope.model.value.split(',');
|
||||
|
||||
$scope.cfg = {multiPicker: false, entityType: "MemberGroup", type: "membergroup", treeAlias: "memberGroup", filter: ""};
|
||||
if($scope.model.config){
|
||||
$scope.cfg = angular.extend($scope.cfg, $scope.model.config);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$scope.openMemberGroupPicker =function(){
|
||||
var d = dialogService.memberGroupPicker(
|
||||
{
|
||||
scope: $scope,
|
||||
multiPicker: $scope.cfg.multiPicker,
|
||||
filter: $scope.cfg.filter,
|
||||
filterCssClass: "not-allowed",
|
||||
callback: populate}
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
$scope.remove =function(index){
|
||||
$scope.renderModel.splice(index, 1);
|
||||
$scope.ids.splice(index, 1);
|
||||
$scope.model.value = trim($scope.ids.join(), ",");
|
||||
};
|
||||
|
||||
$scope.add =function(item){
|
||||
if($scope.ids.indexOf(item) < 0){
|
||||
//item.icon = iconHelper.convertFromLegacyIcon(item.icon);
|
||||
|
||||
$scope.ids.push(item);
|
||||
$scope.renderModel.push({ name: item, id: item, icon: 'icon-users' });
|
||||
$scope.model.value = trim($scope.ids.join(), ",");
|
||||
}
|
||||
};
|
||||
|
||||
$scope.clear = function() {
|
||||
$scope.model.value = "";
|
||||
$scope.renderModel = [];
|
||||
$scope.ids = [];
|
||||
};
|
||||
|
||||
|
||||
$scope.sortableOptions = {
|
||||
update: function(e, ui) {
|
||||
var r = [];
|
||||
angular.forEach($scope.renderModel, function(value, key){
|
||||
r.push(value.id);
|
||||
});
|
||||
|
||||
$scope.ids = r;
|
||||
$scope.model.value = trim($scope.ids.join(), ",");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$scope.$on("formSubmitting", function (ev, args) {
|
||||
$scope.model.value = trim($scope.ids.join(), ",");
|
||||
});
|
||||
|
||||
|
||||
|
||||
function trim(str, chr) {
|
||||
var rgxtrim = (!chr) ? new RegExp('^\\s+|\\s+$', 'g') : new RegExp('^'+chr+'+|'+chr+'+$', 'g');
|
||||
return str.replace(rgxtrim, '');
|
||||
}
|
||||
|
||||
|
||||
function populate(data){
|
||||
if(angular.isArray(data)){
|
||||
$(data).each(function(i, item){
|
||||
$scope.add(item);
|
||||
});
|
||||
}else{
|
||||
$scope.clear();
|
||||
$scope.add(data);
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
<div ng-controller="Umbraco.PropertyEditors.MemberGroupPickerController" class="umb-editor umb-membergrouppicker">
|
||||
|
||||
|
||||
<ul class="unstyled"
|
||||
ui-sortable="sortableOptions"
|
||||
ng-model="renderModel">
|
||||
<li ng-repeat="node in renderModel">
|
||||
|
||||
<i class="icon icon-navigation handle"></i>
|
||||
|
||||
<a href="#" prevent-default ng-click="remove($index)">
|
||||
<i class="icon icon-delete red hover-show"></i>
|
||||
<i class="{{node.icon}} hover-hide"></i>
|
||||
{{node.name}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="unstyled">
|
||||
<li>
|
||||
<a href="#" ng-click="openMemberGroupPicker()" prevent-default>
|
||||
<i class="icon icon-add"></i> <localize key="general_add">Add</localize>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
[PropertyEditor(Constants.PropertyEditors.MemberGroupPickerAlias, "Member Group Picker", "membergrouppicker")]
|
||||
public class MemberGroupPickerPropertyEditor : PropertyEditor
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -345,6 +345,7 @@
|
||||
<Compile Include="PropertyEditors\EmailAddressPropertyEditor.cs" />
|
||||
<Compile Include="PropertyEditors\ListViewPropertyEditor.cs" />
|
||||
<Compile Include="PropertyEditors\MacroContainerPropertyEditor.cs" />
|
||||
<Compile Include="PropertyEditors\MemberGroupPickerPropertyEditor.cs" />
|
||||
<Compile Include="PropertyEditors\MemberPickerPropertyEditor.cs" />
|
||||
<Compile Include="PropertyEditors\MultiNodeTreePickerPropertyEditor.cs" />
|
||||
<Compile Include="PropertyEditors\ParameterEditors\ContentTypeParameterEditor.cs" />
|
||||
|
||||
Reference in New Issue
Block a user