Skip to content

Commit

Permalink
Merge branch 'main' into change-over-time-chart
Browse files Browse the repository at this point in the history
  • Loading branch information
lastminutediorama committed Dec 19, 2024
2 parents 3fb30ea + b0ed926 commit 8294810
Show file tree
Hide file tree
Showing 33 changed files with 547 additions and 280 deletions.
3 changes: 2 additions & 1 deletion src/interface/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
"shpjs",
"geojson-rbush",
"polylabel",
"file-saver"
"file-saver",
"canvg"
]
},
"configurations": {
Expand Down
1 change: 1 addition & 0 deletions src/interface/src/app/map/map-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export class MapManager {
weight: 5,
},
templineStyle: {
radius: 0,
color: '#000',
weight: 5,
},
Expand Down
10 changes: 9 additions & 1 deletion src/interface/src/app/map/map.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ import { getPlanPath } from '../plan/plan-helpers';
import { InvalidLinkDialogComponent } from './invalid-link-dialog/invalid-link-dialog.component';
import { Location } from '@angular/common';
import { MatDialog } from '@angular/material/dialog';
import { AnalyticsService } from '@services/analytics.service';

@UntilDestroy()
@Component({
Expand Down Expand Up @@ -187,7 +188,8 @@ export class MapComponent implements AfterViewInit, OnDestroy, OnInit, DoCheck {
private cdr: ChangeDetectorRef,
private route: ActivatedRoute,
private shareMapService: ShareMapService,
private location: Location
private location: Location,
private analyticsService: AnalyticsService
) {
this.sessionService.mapViewOptions$
.pipe(take(1))
Expand Down Expand Up @@ -651,6 +653,12 @@ export class MapComponent implements AfterViewInit, OnDestroy, OnInit, DoCheck {
);
this.showUploader = false;
this.addDrawingControlToAllMaps();
this.analyticsService.emitEvent(
'shapefiles_uploaded_explore',
'file_uploaded',
'Upload Area',
1
);
},
error: () => {
this.showAreaTooComplexError();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { Region, regionToString } from '@types';
import { Geometry } from 'geojson';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MockProvider } from 'ng-mocks';
import { AnalyticsService } from '@services/analytics.service';

describe('PlanCreateDialogComponent', () => {
let component: PlanCreateDialogComponent;
Expand Down Expand Up @@ -47,6 +49,7 @@ describe('PlanCreateDialogComponent', () => {
],
declarations: [PlanCreateDialogComponent],
providers: [
MockProvider(AnalyticsService),
{
provide: PlanService,
useValue: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Region, regionToString } from '@types';
import { isValidTotalArea } from '../../plan/plan-helpers';
import { Geometry } from 'geojson';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AnalyticsService } from '@services/analytics.service';

export interface PlanCreateDialogData {
shape: Geometry;
Expand All @@ -32,6 +33,7 @@ export class PlanCreateDialogComponent {
private planService: PlanService,
private sessionService: SessionService,
private matSnackBar: MatSnackBar,
private analyticsService: AnalyticsService,
@Inject(MAT_DIALOG_DATA) public data: PlanCreateDialogData
) {}

Expand Down Expand Up @@ -78,6 +80,12 @@ export class PlanCreateDialogComponent {
next: (result) => {
this.dialogRef.close(result!.id);
this.submitting = false;
this.analyticsService.emitEvent(
'polygons_draw_explore',
undefined,
undefined,
(result as any).geometry?.coordinates?.length
);
},
error: (e) => {
this.matSnackBar.open(
Expand Down
25 changes: 24 additions & 1 deletion src/interface/src/app/treatments/direct-impacts.state.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BehaviorSubject } from 'rxjs';
import { BehaviorSubject, combineLatest, map, of } from 'rxjs';
import {
DEFAULT_SLOT,
ImpactsMetric,
Expand Down Expand Up @@ -61,6 +61,25 @@ export class DirectImpactsStateService {
>([[]]);
public changeOverTimeData$ = this._changeOverTimeData$.asObservable();

// todo: placeholder to fill once we have project area filter
projectArea$ = of('All Project Areas');

private _showTreatmentPrescription$ = new BehaviorSubject(false);
public showTreatmentPrescription$ =
this._showTreatmentPrescription$.asObservable();

mapPanelTitle$ = combineLatest([
this.activeMetric$,
this.projectArea$,
this.showTreatmentPrescription$,
]).pipe(
map(([activeMetric, pa, showTreatment]) =>
showTreatment
? 'Applied Treatment Prescription'
: `${activeMetric.metric.label} for ${pa}`
)
);

constructor(private treatmentsService: TreatmentsService) {
this._changeOverTimeData$.next([[]]);
}
Expand Down Expand Up @@ -146,4 +165,8 @@ export class DirectImpactsStateService {
isActiveSlot(slot: ImpactsMetricSlot) {
return this._activeMetric$.value.slot === slot;
}

setShowTreatmentPrescription(show: boolean) {
this._showTreatmentPrescription$.next(show);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
<div class="direct-impacts">
<div class="title-row">
<h4 class="title">Direct Treatment Impacts</h4>
<mat-slide-toggle [(ngModel)]="showTreatmentPrescription"
<mat-slide-toggle
[checked]="(showTreatmentPrescription$ | async) || false"
(change)="saveShowTreatmentPrescription($event)"
>View treatment prescription
</mat-slide-toggle>
<button sg-button variant="ghost" icon="download" [outlined]="true">
Expand Down Expand Up @@ -73,31 +75,34 @@ <h4 class="title">Direct Treatment Impacts</h4>
[paddedContent]="false"
[buttons]="[{ icon: 'open_in_full', actionName: 'expand' }]"
(clickedButton)="expandStandChart()">
<div panelTitle>{{ standChartPanelTitle$ | async }} /</div>
<div panelTitle>{{ standChartPanelTitle$ | async }}</div>
<app-stand-data-chart></app-stand-data-chart>
</sg-panel>

<sg-panel
class="map-panel"
[ngClass]="{ prescriptions: showTreatmentPrescription }"
[ngClass]="{ prescriptions: showTreatmentPrescription$ | async }"
[paddedContent]="false"
[buttons]="[
{ icon: 'layers', actionName: 'layers' },
{ icon: 'open_in_full', actionName: 'expand' }
]">
]"
(clickedButton)="expandMaps()">
<div panelTitle>{{ mapPanelTitle$ | async }}</div>
<app-direct-impacts-synced-maps
*ngIf="!showTreatmentPrescription"></app-direct-impacts-synced-maps>
*ngIf="
(showTreatmentPrescription$ | async) === false
"></app-direct-impacts-synced-maps>
<app-treatment-map
[showProjectAreaTooltips]="false"
*ngIf="showTreatmentPrescription"></app-treatment-map>
*ngIf="showTreatmentPrescription$ | async"></app-treatment-map>
<app-treatment-legend
*ngIf="showTreatmentPrescription"></app-treatment-legend>
*ngIf="showTreatmentPrescription$ | async"></app-treatment-legend>
</sg-panel>
<sg-panel
class="legend-panel"
[paddedContent]="false"
*ngIf="!showTreatmentPrescription">
*ngIf="(showTreatmentPrescription$ | async) === false">
<app-direct-impacts-map-legend></app-direct-impacts-map-legend>
</sg-panel>
</section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import { SharedModule } from '@shared';
import { TreatmentsState } from '../treatments.state';
import { ActivatedRoute, Router } from '@angular/router';
import { catchError, combineLatest, map, of, switchMap } from 'rxjs';
import { catchError, map, switchMap } from 'rxjs';
import { SelectedStandsState } from '../treatment-map/selected-stands.state';
import { TreatedStandsState } from '../treatment-map/treated-stands.state';
import { MapConfigState } from '../treatment-map/map-config.state';
Expand All @@ -25,7 +25,10 @@ import {
ModalComponent,
} from '@styleguide';
import { MatIconModule } from '@angular/material/icon';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import {
MatSlideToggleChange,
MatSlideToggleModule,
} from '@angular/material/slide-toggle';
import { FormsModule } from '@angular/forms';
import { TreatmentMapComponent } from '../treatment-map/treatment-map.component';
import { TreatmentLegendComponent } from '../treatment-legend/treatment-legend.component';
Expand All @@ -34,7 +37,6 @@ import { ImpactsMetric } from '../metrics';
import { DirectImpactsMapLegendComponent } from '../direct-impacts-map-legend/direct-impacts-map-legend.component';
import { DirectImpactsStateService } from '../direct-impacts.state.service';
import { StandDataChartComponent } from '../stand-data-chart/stand-data-chart.component';
import { MapGeoJSONFeature } from 'maplibre-gl';
import { Chart } from 'chart.js';
import ChartDataLabels from 'chartjs-plugin-datalabels';
import { TreatmentTypeIconComponent } from '../../../styleguide/treatment-type-icon/treatment-type-icon.component';
Expand All @@ -43,6 +45,8 @@ import { MatSelectModule } from '@angular/material/select';
import { ExpandedStandDataChartComponent } from '../expanded-stand-data-chart/expanded-stand-data-chart.component';
import { ExpandedChangeOverTimeChartComponent } from '../expanded-change-over-time-chart/expanded-change-over-time-chart.component';
import { MatDialog } from '@angular/material/dialog';
import { ExpandedDirectImpactMapComponent } from '../expanded-direct-impact-map/expanded-direct-impact-map.component';
import { MapGeoJSONFeature } from 'maplibre-gl';

export interface ImpactsProjectArea {
project_area_id: number;
Expand Down Expand Up @@ -132,6 +136,7 @@ export class DirectImpactsComponent implements OnInit, OnDestroy {
breadcrumbs$ = this.treatmentsState.breadcrumbs$;
treatmentPlan$ = this.treatmentsState.treatmentPlan$;
activeStand$ = this.directImpactsStateService.activeStand$;

selectedChartProjectArea$ =
this.directImpactsStateService.selectedProjectAreaForChanges$;
showTreatmentPrescription = false;
Expand All @@ -147,6 +152,9 @@ export class DirectImpactsComponent implements OnInit, OnDestroy {
})
);

showTreatmentPrescription$ =
this.directImpactsStateService.showTreatmentPrescription$;

standChartPanelTitle$ = this.directImpactsStateService.activeStand$.pipe(
map((activeStand) => {
if (!activeStand) {
Expand All @@ -165,15 +173,7 @@ export class DirectImpactsComponent implements OnInit, OnDestroy {
map((m) => m.metric)
);

// todo: placeholder to fill once we have project area filter
projectArea$ = of('All Project Areas');

mapPanelTitle$ = combineLatest([
this.directImpactsStateService.activeMetric$,
this.projectArea$,
]).pipe(
map(([activeMetric, pa]) => `${activeMetric.metric.label} for ${pa}`)
);
mapPanelTitle$ = this.directImpactsStateService.mapPanelTitle$;

getValues(activeStand: MapGeoJSONFeature) {}

Expand Down Expand Up @@ -207,4 +207,14 @@ export class DirectImpactsComponent implements OnInit, OnDestroy {
injector: this.injector, // Pass the current injector to the dialog
});
}

expandMaps() {
this.dialog.open(ExpandedDirectImpactMapComponent, {
injector: this.injector, // Pass the current injector to the dialog
});
}

saveShowTreatmentPrescription(value: MatSlideToggleChange) {
this.directImpactsStateService.setShowTreatmentPrescription(value.checked);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<sg-modal
[title]="(mapPanelTitle$ | async) || ''"
primaryButtonText="Create"
[scrollableContent]="false"
[showBorders]="true"
[hasFooter]="false"
(clickedClose)="close()"
width="full"
class="expanded-maps-modal">
<div modalBodyContent class="expanded-maps">
<app-direct-impacts-synced-maps
*ngIf="
(showTreatmentPrescription$ | async) === false
"></app-direct-impacts-synced-maps>
<app-treatment-map
[showProjectAreaTooltips]="false"
*ngIf="showTreatmentPrescription$ | async"></app-treatment-map>
<app-treatment-legend
*ngIf="showTreatmentPrescription$ | async"></app-treatment-legend>
</div>
</sg-modal>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@import "mixins";

.expanded-maps {
height: 90vh;
position: relative;
}

::ng-deep {
sg-modal.expanded-maps-modal {

&.full {
width: 80vw;
}

.header {
@include h5();
height: 39px;
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ExpandedDirectImpactMapComponent } from './expanded-direct-impact-map.component';
import { MockProvider } from 'ng-mocks';
import { DirectImpactsStateService } from '../direct-impacts.state.service';
import { BehaviorSubject } from 'rxjs';
import { MatDialogRef } from '@angular/material/dialog';

describe('ExpandedDirectImpactMapComponent', () => {
let component: ExpandedDirectImpactMapComponent;
let fixture: ComponentFixture<ExpandedDirectImpactMapComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ExpandedDirectImpactMapComponent],
providers: [
MockProvider(DirectImpactsStateService, {
activeStand$: new BehaviorSubject(null),
}),
{ provide: MatDialogRef, useValue: {} },
],
}).compileComponents();

fixture = TestBed.createComponent(ExpandedDirectImpactMapComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Component } from '@angular/core';
import { AsyncPipe, NgIf } from '@angular/common';
import { ModalComponent } from '@styleguide';
import { StandDataChartComponent } from '../stand-data-chart/stand-data-chart.component';
import { DirectImpactsStateService } from '../direct-impacts.state.service';
import { MatDialogRef } from '@angular/material/dialog';
import { DirectImpactsSyncedMapsComponent } from '../direct-impacts-synced-maps/direct-impacts-synced-maps.component';
import { TreatmentMapComponent } from '../treatment-map/treatment-map.component';
import { TreatmentLegendComponent } from '../treatment-legend/treatment-legend.component';

@Component({
selector: 'app-expanded-direct-impact-map',
standalone: true,
imports: [
AsyncPipe,
ModalComponent,
StandDataChartComponent,
DirectImpactsSyncedMapsComponent,
TreatmentMapComponent,
TreatmentLegendComponent,
NgIf,
],
templateUrl: './expanded-direct-impact-map.component.html',
styleUrl: './expanded-direct-impact-map.component.scss',
})
export class ExpandedDirectImpactMapComponent {
constructor(
private directImpactsStateService: DirectImpactsStateService,
public dialogRef: MatDialogRef<ExpandedDirectImpactMapComponent>
) {}

showTreatmentPrescription$ =
this.directImpactsStateService.showTreatmentPrescription$;

mapPanelTitle$ = this.directImpactsStateService.mapPanelTitle$;

close() {
this.dialogRef.close();
}
}
Loading

0 comments on commit 8294810

Please sign in to comment.