File

components/control-panel/control-panel.component.ts

Description

Control panel with form fields to call disagg service.

Handles disagg service with return period and imt.

Implements

OnInit

Metadata

Index

Properties
Methods

Methods

ngOnInit
ngOnInit()
Returns : void
Private onModelChange
onModelChange()
Returns : void
onSubmit
onSubmit()

On form submit.

Returns : void
setLocation
setLocation(location: Location)
Parameters :
Name Type Optional
location Location No
Returns : void

Properties

Private destroyRef
Default value : inject(DestroyRef)
DisaggTarget
Default value : DisaggTarget

Disaggregation target enum

form
Default value : this.service.formGroup

Form fields state

Private hazardService
Default value : inject(HazardService)
imlRange
Default value : computed(() => { const usage = this.service.usage(); if (usage) { return usage.response.iml.range[this.form.getRawValue().imt]; } })

IML range from usage, based on IMT value

imts
Default value : computed(() => this.service.usage()?.response.model.imts)
Private nshmpService
Default value : inject(NshmpService)
selectSiteData
Type : Signal<SelectSiteDialogData>
Default value : computed(() => { const metadata = this.service.metadata(); if (metadata === undefined) { return { mapUrl: '', }; } const services = environment.webServices.nshmpHazWs.services.curveServices; return this.hazardService.metadataToSiteData(metadata, { faultSections: services.features, map: services.map, testSites: services.sites, }); })

Data for select site component

service
Default value : inject(AppService)
serviceCallInfo
Default value : this.service.serviceCallInfo

Service call info state

siteClasses
Default value : computed(() => this.service.usage()?.response.model.siteClasses)

The site classes

sourceModel
Default value : computed(() => this.service.usage()?.response?.model)

Source model info from usage

import {Component, computed, DestroyRef, inject, OnInit, Signal} from '@angular/core';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {ReactiveFormsModule} from '@angular/forms';
import {MatError, MatFormField, MatLabel} from '@angular/material/form-field';
import {MatInput} from '@angular/material/input';
import {MatRadioButton, MatRadioGroup} from '@angular/material/radio';
import {
  DisaggTarget,
  HazardService,
  NshmpHazardImtFormComponent,
  NshmpHazardLocationFormComponent,
  NshmpHazardMaxDirectionFormComponent,
  NshmpHazardModelFormComponent,
  NshmpHazardModelInfoComponent,
  NshmpHazardReturnPeriodFormComponent,
  NshmpHazardSiteClassFormComponent,
} from '@ghsc/nshmp-lib/hazard';
import {NshmpMapSelectSiteComponent, SelectSiteDialogData} from '@ghsc/nshmp-lib/map';
import {NshmpControlPanelButtonsComponent, NshmpService} from '@ghsc/nshmp-lib/nshmp';
import {Location} from '@ghsc/nshmp-utils-ts/libs/nshmp-lib/geo';
import {environment} from '@nshmp-apps/environments/environment';
import {combineLatest} from 'rxjs';

import {AppService} from '../../services/app.service';

/**
 * Control panel with form fields to call disagg service.
 *
 * Handles disagg service with return period and imt.
 */
@Component({
  host: {id: 'hazard-disagg-control-panel'},
  imports: [
    MatError,
    MatFormField,
    MatInput,
    MatLabel,
    MatRadioButton,
    MatRadioGroup,
    NshmpControlPanelButtonsComponent,
    NshmpControlPanelButtonsComponent,
    NshmpHazardImtFormComponent,
    NshmpHazardLocationFormComponent,
    NshmpHazardMaxDirectionFormComponent,
    NshmpHazardModelFormComponent,
    NshmpHazardModelInfoComponent,
    NshmpHazardReturnPeriodFormComponent,
    NshmpHazardSiteClassFormComponent,
    NshmpMapSelectSiteComponent,
    ReactiveFormsModule,
  ],
  selector: 'app-control-panel',
  styleUrl: './control-panel.component.scss',
  templateUrl: './control-panel.component.html',
})
export class ControlPanelComponent implements OnInit {
  service = inject(AppService);
  private destroyRef = inject(DestroyRef);
  private hazardService = inject(HazardService);
  private nshmpService = inject(NshmpService);

  /** Disaggregation target enum */
  DisaggTarget = DisaggTarget;

  /** Form fields state */
  form = this.service.formGroup;

  /** IML range from usage, based on IMT value */
  imlRange = computed(() => {
    const usage = this.service.usage();

    if (usage) {
      return usage.response.iml.range[this.form.getRawValue().imt];
    }
  });

  /** Data for select site component */
  selectSiteData: Signal<SelectSiteDialogData> = computed(() => {
    const metadata = this.service.metadata();

    if (metadata === undefined) {
      return {
        mapUrl: '',
      };
    }

    const services = environment.webServices.nshmpHazWs.services.curveServices;

    return this.hazardService.metadataToSiteData(metadata, {
      faultSections: services.features,
      map: services.map,
      testSites: services.sites,
    });
  });

  /** Service call info state */
  serviceCallInfo = this.service.serviceCallInfo;

  imts = computed(() => this.service.usage()?.response.model.imts);

  /** The site classes */
  siteClasses = computed(() => this.service.usage()?.response.model.siteClasses);

  /** Source model info from usage */
  sourceModel = computed(() => this.service.usage()?.response?.model);

  ngOnInit(): void {
    const controls = this.form.controls;

    controls.disaggTarget.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
      this.service.onDisaggTarget();
      this.service.resetState();
    });

    controls.model.valueChanges
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe(() => this.onModelChange());

    combineLatest([controls.latitude.valueChanges, controls.longitude.valueChanges])
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe(() => {
        this.service.resetState();
        const values = this.form.getRawValue();

        if (values.latitude && values.longitude) {
          this.selectSiteData().site = {
            latitude: values.latitude,
            longitude: values.longitude,
          };
        }
      });

    combineLatest([
      controls.iml.valueChanges,
      controls.imt.valueChanges,
      controls.returnPeriod.valueChanges,
      controls.vs30.valueChanges,
    ])
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe(() => {
        this.service.resetState();
      });
  }

  /**
   * On form submit.
   */
  onSubmit(): void {
    this.service.callService();
    this.nshmpService.selectPlotControl();
  }

  setLocation(location: Location): void {
    this.form.patchValue({
      latitude: location.latitude,
      longitude: location.longitude,
    });
  }

  private onModelChange(): void {
    const {latitude, longitude} = this.form.getRawValue();
    const latitudeBounds = this.service.usage()?.response.latitude;
    const longitudeBounds = this.service.usage()?.response.longitude;

    if (
      latitudeBounds &&
      longitudeBounds &&
      !(
        latitude >= latitudeBounds.min &&
        latitude <= latitudeBounds.max &&
        longitude >= longitudeBounds.min &&
        longitude <= longitudeBounds.max
      )
    ) {
      this.form.patchValue({
        latitude: NaN,
        longitude: NaN,
      });
    }

    this.form.controls.latitude.markAsPristine();
    this.form.controls.longitude.markAsPristine();
    this.service.resetState();
  }
}
<!-- Control Panel -->
<form class="height-full overflow-auto" [formGroup]="form" (submit)="onSubmit()">
  <!-- Model -->
  <nshmp-hazard-model-form
    [modelControl]="form.controls.model"
    [models]="service.availableModels()"
    [latitudeControl]="form.controls.latitude"
    [longitudeBounds]="service.usage()?.response?.longitude"
    [longitudeControl]="form.controls.longitude"
  />

  <div class="center-x grid-row grid-gap-md">
    <!-- Select site -->
    <nshmp-map-select-site [data]="selectSiteData()" (siteSelect)="setLocation($event)" />

    <!-- Model info -->
    <nshmp-hazard-model-info [modelInfo]="service.modelInfo()" />
  </div>

  <!-- Latitude -->
  <nshmp-hazard-location-form
    class="latitude-input"
    [locationControl]="form.controls.latitude"
    label="Latitude"
    [bounds]="service.usage()?.response?.latitude"
  />

  <!-- Longitude -->
  <nshmp-hazard-location-form
    class="longitude-input"
    [locationControl]="form.controls.longitude"
    label="Longitude"
    [bounds]="service.usage()?.response?.longitude"
  />

  <!-- Site Class -->
  <div class="grid-row grid-gap-1">
    <!-- Site classes -->
    <nshmp-hazard-site-class-form
      [siteClassControl]="form.controls.siteClass"
      [siteClasses]="siteClasses()"
      [vs30Control]="form.controls.vs30"
      [vs30Bounds]="service.usage()?.response?.vs30"
    />
  </div>

  <!-- Imt -->
  <nshmp-hazard-imt-form [imtControl]="form.controls.imt" [imts]="imts()" />

  <!-- Disagg target -->
  <div class="display-flex">
    <!-- Target selector -->
    <div class="disagg-target-selector">
      <mat-radio-group [formControl]="form.controls.disaggTarget">
        <mat-radio-button
          [value]="DisaggTarget.RETURN_PERIOD"
          aria-label="Select return period"
          class="return-period-button"
        />
        <mat-radio-button [value]="DisaggTarget.IML" aria-label="Select IML" class="iml-button" />
      </mat-radio-group>
    </div>

    <div class="grid-col-12">
      <!-- Return Period Controls -->
      <div class="disagg-target-return-period">
        <nshmp-hazard-return-period-form
          [returnPeriodControl]="form.controls.returnPeriod"
          [commonReturnPeriodControl]="form.controls.commonReturnPeriods"
        />
      </div>

      <!-- IML controls -->
      <div class="disagg-target-iml">
        <div class="grid-row grid-gap-1">
          <mat-form-field class="grid-col-6">
            <mat-label> Intensity Measure Level ({{ imlRange()?.units }}) </mat-label>
            <input
              type="number"
              class="iml-input"
              matInput
              [formControl]="form.controls.iml"
              [min]="imlRange()?.min ?? null"
              [max]="imlRange()?.max ?? null"
              step="any"
            />
            <mat-error> [{{ imlRange()?.min }}, {{ imlRange()?.max }}] </mat-error>
          </mat-form-field>

          <div class="center-y">
            <nshmp-hazard-max-direction-form
              label="Max Direction"
              [maxDirectionControl]="form.controls.maxDirection"
            />
          </div>
        </div>
      </div>
    </div>
  </div>

  <nshmp-control-panel-buttons
    [plotDisabled]="form.invalid"
    [serviceCallInfo]="serviceCallInfo()"
    [resetDisabled]="form.pristine"
    (resetClick)="service.resetControlPanel()"
  />
</form>
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""