src/app/shared/components/registration-metadata/registration-metadata.component.ts
Right side registration menu
changeDetection | ChangeDetectionStrategy.OnPush |
selector | ccf-registration-metadata |
styleUrls | ./registration-metadata.component.scss |
templateUrl | ./registration-metadata.component.html |
Properties |
|
Methods |
Outputs |
constructor(model: ModelState, registration: RegistrationState, page: PageState)
|
||||||||||||||||
Creates an instance of registration metadata component.
Parameters :
|
registrationSelected | |
Type : EventEmitter
|
|
Emits when user has uploaded registration |
checkNameValid | ||||||||
checkNameValid(event: Pick<Person | "firstName" | "lastName">)
|
||||||||
Checks to see if a first and last name has been entered
Parameters :
Returns :
void
|
getErrorMessage |
getErrorMessage()
|
Error message to inform user if orcid is invalid
Returns :
string
Error message |
handleRegistrationUpload | ||||||
handleRegistrationUpload(reg: SpatialEntityJsonLd)
|
||||||
Emits registrationSelected and calls editRegistration in state
Parameters :
Returns :
void
|
setSexFromLabel | ||||||||
setSexFromLabel(label: "Female" | "Male")
|
||||||||
Updates current sex selected
Parameters :
Returns :
void
|
updateOrcid | ||||||||
updateOrcid(value: string)
|
||||||||
Updates orcid value
Parameters :
Returns :
void
|
nameValid |
Type : boolean
|
Checks if first and last name has been entered |
Optional orcId |
Type : string
|
Orcid URI converted to regular id |
orcidControl |
Default value : new FormControl('', [Validators.pattern('^[a-zA-Z0-9]{4}(-[a-zA-Z0-9]{4}){3}$')])
|
Form control for validating orcid id |
uploadText |
Type : string
|
Text to inform user if a registration file has been uploaded |
import { ChangeDetectionStrategy, Component, EventEmitter, Output } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
import { SpatialEntityJsonLd } from 'ccf-body-ui';
import { ModelState } from '../../../core/store/model/model.state';
import { PageState, Person } from '../../../core/store/page/page.state';
import { RegistrationState } from '../../../core/store/registration/registration.state';
/**
* Right side registration menu
*/
@Component({
selector: 'ccf-registration-metadata',
templateUrl: './registration-metadata.component.html',
styleUrls: ['./registration-metadata.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RegistrationMetadataComponent {
/** Emits when user has uploaded registration */
@Output() readonly registrationSelected = new EventEmitter<void>();
/** Checks if first and last name has been entered */
nameValid!: boolean;
/** Orcid URI converted to regular id */
orcId?: string;
/** Text to inform user if a registration file has been uploaded */
uploadText!: string;
/** Form control for validating orcid id */
orcidControl = new FormControl('', [Validators.pattern('^[a-zA-Z0-9]{4}(-[a-zA-Z0-9]{4}){3}$')]);
/**
* Creates an instance of registration metadata component.
* @param model Model state
* @param registration Registration state
* @param page Page state
*/
constructor(
readonly model: ModelState,
readonly registration: RegistrationState,
readonly page: PageState,
) {
page.user$.subscribe((user) => {
this.checkNameValid(user);
this.orcId = page.uriToOrcid(user.orcidId);
});
registration.state$.subscribe((reg) => {
this.uploadText = reg.initialRegistration ? 'File(s) uploaded' : 'No file(s) uploaded';
});
}
/**
* Error message to inform user if orcid is invalid
* @returns Error message
*/
getErrorMessage(): string {
return this.orcidControl.hasError('pattern') ? 'Not a valid ORCID' : '';
}
/**
* Updates orcid value
* @param value Orcid value entered
*/
updateOrcid(value: string): void {
this.page.setOrcidId(value);
}
/**
* Emits registrationSelected and calls editRegistration in state
* @param event Registration uploaded
*/
handleRegistrationUpload(reg: SpatialEntityJsonLd): void {
this.registrationSelected.emit();
this.registration.editRegistration(reg);
}
/**
* 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 sex selected
* @param label Sex selected
*/
setSexFromLabel(label: 'Female' | 'Male'): void {
this.model.setSex(label.toLowerCase() as 'male' | 'female');
}
}
<div class="author-section">
<h2 class="section-title">Author Data</h2>
<ccf-name-input [name]="$any(page.user$ | async)" (nameChange)="page.setUserName($event); checkNameValid($event)">
</ccf-name-input>
<mat-form-field class="orcid-input">
<mat-label>ORCID identifier (optional)</mat-label>
<input
matInput
class="input"
[value]="orcId"
[formControl]="orcidControl"
(input)="updateOrcid($any($event.target).value)"
matTooltip="Add ORCID id."
maxlength="19"
/>
<mat-error *ngIf="orcidControl.invalid">{{ getErrorMessage() }}</mat-error>
</mat-form-field>
</div>
<div class="donor-section">
<h2 class="section-title">Donor Data</h2>
<div class="sex-toggle">
<div class="label">Donor Sex:</div>
<mat-radio-group class="radio-group" [value]="model.sex$ | async" (change)="setSexFromLabel($event.value)">
<mat-radio-button class="radio" value="male">Male</mat-radio-button>
<mat-radio-button class="radio" value="female">Female</mat-radio-button>
</mat-radio-group>
</div>
<div class="organ-selector">
<div class="label">Select an organ:</div>
<mat-form-field class="form-field" appearance="fill" subscriptSizing="dynamic">
<div *ngIf="(model.organ$ | async) === undefined" class="label">Organs</div>
<mat-select
disableOptionCentering="true"
panelClass="organ-select"
[value]="model.organ$ | async"
(selectionChange)="model.setOrgan($event.value); model.setOrganDefaults()"
hideSingleSelectionIndicator="true"
>
<mat-option class="organ-select-option" *ngFor="let organ of page.organOptions$ | async" [value]="organ">
{{ organ.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="upload-registration">
<div class="label">Upload previous registration data (optional):</div>
<ccf-json-file-reader
(parsedJson)="handleRegistrationUpload($any($event))"
label="Upload"
matTooltip="Upload a preexisting registration"
></ccf-json-file-reader>
<div>{{ uploadText }}</div>
</div>
</div>
./registration-metadata.component.scss
:host {
display: flex;
flex-direction: column;
gap: 2rem;
.section-title {
font-weight: 400;
line-height: 1.5rem;
margin: 0;
padding-bottom: 1.5rem;
}
.label {
font-size: 1rem;
font-weight: 700;
line-height: 1.5rem;
}
::ng-deep .mat-mdc-form-field-infix {
padding-bottom: 0 !important;
min-height: inherit;
}
::ng-deep .mdc-text-field {
padding: 0;
padding-bottom: 0.3rem !important;
}
.author-section {
display: flex;
flex-direction: column;
.orcid-input {
width: 100%;
font-size: 1rem;
}
}
.donor-section {
display: flex;
flex-direction: column;
.sex-toggle {
display: flex;
align-items: center;
padding-bottom: 1.5rem;
.label {
padding-right: 1rem;
}
mat-radio-group {
display: flex;
gap: 3rem;
}
}
.organ-selector {
padding-bottom: 1.5rem;
::ng-deep .mat-mdc-select-value {
font-size: 1rem;
}
}
.upload-registration {
display: flex;
flex-direction: column;
gap: 1rem;
ccf-json-file-reader {
::ng-deep button {
width: 10rem;
height: 2rem;
padding: 0.25rem 1rem;
border-radius: 0.125rem;
}
}
}
}
::ng-deep .mdc-line-ripple::before,
.mdc-line-ripple::after {
border-bottom-width: 0.125rem !important;
}
}