[ACA-4361] Review permission list (#6974)

* [ACA-4361] permission ux review

* * fixed comments and lint

* * remove space
This commit is contained in:
Dharan
2021-05-05 18:43:34 +05:30
committed by GitHub
parent d65797763e
commit 884d646078
15 changed files with 190 additions and 141 deletions

View File

@@ -386,11 +386,12 @@
},
"ADD-PERMISSION": {
"SEARCH": "Search for users or groups to add",
"TITLE": "Add user or group to",
"TITLE": "Add permission",
"TYPE-MESSAGE": "Type something to start searching groups or people",
"NO-RESULT": "No result found for this search",
"SELECT-ACTION": "SELECT",
"ADD-ACTION": "ADD",
"CLOSE-ACTION": "CLOSE",
"CLOSE-ACTION": "CANCEL",
"BASE-DIALOG-TITLE": "Search a group or people to add...",
"EVERYONE": "EVERYONE"
},
@@ -402,7 +403,7 @@
"LABELS": {
"ON": "On",
"OFF": "Off",
"DIRECT-PERMISSIONS": "Direct Applied Permission",
"DIRECT-PERMISSIONS": "Directly Applied Permission",
"INHERITED-PERMISSIONS": "Inherited Permission",
"INHERITED-SUBTITLE": "{{count}} users or groups are inheriting permission from a parent folder",
"SELECT-ROLE": "Select role"
@@ -414,7 +415,7 @@
"PERMISSION-BULK-UPDATE-SUCCESS": "Updated {{user}} user(s) {{group}} group(s)",
"PERMISSION-UPDATE-SUCCESS": "User/Group updated",
"PERMISSION-UPDATE-FAIL": "Failed to update user/group",
"PERMISSION-BULK-DELETE-SUCCESS": "Deleted {{user}} user(s_ {{group}} group(s)",
"PERMISSION-BULK-DELETE-SUCCESS": "Deleted {{user}} user(s) {{group}} group(s)",
"PERMISSION-DELETE-SUCCESS": "User/Group deleted",
"PERMISSION-DELETE-FAIL": "Failed to delete user/group",
"PERMISSION-ADD-SUCCESS": "Added {{user}} user(s) {{group}} group(s)",

View File

@@ -10,64 +10,66 @@
<mat-icon>search</mat-icon>
</button>
<adf-datatable [rows]="selectedMembers"
selectionMode="none"
stickyHeader="true"
data-automation-id="adf-user-role-selection-table"
*ngIf="selectedMembers.length">
<data-columns>
<data-column class="adf-key-icon" key="icon" type="icon" [sortable]="false">
<ng-template let-context>
<adf-user-icon-column [context]="context"></adf-user-icon-column>
</ng-template>
</data-column>
<div class="adf-new-permission-table">
<adf-datatable [rows]="selectedMembers"
class="adf-datatable-permission"
selectionMode="none"
stickyHeader="true"
data-automation-id="adf-user-role-selection-table"
*ngIf="selectedMembers.length">
<data-columns>
<data-column class="adf-datatable-cell--image adf-authority-icon-column" key="$thumbunail" [sortable]="false">
<ng-template let-context>
<adf-user-icon-column [context]="context"></adf-user-icon-column>
</ng-template>
</data-column>
<data-column class="adf-authorityId-label adf-ellipsis-cell adf-expand-cell-2"
[title]="'Users and Groups (' + selectedMembers.length + ')'"
key="id">
<ng-template let-context>
<adf-user-name-column [context]="context"></adf-user-name-column>
</ng-template>
</data-column>
<data-column class="adf-ellipsis-cell adf-expand-cell-5 adf-authorityId-column"
[title]="'PERMISSION_MANAGER.COLUMN.NAME' | translate:{count:selectedMembers.length}"
key="id">
<ng-template let-context>
<adf-user-name-column [context]="context"></adf-user-name-column>
</ng-template>
</data-column>
<data-column class="adf-ellipsis-cell adf-expand-cell-1"
title="PERMISSION_MANAGER.PERMISSION_DISPLAY.ROLE"
key="role">
<ng-template let-entry="$implicit">
<adf-user-role-column [readonly]="entry.row.obj.readonly"
[placeholder]="entry.data.getValue(entry.row, entry.col)"
[value]="entry.data.getValue(entry.row, entry.col)"
[roles]="data.roles"
id="adf-select-role-permission"
(roleChanged)="onMemberUpdate($event, entry.row.obj)">
</adf-user-role-column>
</ng-template>
<adf-data-column-header>
<ng-template>
<adf-user-role-column class="adf-permission-role-column-header"
placeholder="PERMISSION_MANAGER.COLUMN.BULK-ROLE"
[roles]="data.roles"
id="adf-bulk-select-role-permission"
(roleChanged)="onBulkUpdate($event)">
<data-column class="adf-ellipsis-cell adf-expand-cell-4"
title="PERMISSION_MANAGER.PERMISSION_DISPLAY.ROLE"
key="role">
<ng-template let-entry="$implicit">
<adf-user-role-column [readonly]="entry.row.obj.readonly"
[value]="entry.data.getValue(entry.row, entry.col)"
[roles]="data.roles"
id="adf-select-role-permission"
(roleChanged)="onMemberUpdate($event, entry.row.obj)">
</adf-user-role-column>
</ng-template>
</adf-data-column-header>
</data-column>
<data-column class="adf-delete-permission" key="" sortable="false">
<ng-template let-entry="$implicit">
<button mat-icon-button
class="adf-add-member-action"
[style.display]="entry.row.obj.readonly ? 'none': 'block'"
(click)="onMemberDelete(entry.row.obj)"
data-automation-id="adf-delete-permission-button">
<mat-icon>highlight_off</mat-icon>
</button>
</ng-template>
</data-column>
</data-columns>
</adf-datatable>
<adf-data-column-header>
<ng-template>
<adf-user-role-column class="adf-permission-role-column-header"
placeholder="PERMISSION_MANAGER.COLUMN.BULK-ROLE"
[roles]="data.roles"
id="adf-bulk-select-role-permission"
(roleChanged)="onBulkUpdate($event)">
</adf-user-role-column>
</ng-template>
</adf-data-column-header>
</data-column>
<data-column class="adf-datatable-cell adf-delete-permission-column" key="" sortable="false">
<ng-template let-entry="$implicit">
<button mat-icon-button
class="adf-add-member-action"
[style.display]="entry.row.obj.readonly ? 'none': 'block'"
(click)="onMemberDelete(entry.row.obj)"
data-automation-id="adf-delete-permission-button">
<mat-icon>highlight_off</mat-icon>
</button>
</ng-template>
</data-column>
</data-columns>
</adf-datatable>
</div>
</mat-dialog-content>
@@ -90,7 +92,7 @@
<ng-container *ngIf="isSearchActive">
<mat-dialog-content>
<adf-add-permission-panel (select)="onSelect($event)"></adf-add-permission-panel>
<adf-add-permission-panel class="adf-search-container" (select)="onSelect($event)"></adf-add-permission-panel>
</mat-dialog-content>
<mat-dialog-actions>
@@ -103,7 +105,7 @@
data-automation-id="add-permission-dialog-confirm-button"
[disabled]="!currentSelection.length"
(click)="onSearchAddClicked()">
{{ "PERMISSION_MANAGER.ADD-PERMISSION.ADD-ACTION" | translate }}
{{ "PERMISSION_MANAGER.ADD-PERMISSION.SELECT-ACTION" | translate }}
</button>
</mat-dialog-actions>
</ng-container>

View File

@@ -25,11 +25,21 @@
.mat-dialog-content {
margin: 0;
overflow: auto;
overflow: hidden;
flex-grow: 1;
height: 80vh;
.adf-new-permission-table {
height: 90%;
}
.adf-search-container {
height: 100%;
}
}
.mat-dialog-actions {
padding: 8px;
padding: 0 24px;
background-color: mat-color($background, background);
display: flex;
justify-content: flex-end;

View File

@@ -23,8 +23,9 @@
</mat-form-field>
<div *ngIf="searchedWord?.length === 0"
class="adf-permission-start-message"
id="adf-add-permission-type-search">
<span class="adf-permission-start-message">{{'PERMISSION_MANAGER.ADD-PERMISSION.TYPE-MESSAGE' | translate}}</span>
<span>{{'PERMISSION_MANAGER.ADD-PERMISSION.TYPE-MESSAGE' | translate}}</span>
</div>
<adf-search #search
@@ -36,8 +37,9 @@
<mat-selection-list class="adf-permission-result-list-elements" (keydown.control.a)="selectAll( data?.list?.entries)">
<mat-list-option id="adf-add-permission-group-everyone"
class="adf-list-option-item"
#eveyone
(click)="elementClicked(EVERYONE)">
<adf-user-icon-column [node]="EVERYONE" id="add-group-icon"></adf-user-icon-column>
<adf-user-icon-column [node]="EVERYONE" id="add-group-icon" [selected]="eveyone.selected"></adf-user-icon-column>
<p class="adf-result-name">
{{'PERMISSION_MANAGER.ADD-PERMISSION.EVERYONE' | translate}}
</p>
@@ -46,8 +48,9 @@
<mat-list-option *ngFor="let item of data?.list?.entries; let idx = index"
(click)="elementClicked(item)"
class="adf-list-option-item"
id="result_option_{{idx}}">
<adf-user-icon-column [node]="item"></adf-user-icon-column>
id="result_option_{{idx}}"
#option>
<adf-user-icon-column [node]="item" [selected]="option.selected"></adf-user-icon-column>
<p class="adf-result-name">
<ng-container *ngIf="item.entry?.properties['cm:authorityDisplayName']; else authorityName">
{{item.entry.properties['cm:authorityDisplayName']}}

View File

@@ -5,12 +5,13 @@
$primary: map-get($theme, primary);
$accent: map-get($theme, accent);
$mat-menu-border-radius: 2px !default;
$search-result-height: calc(100% - 75px);
.adf {
&-permission-result-list {
display: flex;
height: 300px;
height: $search-result-height;
overflow: auto;
border: 2px solid mat-color($foreground, base, 0.07);
@@ -27,7 +28,7 @@
display: flex;
align-items: center;
justify-content: space-around;
height: 300px;
height: $search-result-height;
overflow: auto;
border: 2px solid mat-color($foreground, base, 0.07);
}
@@ -54,13 +55,19 @@
}
}
&-list-option-item .mat-list-text {
display: flex;
flex-direction: row !important;
align-items: center;
&-list-option-item {
mat-pseudo-checkbox {
display: none;
}
.adf-result-name {
padding-left: 16px !important;
.mat-list-text {
display: flex;
flex-direction: row !important;
align-items: center;
.adf-result-name {
padding-left: 16px !important;
}
}
}

View File

@@ -2,27 +2,24 @@
id="adf-permission-display-container"
[rows]="permissions"
stickyHeader="true"
selectionMode="multiple">
[selectionMode]="selectionMode">
<data-columns>
<data-column class="adf-key-icon"
key="icon"
type="icon"
[sortable]="false">
<data-column class="adf-datatable-cell--image adf-authority-icon-column" key="$thumbunail" [sortable]="false">
<ng-template let-context>
<adf-user-icon-column [context]="context"></adf-user-icon-column>
</ng-template>
</data-column>
<data-column class="adf-authorityId-label adf-ellipsis-cell adf-expand-cell-2"
<data-column class="adf-ellipsis-cell adf-expand-cell-5 adf-authorityId-column"
[title]="'PERMISSION_MANAGER.COLUMN.NAME' | translate:{count:permissions.length}"
key="authorityId">
<ng-template let-context>
<adf-user-name-column [context]="context"></adf-user-name-column>
</ng-template>
</data-column>
</data-column>d
<data-column class="adf-authorityId-label adf-ellipsis-cell adf-expand-cell-2"
<data-column class="adf-ellipsis-cell adf-expand-cell-5 adf-authorityId-column"
title="PERMISSION_MANAGER.COLUMN.LOCATION"
key="location"
*ngIf="node && showLocation">
@@ -32,7 +29,7 @@
</data-column>
<data-column
class="adf-ellipsis-cell adf-expand-cell-1"
class="adf-ellipsis-cell adf-expand-cell-4"
title="PERMISSION_MANAGER.PERMISSION_DISPLAY.ROLE"
key="name"
sortable="false">
@@ -59,7 +56,7 @@
</adf-data-column-header>
</data-column>
<data-column class="adf-delete-permission" key="delete" *ngIf="!isReadOnly" sortable="false">
<data-column class="adf-datatable-cell adf-delete-permission-column" key="" *ngIf="!isReadOnly" [sortable]="false">
<ng-template let-entry="$implicit">
<button mat-icon-button
(click)="removePermission($event, entry.row.obj)"

View File

@@ -1,44 +1,30 @@
@mixin adf-permission-container-theme($theme) {
$adf-permission-list-width: 100% !default;
.adf {
&-permission-label {
max-width: 130px;
min-width: 100px;
margin-left: 50px;
}
.adf-datatable-permission {
display: flex;
min-width: 450px;
width: $adf-permission-list-width;
&-delete-permission {
max-width: 50px;
}
&.adf-datatable {
overflow: hidden;
&-authorityId-label {
min-width: 100px;
}
.adf-delete-permission-column {
min-width: 80px;
&-key-icon {
max-width: 50px;
}
.adf-cell-value {
width: 80px;
padding-right: 10px;
place-content: flex-end;
}
}
&-ellipsis-cell {
position: sticky;
text-overflow: ellipsis;
white-space: nowrap;
}
.adf-authorityId-column {
flex: 40%;
}
&-display-permission-container {
display: flex;
justify-content: space-around;
flex: 1;
}
&-datatable-permission {
display: flex;
min-width: 450px;
width: $adf-permission-list-width;
&.adf-datatable {
overflow: hidden;
.adf-authority-icon-column {
min-width: 40px;
}
}
}

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core';
import { Component, EventEmitter, Input, OnChanges, Output, ViewEncapsulation } from '@angular/core';
import { Node, PermissionElement } from '@alfresco/js-api';
import { PermissionDisplayModel } from '../../models/permission.model';
import { RoleModel } from '../../models/role.model';
@@ -23,7 +23,8 @@ import { RoleModel } from '../../models/role.model';
@Component({
selector: 'adf-permission-container',
templateUrl: './permission-container.component.html',
styleUrls: ['./permission-container.component.scss']
styleUrls: ['./permission-container.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class PermissionContainerComponent implements OnChanges {
@@ -42,6 +43,9 @@ export class PermissionContainerComponent implements OnChanges {
@Input()
showLocation = false;
@Input()
selectionMode = 'multiple'; // none|single|multiple
/** Emitted when the permission is updated. */
@Output()
update = new EventEmitter<{role: string, permission: PermissionDisplayModel}>();

View File

@@ -57,17 +57,26 @@
[node]="model.node"
[permissions]="model.inheritedPermissions"
[showLocation]="true"
[selectionMode]="'none'"
[roles]="model.roles">
</adf-permission-container>
</div>
</ng-template>
<mat-card-content style="overflow: hidden">
<mat-card-content class="adf-local-permission-container">
<section class="adf-permission-content-header">
<h3>{{'PERMISSION_MANAGER.LABELS.DIRECT-PERMISSIONS' | translate }}</h3>
<div class="adf-toolbar--spacer"></div>
<button
mat-button
[matTooltip]="'PERMISSION_MANAGER.ACTION.ADD-PERMISSION' | translate"
(click)="openAddPermissionDialog()"
data-automation-id="adf-add-permission-button">
<mat-icon>person_add_outline</mat-icon>
</button>
<button
mat-button
[matTooltip]="'PERMISSION_MANAGER.ACTION.DELETE' | translate"
@@ -76,16 +85,6 @@
data-automation-id="adf-delete-selected-permission">
<mat-icon>delete_outline</mat-icon>
</button>
<adf-toolbar-divider></adf-toolbar-divider>
<button
mat-button
[matTooltip]="'PERMISSION_MANAGER.ACTION.ADD-PERMISSION' | translate"
(click)="openAddPermissionDialog()"
data-automation-id="adf-add-permission-button">
<mat-icon>person_add_outline</mat-icon>
</button>
</section>
<adf-permission-container

View File

@@ -25,7 +25,7 @@
justify-content: space-between;
align-items: center;
padding: 10px 15px;
border: 1px solid mat-color($foreground, divider);
border: 1px solid mat-color($foreground, base, 0.07);
}
&-inherit-container {
@@ -70,6 +70,18 @@
display: flex;
height: calc(100% - 63px);
}
&-local-permission-container {
overflow: hidden;
flex: 1 1 auto;
}
&-datatable-list {
.adf-datatable-selected > svg {
width: 40px;
height: 40px;
}
}
}
@@ -79,14 +91,15 @@
padding-right: 10px;
}
.adf-permission-pop-over {
padding-right: 15px;
width: 100%;
.adf-pop-over-card {
width: 100%;
@include mat-elevation(16, mat-color($foreground, divider), 0.8);
overflow: hidden;
box-shadow: 0 8px 9px -5px mat-color($foreground, divider),
0 15px 22px 2px mat-color($foreground, divider);
}
}
}

View File

@@ -102,7 +102,7 @@ export class PermissionListService {
updateNodePermissionByDialog() {
this.nodePermissionDialogService
.openAddPermissionDialog(this.node, this.roles)
.openAddPermissionDialog(this.node, this.roles, 'PERMISSION_MANAGER.ADD-PERMISSION.TITLE')
.pipe(
switchMap(selection => {
const total = selection.length;

View File

@@ -1,6 +1,6 @@
@mixin adf-user-icon-column-theme($theme) {
$primary: map-get($theme, primary);
$foreground: map-get($theme, foreground);
$document-list-selection-color: mat-color($accent) !default;
.adf {
&-people-initial {
@@ -11,7 +11,7 @@
align-items: center;
width: 40px;
height: 40px;
color: mat-color($foreground, text);
color: mat-color($primary, default-contrast) !important;
font-weight: bolder;
font-size: 18px;
text-transform: uppercase;
@@ -23,12 +23,18 @@
background: mat-color($primary);
border-radius: 50%;
padding: 10px;
color: mat-color($foreground, text);
color: mat-color($primary, default-contrast) !important;
font-weight: bolder;
font-size: 20px;
}
&-people-select-icon {
padding: 10px;
margin: 0 !important;
svg {
fill: $document-list-selection-color;
width: 40px;
height: 40px;
}
}
}
}

View File

@@ -115,4 +115,11 @@ describe('UserIconColumnComponent', () => {
});
});
it('should render select icon', () => {
component.selected = true;
component.ngOnInit();
fixture.detectChanges();
expect(element.querySelector('mat-icon[svgIcon="selected"]')).toBeDefined();
expect(component.isSelected).toBe(true);
});
});

View File

@@ -24,14 +24,14 @@ import { NodePermissionService } from '../../services/node-permission.service';
@Component({
selector: 'adf-user-icon-column',
template: `
<div class="adf-cell-value" [attr.id]="group ? 'group-icon' : 'person-icon'" *ngIf="!context?.row?.isSelected">
<div class="adf-cell-value" [attr.id]="group ? 'group-icon' : 'person-icon'" *ngIf="!isSelected">
<ng-container *ngIf="displayText$ | async as user">
<mat-icon *ngIf="group" class="adf-people-icon">people_alt_outline</mat-icon>
<div *ngIf="!group" [outerHTML]="user | usernameInitials: 'adf-people-initial'"></div>
</ng-container>
</div>
<div class="adf-cell-value" *ngIf="context?.row?.isSelected">
<mat-icon class="adf-people-select-icon" svgIcon="selected"></mat-icon>
<div class="adf-cell-value" *ngIf="isSelected">
<mat-icon class="adf-people-select-icon adf-datatable-selected" svgIcon="selected"></mat-icon>
</div>
`,
styleUrls: ['./user-icon-column.component.scss'],
@@ -44,9 +44,16 @@ export class UserIconColumnComponent implements OnInit {
@Input()
node: NodeEntry;
@Input()
selected: boolean = false;
displayText$ = new BehaviorSubject<User>(null);
group = false;
get isSelected(): boolean {
return this.context?.row?.isSelected || this.selected;
}
constructor(private nodePermissionService: NodePermissionService) {}
ngOnInit() {

View File

@@ -33,7 +33,7 @@ import { RoleModel } from '../../models/role.model';
</mat-select>
</mat-form-field>
<span class="adf-datatable-cell-value" [title]="value | adfLocalizedRole" *ngIf="readonly">
<span class="adf-datatable-cell-value adf-readonly-role" [title]="value | adfLocalizedRole" *ngIf="readonly">
{{value | adfLocalizedRole}}
</span>
`,
@@ -41,6 +41,13 @@ import { RoleModel } from '../../models/role.model';
styles: [
`.adf-role-selector-field {
width: 100%;
.mat-form-field {
width: 100%;
max-width: 200px;
}
}
.adf-readonly-role {
padding-left: 0 !important;
}
`
]