From 159f60416a9295d60e96d264870610f212b1409f Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Fri, 13 Sep 2024 12:08:37 -0600
Subject: [PATCH 01/29] new component summary component

---
 .../component-summary.component.html          | 89 +++++++++++++++++++
 .../component-summary.component.scss          |  7 ++
 .../component-summary.component.spec.ts       | 30 +++++++
 .../component-summary.component.ts            | 55 ++++++++++++
 4 files changed, 181 insertions(+)
 create mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
 create mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.scss
 create mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.spec.ts
 create mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.ts

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
new file mode 100644
index 000000000..7f8ebb294
--- /dev/null
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
@@ -0,0 +1,89 @@
+<div class="height-full overflow-auto">
+  <div class="grid-container-widescreen">
+    <div class="padding-y-4">
+      <mat-card class="margin-bottom-2">
+        <mat-card-header>
+          <mat-card-title> Disaggregation Component Summary </mat-card-title>
+        </mat-card-header>
+
+        <!-- Select component -->
+        <mat-card-content>
+          <mat-form-field
+            class="grid-col-12 padding-top-4 disagg-component-select"
+          >
+            <mat-label> Component </mat-label>
+            <mat-select [formControl]="formGroup.controls.disaggComponent">
+              @for (disagg of disaggData()?.data; track disagg) {
+                <mat-option [value]="disagg?.component">
+                  {{ disagg?.component }}
+                </mat-option>
+              }
+            </mat-select>
+          </mat-form-field>
+        </mat-card-content>
+
+        <mat-card-actions>
+          <div class="print-display-none">
+            <button
+              mat-raised-button
+              color="primary"
+              (click)="service.saveComponentSummaryReport()"
+            >
+              Export Summary Report
+            </button>
+          </div>
+        </mat-card-actions>
+      </mat-card>
+
+      <mat-accordion multi>
+        <!-- Summary report -->
+        <mat-expansion-panel
+          class="summary-report print-page-break"
+          [expanded]="disaggData()"
+          [disabled]="disaggData() === null"
+        >
+          <mat-expansion-panel-header>
+            <mat-panel-title
+              >Disaggregation Summary:
+              {{ formGroup.getRawValue().disaggComponent }}</mat-panel-title
+            >
+          </mat-expansion-panel-header>
+
+          <app-disagg-summary [componentData]="componentData$ | async" />
+        </mat-expansion-panel>
+
+        <!-- Contributions -->
+        <mat-expansion-panel
+          class="contributions print-page-break"
+          [expanded]="(componentData$ | async) !== null"
+          [disabled]="(componentData$ | async) === null"
+        >
+          <mat-expansion-panel-header>
+            <mat-panel-title
+              >Disaggregation Contributions:
+              {{ formGroup.getRawValue().disaggComponent }}</mat-panel-title
+            >
+          </mat-expansion-panel-header>
+
+          <app-disagg-contributors [componentData]="componentData$ | async" />
+        </mat-expansion-panel>
+
+        <!-- Data -->
+        <mat-expansion-panel
+          class="print-page-break"
+          [expanded]="(componentData$ | async) !== null"
+          [disabled]="(componentData$ | async) === null"
+        >
+          <mat-expansion-panel-header>
+            <mat-panel-title
+              >Disaggregation Data:
+              {{ formGroup.getRawValue().disaggComponent }}</mat-panel-title
+            >
+          </mat-expansion-panel-header>
+
+          <app-disagg-data [componentData]="componentData$ | async" />
+        </mat-expansion-panel>
+      </mat-accordion>
+    </div>
+  </div>
+</div>
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.scss b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.scss
new file mode 100644
index 000000000..3094eb336
--- /dev/null
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.scss
@@ -0,0 +1,7 @@
+@media print {
+  mat-accordion {
+    mat-expansion-panel {
+      box-shadow: none !important;
+    }
+  }
+}
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.spec.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.spec.ts
new file mode 100644
index 000000000..cf9908a16
--- /dev/null
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.spec.ts
@@ -0,0 +1,30 @@
+import {provideHttpClient} from '@angular/common/http';
+import {ComponentFixture, TestBed} from '@angular/core/testing';
+import {provideNoopAnimations} from '@angular/platform-browser/animations';
+import {provideRouter} from '@angular/router';
+
+import {ComponentSummaryComponent} from './component-summary.component';
+
+describe('ComponentSummaryComponent', () => {
+  let component: ComponentSummaryComponent;
+  let fixture: ComponentFixture<ComponentSummaryComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [ComponentSummaryComponent],
+      providers: [
+        provideHttpClient(),
+        provideNoopAnimations(),
+        provideRouter([]),
+      ],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(ComponentSummaryComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.ts
new file mode 100644
index 000000000..a58543268
--- /dev/null
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.ts
@@ -0,0 +1,55 @@
+import {AsyncPipe} from '@angular/common';
+import {Component} from '@angular/core';
+import {ReactiveFormsModule} from '@angular/forms';
+import {MatButton} from '@angular/material/button';
+import {MatCardModule} from '@angular/material/card';
+import {MatDivider} from '@angular/material/divider';
+import {MatExpansionModule} from '@angular/material/expansion';
+import {
+  MatFormField,
+  MatLabel,
+  MatOption,
+  MatSelect,
+} from '@angular/material/select';
+import {map} from 'rxjs';
+
+import {AppService} from '../../services/app.service';
+import {DisaggContributorsComponent} from '../disagg-contributors/disagg-contributors.component';
+import {DisaggDataComponent} from '../disagg-data/disagg-data.component';
+import {DisaggSummaryComponent} from '../disagg-summary/disagg-summary.component';
+
+@Component({
+  imports: [
+    MatExpansionModule,
+    MatCardModule,
+    DisaggSummaryComponent,
+    DisaggContributorsComponent,
+    DisaggDataComponent,
+    AsyncPipe,
+    MatFormField,
+    MatSelect,
+    ReactiveFormsModule,
+    MatLabel,
+    MatOption,
+    MatDivider,
+    MatButton,
+  ],
+  selector: 'app-component-summary',
+  standalone: true,
+  styleUrl: './component-summary.component.scss',
+  templateUrl: './component-summary.component.html',
+})
+export class ComponentSummaryComponent {
+  /** Disaggregation component data */
+  componentData$ =
+    this.service.formGroup.controls.disaggComponent.valueChanges.pipe(
+      map(() => this.service.componentData())
+    );
+
+  /** Disaggregation data */
+  disaggData = this.service.disaggData;
+
+  formGroup = this.service.formGroup;
+
+  constructor(public service: AppService) {}
+}
-- 
GitLab


From d23915193d7545865649160e571dcbc6eca57a3d Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Fri, 13 Sep 2024 12:08:53 -0600
Subject: [PATCH 02/29] new disagg data component

---
 .../disagg-data/disagg-data.component.html    | 48 ++++++++++++++++++
 .../disagg-data/disagg-data.component.scss    | 29 +++++++++++
 .../disagg-data/disagg-data.component.spec.ts | 30 +++++++++++
 .../disagg-data/disagg-data.component.ts      | 50 +++++++++++++++++++
 4 files changed, 157 insertions(+)
 create mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.html
 create mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.scss
 create mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.spec.ts
 create mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.ts

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.html
new file mode 100644
index 000000000..7bc8ce4ba
--- /dev/null
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.html
@@ -0,0 +1,48 @@
+@if (componentData) {
+  @if (componentData.data.length > 0) {
+    @if (showExportButton) {
+      <!-- Export button -->
+      <div class="print-display-none">
+        <button
+          class="export-button"
+          mat-raised-button
+          color="primary"
+          [disabled]="componentData.data === null"
+          (click)="service.saveComponentData()"
+        >
+          Export Data as CSV
+        </button>
+      </div>
+
+      <mat-divider />
+    }
+
+    <div class="horizontal-scrolling">
+      <div>
+        <table class="grid-col-12">
+          <thead>
+            <tr>
+              <th nowrap>{{ metadata().rlabel }}</th>
+              <th nowrap>{{ metadata().mlabel }}</th>
+              @for (key of epsilonKeys(); track key) {
+                <th nowrap>{{ key }}</th>
+              }
+            </tr>
+          </thead>
+          <tbody>
+            @for (data of componentData.data; track data) {
+              <tr>
+                <td noWrap>{{ data.r }}</td>
+                <td nowrap>{{ data.m }}</td>
+
+                @for (binData of toBinData(data); track $index) {
+                  <td nowrap>{{ binData }}</td>
+                }
+              </tr>
+            }
+          </tbody>
+        </table>
+      </div>
+    </div>
+  }
+}
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.scss b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.scss
new file mode 100644
index 000000000..7128fbaec
--- /dev/null
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.scss
@@ -0,0 +1,29 @@
+table {
+  th:first-child,
+  td:first-child {
+    text-align: left;
+  }
+
+  th,
+  td {
+    background: none;
+    border: none;
+    text-align: center;
+  }
+
+  th {
+    background-color: inherit;
+    border-bottom: 3px solid #ddd;
+    font-size: clamp(12px, 8px + 1vw, 16px);
+    padding: 1em;
+  }
+
+  td {
+    font-size: clamp(8px, 4px + 1vw, 14px);
+    padding: 0 clamp(0.25em, 0.1em + 1vw, 1em);
+  }
+
+  tr {
+    line-height: clamp(0.2em, 0.1em + 1.5vw, 1.5em);
+  }
+}
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.spec.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.spec.ts
new file mode 100644
index 000000000..d5c0d7072
--- /dev/null
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.spec.ts
@@ -0,0 +1,30 @@
+import {provideHttpClient} from '@angular/common/http';
+import {ComponentFixture, TestBed} from '@angular/core/testing';
+import {provideNoopAnimations} from '@angular/platform-browser/animations';
+import {provideRouter} from '@angular/router';
+
+import {DisaggDataComponent} from './disagg-data.component';
+
+describe('DisaggDataComponent', () => {
+  let component: DisaggDataComponent;
+  let fixture: ComponentFixture<DisaggDataComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [DisaggDataComponent],
+      providers: [
+        provideHttpClient(),
+        provideNoopAnimations(),
+        provideRouter([]),
+      ],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(DisaggDataComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.ts
new file mode 100644
index 000000000..092e0d9a1
--- /dev/null
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.ts
@@ -0,0 +1,50 @@
+import {AsyncPipe} from '@angular/common';
+import {Component, computed, Input} from '@angular/core';
+import {MatButton} from '@angular/material/button';
+import {MatDivider} from '@angular/material/divider';
+import {
+  DisaggComponentData,
+  DisaggData,
+} from '@ghsc/nshmp-utils-ts/libs/nshmp-haz/www/disagg-service';
+
+import {AppService} from '../../services/app.service';
+
+@Component({
+  imports: [AsyncPipe, MatDivider, MatButton],
+  selector: 'app-disagg-data',
+  standalone: true,
+  styleUrl: './disagg-data.component.scss',
+  templateUrl: './disagg-data.component.html',
+})
+export class DisaggDataComponent {
+  /** Disaggregation component data state */
+  @Input({required: true})
+  componentData: DisaggComponentData;
+
+  @Input()
+  showExportButton = true;
+
+  metadata = computed(() => this.service.serviceResponse().response.metadata);
+
+  constructor(public service: AppService) {}
+
+  toBinData(data: DisaggData): string[] {
+    const bins = this.service.serviceResponse().response.metadata.εbins;
+
+    const binData = bins.map(
+      bin => data.εdata.find(data => data.εbin === bin.id)?.value ?? 0
+    );
+
+    const total = binData.reduce((a, b) => a + b, 0);
+
+    return [total, ...binData].map(num => num.toExponential(2));
+  }
+
+  epsilonKeys(): string[] {
+    const keys = this.componentData.summary.find(
+      data => data.name.toLowerCase() === 'epsilon keys'
+    );
+
+    return ['ALL_ε', ...keys.data.map(data => `${data.name}=${data.value}`)];
+  }
+}
-- 
GitLab


From 7160363ca4ec68715846480b646555e5969fc387 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Fri, 13 Sep 2024 12:09:07 -0600
Subject: [PATCH 03/29] new full summary component

---
 .../full-summary/full-summary.component.html  | 57 +++++++++++++++++++
 .../full-summary/full-summary.component.scss  |  0
 .../full-summary.component.spec.ts            | 30 ++++++++++
 .../full-summary/full-summary.component.ts    | 31 ++++++++++
 4 files changed, 118 insertions(+)
 create mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
 create mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.scss
 create mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.spec.ts
 create mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.ts

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
new file mode 100644
index 000000000..71373182d
--- /dev/null
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
@@ -0,0 +1,57 @@
+<div class="height-full overflow-auto">
+  <div class="grid-container-widescreen">
+    <div class="padding-y-4">
+      <mat-card class="margin-bottom-2">
+        <mat-card-header>
+          <mat-card-title> Disaggregation Full Summary </mat-card-title>
+        </mat-card-header>
+
+        <mat-card-actions>
+          <div class="print-display-none padding-top-4">
+            <button
+              mat-raised-button
+              color="primary"
+              (click)="service.saveSummaryReport()"
+            >
+              Export Summary Report
+            </button>
+          </div>
+        </mat-card-actions>
+      </mat-card>
+
+      <mat-accordion multi>
+        @for (disagg of disaggData()?.data; track disagg) {
+          <mat-expansion-panel expanded>
+            <mat-expansion-panel-header>
+              <mat-panel-title
+                >Component: {{ disagg.component }}</mat-panel-title
+              >
+            </mat-expansion-panel-header>
+
+            <mat-divider />
+
+            <h2>Disaggregation Summary</h2>
+            <app-disagg-summary
+              [componentData]="disagg"
+              [showExportButton]="false"
+            />
+            <mat-divider />
+
+            <h2>Disaggregation Contributions</h2>
+            <app-disagg-contributors
+              [componentData]="disagg"
+              [showExportButton]="false"
+            />
+            <mat-divider />
+
+            <h2>Disaggregation Data</h2>
+            <app-disagg-data
+              [componentData]="disagg"
+              [showExportButton]="false"
+            />
+          </mat-expansion-panel>
+        }
+      </mat-accordion>
+    </div>
+  </div>
+</div>
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.scss b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.spec.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.spec.ts
new file mode 100644
index 000000000..2175210d1
--- /dev/null
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.spec.ts
@@ -0,0 +1,30 @@
+import {provideHttpClient} from '@angular/common/http';
+import {ComponentFixture, TestBed} from '@angular/core/testing';
+import {provideNoopAnimations} from '@angular/platform-browser/animations';
+import {provideRouter} from '@angular/router';
+
+import {FullSummaryComponent} from './full-summary.component';
+
+describe('FullSummaryComponent', () => {
+  let component: FullSummaryComponent;
+  let fixture: ComponentFixture<FullSummaryComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [FullSummaryComponent],
+      providers: [
+        provideHttpClient(),
+        provideNoopAnimations(),
+        provideRouter([]),
+      ],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(FullSummaryComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.ts
new file mode 100644
index 000000000..e6e82380e
--- /dev/null
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.ts
@@ -0,0 +1,31 @@
+import {Component} from '@angular/core';
+import {MatButton} from '@angular/material/button';
+import {MatCardModule} from '@angular/material/card';
+import {MatDivider} from '@angular/material/divider';
+import {MatExpansionModule} from '@angular/material/expansion';
+
+import {AppService} from '../../services/app.service';
+import {DisaggContributorsComponent} from '../disagg-contributors/disagg-contributors.component';
+import {DisaggDataComponent} from '../disagg-data/disagg-data.component';
+import {DisaggSummaryComponent} from '../disagg-summary/disagg-summary.component';
+
+@Component({
+  imports: [
+    MatExpansionModule,
+    DisaggSummaryComponent,
+    DisaggContributorsComponent,
+    DisaggDataComponent,
+    MatDivider,
+    MatButton,
+    MatCardModule,
+  ],
+  selector: 'app-full-summary',
+  standalone: true,
+  styleUrl: './full-summary.component.scss',
+  templateUrl: './full-summary.component.html',
+})
+export class FullSummaryComponent {
+  disaggData = this.service.disaggData;
+
+  constructor(public service: AppService) {}
+}
-- 
GitLab


From fe3c4562c950e7062ea8fb3a93448a6ef7cb4d83 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Fri, 13 Sep 2024 12:09:30 -0600
Subject: [PATCH 04/29] add tabs

---
 .../components/content/content.component.html | 139 +++++++++---------
 .../components/content/content.component.scss |   1 +
 .../components/content/content.component.ts   |  23 ++-
 3 files changed, 88 insertions(+), 75 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
index 2c11841d1..3b1f3e51a 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
@@ -1,81 +1,84 @@
-<div class="height-full overflow-auto">
-  <div class="grid-container-widescreen">
-    <!-- Report title, show only on print -->
-    <div class="print-content-only">
-      <h2>Disaggregation Report</h2>
-    </div>
+<mat-tab-group class="height-full" [preserveContent]="true">
+  <mat-tab label="Plots">
+    <div class="height-full overflow-auto report">
+      <div class="grid-container-widescreen">
+        <!-- Report title, show only on print -->
+        <div class="print-content-only">
+          <h2>Disaggregation Report</h2>
+        </div>
 
-    <div class="padding-y-4">
-      <mat-accordion multi>
-        <!-- Disagg plot panel -->
-        <mat-expansion-panel expanded class="disagg-panel">
-          <mat-expansion-panel-header>
-            <mat-panel-title>Disaggregation</mat-panel-title>
-          </mat-expansion-panel-header>
+        <div class="padding-y-4">
+          <mat-accordion multi>
+            <!-- Disagg plot panel -->
+            <mat-expansion-panel expanded class="disagg-panel">
+              <mat-expansion-panel-header>
+                <mat-panel-title>Disaggregation</mat-panel-title>
+              </mat-expansion-panel-header>
 
-          <app-plots />
-        </mat-expansion-panel>
+              <app-plots />
+            </mat-expansion-panel>
 
-        <!-- Geographical disagg panel -->
-        <mat-expansion-panel
-          [expanded]="hasLayers()"
-          [disabled]="hasLayers() === false"
-          class="geo-disagg-panel print-page-break"
-        >
-          <mat-expansion-panel-header>
-            <mat-panel-title>Geographical Disaggregation</mat-panel-title>
-          </mat-expansion-panel-header>
+            <!-- Geographical disagg panel -->
+            <mat-expansion-panel
+              [expanded]="hasLayers()"
+              [disabled]="hasLayers() === false"
+              class="geo-disagg-panel print-page-break"
+            >
+              <mat-expansion-panel-header>
+                <mat-panel-title>Geographical Disaggregation</mat-panel-title>
+              </mat-expansion-panel-header>
 
-          <mat-divider />
+              <mat-divider />
 
-          <app-geo-disagg />
-        </mat-expansion-panel>
+              <app-geo-disagg />
+            </mat-expansion-panel>
 
-        <!-- Parameter summary panel -->
-        <mat-expansion-panel expanded>
-          <mat-expansion-panel-header>
-            <mat-panel-title>Parameter Summary</mat-panel-title>
-          </mat-expansion-panel-header>
+            <!-- Parameter summary panel -->
+            <mat-expansion-panel expanded>
+              <mat-expansion-panel-header>
+                <mat-panel-title>Parameter Summary</mat-panel-title>
+              </mat-expansion-panel-header>
 
-          <app-parameter-summary />
-        </mat-expansion-panel>
+              <app-parameter-summary />
+            </mat-expansion-panel>
 
-        <!-- Summary report -->
-        <mat-expansion-panel
-          class="summary-report print-page-break"
-          [expanded]="disaggData()"
-          [disabled]="disaggData() === null"
-        >
-          <mat-expansion-panel-header>
-            <mat-panel-title>Disaggregation Summary</mat-panel-title>
-          </mat-expansion-panel-header>
+            <div class="print-content-only print-full-page">
+              <mat-expansion-panel class="print-page-break" expanded>
+                <app-disagg-summary [componentData]="componentData$ | async" />
+              </mat-expansion-panel>
+            </div>
 
-          <app-disagg-summary />
-        </mat-expansion-panel>
+            <div class="print-content-only print-full-page">
+              <mat-expansion-panel class="print-page-break" expanded>
+                <app-disagg-contributors
+                  [componentData]="componentData$ | async"
+                />
+              </mat-expansion-panel>
+            </div>
 
-        <!-- Contributions -->
-        <mat-expansion-panel
-          class="contributions print-page-break"
-          [expanded]="componentData() !== null"
-          [disabled]="componentData() === null"
-        >
-          <mat-expansion-panel-header>
-            <mat-panel-title>Disaggregation Contributions</mat-panel-title>
-          </mat-expansion-panel-header>
+            <!-- App metadata -->
+            <mat-expansion-panel
+              class="print-page-break print-full-page"
+              expanded
+            >
+              <mat-expansion-panel-header>
+                <mat-panel-title>Application Metadata</mat-panel-title>
+              </mat-expansion-panel-header>
 
-          <app-disagg-contributors />
-        </mat-expansion-panel>
+              <mat-divider />
+              <nshmp-lib-ng-app-metadata [repositories]="repositories()" />
+            </mat-expansion-panel>
+          </mat-accordion>
+        </div>
+      </div>
+    </div>
+  </mat-tab>
 
-        <!-- App metadata -->
-        <mat-expansion-panel expanded class="print-page-break">
-          <mat-expansion-panel-header>
-            <mat-panel-title>Application Metadata</mat-panel-title>
-          </mat-expansion-panel-header>
+  <mat-tab label="Component Summary">
+    <app-component-summary />
+  </mat-tab>
 
-          <mat-divider />
-          <nshmp-lib-ng-app-metadata [repositories]="repositories()" />
-        </mat-expansion-panel>
-      </mat-accordion>
-    </div>
-  </div>
-</div>
+  <mat-tab label="Full Summary">
+    <app-full-summary />
+  </mat-tab>
+</mat-tab-group>
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.scss b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.scss
index 3094eb336..50361509a 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.scss
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.scss
@@ -1,6 +1,7 @@
 @media print {
   mat-accordion {
     mat-expansion-panel {
+      overflow: visible;
       box-shadow: none !important;
     }
   }
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
index 1e50c4085..4a068e67b 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
@@ -1,3 +1,4 @@
+import {AsyncPipe} from '@angular/common';
 import {Component, computed} from '@angular/core';
 import {MatDivider} from '@angular/material/divider';
 import {
@@ -6,11 +7,15 @@ import {
   MatExpansionPanelHeader,
   MatExpansionPanelTitle,
 } from '@angular/material/expansion';
+import {MatTab, MatTabGroup} from '@angular/material/tabs';
 import {NshmpLibNgAppMetadataComponent} from '@ghsc/nshmp-lib-ng/nshmp';
+import {map} from 'rxjs';
 
 import {AppService} from '../../services/app.service';
+import {ComponentSummaryComponent} from '../component-summary/component-summary.component';
 import {DisaggContributorsComponent} from '../disagg-contributors/disagg-contributors.component';
 import {DisaggSummaryComponent} from '../disagg-summary/disagg-summary.component';
+import {FullSummaryComponent} from '../full-summary/full-summary.component';
 import {GeoDisaggComponent} from '../geo-disagg/geo-disagg.component';
 import {ParameterSummaryComponent} from '../parameter-summary/parameter-summary.component';
 import {PlotsComponent} from '../plots/plots.component';
@@ -32,9 +37,14 @@ import {PlotsComponent} from '../plots/plots.component';
     MatDivider,
     GeoDisaggComponent,
     ParameterSummaryComponent,
+    NshmpLibNgAppMetadataComponent,
+    MatTab,
+    MatTabGroup,
+    ComponentSummaryComponent,
+    FullSummaryComponent,
     DisaggSummaryComponent,
     DisaggContributorsComponent,
-    NshmpLibNgAppMetadataComponent,
+    AsyncPipe,
   ],
   selector: 'app-content',
   standalone: true,
@@ -42,6 +52,11 @@ import {PlotsComponent} from '../plots/plots.component';
   templateUrl: './content.component.html',
 })
 export class ContentComponent {
+  componentData$ =
+    this.service.formGroup.controls.disaggComponent.valueChanges.pipe(
+      map(() => this.service.componentData())
+    );
+
   /** Has geo disagg layers */
   hasLayers = computed(() => {
     const serviceResponse = this.service.serviceResponse();
@@ -61,12 +76,6 @@ export class ContentComponent {
     return layers !== undefined;
   });
 
-  /** Disaggregation component data */
-  componentData = this.service.componentData;
-
-  /** Disaggregation data */
-  disaggData = this.service.disaggData;
-
   /** Repo metadata */
   repositories = computed(() => this.service.usage()?.metadata.repositories);
 
-- 
GitLab


From af198f533007eb1c2b1e02a36013cd9474d7776a Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Fri, 13 Sep 2024 12:09:50 -0600
Subject: [PATCH 05/29] add inputs

---
 .../disagg-contributors.component.html        | 132 +++++++++---------
 .../disagg-contributors.component.ts          |  19 +--
 .../disagg-summary.component.html             |  26 ++--
 .../disagg-summary.component.ts               |  13 +-
 4 files changed, 100 insertions(+), 90 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-contributors/disagg-contributors.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-contributors/disagg-contributors.component.html
index 70779f8ec..e13aeab01 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-contributors/disagg-contributors.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-contributors/disagg-contributors.component.html
@@ -1,70 +1,74 @@
 <!-- Disagg contributions -->
-@if (componentData$ | async; as componentData) {
-  <div class="disagg-contributions">
-    @if (serviceResponse()) {
-      <div class="print-display-none">
-        <button
-          mat-raised-button
-          color="primary"
-          (click)="
-            service.saveContributions(componentData(), form.getRawValue())
-          "
-        >
-          Export as CSV
-        </button>
-      </div>
+@if (componentData) {
+  @if (componentData?.sources?.length > 0) {
+    <div class="disagg-contributions">
+      @if (serviceResponse()) {
+        @if (showExportButton) {
+          <div class="print-display-none">
+            <button
+              mat-raised-button
+              color="primary"
+              (click)="
+                service.saveContributions(componentData, form.getRawValue())
+              "
+            >
+              Export as CSV
+            </button>
+          </div>
 
-      <mat-divider />
+          <mat-divider />
+        }
 
-      <div class="horizontal-scrolling">
-        <div>
-          <table #table class="contributing-sources grid-col-12">
-            <thead>
-              <tr>
-                <th nowrap>
-                  Source Set
-                  <mat-icon
-                    class="down-arrow"
-                    aria-label="Down arrow icon"
-                    fontIcon="subdirectory_arrow_right"
-                  />
-                  Source
-                </th>
-                <th nowrap>Type</th>
-                <th nowrap title="Distance (km)">r</th>
-                <th nowrap title="Magnitude">m</th>
-                <th nowrap title="Epsilon (mean values)">ε<sub>0</sub></th>
-                <th nowrap title="Longitude">lon</th>
-                <th nowrap title="Latitude">lat</th>
-                <th nowrap title="Azimuth">az</th>
-                <th nowrap title="Percent contributed">%</th>
-              </tr>
-            </thead>
-
-            <tbody>
-              @for (data of componentData()?.sources; track data) {
-                <tr [ngClass]="{'contributor-set': data.type === 'SET'}">
-                  @if (data.type === 'SET') {
-                    <td nowrap>{{ data?.name }}</td>
-                    <td nowrap>{{ data?.source }}</td>
-                    <td colspan="6"></td>
-                  } @else {
-                    <td nowrap class="indent-name">{{ data?.name }}</td>
-                    <td></td>
-                    <td nowrap>{{ data?.r | number: '1.2-2' }}</td>
-                    <td nowrap>{{ data?.m | number: '1.2-2' }}</td>
-                    <td nowrap>{{ dataEpsilon(data) | number: '1.2-2' }}</td>
-                    <td nowrap>{{ data?.longitude | formatLongitude }}</td>
-                    <td nowrap>{{ data?.latitude | formatLatitude }}</td>
-                    <td nowrap>{{ data?.azimuth | number: '1.2-2' }}</td>
-                  }
-                  <td nowrap>{{ data?.contribution }}</td>
+        <div class="horizontal-scrolling">
+          <div>
+            <table #table class="contributing-sources grid-col-12">
+              <thead>
+                <tr>
+                  <th nowrap>
+                    Source Set
+                    <mat-icon
+                      class="down-arrow"
+                      aria-label="Down arrow icon"
+                      fontIcon="subdirectory_arrow_right"
+                    />
+                    Source
+                  </th>
+                  <th nowrap>Type</th>
+                  <th nowrap title="Distance (km)">r</th>
+                  <th nowrap title="Magnitude">m</th>
+                  <th nowrap title="Epsilon (mean values)">ε<sub>0</sub></th>
+                  <th nowrap title="Longitude">lon</th>
+                  <th nowrap title="Latitude">lat</th>
+                  <th nowrap title="Azimuth">az</th>
+                  <th nowrap title="Percent contributed">%</th>
                 </tr>
-              }
-            </tbody>
-          </table>
+              </thead>
+
+              <tbody>
+                @for (data of componentData?.sources; track data) {
+                  <tr [ngClass]="{'contributor-set': data.type === 'SET'}">
+                    @if (data.type === 'SET') {
+                      <td nowrap>{{ data?.name }}</td>
+                      <td nowrap>{{ data?.source }}</td>
+                      <td colspan="6"></td>
+                    } @else {
+                      <td nowrap class="indent-name">{{ data?.name }}</td>
+                      <td></td>
+                      <td nowrap>{{ data?.r | number: '1.2-2' }}</td>
+                      <td nowrap>{{ data?.m | number: '1.2-2' }}</td>
+                      <td nowrap>{{ dataEpsilon(data) | number: '1.2-2' }}</td>
+                      <td nowrap>{{ data?.longitude | formatLongitude }}</td>
+                      <td nowrap>{{ data?.latitude | formatLatitude }}</td>
+                      <td nowrap>{{ data?.azimuth | number: '1.2-2' }}</td>
+                    }
+                    <td nowrap>{{ data?.contribution }}</td>
+                  </tr>
+                }
+              </tbody>
+            </table>
+          </div>
         </div>
-      </div>
-    }
-  </div>
+      }
+    </div>
+  }
 }
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-contributors/disagg-contributors.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-contributors/disagg-contributors.component.ts
index 3b84a7e86..e0fa11c3c 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-contributors/disagg-contributors.component.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-contributors/disagg-contributors.component.ts
@@ -1,5 +1,5 @@
 import {AsyncPipe, DecimalPipe, NgClass} from '@angular/common';
-import {Component} from '@angular/core';
+import {Component, Input} from '@angular/core';
 import {MatButton} from '@angular/material/button';
 import {MatDivider} from '@angular/material/divider';
 import {MatIcon} from '@angular/material/icon';
@@ -7,8 +7,10 @@ import {
   FormatLatitudePipe,
   FormatLongitudePipe,
 } from '@ghsc/nshmp-lib-ng/hazard';
-import {DisaggSource} from '@ghsc/nshmp-utils-ts/libs/nshmp-haz/www/disagg-service';
-import {map} from 'rxjs';
+import {
+  DisaggComponentData,
+  DisaggSource,
+} from '@ghsc/nshmp-utils-ts/libs/nshmp-haz/www/disagg-service';
 
 import {AppService} from '../../services/app.service';
 
@@ -32,11 +34,12 @@ import {AppService} from '../../services/app.service';
   templateUrl: './disagg-contributors.component.html',
 })
 export class DisaggContributorsComponent {
-  /** Disaggregation data state */
-  componentData$ =
-    this.service.formGroup.controls.disaggComponent.valueChanges.pipe(
-      map(() => this.service.componentData)
-    );
+  /** Disaggregation component data state */
+  @Input({required: true})
+  componentData: DisaggComponentData;
+
+  @Input()
+  showExportButton = true;
 
   /** Form field state */
   form = this.service.formGroup;
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-summary/disagg-summary.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-summary/disagg-summary.component.html
index 18d9b7a89..2ed8ee819 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-summary/disagg-summary.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-summary/disagg-summary.component.html
@@ -1,21 +1,23 @@
-@if (componentData$ | async; as componentData) {
+@if (componentData) {
   <div class="disagg-summaries">
     <!-- Summaries -->
     <div class="summary-group">
-      <div class="print-display-none">
-        <button
-          mat-raised-button
-          color="primary"
-          (click)="service.saveSummary(componentData(), form.getRawValue())"
-        >
-          Export as Text
-        </button>
-      </div>
+      @if (showExportButton) {
+        <div class="print-display-none">
+          <button
+            mat-raised-button
+            color="primary"
+            (click)="service.saveSummary(componentData, form.getRawValue())"
+          >
+            Export as Text
+          </button>
+        </div>
 
-      <mat-divider />
+        <mat-divider />
+      }
 
       <div class="grid-row">
-        @for (summary of componentData()?.summary; track summary) {
+        @for (summary of componentData?.summary; track summary) {
           <div
             class="grid-col-12 mobile:grid-col-6 desktop-lg:grid-col-4 widescreen:grid-col-3 summary-values print-flex-basis-half"
           >
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-summary/disagg-summary.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-summary/disagg-summary.component.ts
index 78a0fb12a..95dc42462 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-summary/disagg-summary.component.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-summary/disagg-summary.component.ts
@@ -1,9 +1,9 @@
 import {AsyncPipe} from '@angular/common';
-import {Component} from '@angular/core';
+import {Component, Input} from '@angular/core';
 import {MatButton} from '@angular/material/button';
 import {MatDivider} from '@angular/material/divider';
 import {MatList, MatListItem} from '@angular/material/list';
-import {map} from 'rxjs';
+import {DisaggComponentData} from '@ghsc/nshmp-utils-ts/libs/nshmp-haz/www/disagg-service';
 
 import {AppService} from '../../services/app.service';
 
@@ -19,10 +19,11 @@ import {AppService} from '../../services/app.service';
 })
 export class DisaggSummaryComponent {
   /** Disaggregation component data state */
-  componentData$ =
-    this.service.formGroup.controls.disaggComponent.valueChanges.pipe(
-      map(() => this.service.componentData)
-    );
+  @Input({required: true})
+  componentData: DisaggComponentData;
+
+  @Input()
+  showExportButton = true;
 
   /** Form field state */
   form = this.service.formGroup;
-- 
GitLab


From cde23d1555d02dcab94ad11c6a933e47c8c50ec5 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Fri, 13 Sep 2024 12:10:14 -0600
Subject: [PATCH 06/29] save report

---
 .../app/hazard/disagg/services/app.service.ts | 156 ++++++++++++++----
 1 file changed, 128 insertions(+), 28 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/services/app.service.ts b/projects/nshmp-apps/src/app/hazard/disagg/services/app.service.ts
index a65a692aa..a1f041077 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/services/app.service.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/services/app.service.ts
@@ -1,15 +1,25 @@
 import {HttpClient} from '@angular/common/http';
-import {computed, Injectable, Signal, signal} from '@angular/core';
+import {
+  computed,
+  Inject,
+  Injectable,
+  LOCALE_ID,
+  Signal,
+  signal,
+} from '@angular/core';
 import {AbstractControl, FormBuilder, Validators} from '@angular/forms';
 import {ActivatedRoute, Router} from '@angular/router';
 import {
   DisaggControlForm,
   DisaggTarget,
+  FormatLatitudePipe,
   HazardService,
   hazardUtils,
+  ReturnPeriodPipe,
 } from '@ghsc/nshmp-lib-ng/hazard';
 import {
   NshmpService,
+  nshmpUtils,
   RETURN_PERIOD_BOUNDS,
   ReturnPeriod,
   ServiceCallInfo,
@@ -70,7 +80,8 @@ export class AppService
     private hazardService: HazardService,
     private route: ActivatedRoute,
     private router: Router,
-    private http: HttpClient
+    private http: HttpClient,
+    @Inject(LOCALE_ID) private localId: string
   ) {
     super();
     this.addValidators();
@@ -95,12 +106,10 @@ export class AppService
         return null;
       }
 
-      return [...serviceResponse.response.disaggs]
-        .pop()
-        .data.find(
-          disagg =>
-            disagg.component === this.formGroup.getRawValue().disaggComponent
-        );
+      return this.disaggData().data.find(
+        disagg =>
+          disagg.component === this.formGroup.getRawValue().disaggComponent
+      );
     });
   }
 
@@ -367,6 +376,17 @@ export class AppService
     this.nshmpService.saveAs(blob, `disagg-${data.component}.csv`);
   }
 
+  saveComponentSummaryReport(): void {
+    const blob = new Blob([this.summaryReportText(this.componentData())], {
+      type: 'text/csv;charset=utf-8;',
+    });
+
+    this.nshmpService.saveAs(
+      blob,
+      `disagg-summary-${this.componentData().component}.txt`
+    );
+  }
+
   /**
    * Save the contributions.
    *
@@ -396,6 +416,18 @@ export class AppService
     this.nshmpService.saveAs(blob, `disagg-summary-${data.component}.txt`);
   }
 
+  saveSummaryReport(): void {
+    const summaries = this.disaggData().data.map((data, index) =>
+      this.summaryReportText(data, index === 0)
+    );
+
+    const blob = new Blob(summaries, {
+      type: 'text/csv;charset=utf-8',
+    });
+
+    this.nshmpService.saveAs(blob, 'dissag-summary.txt');
+  }
+
   /**
    * Set the location form fields.
    *
@@ -446,20 +478,39 @@ export class AppService
    */
   private componentDataToCSV(
     componentData: DisaggComponentData,
-    formValues: DisaggControlForm
+    formValues: DisaggControlForm,
+    showMetadata = true
   ): string {
+    const metadata = this.serviceResponse().response.metadata;
+    const bins = metadata.εbins;
+    const keys = componentData.summary.find(
+      data => data.name.toLowerCase() === 'epsilon keys'
+    );
+
+    const headers = [
+      metadata.rlabel.replace(',', ' -'),
+      metadata.mlabel,
+      'ALL_ε',
+      ...keys.data.map(data => `${data.name}=${data.value}`),
+    ];
+
     const csv = componentData.data.map(data => {
-      const εbin = data.εdata.map(εdata => εdata.εbin).join(', ');
-      const values = data.εdata.map(εdata => εdata.value).join(', ');
-      return (
-        'r, m, rBar, mBar, εBar\n' +
-        `${data.r}, ${data.m}, ${data.rBar}, ${data.mBar}, ${data.εBar}\n\n` +
-        `εbin, ${εbin}\n` +
-        `Value, ${values}\n`
+      const εvalues = bins.map(
+        bin => data.εdata.find(data => data.εbin === bin.id)?.value ?? 0.0
       );
+      const sum = εvalues.reduce((a, b) => a + b, 0);
+      const values = [sum, ...εvalues]
+        .map(num => num.toExponential(3))
+        .join(', ');
+
+      return `${data.r}, ${data.m}, ${values}`;
     });
 
-    return `${this.metadataCSV(formValues)}\n\n\n` + csv.join('\n\n');
+    const table = `${headers.join(', ')}\n${csv.join('\n')}`;
+
+    return showMetadata
+      ? `${this.metadataCSV(formValues)}\n\n\n` + table
+      : table;
   }
 
   /**
@@ -470,10 +521,13 @@ export class AppService
    */
   private contributorsToCSV(
     sources: DisaggSource[],
-    formValues: DisaggControlForm
+    formValues: DisaggControlForm,
+    showMetadata = true
   ): string {
+    const label = 'Disaggregation Contributions';
+
     if (sources === null || sources.length === 0) {
-      throw new Error('No contributing sources');
+      return `${label}: N/A\n\n`;
     }
     const headers = 'Source Set ↳ Source, Type, r, m, ε0, lon, lat, az, %';
 
@@ -488,13 +542,12 @@ export class AppService
       })
       .map(source => source.replace(/null/gi, ''))
       .join('');
-    return (
-      '' +
-      `${this.metadataCSV(formValues)}\n\n` +
-      'Disaggregation Contributions\n' +
-      `${headers}\n` +
-      `${csv}`
-    );
+
+    const table = `${label}\n${headers}\n ${csv}\n\n`;
+
+    return showMetadata
+      ? `${this.metadataCSV(formValues)}\n\n ${table}`
+      : table;
   }
 
   private initialFormSet(): void {
@@ -570,6 +623,28 @@ export class AppService
     );
   }
 
+  private metadataText(formValues: DisaggControlForm): string {
+    const usage = this.usage().response;
+
+    const imt = usage.model.imts.find(
+      imt => imt.value === formValues.imt.toString()
+    )?.display;
+
+    const vs30 =
+      formValues.siteClass === nshmpUtils.selectPlaceHolder().value
+        ? `${formValues.vs30} m/s`
+        : `${formValues.vs30} m/s (${formValues.siteClass})`;
+
+    return (
+      `Model: ${usage.model.name}\n` +
+      `Longitude: ${new FormatLatitudePipe(this.localId).transform(formValues.longitude)} \n` +
+      `Latitude: ${new FormatLatitudePipe(this.localId).transform(formValues.latitude)} \n` +
+      `IMT: ${imt} \n` +
+      `Return Period: ${new ReturnPeriodPipe().transform(formValues.returnPeriod)} \n` +
+      `VS30: ${vs30} \n\n`
+    );
+  }
+
   /**
    * Build the URL to call the appropriate backend service with the given values.
    *
@@ -602,6 +677,28 @@ export class AppService
     }
   }
 
+  private summaryReportText(
+    componentData: DisaggComponentData,
+    showMetadata = true
+  ): string {
+    const formValues = this.formGroup.getRawValue();
+    const firstLine =
+      '*** Deaggregation of Seismic Hazard at One Period of Spectral Acceleration ***';
+    const metadata = showMetadata
+      ? `${firstLine}\n\n${this.metadataText(formValues)}`
+      : '';
+
+    return (
+      metadata +
+      `** Disaggregation Component: ${componentData.component} **\n\n` +
+      this.summaryToText(componentData.summary, formValues, false) +
+      '\n\n' +
+      this.componentDataToCSV(componentData, formValues, false) +
+      '\n\n' +
+      this.contributorsToCSV(componentData.sources, formValues, false)
+    );
+  }
+
   /**
    * Convert the disaggregation summaries to text.
    *
@@ -610,7 +707,8 @@ export class AppService
    */
   private summaryToText(
     summaries: DisaggSummary[],
-    formValues: DisaggControlForm
+    formValues: DisaggControlForm,
+    showMetadata = true
   ): string {
     const text = summaries.map(summary => {
       const name = summary.name;
@@ -621,7 +719,9 @@ export class AppService
       return `${name}:\n` + values.join('\n');
     });
 
-    return `${this.metadataCSV(formValues)}\n\n\n` + `${text.join('\n\n\n')}`;
+    return showMetadata
+      ? `${this.metadataCSV(formValues)}\n\n\n` + `${text.join('\n\n')}`
+      : `${text.join('\n\n')}`;
   }
 
   private updateUrl(): void {
-- 
GitLab


From fda16affe5a3693e14e1f986ccc768e5d51736b6 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Fri, 13 Sep 2024 12:10:21 -0600
Subject: [PATCH 07/29] add css

---
 projects/nshmp-apps/src/styles/_print.scss | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/projects/nshmp-apps/src/styles/_print.scss b/projects/nshmp-apps/src/styles/_print.scss
index b033dcec2..2103c6e0d 100644
--- a/projects/nshmp-apps/src/styles/_print.scss
+++ b/projects/nshmp-apps/src/styles/_print.scss
@@ -23,6 +23,14 @@
     page-break-before: always !important;
   }
 
+  .print-full-page {
+    height: 10in;
+  }
+
+  mat-tab-header {
+    display: none !important;
+  }
+
   mat-accordion {
     mat-expansion-panel {
       .mat-expansion-indicator {
-- 
GitLab


From ed87c18ce2f01f7dabaace77e16b50019db6df49 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Fri, 13 Sep 2024 12:19:49 -0600
Subject: [PATCH 08/29] add export buttons

---
 .../components/plots/plots.component.html     | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
index e0016b796..bac86fee0 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
@@ -11,16 +11,29 @@
     </button>
   </div>
 
-  <!-- Export button -->
+  <!-- Export component summary button -->
   <div>
     <button
       class="export-button"
       mat-raised-button
       color="primary"
       [disabled]="disaggData() === null"
-      (click)="service.saveComponentData()"
+      (click)="service.saveComponentSummaryReport()"
     >
-      Export Data as CSV
+      Export Component Summary
+    </button>
+  </div>
+
+  <!-- Export summary button -->
+  <div>
+    <button
+      class="export-button"
+      mat-raised-button
+      color="primary"
+      [disabled]="disaggData() === null"
+      (click)="service.saveSummaryReport()"
+    >
+      Export Full Summary
     </button>
   </div>
 </div>
-- 
GitLab


From dde008534ad403b2278c5d4882eddbefb8791c94 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Fri, 13 Sep 2024 13:04:32 -0600
Subject: [PATCH 09/29] add disabled check

---
 .../component-summary/component-summary.component.html        | 1 +
 .../hazard/disagg/components/content/content.component.html   | 4 ++--
 .../app/hazard/disagg/components/content/content.component.ts | 2 ++
 .../components/full-summary/full-summary.component.html       | 1 +
 4 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
index 7f8ebb294..6090306f6 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
@@ -28,6 +28,7 @@
               mat-raised-button
               color="primary"
               (click)="service.saveComponentSummaryReport()"
+              [disabled]="disaggData() === null"
             >
               Export Summary Report
             </button>
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
index 3b1f3e51a..be32844c8 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
@@ -74,11 +74,11 @@
     </div>
   </mat-tab>
 
-  <mat-tab label="Component Summary">
+  <mat-tab label="Component Summary" [disabled]="hasData() === false">
     <app-component-summary />
   </mat-tab>
 
-  <mat-tab label="Full Summary">
+  <mat-tab label="Full Summary" [disabled]="hasData() === false">
     <app-full-summary />
   </mat-tab>
 </mat-tab-group>
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
index 4a068e67b..9ff840fa7 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
@@ -57,6 +57,8 @@ export class ContentComponent {
       map(() => this.service.componentData())
     );
 
+  hasData = computed(() => this.service.serviceResponse() !== null);
+
   /** Has geo disagg layers */
   hasLayers = computed(() => {
     const serviceResponse = this.service.serviceResponse();
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
index 71373182d..12df295b6 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
@@ -12,6 +12,7 @@
               mat-raised-button
               color="primary"
               (click)="service.saveSummaryReport()"
+              [disabled]="disaggData() === null"
             >
               Export Summary Report
             </button>
-- 
GitLab


From 381aa01bc54c9260d0133047bf43b3614e450a79 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Mon, 16 Sep 2024 09:29:55 -0600
Subject: [PATCH 10/29] add array check

---
 .../component-summary/component-summary.component.html    | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
index 6090306f6..5daaab051 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
@@ -56,8 +56,8 @@
         <!-- Contributions -->
         <mat-expansion-panel
           class="contributions print-page-break"
-          [expanded]="(componentData$ | async) !== null"
-          [disabled]="(componentData$ | async) === null"
+          [expanded]="(componentData$ | async)?.sources.length > 0"
+          [disabled]="(componentData$ | async)?.sources.length === 0"
         >
           <mat-expansion-panel-header>
             <mat-panel-title
@@ -72,8 +72,8 @@
         <!-- Data -->
         <mat-expansion-panel
           class="print-page-break"
-          [expanded]="(componentData$ | async) !== null"
-          [disabled]="(componentData$ | async) === null"
+          [expanded]="(componentData$ | async)?.data.length > 0"
+          [disabled]="(componentData$ | async)?.data.length === 0"
         >
           <mat-expansion-panel-header>
             <mat-panel-title
-- 
GitLab


From 53db1656eb76b0726bc3e8c1a813f1b190978251 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Mon, 16 Sep 2024 09:30:44 -0600
Subject: [PATCH 11/29] laszy load disagg plot

---
 .../components/content/content.component.html | 124 +++++++++---------
 1 file changed, 64 insertions(+), 60 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
index be32844c8..9715ff773 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
@@ -1,77 +1,81 @@
-<mat-tab-group class="height-full" [preserveContent]="true">
+<mat-tab-group class="height-full">
   <mat-tab label="Plots">
-    <div class="height-full overflow-auto report">
-      <div class="grid-container-widescreen">
-        <!-- Report title, show only on print -->
-        <div class="print-content-only">
-          <h2>Disaggregation Report</h2>
-        </div>
-
-        <div class="padding-y-4">
-          <mat-accordion multi>
-            <!-- Disagg plot panel -->
-            <mat-expansion-panel expanded class="disagg-panel">
-              <mat-expansion-panel-header>
-                <mat-panel-title>Disaggregation</mat-panel-title>
-              </mat-expansion-panel-header>
+    <ng-template matTabContent>
+      <div class="height-full overflow-auto report">
+        <div class="grid-container-widescreen">
+          <!-- Report title, show only on print -->
+          <div class="print-content-only">
+            <h2>Disaggregation Report</h2>
+          </div>
 
-              <app-plots />
-            </mat-expansion-panel>
+          <div class="padding-y-4">
+            <mat-accordion multi>
+              <!-- Disagg plot panel -->
+              <mat-expansion-panel expanded class="disagg-panel">
+                <mat-expansion-panel-header>
+                  <mat-panel-title>Disaggregation</mat-panel-title>
+                </mat-expansion-panel-header>
 
-            <!-- Geographical disagg panel -->
-            <mat-expansion-panel
-              [expanded]="hasLayers()"
-              [disabled]="hasLayers() === false"
-              class="geo-disagg-panel print-page-break"
-            >
-              <mat-expansion-panel-header>
-                <mat-panel-title>Geographical Disaggregation</mat-panel-title>
-              </mat-expansion-panel-header>
+                <app-plots />
+              </mat-expansion-panel>
 
-              <mat-divider />
+              <!-- Geographical disagg panel -->
+              <mat-expansion-panel
+                [expanded]="hasLayers()"
+                [disabled]="hasLayers() === false"
+                class="geo-disagg-panel print-page-break"
+              >
+                <mat-expansion-panel-header>
+                  <mat-panel-title>Geographical Disaggregation</mat-panel-title>
+                </mat-expansion-panel-header>
 
-              <app-geo-disagg />
-            </mat-expansion-panel>
+                <mat-divider />
 
-            <!-- Parameter summary panel -->
-            <mat-expansion-panel expanded>
-              <mat-expansion-panel-header>
-                <mat-panel-title>Parameter Summary</mat-panel-title>
-              </mat-expansion-panel-header>
+                <app-geo-disagg />
+              </mat-expansion-panel>
 
-              <app-parameter-summary />
-            </mat-expansion-panel>
+              <!-- Parameter summary panel -->
+              <mat-expansion-panel expanded>
+                <mat-expansion-panel-header>
+                  <mat-panel-title>Parameter Summary</mat-panel-title>
+                </mat-expansion-panel-header>
 
-            <div class="print-content-only print-full-page">
-              <mat-expansion-panel class="print-page-break" expanded>
-                <app-disagg-summary [componentData]="componentData$ | async" />
+                <app-parameter-summary />
               </mat-expansion-panel>
-            </div>
 
-            <div class="print-content-only print-full-page">
-              <mat-expansion-panel class="print-page-break" expanded>
-                <app-disagg-contributors
-                  [componentData]="componentData$ | async"
-                />
-              </mat-expansion-panel>
-            </div>
+              <div class="print-content-only print-full-page">
+                <mat-expansion-panel class="print-page-break" expanded>
+                  <app-disagg-summary
+                    [componentData]="componentData$ | async"
+                  />
+                </mat-expansion-panel>
+              </div>
+
+              <div class="print-content-only print-full-page">
+                <mat-expansion-panel class="print-page-break" expanded>
+                  <app-disagg-contributors
+                    [componentData]="componentData$ | async"
+                  />
+                </mat-expansion-panel>
+              </div>
 
-            <!-- App metadata -->
-            <mat-expansion-panel
-              class="print-page-break print-full-page"
-              expanded
-            >
-              <mat-expansion-panel-header>
-                <mat-panel-title>Application Metadata</mat-panel-title>
-              </mat-expansion-panel-header>
+              <!-- App metadata -->
+              <mat-expansion-panel
+                class="print-page-break print-full-page"
+                expanded
+              >
+                <mat-expansion-panel-header>
+                  <mat-panel-title>Application Metadata</mat-panel-title>
+                </mat-expansion-panel-header>
 
-              <mat-divider />
-              <nshmp-lib-ng-app-metadata [repositories]="repositories()" />
-            </mat-expansion-panel>
-          </mat-accordion>
+                <mat-divider />
+                <nshmp-lib-ng-app-metadata [repositories]="repositories()" />
+              </mat-expansion-panel>
+            </mat-accordion>
+          </div>
         </div>
       </div>
-    </div>
+    </ng-template>
   </mat-tab>
 
   <mat-tab label="Component Summary" [disabled]="hasData() === false">
-- 
GitLab


From c0a5a4063c946216165902b78c89515fe961f584 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Mon, 16 Sep 2024 09:30:56 -0600
Subject: [PATCH 12/29] simplify imports

---
 .../components/content/content.component.ts     | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
index 9ff840fa7..c97ff5d63 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
@@ -1,13 +1,8 @@
 import {AsyncPipe} from '@angular/common';
 import {Component, computed} from '@angular/core';
 import {MatDivider} from '@angular/material/divider';
-import {
-  MatAccordion,
-  MatExpansionPanel,
-  MatExpansionPanelHeader,
-  MatExpansionPanelTitle,
-} from '@angular/material/expansion';
-import {MatTab, MatTabGroup} from '@angular/material/tabs';
+import {MatExpansionModule} from '@angular/material/expansion';
+import {MatTabsModule} from '@angular/material/tabs';
 import {NshmpLibNgAppMetadataComponent} from '@ghsc/nshmp-lib-ng/nshmp';
 import {map} from 'rxjs';
 
@@ -29,17 +24,13 @@ import {PlotsComponent} from '../plots/plots.component';
  */
 @Component({
   imports: [
-    MatAccordion,
-    MatExpansionPanel,
-    MatExpansionPanelHeader,
-    MatExpansionPanelTitle,
+    MatExpansionModule,
     PlotsComponent,
     MatDivider,
     GeoDisaggComponent,
     ParameterSummaryComponent,
     NshmpLibNgAppMetadataComponent,
-    MatTab,
-    MatTabGroup,
+    MatTabsModule,
     ComponentSummaryComponent,
     FullSummaryComponent,
     DisaggSummaryComponent,
-- 
GitLab


From ae73c3d1a70082db9b1f2ee8f71dcc1f44912705 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Mon, 16 Sep 2024 11:09:27 -0600
Subject: [PATCH 13/29] toglle panels in full summary

---
 .../full-summary/full-summary.component.html  | 70 ++++++++++++++-----
 .../full-summary/full-summary.component.ts    |  6 +-
 2 files changed, 55 insertions(+), 21 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
index 12df295b6..cba9d6433 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
@@ -6,7 +6,7 @@
           <mat-card-title> Disaggregation Full Summary </mat-card-title>
         </mat-card-header>
 
-        <mat-card-actions>
+        <mat-card-content>
           <div class="print-display-none padding-top-4">
             <button
               mat-raised-button
@@ -17,12 +17,42 @@
               Export Summary Report
             </button>
           </div>
+        </mat-card-content>
+
+        <mat-card-actions>
+          <div class="print-display-none padding-right-4">
+            <button
+              mat-raised-button
+              color="primary"
+              [disabled]="disaggData() === null"
+              (click)="panels().openAll()"
+            >
+              Expand All Panels
+            </button>
+          </div>
+
+          <div class="print-display-none">
+            <button
+              mat-raised-button
+              color="primary"
+              [disabled]="disaggData() === null"
+              (click)="panels().closeAll()"
+            >
+              Close All Panels
+            </button>
+          </div>
+
+          <!--
+          Action to expanded all panels and action to cloase all
+
+          Close by default?
+          -->
         </mat-card-actions>
       </mat-card>
 
       <mat-accordion multi>
         @for (disagg of disaggData()?.data; track disagg) {
-          <mat-expansion-panel expanded>
+          <mat-expansion-panel>
             <mat-expansion-panel-header>
               <mat-panel-title
                 >Component: {{ disagg.component }}</mat-panel-title
@@ -31,25 +61,27 @@
 
             <mat-divider />
 
-            <h2>Disaggregation Summary</h2>
-            <app-disagg-summary
-              [componentData]="disagg"
-              [showExportButton]="false"
-            />
-            <mat-divider />
+            <ng-template matExpansionPanelContent>
+              <h2>Disaggregation Summary</h2>
+              <app-disagg-summary
+                [componentData]="disagg"
+                [showExportButton]="false"
+              />
+              <mat-divider />
 
-            <h2>Disaggregation Contributions</h2>
-            <app-disagg-contributors
-              [componentData]="disagg"
-              [showExportButton]="false"
-            />
-            <mat-divider />
+              <h2>Disaggregation Contributions</h2>
+              <app-disagg-contributors
+                [componentData]="disagg"
+                [showExportButton]="false"
+              />
+              <mat-divider />
 
-            <h2>Disaggregation Data</h2>
-            <app-disagg-data
-              [componentData]="disagg"
-              [showExportButton]="false"
-            />
+              <h2>Disaggregation Data</h2>
+              <app-disagg-data
+                [componentData]="disagg"
+                [showExportButton]="false"
+              />
+            </ng-template>
           </mat-expansion-panel>
         }
       </mat-accordion>
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.ts
index e6e82380e..5b52886b0 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.ts
@@ -1,8 +1,8 @@
-import {Component} from '@angular/core';
+import {Component, viewChild} from '@angular/core';
 import {MatButton} from '@angular/material/button';
 import {MatCardModule} from '@angular/material/card';
 import {MatDivider} from '@angular/material/divider';
-import {MatExpansionModule} from '@angular/material/expansion';
+import {MatAccordion, MatExpansionModule} from '@angular/material/expansion';
 
 import {AppService} from '../../services/app.service';
 import {DisaggContributorsComponent} from '../disagg-contributors/disagg-contributors.component';
@@ -27,5 +27,7 @@ import {DisaggSummaryComponent} from '../disagg-summary/disagg-summary.component
 export class FullSummaryComponent {
   disaggData = this.service.disaggData;
 
+  panels = viewChild.required(MatAccordion);
+
   constructor(public service: AppService) {}
 }
-- 
GitLab


From 1f89335a7cc587987124783ca14c92b0bd3cb4d2 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Mon, 16 Sep 2024 13:02:37 -0600
Subject: [PATCH 14/29] update deps

---
 package-lock.json | 8 ++++----
 package.json      | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 593966d57..ed8e49cd7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,7 +21,7 @@
         "@asymmetrik/ngx-leaflet": "^18.0.1",
         "@compodoc/compodoc": "^1.1.25",
         "@ghsc/disagg-d3": "^0.9.0",
-        "@ghsc/nshmp-lib-ng": "^18.15.0",
+        "@ghsc/nshmp-lib-ng": "^18.9.1",
         "@ghsc/nshmp-template": "^18.0.3",
         "@ghsc/nshmp-utils-ts": "^3.8.1",
         "angular-plotly.js": "^6.0.0",
@@ -4281,9 +4281,9 @@
       }
     },
     "node_modules/@ghsc/nshmp-lib-ng": {
-      "version": "18.15.0",
-      "resolved": "https://code.usgs.gov/api/v4/projects/12416/packages/npm/@ghsc/nshmp-lib-ng/-/@ghsc/nshmp-lib-ng-18.15.0.tgz",
-      "integrity": "sha1-3MS89MMp78znBiSMTqAki+PGrso=",
+      "version": "18.9.1",
+      "resolved": "https://code.usgs.gov/api/v4/projects/12416/packages/npm/@ghsc/nshmp-lib-ng/-/@ghsc/nshmp-lib-ng-18.9.1.tgz",
+      "integrity": "sha1-HKufPGK4O76X6Cnf2WhK/hNqd4g=",
       "dependencies": {
         "tslib": "^2.3.0"
       },
diff --git a/package.json b/package.json
index 43b7c9b6c..ee25b90c1 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
     "@asymmetrik/ngx-leaflet": "^18.0.1",
     "@compodoc/compodoc": "^1.1.25",
     "@ghsc/disagg-d3": "^0.9.0",
-    "@ghsc/nshmp-lib-ng": "^18.15.0",
+    "@ghsc/nshmp-lib-ng": "^18.9.1",
     "@ghsc/nshmp-template": "^18.0.3",
     "@ghsc/nshmp-utils-ts": "^3.8.1",
     "angular-plotly.js": "^6.0.0",
-- 
GitLab


From 50687780acab9da57453a26711c02681b02c6dd0 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Mon, 16 Sep 2024 15:13:44 -0600
Subject: [PATCH 15/29] update deps

---
 package-lock.json | 8 ++++----
 package.json      | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index ed8e49cd7..7aa7743a5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,7 +21,7 @@
         "@asymmetrik/ngx-leaflet": "^18.0.1",
         "@compodoc/compodoc": "^1.1.25",
         "@ghsc/disagg-d3": "^0.9.0",
-        "@ghsc/nshmp-lib-ng": "^18.9.1",
+        "@ghsc/nshmp-lib-ng": "^18.10.0",
         "@ghsc/nshmp-template": "^18.0.3",
         "@ghsc/nshmp-utils-ts": "^3.8.1",
         "angular-plotly.js": "^6.0.0",
@@ -4281,9 +4281,9 @@
       }
     },
     "node_modules/@ghsc/nshmp-lib-ng": {
-      "version": "18.9.1",
-      "resolved": "https://code.usgs.gov/api/v4/projects/12416/packages/npm/@ghsc/nshmp-lib-ng/-/@ghsc/nshmp-lib-ng-18.9.1.tgz",
-      "integrity": "sha1-HKufPGK4O76X6Cnf2WhK/hNqd4g=",
+      "version": "18.10.0",
+      "resolved": "https://code.usgs.gov/api/v4/projects/12416/packages/npm/@ghsc/nshmp-lib-ng/-/@ghsc/nshmp-lib-ng-18.10.0.tgz",
+      "integrity": "sha1-Z21zSauQre5x7AyZoCFv4wlqqWw=",
       "dependencies": {
         "tslib": "^2.3.0"
       },
diff --git a/package.json b/package.json
index ee25b90c1..317ee88b2 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
     "@asymmetrik/ngx-leaflet": "^18.0.1",
     "@compodoc/compodoc": "^1.1.25",
     "@ghsc/disagg-d3": "^0.9.0",
-    "@ghsc/nshmp-lib-ng": "^18.9.1",
+    "@ghsc/nshmp-lib-ng": "^18.10.0",
     "@ghsc/nshmp-template": "^18.0.3",
     "@ghsc/nshmp-utils-ts": "^3.8.1",
     "angular-plotly.js": "^6.0.0",
-- 
GitLab


From 3e3cafe8f1241d727c7de78050cc69007b4738ed Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Mon, 16 Sep 2024 16:14:11 -0600
Subject: [PATCH 16/29] update deps

---
 package-lock.json | 8 ++++----
 package.json      | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 7aa7743a5..09bdb170e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,7 +20,7 @@
         "@angular/router": "18.1.1",
         "@asymmetrik/ngx-leaflet": "^18.0.1",
         "@compodoc/compodoc": "^1.1.25",
-        "@ghsc/disagg-d3": "^0.9.0",
+        "@ghsc/disagg-d3": "^0.11.0",
         "@ghsc/nshmp-lib-ng": "^18.10.0",
         "@ghsc/nshmp-template": "^18.0.3",
         "@ghsc/nshmp-utils-ts": "^3.8.1",
@@ -4272,9 +4272,9 @@
       "license": "MIT"
     },
     "node_modules/@ghsc/disagg-d3": {
-      "version": "0.9.0",
-      "resolved": "https://code.usgs.gov/api/v4/projects/4335/packages/npm/@ghsc/disagg-d3/-/@ghsc/disagg-d3-0.9.0.tgz",
-      "integrity": "sha1-FFrDhBgysXUcubuws7o7yK1WrCQ=",
+      "version": "0.11.0",
+      "resolved": "https://code.usgs.gov/api/v4/projects/4335/packages/npm/@ghsc/disagg-d3/-/@ghsc/disagg-d3-0.11.0.tgz",
+      "integrity": "sha1-ZnUPHhgMLS5z2OKuQ2rylyoVT/U=",
       "dependencies": {
         "@ghsc/nshmp-utils-ts": "^3.0.0",
         "d3": "^7.6.1"
diff --git a/package.json b/package.json
index 317ee88b2..960b1ef8b 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,7 @@
     "@angular/router": "18.1.1",
     "@asymmetrik/ngx-leaflet": "^18.0.1",
     "@compodoc/compodoc": "^1.1.25",
-    "@ghsc/disagg-d3": "^0.9.0",
+    "@ghsc/disagg-d3": "^0.11.0",
     "@ghsc/nshmp-lib-ng": "^18.10.0",
     "@ghsc/nshmp-template": "^18.0.3",
     "@ghsc/nshmp-utils-ts": "^3.8.1",
-- 
GitLab


From 1b983836217d5c992536284537aa2b6a312733e6 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Mon, 16 Sep 2024 16:17:50 -0600
Subject: [PATCH 17/29] clean

---
 .../components/full-summary/full-summary.component.html     | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
index cba9d6433..2d19ce1f0 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
@@ -41,12 +41,6 @@
               Close All Panels
             </button>
           </div>
-
-          <!--
-          Action to expanded all panels and action to cloase all
-
-          Close by default?
-          -->
         </mat-card-actions>
       </mat-card>
 
-- 
GitLab


From e08610fb6eba6a68ca88abbaf92cd0d2cadfca30 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Mon, 16 Sep 2024 16:18:02 -0600
Subject: [PATCH 18/29] add sliders

---
 .../components/plots/plots.component.html     | 40 +++++++++++++++++++
 .../components/plots/plots.component.ts       | 30 +++++++++++++-
 2 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
index bac86fee0..18e337e2e 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
@@ -62,9 +62,49 @@
 
 <!-- Disagg plot -->
 <nshmp-lib-ng-hazard-disagg-plot
+  #disaggPlot
   [inputs]="{
+    allowDrag: true,
     component: form.value.disaggComponent,
     imt: form.value.imt,
     responseData: serviceResponse()?.response,
   }"
 />
+
+<div>
+  <div>
+    X:
+    <mat-slider min="-330" max="300" step="1">
+      <input
+        type="range"
+        matSliderThumb
+        [(ngModel)]="cameraOrigin.x"
+        (valueChange)="setOrigin()"
+      />
+    </mat-slider>
+  </div>
+
+  <div>
+    Y:
+    <mat-slider min="-330" max="300" step="1">
+      <input
+        type="range"
+        matSliderThumb
+        [(ngModel)]="cameraOrigin.y"
+        (valueChange)="setOrigin()"
+      />
+    </mat-slider>
+  </div>
+
+  <div>
+    Z:
+    <mat-slider min="-330" max="300" step="1">
+      <input
+        type="range"
+        matSliderThumb
+        [(ngModel)]="cameraOrigin.z"
+        (valueChange)="setOrigin()"
+      />
+    </mat-slider>
+  </div>
+</div>
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.ts
index 9e5b92f31..e23c0ffa0 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.ts
@@ -1,16 +1,23 @@
 import {AsyncPipe} from '@angular/common';
-import {Component} from '@angular/core';
-import {ReactiveFormsModule} from '@angular/forms';
+import {Component, viewChild} from '@angular/core';
+import {FormsModule, ReactiveFormsModule} from '@angular/forms';
 import {MatButton} from '@angular/material/button';
 import {MatOption} from '@angular/material/core';
 import {MatDivider} from '@angular/material/divider';
 import {MatFormField, MatLabel} from '@angular/material/form-field';
 import {MatSelect} from '@angular/material/select';
+import {MatSliderModule} from '@angular/material/slider';
 import {NshmpLibNgHazardDisaggPlotComponent} from '@ghsc/nshmp-lib-ng/hazard';
 import {NshmpTemplateService} from '@ghsc/nshmp-template';
 
 import {AppService} from '../../services/app.service';
 
+interface CameraOrigin {
+  x: number;
+  y: number;
+  z: number;
+}
+
 /**
  * Disaggregation plot with select menu of component.
  */
@@ -25,6 +32,8 @@ import {AppService} from '../../services/app.service';
     MatOption,
     AsyncPipe,
     ReactiveFormsModule,
+    MatSliderModule,
+    FormsModule,
   ],
   selector: 'app-plots',
   standalone: true,
@@ -39,6 +48,14 @@ export class PlotsComponent {
   /** Disaggreagtion service response */
   serviceResponse = this.service.serviceResponse;
 
+  cameraOrigin: CameraOrigin = {
+    x: 280,
+    y: -150,
+    z: 180,
+  };
+
+  disaggPlot = viewChild.required(NshmpLibNgHazardDisaggPlotComponent);
+
   constructor(
     public service: AppService,
     public templateService: NshmpTemplateService
@@ -48,4 +65,13 @@ export class PlotsComponent {
   exportReport(): void {
     print();
   }
+
+  setOrigin(): void {
+    // eslint-disable-next-line @typescript-eslint/no-unsafe-call
+    this.disaggPlot().view.setOrigin(
+      this.cameraOrigin.x,
+      this.cameraOrigin.y,
+      this.cameraOrigin.z
+    );
+  }
 }
-- 
GitLab


From 24f4e389ccb5c070e958636263304223d36644a6 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Tue, 17 Sep 2024 09:24:45 -0600
Subject: [PATCH 19/29] remove sliders

---
 .../components/plots/plots.component.html     | 38 -------------------
 .../components/plots/plots.component.ts       | 21 ----------
 2 files changed, 59 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
index 18e337e2e..e423fe417 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
@@ -70,41 +70,3 @@
     responseData: serviceResponse()?.response,
   }"
 />
-
-<div>
-  <div>
-    X:
-    <mat-slider min="-330" max="300" step="1">
-      <input
-        type="range"
-        matSliderThumb
-        [(ngModel)]="cameraOrigin.x"
-        (valueChange)="setOrigin()"
-      />
-    </mat-slider>
-  </div>
-
-  <div>
-    Y:
-    <mat-slider min="-330" max="300" step="1">
-      <input
-        type="range"
-        matSliderThumb
-        [(ngModel)]="cameraOrigin.y"
-        (valueChange)="setOrigin()"
-      />
-    </mat-slider>
-  </div>
-
-  <div>
-    Z:
-    <mat-slider min="-330" max="300" step="1">
-      <input
-        type="range"
-        matSliderThumb
-        [(ngModel)]="cameraOrigin.z"
-        (valueChange)="setOrigin()"
-      />
-    </mat-slider>
-  </div>
-</div>
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.ts
index e23c0ffa0..19656ca37 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.ts
@@ -12,12 +12,6 @@ import {NshmpTemplateService} from '@ghsc/nshmp-template';
 
 import {AppService} from '../../services/app.service';
 
-interface CameraOrigin {
-  x: number;
-  y: number;
-  z: number;
-}
-
 /**
  * Disaggregation plot with select menu of component.
  */
@@ -48,12 +42,6 @@ export class PlotsComponent {
   /** Disaggreagtion service response */
   serviceResponse = this.service.serviceResponse;
 
-  cameraOrigin: CameraOrigin = {
-    x: 280,
-    y: -150,
-    z: 180,
-  };
-
   disaggPlot = viewChild.required(NshmpLibNgHazardDisaggPlotComponent);
 
   constructor(
@@ -65,13 +53,4 @@ export class PlotsComponent {
   exportReport(): void {
     print();
   }
-
-  setOrigin(): void {
-    // eslint-disable-next-line @typescript-eslint/no-unsafe-call
-    this.disaggPlot().view.setOrigin(
-      this.cameraOrigin.x,
-      this.cameraOrigin.y,
-      this.cameraOrigin.z
-    );
-  }
 }
-- 
GitLab


From 99687c352c2eb00f24b4c3fd1217c77ab3543e23 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Tue, 17 Sep 2024 09:27:14 -0600
Subject: [PATCH 20/29] change to accent color

---
 .../components/full-summary/full-summary.component.html       | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
index 2d19ce1f0..10525c37e 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
@@ -23,7 +23,7 @@
           <div class="print-display-none padding-right-4">
             <button
               mat-raised-button
-              color="primary"
+              color="accent"
               [disabled]="disaggData() === null"
               (click)="panels().openAll()"
             >
@@ -34,7 +34,7 @@
           <div class="print-display-none">
             <button
               mat-raised-button
-              color="primary"
+              color="accent"
               [disabled]="disaggData() === null"
               (click)="panels().closeAll()"
             >
-- 
GitLab


From b4b024d85cf69473aec83087c1c43e40923aeca8 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Tue, 17 Sep 2024 10:37:43 -0600
Subject: [PATCH 21/29] update deps

---
 package-lock.json | 16 ++++++++--------
 package.json      |  4 ++--
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 09bdb170e..3659ca41b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,8 +20,8 @@
         "@angular/router": "18.1.1",
         "@asymmetrik/ngx-leaflet": "^18.0.1",
         "@compodoc/compodoc": "^1.1.25",
-        "@ghsc/disagg-d3": "^0.11.0",
-        "@ghsc/nshmp-lib-ng": "^18.10.0",
+        "@ghsc/disagg-d3": "^0.11.1",
+        "@ghsc/nshmp-lib-ng": "^18.10.1",
         "@ghsc/nshmp-template": "^18.0.3",
         "@ghsc/nshmp-utils-ts": "^3.8.1",
         "angular-plotly.js": "^6.0.0",
@@ -4272,18 +4272,18 @@
       "license": "MIT"
     },
     "node_modules/@ghsc/disagg-d3": {
-      "version": "0.11.0",
-      "resolved": "https://code.usgs.gov/api/v4/projects/4335/packages/npm/@ghsc/disagg-d3/-/@ghsc/disagg-d3-0.11.0.tgz",
-      "integrity": "sha1-ZnUPHhgMLS5z2OKuQ2rylyoVT/U=",
+      "version": "0.11.1",
+      "resolved": "https://code.usgs.gov/api/v4/projects/4335/packages/npm/@ghsc/disagg-d3/-/@ghsc/disagg-d3-0.11.1.tgz",
+      "integrity": "sha1-+OURoMrE1N5mmYfD2cQjC0xUGuE=",
       "dependencies": {
         "@ghsc/nshmp-utils-ts": "^3.0.0",
         "d3": "^7.6.1"
       }
     },
     "node_modules/@ghsc/nshmp-lib-ng": {
-      "version": "18.10.0",
-      "resolved": "https://code.usgs.gov/api/v4/projects/12416/packages/npm/@ghsc/nshmp-lib-ng/-/@ghsc/nshmp-lib-ng-18.10.0.tgz",
-      "integrity": "sha1-Z21zSauQre5x7AyZoCFv4wlqqWw=",
+      "version": "18.10.1",
+      "resolved": "https://code.usgs.gov/api/v4/projects/12416/packages/npm/@ghsc/nshmp-lib-ng/-/@ghsc/nshmp-lib-ng-18.10.1.tgz",
+      "integrity": "sha1-aFF4wuaOzgaR6aUX0YyhyD8bNig=",
       "dependencies": {
         "tslib": "^2.3.0"
       },
diff --git a/package.json b/package.json
index 960b1ef8b..2bbe98d65 100644
--- a/package.json
+++ b/package.json
@@ -44,8 +44,8 @@
     "@angular/router": "18.1.1",
     "@asymmetrik/ngx-leaflet": "^18.0.1",
     "@compodoc/compodoc": "^1.1.25",
-    "@ghsc/disagg-d3": "^0.11.0",
-    "@ghsc/nshmp-lib-ng": "^18.10.0",
+    "@ghsc/disagg-d3": "^0.11.1",
+    "@ghsc/nshmp-lib-ng": "^18.10.1",
     "@ghsc/nshmp-template": "^18.0.3",
     "@ghsc/nshmp-utils-ts": "^3.8.1",
     "angular-plotly.js": "^6.0.0",
-- 
GitLab


From 90b222f9be62cd9422a25184c3f8136608d344f3 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Tue, 17 Sep 2024 10:53:46 -0600
Subject: [PATCH 22/29] remove allow drag

---
 .../src/app/hazard/disagg/components/plots/plots.component.html  | 1 -
 1 file changed, 1 deletion(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
index e423fe417..ed0b48bca 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
@@ -64,7 +64,6 @@
 <nshmp-lib-ng-hazard-disagg-plot
   #disaggPlot
   [inputs]="{
-    allowDrag: true,
     component: form.value.disaggComponent,
     imt: form.value.imt,
     responseData: serviceResponse()?.response,
-- 
GitLab


From 84a38cccd10fcc43470fa9b02d554ee1cd809c86 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Tue, 17 Sep 2024 14:55:49 -0600
Subject: [PATCH 23/29] update deps

---
 package-lock.json | 16 ++++++++--------
 package.json      |  4 ++--
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 3659ca41b..ae8cdbe55 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,8 +20,8 @@
         "@angular/router": "18.1.1",
         "@asymmetrik/ngx-leaflet": "^18.0.1",
         "@compodoc/compodoc": "^1.1.25",
-        "@ghsc/disagg-d3": "^0.11.1",
-        "@ghsc/nshmp-lib-ng": "^18.10.1",
+        "@ghsc/disagg-d3": "^0.12.0",
+        "@ghsc/nshmp-lib-ng": "^18.11.0",
         "@ghsc/nshmp-template": "^18.0.3",
         "@ghsc/nshmp-utils-ts": "^3.8.1",
         "angular-plotly.js": "^6.0.0",
@@ -4272,18 +4272,18 @@
       "license": "MIT"
     },
     "node_modules/@ghsc/disagg-d3": {
-      "version": "0.11.1",
-      "resolved": "https://code.usgs.gov/api/v4/projects/4335/packages/npm/@ghsc/disagg-d3/-/@ghsc/disagg-d3-0.11.1.tgz",
-      "integrity": "sha1-+OURoMrE1N5mmYfD2cQjC0xUGuE=",
+      "version": "0.12.0",
+      "resolved": "https://code.usgs.gov/api/v4/projects/4335/packages/npm/@ghsc/disagg-d3/-/@ghsc/disagg-d3-0.12.0.tgz",
+      "integrity": "sha1-1CgSNTwwouZmtGiJnHTBbOd354k=",
       "dependencies": {
         "@ghsc/nshmp-utils-ts": "^3.0.0",
         "d3": "^7.6.1"
       }
     },
     "node_modules/@ghsc/nshmp-lib-ng": {
-      "version": "18.10.1",
-      "resolved": "https://code.usgs.gov/api/v4/projects/12416/packages/npm/@ghsc/nshmp-lib-ng/-/@ghsc/nshmp-lib-ng-18.10.1.tgz",
-      "integrity": "sha1-aFF4wuaOzgaR6aUX0YyhyD8bNig=",
+      "version": "18.11.0",
+      "resolved": "https://code.usgs.gov/api/v4/projects/12416/packages/npm/@ghsc/nshmp-lib-ng/-/@ghsc/nshmp-lib-ng-18.11.0.tgz",
+      "integrity": "sha1-UgyXPP1rXvpUSsEV98Ly8L7LaDA=",
       "dependencies": {
         "tslib": "^2.3.0"
       },
diff --git a/package.json b/package.json
index 2bbe98d65..250a4bb3d 100644
--- a/package.json
+++ b/package.json
@@ -44,8 +44,8 @@
     "@angular/router": "18.1.1",
     "@asymmetrik/ngx-leaflet": "^18.0.1",
     "@compodoc/compodoc": "^1.1.25",
-    "@ghsc/disagg-d3": "^0.11.1",
-    "@ghsc/nshmp-lib-ng": "^18.10.1",
+    "@ghsc/disagg-d3": "^0.12.0",
+    "@ghsc/nshmp-lib-ng": "^18.11.0",
     "@ghsc/nshmp-template": "^18.0.3",
     "@ghsc/nshmp-utils-ts": "^3.8.1",
     "angular-plotly.js": "^6.0.0",
-- 
GitLab


From 27f87be1ecf7a6732664b65188870a98ef95e955 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Tue, 17 Sep 2024 14:56:06 -0600
Subject: [PATCH 24/29] switch to signal

---
 .../component-summary.component.html               | 14 +++++++-------
 .../component-summary.component.ts                 |  6 +-----
 .../components/content/content.component.html      | 12 +++++-------
 .../disagg/components/content/content.component.ts |  6 +-----
 4 files changed, 14 insertions(+), 24 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
index 5daaab051..dae869a8f 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
@@ -50,14 +50,14 @@
             >
           </mat-expansion-panel-header>
 
-          <app-disagg-summary [componentData]="componentData$ | async" />
+          <app-disagg-summary [componentData]="componentData()" />
         </mat-expansion-panel>
 
         <!-- Contributions -->
         <mat-expansion-panel
           class="contributions print-page-break"
-          [expanded]="(componentData$ | async)?.sources.length > 0"
-          [disabled]="(componentData$ | async)?.sources.length === 0"
+          [expanded]="componentData()?.sources.length > 0"
+          [disabled]="componentData()?.sources.length === 0"
         >
           <mat-expansion-panel-header>
             <mat-panel-title
@@ -66,14 +66,14 @@
             >
           </mat-expansion-panel-header>
 
-          <app-disagg-contributors [componentData]="componentData$ | async" />
+          <app-disagg-contributors [componentData]="componentData()" />
         </mat-expansion-panel>
 
         <!-- Data -->
         <mat-expansion-panel
           class="print-page-break"
-          [expanded]="(componentData$ | async)?.data.length > 0"
-          [disabled]="(componentData$ | async)?.data.length === 0"
+          [expanded]="componentData()?.data.length > 0"
+          [disabled]="componentData()?.data.length === 0"
         >
           <mat-expansion-panel-header>
             <mat-panel-title
@@ -82,7 +82,7 @@
             >
           </mat-expansion-panel-header>
 
-          <app-disagg-data [componentData]="componentData$ | async" />
+          <app-disagg-data [componentData]="componentData()" />
         </mat-expansion-panel>
       </mat-accordion>
     </div>
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.ts
index a58543268..d36a2d4aa 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.ts
@@ -11,7 +11,6 @@ import {
   MatOption,
   MatSelect,
 } from '@angular/material/select';
-import {map} from 'rxjs';
 
 import {AppService} from '../../services/app.service';
 import {DisaggContributorsComponent} from '../disagg-contributors/disagg-contributors.component';
@@ -41,10 +40,7 @@ import {DisaggSummaryComponent} from '../disagg-summary/disagg-summary.component
 })
 export class ComponentSummaryComponent {
   /** Disaggregation component data */
-  componentData$ =
-    this.service.formGroup.controls.disaggComponent.valueChanges.pipe(
-      map(() => this.service.componentData())
-    );
+  componentData = this.service.componentData;
 
   /** Disaggregation data */
   disaggData = this.service.disaggData;
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
index 9715ff773..1573a5b20 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
@@ -45,17 +45,13 @@
 
               <div class="print-content-only print-full-page">
                 <mat-expansion-panel class="print-page-break" expanded>
-                  <app-disagg-summary
-                    [componentData]="componentData$ | async"
-                  />
+                  <app-disagg-summary [componentData]="componentData()" />
                 </mat-expansion-panel>
               </div>
 
               <div class="print-content-only print-full-page">
                 <mat-expansion-panel class="print-page-break" expanded>
-                  <app-disagg-contributors
-                    [componentData]="componentData$ | async"
-                  />
+                  <app-disagg-contributors [componentData]="componentData()" />
                 </mat-expansion-panel>
               </div>
 
@@ -79,7 +75,9 @@
   </mat-tab>
 
   <mat-tab label="Component Summary" [disabled]="hasData() === false">
-    <app-component-summary />
+    <ng-template matTabContent>
+      <app-component-summary />
+    </ng-template>
   </mat-tab>
 
   <mat-tab label="Full Summary" [disabled]="hasData() === false">
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
index c97ff5d63..b27b32f63 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
@@ -4,7 +4,6 @@ import {MatDivider} from '@angular/material/divider';
 import {MatExpansionModule} from '@angular/material/expansion';
 import {MatTabsModule} from '@angular/material/tabs';
 import {NshmpLibNgAppMetadataComponent} from '@ghsc/nshmp-lib-ng/nshmp';
-import {map} from 'rxjs';
 
 import {AppService} from '../../services/app.service';
 import {ComponentSummaryComponent} from '../component-summary/component-summary.component';
@@ -43,10 +42,7 @@ import {PlotsComponent} from '../plots/plots.component';
   templateUrl: './content.component.html',
 })
 export class ContentComponent {
-  componentData$ =
-    this.service.formGroup.controls.disaggComponent.valueChanges.pipe(
-      map(() => this.service.componentData())
-    );
+  componentData = this.service.componentData;
 
   hasData = computed(() => this.service.serviceResponse() !== null);
 
-- 
GitLab


From 4bd778f1c93236a8f3a7ece51312413fb8148039 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Tue, 17 Sep 2024 14:56:14 -0600
Subject: [PATCH 25/29] add state

---
 .../app/hazard/disagg/models/state.model.ts   |  6 ++
 .../app/hazard/disagg/services/app.service.ts | 60 +++++++++++--------
 2 files changed, 41 insertions(+), 25 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/models/state.model.ts b/projects/nshmp-apps/src/app/hazard/disagg/models/state.model.ts
index 00a8de0fb..c25958222 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/models/state.model.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/models/state.model.ts
@@ -2,7 +2,9 @@ import {ResponseSpectra} from '@ghsc/nshmp-lib-ng/hazard';
 import {ServiceCallInfo} from '@ghsc/nshmp-lib-ng/nshmp';
 import {NshmpPlot} from '@ghsc/nshmp-lib-ng/plot';
 import {
+  DisaggComponentData,
   DisaggResponse,
+  DisaggResponseDataValues,
   DisaggUsage,
 } from '@ghsc/nshmp-utils-ts/libs/nshmp-haz/www/disagg-service';
 import {NshmMetadata} from '@ghsc/nshmp-utils-ts/libs/nshmp-haz/www/nshm-service';
@@ -14,6 +16,10 @@ import {Parameter} from '@ghsc/nshmp-utils-ts/libs/nshmp-ws-utils/metadata';
 export interface AppState {
   /** Available NSHMs */
   availableModels: Parameter[];
+  /** Current component data */
+  componentData: DisaggComponentData;
+  /** Current disagg data */
+  disaggData: DisaggResponseDataValues;
   /** Fault sections */
   faults: GeoJSON.FeatureCollection;
   /** NSHM service metadata */
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/services/app.service.ts b/projects/nshmp-apps/src/app/hazard/disagg/services/app.service.ts
index a1f041077..0450721e0 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/services/app.service.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/services/app.service.ts
@@ -86,6 +86,10 @@ export class AppService
     super();
     this.addValidators();
     this.formGroup.controls.disaggComponent.disable();
+
+    this.formGroup.controls.disaggComponent.valueChanges.subscribe(() =>
+      this.updateComponentData()
+    );
   }
 
   /**
@@ -99,36 +103,14 @@ export class AppService
    * Returns the disagg response values observable.
    */
   get componentData(): Signal<DisaggComponentData> {
-    return computed(() => {
-      const {serviceResponse} = this.state();
-
-      if (serviceResponse === null) {
-        return null;
-      }
-
-      return this.disaggData().data.find(
-        disagg =>
-          disagg.component === this.formGroup.getRawValue().disaggComponent
-      );
-    });
+    return computed(() => this.state().componentData);
   }
 
   /**
    * Returns the disaggregation data observable.
    */
   get disaggData(): Signal<DisaggResponseDataValues> {
-    return computed(() => {
-      const {serviceResponse} = this.state();
-
-      if (serviceResponse === null) {
-        return null;
-      }
-
-      return serviceResponse.response.disaggs.find(
-        disagg =>
-          disagg.imt.value === this.formGroup.getRawValue().imt.toString()
-      );
-    });
+    return computed(() => this.state().disaggData);
   }
 
   get faults(): Signal<GeoJSON.FeatureCollection> {
@@ -246,6 +228,9 @@ export class AppService
           serviceResponse,
         });
 
+        this.updateComponentData();
+        this.updateDisaggData();
+
         this.formGroup.controls.disaggComponent.enable();
       });
   }
@@ -310,6 +295,8 @@ export class AppService
 
     return {
       availableModels: [],
+      componentData: null,
+      disaggData: null,
       faults: null,
       nshmServices: [],
       plots: null,
@@ -440,6 +427,19 @@ export class AppService
     });
   }
 
+  updateComponentData(): void {
+    this.updateDisaggData();
+
+    const componentData = this.disaggData()?.data.find(
+      disagg =>
+        disagg.component === this.formGroup.getRawValue().disaggComponent
+    );
+
+    this.updateState({
+      componentData,
+    });
+  }
+
   updateState(state: Partial<AppState>): void {
     const updatedState = {
       ...this.state(),
@@ -724,6 +724,16 @@ export class AppService
       : `${text.join('\n\n')}`;
   }
 
+  private updateDisaggData(): void {
+    const disaggData = this.state().serviceResponse?.response.disaggs.find(
+      disagg => disagg.imt.value === this.formGroup.getRawValue().imt.toString()
+    );
+
+    this.updateState({
+      disaggData,
+    });
+  }
+
   private updateUrl(): void {
     const value = this.formGroup.getRawValue();
 
@@ -744,7 +754,7 @@ export class AppService
     this.updateState({
       serviceCallInfo: {
         ...this.state().serviceCallInfo,
-        usage: [nshmService.url],
+        usage: [`${nshmService.url}${this.endpoint}`],
       },
     });
   }
-- 
GitLab


From f896ce3025b8ed65f2043afa54edfbec33944a77 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Tue, 17 Sep 2024 14:56:19 -0600
Subject: [PATCH 26/29] clean

---
 .../src/app/hazard/disagg/components/plots/plots.component.ts | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.ts
index 19656ca37..a990f887b 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.ts
@@ -1,5 +1,5 @@
 import {AsyncPipe} from '@angular/common';
-import {Component, viewChild} from '@angular/core';
+import {Component} from '@angular/core';
 import {FormsModule, ReactiveFormsModule} from '@angular/forms';
 import {MatButton} from '@angular/material/button';
 import {MatOption} from '@angular/material/core';
@@ -42,8 +42,6 @@ export class PlotsComponent {
   /** Disaggreagtion service response */
   serviceResponse = this.service.serviceResponse;
 
-  disaggPlot = viewChild.required(NshmpLibNgHazardDisaggPlotComponent);
-
   constructor(
     public service: AppService,
     public templateService: NshmpTemplateService
-- 
GitLab


From 26021c5cec303053b79ffd0dd554df3c813a1eeb Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Mon, 30 Sep 2024 09:41:59 -0600
Subject: [PATCH 27/29] remove components

---
 .../component-summary.component.html          | 90 -------------------
 .../component-summary.component.scss          |  7 --
 .../component-summary.component.spec.ts       | 30 -------
 .../component-summary.component.ts            | 51 -----------
 .../full-summary/full-summary.component.html  | 84 -----------------
 .../full-summary/full-summary.component.scss  |  0
 .../full-summary.component.spec.ts            | 30 -------
 .../full-summary/full-summary.component.ts    | 33 -------
 8 files changed, 325 deletions(-)
 delete mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
 delete mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.scss
 delete mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.spec.ts
 delete mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.ts
 delete mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
 delete mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.scss
 delete mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.spec.ts
 delete mode 100644 projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.ts

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
deleted file mode 100644
index dae869a8f..000000000
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.html
+++ /dev/null
@@ -1,90 +0,0 @@
-<div class="height-full overflow-auto">
-  <div class="grid-container-widescreen">
-    <div class="padding-y-4">
-      <mat-card class="margin-bottom-2">
-        <mat-card-header>
-          <mat-card-title> Disaggregation Component Summary </mat-card-title>
-        </mat-card-header>
-
-        <!-- Select component -->
-        <mat-card-content>
-          <mat-form-field
-            class="grid-col-12 padding-top-4 disagg-component-select"
-          >
-            <mat-label> Component </mat-label>
-            <mat-select [formControl]="formGroup.controls.disaggComponent">
-              @for (disagg of disaggData()?.data; track disagg) {
-                <mat-option [value]="disagg?.component">
-                  {{ disagg?.component }}
-                </mat-option>
-              }
-            </mat-select>
-          </mat-form-field>
-        </mat-card-content>
-
-        <mat-card-actions>
-          <div class="print-display-none">
-            <button
-              mat-raised-button
-              color="primary"
-              (click)="service.saveComponentSummaryReport()"
-              [disabled]="disaggData() === null"
-            >
-              Export Summary Report
-            </button>
-          </div>
-        </mat-card-actions>
-      </mat-card>
-
-      <mat-accordion multi>
-        <!-- Summary report -->
-        <mat-expansion-panel
-          class="summary-report print-page-break"
-          [expanded]="disaggData()"
-          [disabled]="disaggData() === null"
-        >
-          <mat-expansion-panel-header>
-            <mat-panel-title
-              >Disaggregation Summary:
-              {{ formGroup.getRawValue().disaggComponent }}</mat-panel-title
-            >
-          </mat-expansion-panel-header>
-
-          <app-disagg-summary [componentData]="componentData()" />
-        </mat-expansion-panel>
-
-        <!-- Contributions -->
-        <mat-expansion-panel
-          class="contributions print-page-break"
-          [expanded]="componentData()?.sources.length > 0"
-          [disabled]="componentData()?.sources.length === 0"
-        >
-          <mat-expansion-panel-header>
-            <mat-panel-title
-              >Disaggregation Contributions:
-              {{ formGroup.getRawValue().disaggComponent }}</mat-panel-title
-            >
-          </mat-expansion-panel-header>
-
-          <app-disagg-contributors [componentData]="componentData()" />
-        </mat-expansion-panel>
-
-        <!-- Data -->
-        <mat-expansion-panel
-          class="print-page-break"
-          [expanded]="componentData()?.data.length > 0"
-          [disabled]="componentData()?.data.length === 0"
-        >
-          <mat-expansion-panel-header>
-            <mat-panel-title
-              >Disaggregation Data:
-              {{ formGroup.getRawValue().disaggComponent }}</mat-panel-title
-            >
-          </mat-expansion-panel-header>
-
-          <app-disagg-data [componentData]="componentData()" />
-        </mat-expansion-panel>
-      </mat-accordion>
-    </div>
-  </div>
-</div>
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.scss b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.scss
deleted file mode 100644
index 3094eb336..000000000
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-@media print {
-  mat-accordion {
-    mat-expansion-panel {
-      box-shadow: none !important;
-    }
-  }
-}
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.spec.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.spec.ts
deleted file mode 100644
index cf9908a16..000000000
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.spec.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import {provideHttpClient} from '@angular/common/http';
-import {ComponentFixture, TestBed} from '@angular/core/testing';
-import {provideNoopAnimations} from '@angular/platform-browser/animations';
-import {provideRouter} from '@angular/router';
-
-import {ComponentSummaryComponent} from './component-summary.component';
-
-describe('ComponentSummaryComponent', () => {
-  let component: ComponentSummaryComponent;
-  let fixture: ComponentFixture<ComponentSummaryComponent>;
-
-  beforeEach(async () => {
-    await TestBed.configureTestingModule({
-      imports: [ComponentSummaryComponent],
-      providers: [
-        provideHttpClient(),
-        provideNoopAnimations(),
-        provideRouter([]),
-      ],
-    }).compileComponents();
-
-    fixture = TestBed.createComponent(ComponentSummaryComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.ts
deleted file mode 100644
index d36a2d4aa..000000000
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/component-summary/component-summary.component.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import {AsyncPipe} from '@angular/common';
-import {Component} from '@angular/core';
-import {ReactiveFormsModule} from '@angular/forms';
-import {MatButton} from '@angular/material/button';
-import {MatCardModule} from '@angular/material/card';
-import {MatDivider} from '@angular/material/divider';
-import {MatExpansionModule} from '@angular/material/expansion';
-import {
-  MatFormField,
-  MatLabel,
-  MatOption,
-  MatSelect,
-} from '@angular/material/select';
-
-import {AppService} from '../../services/app.service';
-import {DisaggContributorsComponent} from '../disagg-contributors/disagg-contributors.component';
-import {DisaggDataComponent} from '../disagg-data/disagg-data.component';
-import {DisaggSummaryComponent} from '../disagg-summary/disagg-summary.component';
-
-@Component({
-  imports: [
-    MatExpansionModule,
-    MatCardModule,
-    DisaggSummaryComponent,
-    DisaggContributorsComponent,
-    DisaggDataComponent,
-    AsyncPipe,
-    MatFormField,
-    MatSelect,
-    ReactiveFormsModule,
-    MatLabel,
-    MatOption,
-    MatDivider,
-    MatButton,
-  ],
-  selector: 'app-component-summary',
-  standalone: true,
-  styleUrl: './component-summary.component.scss',
-  templateUrl: './component-summary.component.html',
-})
-export class ComponentSummaryComponent {
-  /** Disaggregation component data */
-  componentData = this.service.componentData;
-
-  /** Disaggregation data */
-  disaggData = this.service.disaggData;
-
-  formGroup = this.service.formGroup;
-
-  constructor(public service: AppService) {}
-}
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
deleted file mode 100644
index 10525c37e..000000000
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.html
+++ /dev/null
@@ -1,84 +0,0 @@
-<div class="height-full overflow-auto">
-  <div class="grid-container-widescreen">
-    <div class="padding-y-4">
-      <mat-card class="margin-bottom-2">
-        <mat-card-header>
-          <mat-card-title> Disaggregation Full Summary </mat-card-title>
-        </mat-card-header>
-
-        <mat-card-content>
-          <div class="print-display-none padding-top-4">
-            <button
-              mat-raised-button
-              color="primary"
-              (click)="service.saveSummaryReport()"
-              [disabled]="disaggData() === null"
-            >
-              Export Summary Report
-            </button>
-          </div>
-        </mat-card-content>
-
-        <mat-card-actions>
-          <div class="print-display-none padding-right-4">
-            <button
-              mat-raised-button
-              color="accent"
-              [disabled]="disaggData() === null"
-              (click)="panels().openAll()"
-            >
-              Expand All Panels
-            </button>
-          </div>
-
-          <div class="print-display-none">
-            <button
-              mat-raised-button
-              color="accent"
-              [disabled]="disaggData() === null"
-              (click)="panels().closeAll()"
-            >
-              Close All Panels
-            </button>
-          </div>
-        </mat-card-actions>
-      </mat-card>
-
-      <mat-accordion multi>
-        @for (disagg of disaggData()?.data; track disagg) {
-          <mat-expansion-panel>
-            <mat-expansion-panel-header>
-              <mat-panel-title
-                >Component: {{ disagg.component }}</mat-panel-title
-              >
-            </mat-expansion-panel-header>
-
-            <mat-divider />
-
-            <ng-template matExpansionPanelContent>
-              <h2>Disaggregation Summary</h2>
-              <app-disagg-summary
-                [componentData]="disagg"
-                [showExportButton]="false"
-              />
-              <mat-divider />
-
-              <h2>Disaggregation Contributions</h2>
-              <app-disagg-contributors
-                [componentData]="disagg"
-                [showExportButton]="false"
-              />
-              <mat-divider />
-
-              <h2>Disaggregation Data</h2>
-              <app-disagg-data
-                [componentData]="disagg"
-                [showExportButton]="false"
-              />
-            </ng-template>
-          </mat-expansion-panel>
-        }
-      </mat-accordion>
-    </div>
-  </div>
-</div>
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.scss b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.scss
deleted file mode 100644
index e69de29bb..000000000
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.spec.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.spec.ts
deleted file mode 100644
index 2175210d1..000000000
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.spec.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import {provideHttpClient} from '@angular/common/http';
-import {ComponentFixture, TestBed} from '@angular/core/testing';
-import {provideNoopAnimations} from '@angular/platform-browser/animations';
-import {provideRouter} from '@angular/router';
-
-import {FullSummaryComponent} from './full-summary.component';
-
-describe('FullSummaryComponent', () => {
-  let component: FullSummaryComponent;
-  let fixture: ComponentFixture<FullSummaryComponent>;
-
-  beforeEach(async () => {
-    await TestBed.configureTestingModule({
-      imports: [FullSummaryComponent],
-      providers: [
-        provideHttpClient(),
-        provideNoopAnimations(),
-        provideRouter([]),
-      ],
-    }).compileComponents();
-
-    fixture = TestBed.createComponent(FullSummaryComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.ts
deleted file mode 100644
index 5b52886b0..000000000
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/full-summary/full-summary.component.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import {Component, viewChild} from '@angular/core';
-import {MatButton} from '@angular/material/button';
-import {MatCardModule} from '@angular/material/card';
-import {MatDivider} from '@angular/material/divider';
-import {MatAccordion, MatExpansionModule} from '@angular/material/expansion';
-
-import {AppService} from '../../services/app.service';
-import {DisaggContributorsComponent} from '../disagg-contributors/disagg-contributors.component';
-import {DisaggDataComponent} from '../disagg-data/disagg-data.component';
-import {DisaggSummaryComponent} from '../disagg-summary/disagg-summary.component';
-
-@Component({
-  imports: [
-    MatExpansionModule,
-    DisaggSummaryComponent,
-    DisaggContributorsComponent,
-    DisaggDataComponent,
-    MatDivider,
-    MatButton,
-    MatCardModule,
-  ],
-  selector: 'app-full-summary',
-  standalone: true,
-  styleUrl: './full-summary.component.scss',
-  templateUrl: './full-summary.component.html',
-})
-export class FullSummaryComponent {
-  disaggData = this.service.disaggData;
-
-  panels = viewChild.required(MatAccordion);
-
-  constructor(public service: AppService) {}
-}
-- 
GitLab


From 8f9f3e4ca73fc128dd49cb3eb1b454ad65ec316a Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Mon, 30 Sep 2024 09:42:16 -0600
Subject: [PATCH 28/29] add cmomponent and data panels

---
 .../components/content/content.component.html | 163 ++++++++++--------
 .../components/content/content.component.ts   |  11 +-
 .../disagg-data/disagg-data.component.html    |   2 +-
 .../disagg-data/disagg-data.component.scss    |   5 +
 .../components/plots/plots.component.html     |  17 +-
 5 files changed, 103 insertions(+), 95 deletions(-)

diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
index 1573a5b20..58c70ef6f 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.html
@@ -1,86 +1,103 @@
-<mat-tab-group class="height-full">
-  <mat-tab label="Plots">
-    <ng-template matTabContent>
-      <div class="height-full overflow-auto report">
-        <div class="grid-container-widescreen">
-          <!-- Report title, show only on print -->
-          <div class="print-content-only">
-            <h2>Disaggregation Report</h2>
-          </div>
+<div class="height-full overflow-auto report">
+  <div class="grid-container-widescreen">
+    <!-- Report title, show only on print -->
+    <div class="print-content-only">
+      <h2>Disaggregation Report</h2>
+    </div>
 
-          <div class="padding-y-4">
-            <mat-accordion multi>
-              <!-- Disagg plot panel -->
-              <mat-expansion-panel expanded class="disagg-panel">
-                <mat-expansion-panel-header>
-                  <mat-panel-title>Disaggregation</mat-panel-title>
-                </mat-expansion-panel-header>
+    <div class="padding-y-4">
+      <mat-accordion multi>
+        <!-- Disagg plot panel -->
+        <mat-expansion-panel expanded class="disagg-panel">
+          <mat-expansion-panel-header>
+            <mat-panel-title>Disaggregation</mat-panel-title>
+          </mat-expansion-panel-header>
 
-                <app-plots />
-              </mat-expansion-panel>
+          <app-plots />
+        </mat-expansion-panel>
 
-              <!-- Geographical disagg panel -->
-              <mat-expansion-panel
-                [expanded]="hasLayers()"
-                [disabled]="hasLayers() === false"
-                class="geo-disagg-panel print-page-break"
-              >
-                <mat-expansion-panel-header>
-                  <mat-panel-title>Geographical Disaggregation</mat-panel-title>
-                </mat-expansion-panel-header>
+        <!-- Geographical disagg panel -->
+        <mat-expansion-panel
+          [expanded]="hasLayers()"
+          [disabled]="hasLayers() === false"
+          class="geo-disagg-panel print-page-break"
+        >
+          <mat-expansion-panel-header>
+            <mat-panel-title>Geographical Disaggregation</mat-panel-title>
+          </mat-expansion-panel-header>
 
-                <mat-divider />
+          <mat-divider />
 
-                <app-geo-disagg />
-              </mat-expansion-panel>
+          <app-geo-disagg />
+        </mat-expansion-panel>
 
-              <!-- Parameter summary panel -->
-              <mat-expansion-panel expanded>
-                <mat-expansion-panel-header>
-                  <mat-panel-title>Parameter Summary</mat-panel-title>
-                </mat-expansion-panel-header>
+        <!-- Parameter summary panel -->
+        <mat-expansion-panel expanded>
+          <mat-expansion-panel-header>
+            <mat-panel-title>Parameter Summary</mat-panel-title>
+          </mat-expansion-panel-header>
 
-                <app-parameter-summary />
-              </mat-expansion-panel>
+          <app-parameter-summary />
+        </mat-expansion-panel>
 
-              <div class="print-content-only print-full-page">
-                <mat-expansion-panel class="print-page-break" expanded>
-                  <app-disagg-summary [componentData]="componentData()" />
-                </mat-expansion-panel>
-              </div>
+        <!-- Summary report -->
+        <mat-expansion-panel
+          class="summary-report print-full-page"
+          [expanded]="disaggData()"
+          [disabled]="disaggData() === null"
+        >
+          <mat-expansion-panel-header>
+            <mat-panel-title
+              >Disaggregation Summary:
+              {{ formGroup.getRawValue().disaggComponent }}</mat-panel-title
+            >
+          </mat-expansion-panel-header>
 
-              <div class="print-content-only print-full-page">
-                <mat-expansion-panel class="print-page-break" expanded>
-                  <app-disagg-contributors [componentData]="componentData()" />
-                </mat-expansion-panel>
-              </div>
+          <app-disagg-summary [componentData]="componentData()" />
+        </mat-expansion-panel>
 
-              <!-- App metadata -->
-              <mat-expansion-panel
-                class="print-page-break print-full-page"
-                expanded
-              >
-                <mat-expansion-panel-header>
-                  <mat-panel-title>Application Metadata</mat-panel-title>
-                </mat-expansion-panel-header>
+        <!-- Contributions -->
+        <mat-expansion-panel
+          class="contributions print-full-page"
+          [expanded]="componentData()?.sources.length > 0"
+          [disabled]="componentData()?.sources.length === 0"
+        >
+          <mat-expansion-panel-header>
+            <mat-panel-title
+              >Disaggregation Contributions:
+              {{ formGroup.getRawValue().disaggComponent }}</mat-panel-title
+            >
+          </mat-expansion-panel-header>
 
-                <mat-divider />
-                <nshmp-lib-ng-app-metadata [repositories]="repositories()" />
-              </mat-expansion-panel>
-            </mat-accordion>
-          </div>
-        </div>
-      </div>
-    </ng-template>
-  </mat-tab>
+          <app-disagg-contributors [componentData]="componentData()" />
+        </mat-expansion-panel>
 
-  <mat-tab label="Component Summary" [disabled]="hasData() === false">
-    <ng-template matTabContent>
-      <app-component-summary />
-    </ng-template>
-  </mat-tab>
+        <!-- Data -->
+        <mat-expansion-panel
+          class="print-display-none"
+          [expanded]="componentData()?.data.length > 0"
+          [disabled]="componentData()?.data.length === 0"
+        >
+          <mat-expansion-panel-header>
+            <mat-panel-title
+              >Disaggregation Data:
+              {{ formGroup.getRawValue().disaggComponent }}</mat-panel-title
+            >
+          </mat-expansion-panel-header>
 
-  <mat-tab label="Full Summary" [disabled]="hasData() === false">
-    <app-full-summary />
-  </mat-tab>
-</mat-tab-group>
+          <app-disagg-data [componentData]="componentData()" />
+        </mat-expansion-panel>
+
+        <!-- App metadata -->
+        <mat-expansion-panel class="print-page-break print-full-page" expanded>
+          <mat-expansion-panel-header>
+            <mat-panel-title>Application Metadata</mat-panel-title>
+          </mat-expansion-panel-header>
+
+          <mat-divider />
+          <nshmp-lib-ng-app-metadata [repositories]="repositories()" />
+        </mat-expansion-panel>
+      </mat-accordion>
+    </div>
+  </div>
+</div>
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
index b27b32f63..c7929d963 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/content/content.component.ts
@@ -2,14 +2,12 @@ import {AsyncPipe} from '@angular/common';
 import {Component, computed} from '@angular/core';
 import {MatDivider} from '@angular/material/divider';
 import {MatExpansionModule} from '@angular/material/expansion';
-import {MatTabsModule} from '@angular/material/tabs';
 import {NshmpLibNgAppMetadataComponent} from '@ghsc/nshmp-lib-ng/nshmp';
 
 import {AppService} from '../../services/app.service';
-import {ComponentSummaryComponent} from '../component-summary/component-summary.component';
 import {DisaggContributorsComponent} from '../disagg-contributors/disagg-contributors.component';
+import {DisaggDataComponent} from '../disagg-data/disagg-data.component';
 import {DisaggSummaryComponent} from '../disagg-summary/disagg-summary.component';
-import {FullSummaryComponent} from '../full-summary/full-summary.component';
 import {GeoDisaggComponent} from '../geo-disagg/geo-disagg.component';
 import {ParameterSummaryComponent} from '../parameter-summary/parameter-summary.component';
 import {PlotsComponent} from '../plots/plots.component';
@@ -29,11 +27,9 @@ import {PlotsComponent} from '../plots/plots.component';
     GeoDisaggComponent,
     ParameterSummaryComponent,
     NshmpLibNgAppMetadataComponent,
-    MatTabsModule,
-    ComponentSummaryComponent,
-    FullSummaryComponent,
     DisaggSummaryComponent,
     DisaggContributorsComponent,
+    DisaggDataComponent,
     AsyncPipe,
   ],
   selector: 'app-content',
@@ -43,6 +39,9 @@ import {PlotsComponent} from '../plots/plots.component';
 })
 export class ContentComponent {
   componentData = this.service.componentData;
+  /** Disaggregation data */
+  disaggData = this.service.disaggData;
+  formGroup = this.service.formGroup;
 
   hasData = computed(() => this.service.serviceResponse() !== null);
 
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.html
index 7bc8ce4ba..e4e80db7e 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.html
@@ -17,7 +17,7 @@
       <mat-divider />
     }
 
-    <div class="horizontal-scrolling">
+    <div class="horizontal-scrolling disagg-data">
       <div>
         <table class="grid-col-12">
           <thead>
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.scss b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.scss
index 7128fbaec..f42f51ca2 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.scss
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/disagg-data/disagg-data.component.scss
@@ -27,3 +27,8 @@ table {
     line-height: clamp(0.2em, 0.1em + 1.5vw, 1.5em);
   }
 }
+
+.disagg-data {
+  max-height: 1000px;
+  overflow: scroll;
+}
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
index ed0b48bca..edd15e955 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
+++ b/projects/nshmp-apps/src/app/hazard/disagg/components/plots/plots.component.html
@@ -7,20 +7,7 @@
       [disabled]="disaggData() === null"
       (click)="exportReport()"
     >
-      Print Report
-    </button>
-  </div>
-
-  <!-- Export component summary button -->
-  <div>
-    <button
-      class="export-button"
-      mat-raised-button
-      color="primary"
-      [disabled]="disaggData() === null"
-      (click)="service.saveComponentSummaryReport()"
-    >
-      Export Component Summary
+      Print Report (PDF)
     </button>
   </div>
 
@@ -33,7 +20,7 @@
       [disabled]="disaggData() === null"
       (click)="service.saveSummaryReport()"
     >
-      Export Full Summary
+      Save Report (TXT)
     </button>
   </div>
 </div>
-- 
GitLab


From 4420db237dc84f9cae7ab601c22624e743eedea9 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Thu, 3 Oct 2024 09:17:34 -0600
Subject: [PATCH 29/29] disagg

---
 package-lock.json                                  |  8 ++++----
 package.json                                       |  2 +-
 .../src/app/hazard/disagg/services/app.service.ts  | 14 +++++++-------
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index ae8cdbe55..50f3a4fb0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,7 +21,7 @@
         "@asymmetrik/ngx-leaflet": "^18.0.1",
         "@compodoc/compodoc": "^1.1.25",
         "@ghsc/disagg-d3": "^0.12.0",
-        "@ghsc/nshmp-lib-ng": "^18.11.0",
+        "@ghsc/nshmp-lib-ng": "^18.15.0",
         "@ghsc/nshmp-template": "^18.0.3",
         "@ghsc/nshmp-utils-ts": "^3.8.1",
         "angular-plotly.js": "^6.0.0",
@@ -4281,9 +4281,9 @@
       }
     },
     "node_modules/@ghsc/nshmp-lib-ng": {
-      "version": "18.11.0",
-      "resolved": "https://code.usgs.gov/api/v4/projects/12416/packages/npm/@ghsc/nshmp-lib-ng/-/@ghsc/nshmp-lib-ng-18.11.0.tgz",
-      "integrity": "sha1-UgyXPP1rXvpUSsEV98Ly8L7LaDA=",
+      "version": "18.15.0",
+      "resolved": "https://code.usgs.gov/api/v4/projects/12416/packages/npm/@ghsc/nshmp-lib-ng/-/@ghsc/nshmp-lib-ng-18.15.0.tgz",
+      "integrity": "sha1-3MS89MMp78znBiSMTqAki+PGrso=",
       "dependencies": {
         "tslib": "^2.3.0"
       },
diff --git a/package.json b/package.json
index 250a4bb3d..8141a044b 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
     "@asymmetrik/ngx-leaflet": "^18.0.1",
     "@compodoc/compodoc": "^1.1.25",
     "@ghsc/disagg-d3": "^0.12.0",
-    "@ghsc/nshmp-lib-ng": "^18.11.0",
+    "@ghsc/nshmp-lib-ng": "^18.15.0",
     "@ghsc/nshmp-template": "^18.0.3",
     "@ghsc/nshmp-utils-ts": "^3.8.1",
     "angular-plotly.js": "^6.0.0",
diff --git a/projects/nshmp-apps/src/app/hazard/disagg/services/app.service.ts b/projects/nshmp-apps/src/app/hazard/disagg/services/app.service.ts
index 0450721e0..cb0cfdb8e 100644
--- a/projects/nshmp-apps/src/app/hazard/disagg/services/app.service.ts
+++ b/projects/nshmp-apps/src/app/hazard/disagg/services/app.service.ts
@@ -13,6 +13,7 @@ import {
   DisaggControlForm,
   DisaggTarget,
   FormatLatitudePipe,
+  FormatLongitudePipe,
   HazardService,
   hazardUtils,
   ReturnPeriodPipe,
@@ -488,10 +489,10 @@ export class AppService
     );
 
     const headers = [
-      metadata.rlabel.replace(',', ' -'),
-      metadata.mlabel,
-      'ALL_ε',
-      ...keys.data.map(data => `${data.name}=${data.value}`),
+      'Distance (km)',
+      'Magnitude (Mw)',
+      'ε total',
+      ...keys.data.map(data => data.name),
     ];
 
     const csv = componentData.data.map(data => {
@@ -637,7 +638,7 @@ export class AppService
 
     return (
       `Model: ${usage.model.name}\n` +
-      `Longitude: ${new FormatLatitudePipe(this.localId).transform(formValues.longitude)} \n` +
+      `Longitude: ${new FormatLongitudePipe(this.localId).transform(formValues.longitude)} \n` +
       `Latitude: ${new FormatLatitudePipe(this.localId).transform(formValues.latitude)} \n` +
       `IMT: ${imt} \n` +
       `Return Period: ${new ReturnPeriodPipe().transform(formValues.returnPeriod)} \n` +
@@ -682,8 +683,7 @@ export class AppService
     showMetadata = true
   ): string {
     const formValues = this.formGroup.getRawValue();
-    const firstLine =
-      '*** Deaggregation of Seismic Hazard at One Period of Spectral Acceleration ***';
+    const firstLine = '*** Disaggregation of Seismic Hazard ***';
     const metadata = showMetadata
       ? `${firstLine}\n\n${this.metadataText(formValues)}`
       : '';
-- 
GitLab