File

src/app/modules/registration-modal/registration-content/registration-content.component.ts

Description

Component containing content of the initial registration modal

Metadata

Index

Properties
Methods
HostBindings

Constructor

constructor(page: PageState, model: ModelState, dialogRef: MatDialogRef, cdr: ChangeDetectorRef)

Creates an instance of the registration dialog

Parameters :
Name Type Optional Description
page PageState No

Page state

model ModelState No

Model state

dialogRef MatDialogRef<RegistrationContentComponent> No

Registration dialog

cdr ChangeDetectorRef No

Change detection

HostBindings

class
Type : "ccf-registration-content"
Default value : 'ccf-registration-content'

HTML class name

Methods

checkNameValid
checkNameValid(event: Pick<Person | "firstName" | "lastName">)

Checks to see if a first and last name has been entered

Parameters :
Name Type Optional Description
event Pick<Person | "firstName" | "lastName"> No

Name input event

Returns : void
closeDialog
closeDialog()

Closes the dialog and sets the correct sex and organ in the model state Sets block to default position and rotation if user didn't select a registration Updates page state to signal registration has started

Returns : void
handleRegistrationSelect
handleRegistrationSelect()

Sets registrationSelected to true when a registration is uploaded

Returns : void
organSelect
organSelect(organ: OrganInfo)

Updates current organ selected

Parameters :
Name Type Optional Description
organ OrganInfo No

Organ selected

Returns : void
registerButtonClick
registerButtonClick(event?: MouseEvent)

Handles button click

Parameters :
Name Type Optional Description
event MouseEvent Yes

The click event

Returns : void

Returns nothing is no organ is selected

setSexFromLabel
setSexFromLabel(label: "Female" | "Male")

Updates current sex selected

Parameters :
Name Type Optional Description
label "Female" | "Male" No

Sex selected

Returns : void

Properties

Readonly clsName
Type : string
Default value : 'ccf-registration-content'
Decorators :
@HostBinding('class')

HTML class name

currentOrgan
Type : OrganInfo

Current organ selected

currentSex
Type : string

Current sex selected

Public dialogRef
Type : MatDialogRef<RegistrationContentComponent>
Registration dialog
nameValid
Type : boolean

Checks if the user has entered a first and last name

orcidValid
Type : boolean

Checks if the entered orcid is valid

organList
Default value : RUI_ORGANS

List of selectable organs

organSelected
Type : boolean

Whether an organ has been selected

registrationSelected
Type : boolean

Checks if a preexisting registration was uploaded

Readonly sexByLabel$
Default value : this.model.sex$.pipe(map((sex) => (sex === 'female' ? 'Female' : 'Male')))

Current sex in the model state

sexSelected
Type : boolean

Whether sex has been selected

import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';
import { OrganInfo } from 'ccf-shared';
import { map } from 'rxjs/operators';

import { ModelState, RUI_ORGANS } from '../../../core/store/model/model.state';
import { PageState, Person } from '../../../core/store/page/page.state';

/**
 * Component containing content of the initial registration modal
 */
@Component({
  selector: 'ccf-registration-content',
  templateUrl: './registration-content.component.html',
  styleUrls: ['./registration-content.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RegistrationContentComponent {
  /** HTML class name */
  @HostBinding('class') readonly clsName = 'ccf-registration-content';

  /** Current sex in the model state */
  readonly sexByLabel$ = this.model.sex$.pipe(map((sex) => (sex === 'female' ? 'Female' : 'Male')));

  /** List of selectable organs */
  organList = RUI_ORGANS;

  /** Whether sex has been selected */
  sexSelected!: boolean;

  /** Whether an organ has been selected */
  organSelected!: boolean;

  /** Current sex selected */
  currentSex!: string;

  /** Current organ selected */
  currentOrgan!: OrganInfo;

  /** Checks if the user has entered a first and last name */
  nameValid!: boolean;

  /** Checks if the entered orcid is valid */
  orcidValid!: boolean;

  /** Checks if a preexisting registration was uploaded */
  registrationSelected: boolean;

  /**
   * Creates an instance of the registration dialog
   *
   * @param page Page state
   * @param model Model state
   * @param dialogRef Registration dialog
   * @param cdr Change detection
   */
  constructor(
    readonly page: PageState,
    readonly model: ModelState,
    public dialogRef: MatDialogRef<RegistrationContentComponent>,
    cdr: ChangeDetectorRef,
  ) {
    this.registrationSelected = false;
    page.user$.subscribe((user) => {
      this.checkNameValid(user);
      this.orcidValid = page.isOrcidValid();
      cdr.markForCheck();
    });
    model.organ$.subscribe((organ) => {
      this.organSelected = organ.src !== '';
      cdr.markForCheck();
    });
    this.sexByLabel$.subscribe((sex) => {
      this.setSexFromLabel(sex);
      cdr.markForCheck();
    });
    dialogRef.disableClose = true;
    this.page.organOptions$.subscribe((options) => {
      this.organList = options as OrganInfo[];
      cdr.markForCheck();
    });
  }

  /**
   * Updates current sex selected
   *
   * @param label Sex selected
   */
  setSexFromLabel(label: 'Female' | 'Male'): void {
    this.currentSex = label;
    this.sexSelected = true;
  }

  /**
   * Checks to see if a first and last name has been entered
   *
   * @param event Name input event
   */
  checkNameValid(event: Pick<Person, 'firstName' | 'lastName'>): void {
    this.nameValid = event.firstName.length > 0 && event.lastName.length > 0;
  }

  /**
   * Updates current organ selected
   *
   * @param organ Organ selected
   */
  organSelect(organ: OrganInfo): void {
    this.currentOrgan = organ;
    this.organSelected = true;
  }

  /**
   * Handles button click
   *
   * @param [event] The click event
   * @returns  Returns nothing is no organ is selected
   */
  registerButtonClick(event?: MouseEvent): void {
    if (event) {
      event.preventDefault();
    }
    if (!this.organSelected || !this.nameValid) {
      return;
    }
    this.closeDialog();
  }

  /**
   * Sets registrationSelected to true when a registration is uploaded
   */
  handleRegistrationSelect() {
    this.registrationSelected = true;
  }

  /**
   * Closes the dialog and sets the correct sex and organ in the model state
   * Sets block to default position and rotation if user didn't select a registration
   * Updates page state to signal registration has started
   */
  closeDialog(): void {
    this.model.setSex(this.currentSex === 'Female' ? 'female' : 'male');
    this.model.setOrgan(this.currentOrgan);
    if (!this.registrationSelected) {
      this.model.setOrganDefaults();
    }
    this.dialogRef.close(true);
    this.page.registrationStarted();
  }
}
<div class="modal">
  <div class="title">Start Registration</div>
  <ccf-registration-metadata (registrationSelected)="handleRegistrationSelect()"></ccf-registration-metadata>
  <button
    [class.disabled]="!organSelected || !nameValid || !orcidValid"
    mat-button
    class="registration-button"
    (click)="registerButtonClick($event)"
    [matTooltip]="!organSelected || !nameValid ? 'Required: Enter first and last name, and select an organ' : ''"
  >
    Continue
  </button>
</div>

./registration-content.component.scss

.modal {
  padding: 2rem;
  border-radius: 0.5rem;
  max-width: 47rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;

  .title {
    font-size: 1.25rem;
    font-weight: 600;
  }

  .organ-sliders {
    .slider-label {
      font-weight: 600;
    }

    display: flex;
    height: 3rem;
    align-items: center;
  }

  .selector-label {
    font-weight: 600;
    height: 3rem;
    line-height: 3rem;
  }

  .selector-container {
    margin: 0 auto;
  }

  .registration-button {
    transition: 0.6s;
    display: flex;
    width: 10rem;
    height: 2rem;
    padding: 0.25rem 1rem;
    justify-content: center;
    align-items: center;
    border-radius: 0.125rem;
    box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.16);
    cursor: pointer;

    &.disabled {
      pointer-events: none;
    }
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""