Merge pull request #4948 from umbraco/temp8-temp-gather-url-for-list-items

V8: Provide url in content lists for ability to open item in a new tab
This commit is contained in:
Bjarke Berg
2019-03-19 13:35:45 +01:00
committed by GitHub
13 changed files with 213 additions and 75 deletions

View File

@@ -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();
};
}

View File

@@ -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) {

View File

@@ -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";

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -30,7 +30,7 @@
position: absolute;
padding: 5px 8px;
pointer-events: none;
top: 0;
top: 2px;
}
input[type="text"] {

View File

@@ -10,10 +10,13 @@
<div class="umb-content-grid__content">
<div class="umb-content-grid__item-name" ng-click="clickItemName(item, $event, $index)" ng-class="{'-light': !item.published && item.updater != null}">
<a class="umb-content-grid__item-name"
ng-href="{{'#' + item.editPath}}"
ng-click="clickItemName(item, $event, $index)"
ng-class="{'-light': !item.published && item.updater != null}">
<i class="umb-content-grid__icon {{ item.icon }}"></i>
<span>{{ item.name }}</span>
</div>
</a>
<ul class="umb-content-grid__details-list" ng-class="{'-light': !item.published && item.updater != null}">
<li class="umb-content-grid__details-item" ng-if="item.state">

View File

@@ -40,7 +40,8 @@
<i class="umb-table-body__icon umb-table-body__checkicon icon-check"></i>
</div>
<div class="umb-table-cell umb-table__name">
<a title="{{ item.name }}" class="umb-table-body__link" href=""
<a title="{{ item.name }}" class="umb-table-body__link"
ng-href="{{'#' + item.editPath}}"
ng-click="vm.clickItem(item, $event)"
ng-bind="item.name">
</a>

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -191,18 +191,18 @@
<!-- Layout: Cards -->
<div class="umb-user-cards" ng-if="vm.activeLayout.path === '1' && vm.loading === false">
<div class="umb-user-card" ng-class="{'-selected': user.selected}" ng-repeat="user in vm.users track by user.key" ng-click="vm.selectUser(user)">
<div class="umb-user-card" ng-class="{'-selected': user.selected, '-selectable': vm.isSelectable(user)}" ng-repeat="user in vm.users track by user.key" ng-click="vm.selectUser(user, $event)">
<div class="umb-user-card__content">
<div class="umb-user-card__goToUser" ng-click="vm.clickUser(user)">
<umb-badge class="umb-user-card__badge" size="xs" ng-if="user.userDisplayState.key !== 'Active'" color="{{user.userDisplayState.color}}">
{{ user.userDisplayState.name }}
</umb-badge>
<umb-badge class="umb-user-card__badge" size="xs" ng-if="user.userDisplayState.key !== 'Active'" color="{{user.userDisplayState.color}}">
{{ user.userDisplayState.name }}
</umb-badge>
<a class="umb-user-card__goToUser" ng-click="vm.clickUser(user, $event)" ng-href="#{{::vm.getEditPath(user)}}">
<div class="umb-user-card__avatar">
<umb-avatar size="l" color="secondary" name="{{user.name}}" img-src="{{user.avatars[2]}}" img-srcset="{{user.avatars[3]}} 2x, {{user.avatars[4]}} 3x">
</umb-avatar>
</div>
<div class="umb-user-card__name">{{user.name}}</div>
</div>
</a>
<div class="umb-user-card__group">
<span ng-repeat="userGroup in user.userGroups">{{ userGroup.name }}<span ng-if="!$last">, </span></span>
</div>
@@ -226,60 +226,65 @@
<!-- Layout: Table -->
<div ng-if="vm.activeLayout.path === '2'">
<table class="table table-hover">
<thead>
<tr>
<th style="padding-left: 10px; width: 10px;">
<div class="umb-table umb-user-table">
<div class="umb-table-head">
<div class="umb-table-row">
<div class="umb-table-cell" style="padding-left: 10px; width: 10px;">
<a href="" style="text-decoration: none;" ng-click="vm.selectAll()">
<umb-checkmark checked="vm.areAllSelected()" size="xs"></umb-checkmark>
</a>
</th>
<th style="width: 70px;"></th>
<th><localize key="general_name">Name</localize></th>
<th><localize key="user_usergroup">User group</localize></th>
<th><localize key="user_lastLogin">Last login</localize></th>
<th><localize key="general_status">Status</localize></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in vm.users track by user.key"
</div>
<div class="umb-table-cell umb-user-table-col-avatar" style="width: 70px;"></div>
<div class="umb-table-cell umb-table__name"><localize key="general_name">Name</localize></div>
<div class="umb-table-cell"><localize key="user_usergroup">User group</localize></div>
<div class="umb-table-cell"><localize key="user_lastLogin">Last login</localize></div>
<div class="umb-table-cell"><localize key="general_status">Status</localize></div>
</div>
</div>
<div class="umb-table-body">
<div ng-repeat="user in vm.users track by user.key"
ng-click="vm.selectUser(user, vm.selection, $event)"
ng-class="{'--selected': user.selected}"
style="cursor: pointer;"
ng-mouseenter="user.hover = true"
ng-mouseleave="user.hover = false">
<td style="padding-left: 10px;">
ng-class="{'-selected': user.selected, '-selectable': vm.isSelectable(user)}"
class="umb-table-row umb-user-table-row">
<div class="umb-table-cell" style="padding-left: 10px;">
<div ng-if="!user.isCurrentUser">
<umb-checkmark
ng-if="vm.selection.length > 0 || user.hover"
checked="user.selected"
size="xs">
</umb-checkmark>
</div>
</td>
<td scope="row" ng-click="vm.clickUser(user)">
<umb-avatar
size="xs"
color="secondary"
name="{{user.name}}"
img-src="{{user.avatars[0]}}"
img-srcset="{{user.avatars[1]}} 2x, {{user.avatars[2]}} 3x">
</umb-avatar>
</td>
<td class="bold" ng-click="vm.clickUser(user)">{{user.name}}</td>
<td><span ng-repeat="userGroup in user.userGroups">{{ userGroup.name }}<span ng-if="!$last">, </span></span></td>
<td>{{ user.formattedLastLogin }}</td>
<td style="text-transform: capitalize;">
</div>
<div class="umb-table-cell umb-user-table-col-avatar" scope="row">
<a ng-click="vm.clickUser(user, $event)" ng-href="#{{::vm.getEditPath(user)}}">
<umb-avatar
size="xs"
color="secondary"
name="{{user.name}}"
img-src="{{user.avatars[0]}}"
img-srcset="{{user.avatars[1]}} 2x, {{user.avatars[2]}} 3x">
</umb-avatar>
</a>
</div>
<div class="umb-table-cell umb-table__name">
<a ng-click="vm.clickUser(user, $event)" ng-href="#{{::vm.getEditPath(user)}}">
<span>
{{user.name}}
</span>
</a>
</div>
<div class="umb-table-cell"><span ng-repeat="userGroup in user.userGroups">{{ userGroup.name }}<span ng-if="!$last">, </span></span></div>
<div class="umb-table-cell">{{ user.formattedLastLogin }}</div>
<div class="umb-table-cell" style="text-transform: capitalize;">
<umb-badge
size="xs"
ng-if="user.userDisplayState.key !== 'Active'"
color="{{user.userDisplayState.color}}">
{{ user.userDisplayState.name }}
</umb-badge>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
@@ -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">
</umb-button>
</div>
@@ -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">
</umb-button>
</div>