Pull request #190: add scroll button

Merge in RED/ui from RED-1486 to master

* commit '4f8b2adaf32f82881ad290d8a68f8f66743d950b':
  add scroll button
This commit is contained in:
Timo Bejan 2021-05-31 09:19:49 +02:00
commit b9f8d28e8d
11 changed files with 107 additions and 10 deletions

View File

@ -18,6 +18,7 @@ export class IconsModule {
'analyse',
'approved',
'arrow-down',
'arrow-down-o',
'arrow-right',
'arrow-up',
'assign',

View File

@ -0,0 +1,3 @@
<button class="scroll-button pointer" *ngIf="showScrollButton()" (click)="scroll()">
<mat-icon svgIcon="red:arrow-down-o"></mat-icon>
</button>

View File

@ -0,0 +1,19 @@
@import 'apps/red-ui/src/assets/styles/red-variables';
.scroll-button {
background-color: $white;
position: absolute;
bottom: 30px;
right: 0;
height: 40px;
width: 44px;
border: none;
border-radius: 8px 0 0 8px;
box-shadow: -1px 1px 5px 0 rgba(40, 50, 65, 0.25);
}
mat-icon {
width: 22px;
height: 22px;
color: $grey-7;
}

View File

@ -0,0 +1,37 @@
import { Component, HostListener, Input } from '@angular/core';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
@Component({
selector: 'redaction-scroll-button',
templateUrl: './scroll-button.component.html',
styleUrls: ['./scroll-button.component.scss']
})
export class ScrollButtonComponent {
@Input()
scrollViewport: CdkVirtualScrollViewport;
@Input()
itemSize: number;
scroll(): void {
const scrollOffset = this.scrollViewport.measureScrollOffset('top');
const ligaturePortion = 50;
const viewportSize = this.scrollViewport.getViewportSize() - ligaturePortion;
this.scrollViewport.scrollToOffset(scrollOffset + viewportSize, 'smooth');
}
showScrollButton(): boolean {
const reachedBottom = this.scrollViewport.measureScrollOffset('bottom') === 0;
const scrollSize = this.scrollViewport.getDataLength() * this.itemSize;
const scrollIsNeeded = this.scrollViewport.getViewportSize() < scrollSize;
return scrollIsNeeded && !reachedBottom;
}
@HostListener('document:keyup', ['$event'])
spaceAndPageDownScroll(event: KeyboardEvent): void {
if (['Space', 'PageDown'].includes(event.code)) {
this.scroll();
}
}
}

View File

@ -44,6 +44,7 @@ import { EditProjectDictionaryComponent } from './dialogs/edit-project-dialog/di
import { EditProjectTeamMembersComponent } from './dialogs/edit-project-dialog/team-members/edit-project-team-members.component';
import { TeamMembersManagerComponent } from './components/team-members-manager/team-members-manager.component';
import { TeamMembersDialogComponent } from './dialogs/team-members-dialog/team-members-dialog.component';
import { ScrollButtonComponent } from './components/scroll-button/scroll-button.component';
const screens = [
ProjectListingScreenComponent,
@ -59,7 +60,8 @@ const dialogs = [
ForceRedactionDialogComponent,
RemoveAnnotationsDialogComponent,
DocumentInfoDialogComponent,
AssignReviewerApproverDialogComponent
AssignReviewerApproverDialogComponent,
DossierDictionaryDialogComponent
];
const components = [
@ -84,6 +86,7 @@ const components = [
EditProjectDictionaryComponent,
EditProjectTeamMembersComponent,
TeamMembersManagerComponent,
ScrollButtonComponent,
...screens,
...dialogs
@ -101,7 +104,7 @@ const services = [
];
@NgModule({
declarations: [...components, DossierDictionaryDialogComponent],
declarations: [...components],
providers: [...services],
imports: [CommonModule, SharedModule, FileUploadDownloadModule, ProjectsRoutingModule]
})

View File

@ -104,7 +104,7 @@
type="no-match"
></redaction-empty-state>
<cdk-virtual-scroll-viewport [itemSize]="85" redactionHasScrollbar>
<cdk-virtual-scroll-viewport [itemSize]="itemSize" redactionHasScrollbar>
<div
*cdkVirtualFor="
let pw of displayedEntities
@ -169,6 +169,12 @@
<div class="scrollbar-placeholder"></div>
</div>
</cdk-virtual-scroll-viewport>
<redaction-scroll-button
[scrollViewport]="scrollBar"
[itemSize]="itemSize"
*ngIf="scrollBar && itemSize > 0"
></redaction-scroll-button>
</div>
<div class="right-container" redactionHasScrollbar>

View File

@ -2,6 +2,8 @@
@import '../../../../../assets/styles/red-variables';
.content-container {
position: relative;
cdk-virtual-scroll-viewport {
::ng-deep.cdk-virtual-scroll-content-wrapper {
grid-template-columns: 2fr 1fr 1fr auto 11px;

View File

@ -47,12 +47,13 @@ export class ProjectListingScreenComponent
} = {
statusFilters: []
};
readonly itemSize = 85;
protected readonly _searchKey = 'name';
protected readonly _sortKey = 'project-listing';
private _projectAutoUpdateTimer: Subscription;
private _lastScrollPosition: number;
@ViewChild(CdkVirtualScrollViewport) private _scrollBar: CdkVirtualScrollViewport;
@ViewChild(CdkVirtualScrollViewport) scrollBar: CdkVirtualScrollViewport;
@ViewChild('statusFilter') private _statusFilterComponent: FilterComponent;
@ViewChild('peopleFilter') private _peopleFilterComponent: FilterComponent;
@ -146,7 +147,7 @@ export class ProjectListingScreenComponent
)
.subscribe((event) => {
if (event instanceof NavigationStart && event.url !== '/main/projects') {
this._lastScrollPosition = this._scrollBar.measureScrollOffset('top');
this._lastScrollPosition = this.scrollBar.measureScrollOffset('top');
}
});
}
@ -155,7 +156,7 @@ export class ProjectListingScreenComponent
this._appStateService.reset();
this._loadEntitiesFromState();
this.ngOnInit();
this._scrollBar.scrollTo({ top: this._lastScrollPosition });
this.scrollBar.scrollTo({ top: this._lastScrollPosition });
}
ngOnDetach() {

View File

@ -184,7 +184,7 @@
type="no-match"
></redaction-empty-state>
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
<cdk-virtual-scroll-viewport [itemSize]="itemSize" redactionHasScrollbar>
<div
*cdkVirtualFor="
let fileStatus of displayedEntities
@ -309,6 +309,12 @@
<div class="scrollbar-placeholder"></div>
</div>
</cdk-virtual-scroll-viewport>
<redaction-scroll-button
[scrollViewport]="scrollBar"
[itemSize]="itemSize"
*ngIf="scrollBar && itemSize > 0"
></redaction-scroll-button>
</div>
<div [class.collapsed]="collapsedDetails" class="right-container" redactionHasScrollbar>

View File

@ -48,6 +48,7 @@ export class ProjectOverviewScreenComponent
needsWorkFilters: FilterModel[];
statusFilters: FilterModel[];
} = { needsWorkFilters: [], statusFilters: [] };
readonly itemSize = 80;
protected readonly _searchKey = 'searchField';
protected readonly _selectionKey = 'fileId';
protected readonly _sortKey = 'project-overview';
@ -59,7 +60,7 @@ export class ProjectOverviewScreenComponent
private _lastScrollPosition: number;
private _lastOpenedFileId = '';
@ViewChild(CdkVirtualScrollViewport) private _scrollBar: CdkVirtualScrollViewport;
@ViewChild(CdkVirtualScrollViewport) scrollBar: CdkVirtualScrollViewport;
@ViewChild('statusFilter') private _statusFilterComponent: FilterComponent;
@ViewChild('peopleFilter') private _peopleFilterComponent: FilterComponent;
@ -147,7 +148,7 @@ export class ProjectOverviewScreenComponent
.pipe(filter((events) => events instanceof NavigationStart))
.subscribe((event: NavigationStart) => {
if (!event.url.endsWith(this._appStateService.activeProjectId)) {
this._lastScrollPosition = this._scrollBar.measureScrollOffset('top');
this._lastScrollPosition = this.scrollBar.measureScrollOffset('top');
}
});
}
@ -162,7 +163,7 @@ export class ProjectOverviewScreenComponent
ngOnAttach() {
this._loadEntitiesFromState();
this.ngOnInit();
this._scrollBar.scrollTo({ top: this._lastScrollPosition });
this.scrollBar.scrollTo({ top: this._lastScrollPosition });
}
ngOnDetach() {

View File

@ -0,0 +1,18 @@
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M14.8285 12.0259L16.2427 13.4402L12 17.6828L7.7574 13.4402L9.17161 12.0259L11 13.8544V6.31724H13V13.8544L14.8285 12.0259Z"
fill="currentColor"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M19.7782 19.7782C15.4824 24.0739 8.51759 24.0739 4.22183 19.7782C-0.0739417 15.4824 -0.0739417 8.51759 4.22183 4.22183C8.51759 -0.0739419 15.4824 -0.0739419 19.7782 4.22183C24.0739 8.51759 24.0739 15.4824 19.7782 19.7782ZM18.364 18.364C14.8492 21.8787 9.15076 21.8787 5.63604 18.364C2.12132 14.8492 2.12132 9.15076 5.63604 5.63604C9.15076 2.12132 14.8492 2.12132 18.364 5.63604C21.8787 9.15076 21.8787 14.8492 18.364 18.364Z"
fill="currentColor"
/>
</svg>

After

Width:  |  Height:  |  Size: 841 B