diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbcontentgrid.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbcontentgrid.directive.js index 3994770c8e..f226d924af 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbcontentgrid.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbcontentgrid.directive.js @@ -117,9 +117,11 @@ Use this directive to generate a list of content items presented as a flexbox gr }; scope.clickItemName = function(item, $event, $index) { - if(scope.onClickName) { + if(scope.onClickName && !($event.metaKey || $event.ctrlKey)) { scope.onClickName(item, $event, $index); + $event.preventDefault(); } + $event.stopPropagation(); }; } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbtable.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbtable.directive.js index ae41073c0d..3f1929e97d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbtable.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbtable.directive.js @@ -117,10 +117,11 @@ var vm = this; vm.clickItem = function (item, $event) { - if (vm.onClick) { + if (vm.onClick && !($event.metaKey || $event.ctrlKey)) { vm.onClick({ item: item}); - $event.stopPropagation(); + $event.preventDefault(); } + $event.stopPropagation(); }; vm.selectItem = function (item, $index, $event) { diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less index 88988485fe..8c0df988d1 100644 --- a/src/Umbraco.Web.UI.Client/src/less/belle.less +++ b/src/Umbraco.Web.UI.Client/src/less/belle.less @@ -167,6 +167,7 @@ @import "components/umb-property-file-upload.less"; @import "components/users/umb-user-cards.less"; +@import "components/users/umb-user-table.less"; @import "components/users/umb-user-details.less"; @import "components/users/umb-user-group-picker-list.less"; @import "components/users/umb-user-group-preview.less"; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-content-grid.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-content-grid.less index d2fa2be0c7..2a4a3be2e4 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-content-grid.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-content-grid.less @@ -13,7 +13,6 @@ user-select: none; box-shadow: 0 1px 1px 0 rgba(0,0,0,0.16); border-radius: 3px; - } .umb-content-grid__item.-selected { @@ -59,7 +58,8 @@ display: inline-flex; color: @ui-option-type; - &:hover { + &:hover, &:focus { + text-decoration: none; color:@ui-option-type-hover; } } diff --git a/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-cards.less b/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-cards.less index e24f68078b..190f977880 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-cards.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-cards.less @@ -17,6 +17,10 @@ outline: none; text-decoration: none !important; } + +.umb-user-card.-selectable { + cursor: pointer; +} .umb-user-card.-selected { &::before { content: ""; @@ -31,7 +35,6 @@ box-shadow: 0 0 4px 0 darken(@ui-selected-border, 20), inset 0 0 2px 0 darken(@ui-selected-border, 20); pointer-events: none; } - } .umb-user-card__content { @@ -44,14 +47,18 @@ box-sizing: border-box; display: flex; flex-direction: column; - cursor: pointer; max-width: 100%; } .umb-user-card__goToUser { - &:hover { + &:hover, &:focus { + text-decoration: none; .umb-user-card__name { - text-decoration: underline; + text-decoration: underline; + color: @ui-option-type-hover; + } + .umb-avatar { + border: 1px solid @ui-option-type-hover; } } } diff --git a/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-table.less b/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-table.less new file mode 100644 index 0000000000..1fcaf04183 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-table.less @@ -0,0 +1,73 @@ +.umb-user-table { + + .umb-user-table-col-avatar { + flex: 0 0 32px; + padding: 15px 0; + } + + .umb-table-cell a { + &:hover, &:focus { + .umb-avatar { + border: 1px solid @ui-option-type-hover; + } + } + } + + .umb-table-body .umb-table-cell.umb-table__name { + margin: 0; + padding: 0; + a { + display: flex; + padding: 6px 2px; + height: 42px; + span { + margin: auto 14px; + } + } + } + .umb-table-cell.umb-table__name a { + &:hover, &:focus { + text-decoration: underline; + } + } + + .umb-user-table-row { + cursor: default; + .umb-checkmark { + visibility: hidden; + } + } + + .umb-user-table-row.-selectable { + cursor: pointer; + + + } + + .umb-user-table-row.-selectable:hover { + .umb-checkmark { + visibility: visible; + } + } + + .umb-user-table-row.-selected { + + .umb-checkmark { + visibility: visible; + } + + &::before { + content: ""; + position: absolute; + z-index:1; + top: 1px; + left: 1px; + right: 1px; + bottom: 1px; + border: 2px solid @ui-selected-border; + box-shadow: 0 0 2px 0 fade(@ui-selected-border, 80%); + pointer-events: none; + } + } + +} diff --git a/src/Umbraco.Web.UI.Client/src/less/listview.less b/src/Umbraco.Web.UI.Client/src/less/listview.less index 8b5a295752..c77e4fd1a4 100644 --- a/src/Umbraco.Web.UI.Client/src/less/listview.less +++ b/src/Umbraco.Web.UI.Client/src/less/listview.less @@ -30,7 +30,7 @@ position: absolute; padding: 5px 8px; pointer-events: none; - top: 0; + top: 2px; } input[type="text"] { diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-content-grid.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-content-grid.html index 487be4af87..ce85537d7c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-content-grid.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-content-grid.html @@ -10,10 +10,13 @@
-
+ {{ item.name }} -
+
- diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.listviewlayout.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.listviewlayout.controller.js index 9a28627aa1..292ca3f975 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.listviewlayout.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.listviewlayout.controller.js @@ -9,7 +9,7 @@ (function () { "use strict"; - function ListViewGridLayoutController($scope, $routeParams, mediaHelper, mediaResource, $location, listViewHelper, mediaTypeHelper) { + function ListViewGridLayoutController($scope, mediaHelper, $location, listViewHelper, mediaTypeHelper) { var vm = this; var umbracoSettings = Umbraco.Sys.ServerVariables.umbracoSettings; @@ -115,7 +115,7 @@ function selectFolder(folder, $event, $index) { listViewHelper.selectHandler(folder, $index, $scope.folders, $scope.selection, $event); } - + function goToItem(item, $event, $index) { $location.path($scope.entityType + '/' + $scope.entityType + '/edit/' + item.id); } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/list/list.listviewlayout.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/list/list.listviewlayout.controller.js index b796da8d0f..f26f077e66 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/list/list.listviewlayout.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/list/list.listviewlayout.controller.js @@ -19,7 +19,7 @@ vm.activeDrag = false; vm.isRecycleBin = $scope.contentId === '-21' || $scope.contentId === '-20'; vm.acceptedMediatypes = []; - + vm.selectItem = selectItem; vm.clickItem = clickItem; vm.selectAll = selectAll; @@ -55,7 +55,7 @@ function clickItem(item) { // if item.id is 2147483647 (int.MaxValue) use item.key $location.path($scope.entityType + '/' + $scope.entityType + '/edit/' + (item.id === 2147483647 ? item.key : item.id)); - } + } function isSortDirection(col, direction) { return listViewHelper.setSortingDirection(col, direction, $scope.options); diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/users/users.controller.js b/src/Umbraco.Web.UI.Client/src/views/users/views/users/users.controller.js index 941d72b8c9..f2cf4e6fd8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/users/users.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/users/users.controller.js @@ -1,7 +1,9 @@ (function () { "use strict"; - function UsersController($scope, $timeout, $location, $routeParams, usersResource, userGroupsResource, userService, localizationService, contentEditingHelper, usersHelper, formHelper, notificationsService, dateHelper, editorService) { + function UsersController($scope, $timeout, $location, $routeParams, usersResource, + userGroupsResource, userService, localizationService, usersHelper, formHelper, + dateHelper, editorService, $cookies) { var vm = this; var localizeSaving = localizationService.localize("general_saving"); @@ -63,10 +65,18 @@ "selected": true } ]; - - // Set card layout to active by default - vm.activeLayout = vm.layouts[0]; - + + var cookieUmbUserLayout = $cookies.get("umbUserLayout"); + + if (cookieUmbUserLayout) { + vm.activeLayout = vm.layouts.find(x => x.path === cookieUmbUserLayout); + } + if (vm.activeLayout === undefined) { + // Set card layout to active by default + vm.activeLayout = vm.layouts[0]; + } + + // Don't show the invite button if no email is configured if (Umbraco.Sys.ServerVariables.umbracoSettings.showUserInvite) { vm.defaultButton = { @@ -96,9 +106,11 @@ vm.toggleFilter = toggleFilter; vm.setUsersViewState = setUsersViewState; vm.selectLayout = selectLayout; + vm.isSelectable = isSelectable; vm.selectUser = selectUser; vm.clearSelection = clearSelection; vm.clickUser = clickUser; + vm.getEditPath = getEditPath; vm.disableUsers = disableUsers; vm.enableUsers = enableUsers; vm.unlockUsers = unlockUsers; @@ -199,11 +211,19 @@ }); selectedLayout.active = true; vm.activeLayout = selectedLayout; + + var expireDate = new Date(); + expireDate.setDate(expireDate.getDate() + 365); + $cookies.put("umbUserLayout", selectedLayout.path, {path: "/", expires: expireDate}); } - + + function isSelectable(user) { + return !user.isCurrentUser; + } + function selectUser(user) { - if (user.isCurrentUser) { + if (!isSelectable(user)) { return; } @@ -226,9 +246,26 @@ }); vm.selection = []; } + + function clickUser(user, $event) { + + $event.stopPropagation(); + + if ($event) { + // targeting a new tab/window? + if ($event.ctrlKey || + $event.shiftKey || + $event.metaKey || // apple + ($event.button && $event.button === 1) // middle click, >IE9 + everyone else + ) { + // yes, let the link open itself + return; + } + } + + goToUser(user); + $event.preventDefault(); - function clickUser(user) { - goToUser(user.id); } function disableUsers() { @@ -551,8 +588,16 @@ vm.page.copyPasswordButtonState = "init"; } - function goToUser(userId) { - $location.path('users/users/user/' + userId).search("create", null).search("invite", null); + function goToUser(user) { + $location.path(pathToUser(user)).search("create", null).search("invite", null); + } + + function getEditPath(user) { + return pathToUser(user) + "?mculture=" + $location.search().mculture; + } + + function pathToUser(user) { + return "/users/users/user/" + user.id; } // helpers @@ -569,7 +614,7 @@ vm.usersOptions.pageSize = data.pageSize; vm.usersOptions.totalItems = data.totalItems; vm.usersOptions.totalPages = data.totalPages; - + formatDates(vm.users); setUserDisplayState(vm.users); vm.userStatesFilter = usersHelper.getUserStatesFilter(data.userStates); diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/users/users.html b/src/Umbraco.Web.UI.Client/src/views/users/views/users/users.html index cefc3c5c86..26bc478b08 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/users/users.html +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/users/users.html @@ -191,18 +191,18 @@
-
+
-
- - {{ user.userDisplayState.name }} - + + {{ user.userDisplayState.name }} + +
{{user.name}}
-
+
{{ userGroup.name }},
@@ -226,60 +226,65 @@
- - - - - - - - - - - - - +
+
Name
+
User group
+
Last login
+
Status
+ + +
+
-
- - - - - - - -
+
+
+
+
-
NameUser groupLast loginStatus
+ ng-class="{'-selected': user.selected, '-selectable': vm.isSelectable(user)}" + class="umb-table-row umb-user-table-row"> +
-
- - - {{user.name}}{{ userGroup.name }}, {{ user.formattedLastLogin }} + + + +
{{ userGroup.name }},
+
{{ user.formattedLastLogin }}
+
{{ user.userDisplayState.name }} -
+
+
+
+
@@ -490,7 +495,7 @@ type="button" button-style="action" label-key="user_goToProfile" - action="vm.goToUser(vm.newUser.id);" + action="vm.goToUser(vm.newUser);" size="m">
@@ -540,7 +545,7 @@ type="button" button-style="action" label-key="user_goToProfile" - action="vm.goToUser(vm.newUser.id);" + action="vm.goToUser(vm.newUser);" size="m">