mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
[SG-286] Allow vault filter to be scrollable (#2687)
* Switch to programmatic CdkOverlay instead of directive * lint && prettier
This commit is contained in:
@@ -112,12 +112,14 @@ app-root > div {
|
||||
}
|
||||
|
||||
main::-webkit-scrollbar,
|
||||
cdk-virtual-scroll-viewport::-webkit-scrollbar {
|
||||
cdk-virtual-scroll-viewport::-webkit-scrollbar,
|
||||
.vault-select::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
main::-webkit-scrollbar-track {
|
||||
main::-webkit-scrollbar-track,
|
||||
.vault-select::-webkit-scrollbar-track {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
@@ -128,7 +130,8 @@ cdk-virtual-scroll-viewport::-webkit-scrollbar-track {
|
||||
}
|
||||
|
||||
main::-webkit-scrollbar-thumb,
|
||||
cdk-virtual-scroll-viewport::-webkit-scrollbar-thumb {
|
||||
cdk-virtual-scroll-viewport::-webkit-scrollbar-thumb,
|
||||
.vault-select::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
margin-right: 1px;
|
||||
|
||||
@@ -483,6 +486,10 @@ main {
|
||||
}
|
||||
}
|
||||
.vault-select {
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@include themify($themes) {
|
||||
background-color: themed("boxBackgroundColor");
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<div class="content org-filter-content" *ngIf="loaded && show">
|
||||
<button
|
||||
#toggleVaults
|
||||
class="org-filter"
|
||||
(click)="toggle()"
|
||||
cdkOverlayOrigin
|
||||
#trigger="cdkOverlayOrigin"
|
||||
(click)="openOverlay()"
|
||||
aria-haspopup="menu"
|
||||
aria-controls="cdk-overlay-container"
|
||||
[attr.aria-expanded]="isOpen"
|
||||
@@ -16,16 +15,7 @@
|
||||
[ngClass]="{ 'bwi-angle-down': !isOpen, 'bwi-chevron-up': isOpen }"
|
||||
></i>
|
||||
</button>
|
||||
<ng-template
|
||||
cdkConnectedOverlay
|
||||
[cdkConnectedOverlayOrigin]="trigger"
|
||||
[cdkConnectedOverlayHasBackdrop]="true"
|
||||
[cdkConnectedOverlayBackdropClass]="'cdk-overlay-transparent-backdrop'"
|
||||
[cdkConnectedOverlayOpen]="isOpen"
|
||||
[cdkConnectedOverlayPositions]="overlayPostition"
|
||||
(backdropClick)="close()"
|
||||
(detach)="close()"
|
||||
>
|
||||
<ng-template class="vault-select-container" #vaultSelectorTemplate>
|
||||
<div
|
||||
class="vault-select"
|
||||
[@transformPanel]="'open'"
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
import { animate, state, style, transition, trigger } from "@angular/animations";
|
||||
import { ConnectedPosition } from "@angular/cdk/overlay";
|
||||
import { Component, EventEmitter, NgZone, OnInit, Output } from "@angular/core";
|
||||
import { ConnectedPosition, Overlay, OverlayRef } from "@angular/cdk/overlay";
|
||||
import { TemplatePortal } from "@angular/cdk/portal";
|
||||
import {
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
NgZone,
|
||||
OnInit,
|
||||
Output,
|
||||
TemplateRef,
|
||||
ViewChild,
|
||||
ViewContainerRef,
|
||||
} from "@angular/core";
|
||||
import { merge } from "rxjs";
|
||||
|
||||
import { VaultFilter } from "jslib-angular/modules/vault-filter/models/vault-filter.model";
|
||||
import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
|
||||
@@ -36,6 +48,10 @@ import { VaultFilterService } from "../../services/vaultFilter.service";
|
||||
export class VaultSelectComponent implements OnInit {
|
||||
@Output() onVaultSelectionChanged = new EventEmitter();
|
||||
|
||||
@ViewChild("toggleVaults", { read: ElementRef })
|
||||
buttonRef: ElementRef<HTMLButtonElement>;
|
||||
@ViewChild("vaultSelectorTemplate", { read: TemplateRef }) templateRef: TemplateRef<HTMLElement>;
|
||||
|
||||
isOpen = false;
|
||||
loaded = false;
|
||||
organizations: Organization[];
|
||||
@@ -51,6 +67,8 @@ export class VaultSelectComponent implements OnInit {
|
||||
},
|
||||
];
|
||||
|
||||
private overlayRef: OverlayRef;
|
||||
|
||||
get show() {
|
||||
return (
|
||||
(this.organizations.length > 0 && !this.enforcePersonalOwnwership) ||
|
||||
@@ -62,7 +80,9 @@ export class VaultSelectComponent implements OnInit {
|
||||
private vaultFilterService: VaultFilterService,
|
||||
private i18nService: I18nService,
|
||||
private ngZone: NgZone,
|
||||
private broadcasterService: BroadcasterService
|
||||
private broadcasterService: BroadcasterService,
|
||||
private overlay: Overlay,
|
||||
private viewContainerRef: ViewContainerRef
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
@@ -108,11 +128,44 @@ export class VaultSelectComponent implements OnInit {
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.isOpen = !this.isOpen;
|
||||
openOverlay() {
|
||||
const viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
|
||||
const positionStrategyBuilder = this.overlay.position();
|
||||
|
||||
const positionStrategy = positionStrategyBuilder
|
||||
.flexibleConnectedTo(this.buttonRef.nativeElement)
|
||||
.withFlexibleDimensions(true)
|
||||
.withPush(true)
|
||||
.withViewportMargin(10)
|
||||
.withGrowAfterOpen(true)
|
||||
.withPositions(this.overlayPostition);
|
||||
|
||||
this.overlayRef = this.overlay.create({
|
||||
hasBackdrop: false,
|
||||
positionStrategy,
|
||||
maxHeight: viewPortHeight - 160,
|
||||
backdropClass: "cdk-overlay-transparent-backdrop",
|
||||
});
|
||||
|
||||
const templatePortal = new TemplatePortal(this.templateRef, this.viewContainerRef);
|
||||
this.overlayRef.attach(templatePortal);
|
||||
this.isOpen = true;
|
||||
|
||||
// Handle closing
|
||||
merge(
|
||||
this.overlayRef.outsidePointerEvents(),
|
||||
this.overlayRef.backdropClick(),
|
||||
this.overlayRef.detachments()
|
||||
).subscribe(() => {
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
|
||||
close() {
|
||||
if (this.overlayRef) {
|
||||
this.overlayRef.dispose();
|
||||
this.overlayRef = undefined;
|
||||
}
|
||||
this.isOpen = false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user