File

src/app/modules/results-browser/results-browser/results-browser.component.ts

Description

ResultsBrowser is the container component in charge of rendering the label and stats of the results as well as handling the virtual scrolling and click emitters of ResultsBrowserItems.

Metadata

Index

Properties
Methods
Inputs
Outputs

Constructor

constructor(ga: GoogleAnalyticsService)

Creates an instance of results browser component.

Parameters :
Name Type Optional Description
ga GoogleAnalyticsService No

Analytics service

Inputs

aggregateData
Type : Immutable<AggregateResult[]>

Input used to add a list of stats at the top the results browser

header
Type : boolean
highlighted
Type : string
listResults
Type : Immutable<ListResult[]>

Input array of List Results to display

resultLabel
Type : string

Input allowing the title of the result browser to be set outside of the component

Outputs

itemHovered
Type : EventEmitter
itemUnhovered
Type : EventEmitter
linkClicked
Type : EventEmitter

Output emitting the result that was clicked on and its relevant information. Used for opening and rendering the result viewer.

listResultDeselected
Type : EventEmitter

Output emitting the link result deselected

listResultSelected
Type : EventEmitter

Output emitting the link result selected

Methods

asMutable
asMutable(value: Immutable)
Type parameters :
  • T
Parameters :
Name Type Optional
value Immutable<T> No
Returns : T
handleHover
handleHover(id: string)
Parameters :
Name Type Optional
id string No
Returns : void
handleLinkClick
handleLinkClick(link: string)

Notifies on link click

Parameters :
Name Type Optional Description
link string No

the link clicked

Returns : void
handleSelection
handleSelection(result: Immutable<ListResult>, selected: boolean)

Notifies listeners when a selection/deselection is made

Parameters :
Name Type Optional Description
result Immutable<ListResult> No

the list result

selected boolean No

whether to select or deselect the result

Returns : void
handleUnhover
handleUnhover()
Returns : void
onScroll
onScroll(event: Event)

Handles the scroll event to detect when scroll is at the bottom.

Parameters :
Name Type Optional Description
event Event No

The scroll event.

Returns : void

Properties

atScrollBottom
Default value : false

Keeps track of whether or not the virtual scroll viewport is scrolled all the way to the bottom. Used to determine whether or not to render the gradient at the bottom.

import { Immutable } from '@angular-ru/common/typings/immutability';
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { AggregateResult } from 'ccf-database';
import { GoogleAnalyticsService } from 'ngx-google-analytics';

import { ListResult } from '../../../core/models/list-result';

/**
 * ResultsBrowser is the container component in charge of rendering the label and stats of
 * the results as well as handling the virtual scrolling and click emitters of
 * ResultsBrowserItems.
 */
@Component({
  selector: 'ccf-results-browser',
  templateUrl: './results-browser.component.html',
  styleUrls: ['./results-browser.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ResultsBrowserComponent {
  /**
   * Input array of List Results to display
   */
  @Input() listResults!: Immutable<ListResult[]>;

  /**
   * Input used to add a list of stats at the top the results browser
   */
  @Input() aggregateData!: Immutable<AggregateResult[]>;

  /**
   * Input allowing the title of the result browser to be set outside of the component
   */
  @Input() resultLabel!: string;

  @Input() highlighted!: string;

  @Input() header!: boolean;

  /**
   * Output emitting the result that was clicked on and its relevant information.
   * Used for opening and rendering the result viewer.
   */
  @Output() readonly linkClicked = new EventEmitter<string>();

  /**
   * Output emitting the link result selected
   */
  @Output() readonly listResultSelected = new EventEmitter<Immutable<ListResult>>();

  /**
   * Output emitting the link result deselected
   */
  @Output() readonly listResultDeselected = new EventEmitter<Immutable<ListResult>>();

  @Output() readonly itemHovered = new EventEmitter<string>();

  @Output() readonly itemUnhovered = new EventEmitter();

  /**
   * Keeps track of whether or not the virtual scroll viewport is scrolled all the way to the bottom.
   * Used to determine whether or not to render the gradient at the bottom.
   */
  atScrollBottom = false;

  /**
   * Creates an instance of results browser component.
   *
   * @param ga Analytics service
   */
  constructor(private readonly ga: GoogleAnalyticsService) {}

  /**
   * Notifies listeners when a selection/deselection is made
   *
   * @param result the list result
   * @param selected whether to select or deselect the result
   */
  handleSelection(result: Immutable<ListResult>, selected: boolean): void {
    this.ga.event('list_result_selected', 'results_browser', this.resultLabel, +selected);
    if (selected) {
      this.listResultSelected.next(result);
    } else {
      this.listResultDeselected.next(result);
    }
  }

  /**
   * Notifies on link click
   *
   * @param link the link clicked
   */
  handleLinkClick(link: string): void {
    this.linkClicked.emit(link);
  }

  /**
   * Handles the scroll event to detect when scroll is at the bottom.
   *
   * @param event The scroll event.
   */
  onScroll(event: Event): void {
    if (!event.target) {
      return;
    }
    const { clientHeight, scrollHeight, scrollTop } = event.target as Element;
    const diff = scrollHeight - scrollTop - clientHeight;
    this.atScrollBottom = diff < 64;
  }

  handleHover(id: string): void {
    this.itemHovered.emit(id);
  }

  handleUnhover(): void {
    this.itemUnhovered.emit();
  }

  asMutable<T>(value: Immutable<T>): T {
    return value as T;
  }
}
<div class="results-browser-container">
  <div class="stat-box">
    <div id="title">{{ resultLabel }}</div>
    <div class="stat-row" *ngFor="let stat of aggregateData">
      <div class="stat-value">{{ stat.count }}</div>
      <div class="stat-label">{{ stat.label }}</div>
    </div>
  </div>

  <div class="results-browser-list" [class.header-hidden]="!header" (scroll)="onScroll($event)">
    <div
      class="browser-item-container"
      (mouseenter)="handleHover(result.tissueBlock.spatialEntityId)"
      (mouseleave)="handleUnhover()"
      *ngFor="let result of listResults"
    >
      <ccf-donor-card
        [tissueBlock]="asMutable(result.tissueBlock)"
        [selected]="result.selected"
        [color]="result.color ?? ''"
        (checked)="handleSelection(result, $event)"
        (linkClick)="handleLinkClick($event)"
        [highlighted]="result.tissueBlock.spatialEntityId === highlighted"
      >
      </ccf-donor-card>
    </div>
  </div>
  <div class="scroll-gradient" [class.hidden]="!!atScrollBottom"></div>
</div>

./results-browser.component.scss

.results-browser-container {
  display: flex;
  flex-direction: column;
  height: calc(100% - 3rem);
  padding: 0 1.5rem 1.5rem 1.5rem;

  .stat-box {
    margin-bottom: 1.5rem;
    line-height: 1.25;
    min-height: 7.75rem;

    #title {
      font-size: 1.25rem;
      margin-bottom: 0.75rem;
    }

    .stat-row {
      display: flex;
      flex-direction: row;

      .stat-value {
        margin-right: 1rem;
        width: 5.5rem;
        text-align: right;
        font-weight: 600;
      }
      .stat-label {
        font-weight: 300;
      }
    }
  }

  .results-browser-list {
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    scrollbar-width: thin;
    padding-right: 0.5rem;
    height: calc(100vh - 20rem);

    &.header-hidden {
      height: calc(100vh - 16rem);
    }

    .browser-item-container {
      width: 100%;
    }
  }

  .scroll-gradient {
    position: absolute;
    height: 3rem;
    width: 95%;
    bottom: 0;
    pointer-events: none;

    &.hidden {
      display: none;
    }
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""