mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-06-30 18:15:11 +00:00
[ADF-3053] breadcrumb fixes (#3406)
* translate breadcrumb root in demo shell * optional "max items" feature and style fixes * should not be restricted by default * style updates * toolbar and breadcrumb layout fixes * breadcrumb demo and testing page * full toolbar scenario * fix translation issue with the dropdown and custom root * a11y fixes * fix issue with duplicate id, remove unused attribute
This commit is contained in:
parent
11bac7e796
commit
fd729e76c0
@ -11,7 +11,8 @@
|
||||
"SHOW_COMMENTS" : "Show comments on versions",
|
||||
"ALLOW_DOWNLOAD" :"Enable version download",
|
||||
"READ_ONLY" : "Read only"
|
||||
}
|
||||
},
|
||||
"PERSONAL-FILES": "Personal Files"
|
||||
},
|
||||
"title": "Welcome",
|
||||
"VERSION": {
|
||||
@ -33,6 +34,7 @@
|
||||
"APP_NAME": "ADF Demo Application",
|
||||
"HOME": "Home",
|
||||
"CONTENT_SERVICES": "Content Services",
|
||||
"BREADCRUMB": "Breadcrumb",
|
||||
"PROCESS_SERVICES": "Process Services",
|
||||
"LOGIN": "Login",
|
||||
"CUSTOM_SOURCES": "Custom Sources",
|
||||
|
@ -10,7 +10,8 @@
|
||||
"ALLOW_DELETE": "Разрешить удаление",
|
||||
"SHOW_COMMENTS": "Показать комментарии к версиям",
|
||||
"ALLOW_DOWNLOAD": "Разрешить загрузку версии"
|
||||
}
|
||||
},
|
||||
"PERSONAL-FILES": "Личные файлы"
|
||||
},
|
||||
"title": "Добро пожаловать",
|
||||
"VERSION": {
|
||||
@ -171,4 +172,4 @@
|
||||
"INHERIT_PERMISSION_BUTTON": "Наследовать разрешение",
|
||||
"INHERITED_PERMISSIONS_BUTTON": "Разрешение унаследовано"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ import { ProcessAttachmentsComponent } from './components/process-service/proces
|
||||
import { SharedLinkViewComponent } from './components/shared-link-view/shared-link-view.component';
|
||||
import { DemoPermissionComponent } from './components/permissions/demo-permissions.component';
|
||||
import { PreviewService } from './services/preview.service';
|
||||
import { BreadcrumbDemoComponent } from './components/breadcrumb-demo/breadcrumb-demo.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -101,7 +102,8 @@ import { PreviewService } from './services/preview.service';
|
||||
FormLoadingComponent,
|
||||
DemoPermissionComponent,
|
||||
FormLoadingComponent,
|
||||
BlobPreviewComponent
|
||||
BlobPreviewComponent,
|
||||
BreadcrumbDemoComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: AppConfigService, useClass: DebugAppConfigService },
|
||||
|
@ -47,6 +47,7 @@ import { SharedLinkViewComponent } from './components/shared-link-view/shared-li
|
||||
import { FormLoadingComponent } from './components/form/form-loading.component';
|
||||
import { DemoPermissionComponent } from './components/permissions/demo-permissions.component';
|
||||
import { BlobPreviewComponent } from './components/blob-preview/blob-preview.component';
|
||||
import { BreadcrumbDemoComponent } from './components/breadcrumb-demo/breadcrumb-demo.component';
|
||||
|
||||
export const appRoutes: Routes = [
|
||||
{ path: 'login', component: LoginComponent },
|
||||
@ -54,6 +55,11 @@ export const appRoutes: Routes = [
|
||||
{ path: 'files/:nodeId/view', component: FileViewComponent, canActivate: [AuthGuardEcm], outlet: 'overlay' },
|
||||
{ path: 'preview/blob', component: BlobPreviewComponent, outlet: 'overlay', pathMatch: 'full' },
|
||||
{ path: 'preview/s/:id', component: SharedLinkViewComponent },
|
||||
{
|
||||
path: 'breadcrumb',
|
||||
component: BreadcrumbDemoComponent,
|
||||
canActivate: [AuthGuardEcm]
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
component: AppLayoutComponent,
|
||||
|
@ -32,6 +32,7 @@ export class AppLayoutComponent implements OnInit {
|
||||
links: Array<any> = [
|
||||
{ href: '/home', icon: 'home', title: 'APP_LAYOUT.HOME' },
|
||||
{ href: '/files', icon: 'folder_open', title: 'APP_LAYOUT.CONTENT_SERVICES' },
|
||||
{ href: '/breadcrumb', icon: 'label', title: 'APP_LAYOUT.BREADCRUMB' },
|
||||
{ href: '/activiti', icon: 'device_hub', title: 'APP_LAYOUT.PROCESS_SERVICES' },
|
||||
{ href: '/login', icon: 'vpn_key', title: 'APP_LAYOUT.LOGIN' },
|
||||
{ href: '/trashcan', icon: 'delete', title: 'APP_LAYOUT.TRASHCAN' },
|
||||
|
@ -0,0 +1,72 @@
|
||||
<main>
|
||||
<h1>Breadcrumb</h1>
|
||||
<ul>
|
||||
<li>Try creating and navigating long paths</li>
|
||||
<li>Try resizing the browser width to ensure items are trimmed as expected</li>
|
||||
</ul>
|
||||
|
||||
<h2>1. Standalone (fixed size)</h2>
|
||||
<small>Component is used in the fixed-width layout</small>
|
||||
|
||||
<div class="breadcrumb-container-restricted">
|
||||
<adf-breadcrumb root="APP.PERSONAL-FILES" [target]="documentList" [folderNode]="documentList.folderNode">
|
||||
</adf-breadcrumb>
|
||||
</div>
|
||||
|
||||
<h2>2. Standalone (full width)</h2>
|
||||
<small>Component fits the parent container width</small>
|
||||
|
||||
<div>
|
||||
<adf-breadcrumb root="APP.PERSONAL-FILES" [target]="documentList" [folderNode]="documentList.folderNode">
|
||||
</adf-breadcrumb>
|
||||
</div>
|
||||
|
||||
<h2>3. Toolbar (standalone)</h2>
|
||||
<small>Component used as a child of the Toolbar component</small>
|
||||
|
||||
<adf-toolbar>
|
||||
<adf-breadcrumb root="APP.PERSONAL-FILES" [target]="documentList" [folderNode]="documentList.folderNode">
|
||||
</adf-breadcrumb>
|
||||
</adf-toolbar>
|
||||
|
||||
<h2>4. Toolbar (title)</h2>
|
||||
<small>Component is wrapped into the Toolbar Title component</small>
|
||||
|
||||
<adf-toolbar>
|
||||
<adf-toolbar-title>
|
||||
<adf-breadcrumb root="APP.PERSONAL-FILES" [target]="documentList" [folderNode]="documentList.folderNode">
|
||||
</adf-breadcrumb>
|
||||
</adf-toolbar-title>
|
||||
</adf-toolbar>
|
||||
|
||||
<h2>5. Toolbar with separators and buttons</h2>
|
||||
<small>
|
||||
Component is wrapped into the Toolbar Title component.
|
||||
The toolbar also has separators and buttons that might provide impact on breadcrumb layout.
|
||||
Buttons do nothing and are present for layout purposes.
|
||||
</small>
|
||||
|
||||
<adf-toolbar class="full-content-toolbar">
|
||||
<adf-toolbar-title fxFlex="0 1 auto">
|
||||
<adf-breadcrumb root="APP.PERSONAL-FILES" [target]="documentList" [folderNode]="documentList.folderNode">
|
||||
</adf-breadcrumb>
|
||||
</adf-toolbar-title>
|
||||
<adf-toolbar-divider fxFlex="0 0 auto"></adf-toolbar-divider>
|
||||
<div fxFlex="0 0 auto">
|
||||
<button mat-icon-button aria-label="Create a new folder button">
|
||||
<mat-icon>create_new_folder</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button aria-label="Edit node button">
|
||||
<mat-icon>create</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button aria-label="Delete node icon button">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</adf-toolbar>
|
||||
|
||||
<div class="content">
|
||||
<adf-document-list #documentList currentFolderId="-my-">
|
||||
</adf-document-list>
|
||||
</div>
|
||||
</main>
|
@ -0,0 +1,20 @@
|
||||
.breadcrumb-container-restricted {
|
||||
width: 800px;
|
||||
max-width: 800px;
|
||||
border: 1px solid lightgray;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.full-content-toolbar {
|
||||
.adf-toolbar-title {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
.adf-breadcrumb {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
templateUrl: './breadcrumb-demo.component.html',
|
||||
styleUrls: [`./breadcrumb-demo.component.scss`],
|
||||
})
|
||||
export class BreadcrumbDemoComponent {
|
||||
|
||||
}
|
@ -33,10 +33,6 @@
|
||||
</adf-sites-dropdown>
|
||||
</div>
|
||||
|
||||
<!-- demonstrates breadcrumb use outside of the toolbar -->
|
||||
<adf-breadcrumb root="Personal Files" [target]="documentList" [folderNode]="documentList.folderNode">
|
||||
</adf-breadcrumb>
|
||||
|
||||
<div class="document-list-container" fxLayout="row" fxLayoutAlign="start stretch" fxLayoutGap="16px">
|
||||
<adf-upload-drag-area fxFlex="1 1 auto"
|
||||
[disabled]="disableDragArea"
|
||||
@ -54,7 +50,7 @@
|
||||
<adf-toolbar-title fxFlex="0 1 auto">
|
||||
<adf-breadcrumb fxShow fxHide.lt-sm="true"
|
||||
class="files-breadcrumb"
|
||||
root="Personal Files"
|
||||
root="APP.PERSONAL-FILES"
|
||||
[target]="documentList"
|
||||
[folderNode]="documentList.folderNode">
|
||||
</adf-breadcrumb>
|
||||
|
@ -30,6 +30,7 @@ Indicates the current position within a navigation hierarchy.
|
||||
| rootId | `string` | null | (optional) The id of the root element. You can use this property to set a custom element the breadcrumb should start with. |
|
||||
| target | [`DocumentListComponent`](../content-services/document-list.component.md) | | (optional) [Document List component](../content-services/document-list.component.md) to operate with. The list will update when the breadcrumb is clicked. |
|
||||
| transform | `function` | | Transformation to be performed on the chosen/folder node before building the breadcrumb UI. Can be useful when custom formatting is needed for the breadcrumb. You can change the path elements from the node that are used to build the breadcrumb using this function. |
|
||||
| maxItems | `number` | | Maximum number of nodes to display before wrapping them with a dropdown element. Not restricted by default. |
|
||||
|
||||
### Events
|
||||
|
||||
@ -86,7 +87,7 @@ A transform function to remove the "Sites" folder from the path would look somet
|
||||
|
||||
Below, the breadcrumb is shown before and after the transform function is applied:
|
||||
|
||||

|
||||

|
||||
|
||||
## See also
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div *ngIf="folderNode" data-automation-id="breadcrumb" class="adf-breadcrumb-container">
|
||||
<nav *ngIf="folderNode" data-automation-id="breadcrumb" class="adf-breadcrumb-container" role="list">
|
||||
<button
|
||||
*ngIf="hasPreviousNodes()"
|
||||
tabindex="0"
|
||||
@ -11,7 +11,7 @@
|
||||
</button>
|
||||
|
||||
<mat-select
|
||||
#select
|
||||
#dropdown
|
||||
*ngIf="hasPreviousNodes()"
|
||||
class="adf-breadcrumb-dropdown-path"
|
||||
tabindex="0">
|
||||
@ -21,15 +21,16 @@
|
||||
(click)="onRoutePathClick(node, $event)"
|
||||
class="adf-breadcrumb-path-option"
|
||||
tabindex="0">
|
||||
{{ node.name }}
|
||||
{{ node.name | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
|
||||
<li *ngFor="let item of lastNodes; let last = last"
|
||||
<div *ngFor="let item of lastNodes; let last = last"
|
||||
[class.active]="last"
|
||||
[ngSwitch]="last"
|
||||
title="{{ item.name | translate }}"
|
||||
class="adf-breadcrumb-item">
|
||||
class="adf-breadcrumb-item"
|
||||
role="listitem">
|
||||
|
||||
<a *ngSwitchDefault href="#" [attr.data-automation-id]="'breadcrumb_' + item.name"
|
||||
class="adf-breadcrumb-item-anchor"
|
||||
@ -44,13 +45,13 @@
|
||||
<mat-icon class="adf-breadcrumb-item-chevron" *ngIf="!last">
|
||||
chevron_right
|
||||
</mat-icon>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div *ngIf="!folderNode && hasRoot" data-automation-id="breadcrumb">
|
||||
<li class="adf-breadcrumb-item active">
|
||||
<nav *ngIf="!folderNode && hasRoot" data-automation-id="breadcrumb" role="navigation">
|
||||
<div class="adf-breadcrumb-item active" role="listitem">
|
||||
<div class="adf-breadcrumb-item-current">
|
||||
{{ root | translate }}
|
||||
</div>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
@ -15,6 +15,7 @@
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.2px;
|
||||
color: mat-color($foreground, text, 0.54);
|
||||
overflow: hidden;
|
||||
|
||||
&-container {
|
||||
margin: 0;
|
||||
@ -89,14 +90,20 @@
|
||||
text-align: left;
|
||||
opacity: 0.6;
|
||||
|
||||
flex: 0 10 auto;
|
||||
min-width: 35px;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&.active {
|
||||
flex: 1 0 auto;
|
||||
flex: 1 1 auto;
|
||||
color: mat-color($foreground, text, 0.87);
|
||||
min-width: initial;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
&-chevron {
|
||||
@ -118,23 +125,21 @@
|
||||
}
|
||||
|
||||
&-anchor {
|
||||
box-sizing: border-box;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&.active {
|
||||
display: block;
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
&-current {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
max-width: 300px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,16 +62,16 @@ export class BreadcrumbComponent implements OnInit, OnChanges {
|
||||
@Input()
|
||||
transform: (node) => any;
|
||||
|
||||
@ViewChild('select') selectbox: MatSelect;
|
||||
@ViewChild('dropdown')
|
||||
dropdown: MatSelect;
|
||||
|
||||
/** Maximum number of nodes to display before wrapping them with a dropdown element. */
|
||||
@Input()
|
||||
maxItems: number;
|
||||
|
||||
previousNodes: PathElementEntity[];
|
||||
lastNodes: PathElementEntity[];
|
||||
|
||||
/** Number of successive nodes that are going to be shown inside the
|
||||
* breadcrumb
|
||||
*/
|
||||
SUCCESSIVE_NODES = 3;
|
||||
|
||||
route: PathElementEntity[] = [];
|
||||
|
||||
get hasRoot(): boolean {
|
||||
@ -80,7 +80,7 @@ export class BreadcrumbComponent implements OnInit, OnChanges {
|
||||
|
||||
/** Emitted when the user clicks on a breadcrumb. */
|
||||
@Output()
|
||||
navigate: EventEmitter<PathElementEntity> = new EventEmitter<PathElementEntity>();
|
||||
navigate = new EventEmitter<PathElementEntity>();
|
||||
|
||||
ngOnInit() {
|
||||
this.transform = this.transform ? this.transform : null;
|
||||
@ -101,9 +101,9 @@ export class BreadcrumbComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
protected recalculateNodes(): void {
|
||||
if (this.route.length > this.SUCCESSIVE_NODES) {
|
||||
this.lastNodes = this.route.slice(this.route.length - this.SUCCESSIVE_NODES);
|
||||
this.previousNodes = this.route.slice(0, this.route.length - this.SUCCESSIVE_NODES);
|
||||
if (this.maxItems && this.route.length > this.maxItems) {
|
||||
this.lastNodes = this.route.slice(this.route.length - this.maxItems);
|
||||
this.previousNodes = this.route.slice(0, this.route.length - this.maxItems);
|
||||
this.previousNodes.reverse();
|
||||
} else {
|
||||
this.lastNodes = this.route;
|
||||
@ -112,8 +112,8 @@ export class BreadcrumbComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
open(): void {
|
||||
if (this.selectbox) {
|
||||
this.selectbox.open();
|
||||
if (this.dropdown) {
|
||||
this.dropdown.open();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
<mat-icon class="adf-dropdown-breadcrumb-item-chevron">chevron_right</mat-icon>
|
||||
|
||||
<mat-select
|
||||
#select
|
||||
#dropdown
|
||||
*ngIf="hasPreviousNodes()"
|
||||
class="adf-dropdown-breadcrumb-path"
|
||||
tabindex="0"
|
||||
|
@ -166,7 +166,7 @@ describe('DropdownBreadcrumb', () => {
|
||||
|
||||
it('should open the selectbox when clicking on the folder icon', (done) => {
|
||||
triggerComponentChange(fakeNodeWithCreatePermission);
|
||||
spyOn(component.selectbox, 'open');
|
||||
spyOn(component.dropdown, 'open');
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
|
||||
@ -174,7 +174,7 @@ describe('DropdownBreadcrumb', () => {
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
|
||||
expect(component.selectbox.open).toHaveBeenCalled();
|
||||
expect(component.dropdown.open).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -31,8 +31,8 @@ import { BreadcrumbComponent } from './breadcrumb.component';
|
||||
})
|
||||
export class DropdownBreadcrumbComponent extends BreadcrumbComponent implements OnChanges {
|
||||
|
||||
@ViewChild('select')
|
||||
selectbox: MatSelect;
|
||||
@ViewChild('dropdown')
|
||||
dropdown: MatSelect;
|
||||
|
||||
currentNode: PathElementEntity;
|
||||
previousNodes: PathElementEntity[];
|
||||
@ -60,11 +60,11 @@ export class DropdownBreadcrumbComponent extends BreadcrumbComponent implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the selectbox overlay
|
||||
* Opens the node picker menu
|
||||
*/
|
||||
open(): void {
|
||||
if (this.selectbox) {
|
||||
this.selectbox.open();
|
||||
if (this.dropdown) {
|
||||
this.dropdown.open();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div [file-draggable]="isDroppable()" id="UploadBorder" class="upload-border"
|
||||
<div [file-draggable]="isDroppable()" class="upload-border"
|
||||
(filesDropped)="onFilesDropped($event)"
|
||||
(filesEntityDropped)="onFilesEntityDropped($event)"
|
||||
(folderEntityDropped)="onFolderEntityDropped($event)"
|
||||
|
@ -1,6 +1,5 @@
|
||||
<mat-toolbar [color]="color">
|
||||
<span *ngIf="title">{{ title }}</span>
|
||||
<ng-content select="adf-toolbar-title"></ng-content>
|
||||
<span class="adf-toolbar--spacer"></span>
|
||||
<ng-content></ng-content>
|
||||
</mat-toolbar>
|
||||
|
Loading…
x
Reference in New Issue
Block a user