Skip to content

Commit

Permalink
Scenario cards list (PLAN-1363) (#1666)
Browse files Browse the repository at this point in the history
  • Loading branch information
lastminutediorama authored Sep 3, 2024
1 parent 186b9ad commit 43840b4
Show file tree
Hide file tree
Showing 16 changed files with 215 additions and 75 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AuthService, PlanNotesService } from '@services';
import { MatLegacyDialogModule as MatDialogModule } from '@angular/material/legacy-dialog';
import { MatLegacySnackBarModule as MatSnackBarModule } from '@angular/material/legacy-snack-bar';
import { MatDialogModule } from '@angular/material/dialog';
import { MatSnackBarModule } from '@angular/material/snack-bar';

import { AreaScrollingNotesComponent } from './area-scrolling-notes.component';
import { MockProvider } from 'ng-mocks';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Input, OnInit } from '@angular/core';
import { MatLegacyDialog as MatDialog } from '@angular/material/legacy-dialog';
import { MatLegacySnackBar as MatSnackBar } from '@angular/material/legacy-snack-bar';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { DeleteNoteDialogComponent } from '../delete-note-dialog/delete-note-dialog.component';
import { take } from 'rxjs';
import { Plan } from '@types';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@
mat-align-tabs="start"
(selectedTabChange)="tabChange($event)">
<mat-tab label="ACTIVE">
<mat-card-content>
<div class="empty-state" *ngIf="activeScenarios.length === 0">
No active scenarios
</div>
</mat-card-content>
<mat-card-content>
<app-scenarios-table-list
*ngIf="activeScenarios.length > 0"
Expand Down Expand Up @@ -183,14 +188,10 @@ <h4>Scenarios</h4>
(selectedTabChange)="tabChange($event)">
<mat-tab label="ACTIVE">
<mat-card-content>
<app-scenarios-table-list
<app-scenarios-card-list
*ngIf="activeScenarios.length > 0"
[scenarios]="activeScenarios"
[highlightedScenarioRow]="highlightedScenarioRow"
(viewScenario)="viewScenario()"
(selectScenario)="
highlightScenario($event)
"></app-scenarios-table-list>
(viewScenario)="viewScenario()"></app-scenarios-card-list>

<div class="empty-state" *ngIf="activeScenarios.length === 0">
No active scenarios
Expand All @@ -199,37 +200,15 @@ <h4>Scenarios</h4>
</mat-tab>
<mat-tab label="ARCHIVED">
<mat-card-content>
<app-scenarios-table-list
<app-scenarios-card-list
*ngIf="archivedScenarios.length > 0"
[scenarios]="archivedScenarios"
[highlightedScenarioRow]="highlightedScenarioRow"
(viewScenario)="viewScenario()"
(selectScenario)="
highlightScenario($event)
"></app-scenarios-table-list>
(viewScenario)="viewScenario()"></app-scenarios-card-list>
<div class="empty-state" *ngIf="archivedScenarios.length === 0">
No scenarios in Archived.
</div>
</mat-card-content>
</mat-tab>
</mat-tab-group>

<mat-card-actions align="end">
<button
sg-button
*ngIf="showArchiveScenario"
[disabled]="!canArchiveScenario"
(click)="toggleScenarioStatus(selectedTabIndex === 0)"
[icon]="selectedTabIndex === 0 ? 'archive' : 'unarchive'">
{{ selectedTabIndex === 0 ? 'Archive' : 'Restore' }}
</button>
<button
sg-button
[disabled]="highlightedScenarioRow === null"
(click)="viewScenario()"
icon="description">
View scenario
</button>
</mat-card-actions>
</app-section-loader>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { UploadProjectAreasModalComponent } from '../../upload-project-areas-mod
import { ScenarioCreateConfirmationComponent } from '../../scenario-create-confirmation/scenario-create-confirmation.component';
export interface ScenarioRow extends Scenario {
selected?: boolean;
created_at?: string;
}

@UntilDestroy()
Expand Down Expand Up @@ -68,7 +69,6 @@ export class SavedScenariosComponent implements OnInit {
.pipe(take(1))
.subscribe((scenarios) => {
this.totalScenarios = scenarios.length;

this.scenariosForUser = this.showOnlyMyScenarios
? scenarios.filter((s) => s.user === this.user$.value?.id)
: scenarios;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<sg-scenario-card
*ngFor="let s of scenarios"
[name]="s.name"
[creator]="s.creator"
[areas]="s.max_treatment_area"
[created_at]="s.created_at"
[budget]="s.max_budget"
[treatmentPlansCount]="s.tx_plan_count"
[status]="s.scenario_result?.status || 'PENDING'"
(click)="handleClickedScenario(s)"
[selected]="isSelected(s)">
</sg-scenario-card>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@import 'mixins';
@import 'colors';

:host {
display: flex;
flex-wrap: wrap;
flex-direction: column;
justify-content: space-between;
gap: 20px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ScenariosCardListComponent } from './scenarios-card-list.component';

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

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ScenariosCardListComponent],
}).compileComponents();

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

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { NgFor } from '@angular/common';

import { ScenarioRow } from '../saved-scenarios/saved-scenarios.component';
import { Scenario, ScenarioResult } from '@types';
import { ScenarioCardComponent } from '../../../../styleguide/scenario-card/scenario-card.component';
import {
parseResultsToProjectAreas,
parseResultsToTotals,
} from '../../plan-helpers';

@Component({
selector: 'app-scenarios-card-list',
standalone: true,
imports: [ScenarioCardComponent, NgFor],
templateUrl: './scenarios-card-list.component.html',
styleUrl: './scenarios-card-list.component.scss',
})
export class ScenariosCardListComponent {
selectedCard: ScenarioRow | null = null;
@Input() scenarios: ScenarioRow[] = [];
@Output() selectScenario = new EventEmitter<ScenarioRow>();
@Output() clickedScenario = new EventEmitter<ScenarioRow>();

hasResults(scenario: Scenario) {
return (
!!scenario.scenario_result &&
scenario.scenario_result.result?.features?.length > 0
);
}

handleClickedScenario(row: ScenarioRow): void {
if (
row.scenario_result?.status === 'FAILURE' ||
row.scenario_result?.status === 'SUCCESS'
) {
this.selectedCard = row;
this.selectScenario.emit(row);
}
}

calculateTotals(results: ScenarioResult) {
const projectAreas = parseResultsToProjectAreas(results);
return parseResultsToTotals(projectAreas);
}

isSelected(s: ScenarioRow): boolean {
return this.selectedCard == s;
}
}
4 changes: 4 additions & 0 deletions src/interface/src/app/plan/plan.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ import { ButtonComponent } from '@styleguide';
import { DeleteDialogComponent } from '../standalone/delete-dialog/delete-dialog.component';
import { UploadProjectAreasModalComponent } from './upload-project-areas-modal/upload-project-areas-modal.component';
import { PlanningAreaTitlebarMenuComponent } from '../standalone/planning-area-titlebar-menu/planning-area-titlebar-menu.component';
import { ScenarioCardComponent } from '../../styleguide/scenario-card/scenario-card.component';
import { ScenariosCardListComponent } from './plan-summary/scenarios-card-list/scenarios-card-list.component';
import { TreatmentCardComponent } from '../../styleguide/treatment-card/treatment-card.component';
import { TreatmentsTabComponent } from './create-scenarios/treatments-tab/treatments-tab.component';

Expand Down Expand Up @@ -99,6 +101,8 @@ import { TreatmentsTabComponent } from './create-scenarios/treatments-tab/treatm
DeleteDialogComponent,
UploadProjectAreasModalComponent,
PlanningAreaTitlebarMenuComponent,
ScenarioCardComponent,
ScenariosCardListComponent,
TreatmentCardComponent,
],
})
Expand Down
4 changes: 4 additions & 0 deletions src/interface/src/app/types/scenario.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export interface Scenario {
scenario_result?: ScenarioResult;
status: SCENARIO_STATUS;
user?: number;
max_treatment_area?: number;
created_at?: string;
max_budget?: number;
tx_plan_count?: number | undefined;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
.right-items-box {
display: flex;
flex-direction: row;
justify-content: end;
justify-content: flex-end;
min-width: 60px;
width: 60px;
align-items: center;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
<div class="title-row">
<div class="title-section">
<h4>
<div class="scenario-name">
{{ name }}
</h4>

</div>
<sg-status-chip
*ngIf="status"
[status]="getChipStatus()"
[label]="status"></sg-status-chip>
[label]="getChipLabel()"></sg-status-chip>
<div *ngIf="hasFailed()" class="failed-message">
<mat-icon class="error-icon">error</mat-icon>
Create a new scenario to proceed to treatment plan
Expand Down Expand Up @@ -44,17 +43,17 @@ <h4>
<div class="detail-column">
<div class="detail-header">Creator</div>
<div class="detail-info">
{{ creator }}
{{ creator ?? 'N/A' }}
</div>
</div>
<ng-container *ngIf="!isRunning()">
<div class="detail-column">
<div class="detail-header">Areas</div>
<div class="detail-info">{{ areas }}</div>
<div class="detail-info">{{ areas ?? 'N/A' }}</div>
</div>
<div class="detail-column">
<div class="detail-header">Est Budget</div>
<div class="detail-info">{{ budget | currency }}</div>
<div class="detail-info">{{ (budget | currency) ?? 'N/A' }}</div>
</div>
<div class="detail-column">
<div class="detail-header">Treatment Plans</div>
Expand All @@ -63,7 +62,7 @@ <h4>
<div class="detail-column">
<div class="detail-header">Created</div>
<div class="detail-info">
{{ created_at | date: 'MMM d, y, h:mm:ss a ' }}
{{ created_at | date: "MMMM d, y 'at' h:mm a" }}
</div>
</div>
</ng-container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,38 @@

:host {
@include xs-label();
align-items: center;
background-color: white;
border-radius: 4px;
border: 1px solid $color-soft-gray;
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.2);
box-sizing: border-box;
display: inline-flex;
flex-direction: column;
gap: 1em;
height: 140px;
justify-content: center;
left: 0px;
padding: 8px 12px;
right: 0px;
top: 40px;
background: #ffffff;
border: 1px solid $color-soft-gray;
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.2);
border-radius: 4px;
display: inline-flex;
padding: 8px 12px;
justify-content: center;
align-items: center;
width: 100%;
background-color: white;
flex-direction: column;
gap: 1em;

&:hover {
background-color: $color-light-gray;
cursor: pointer;
}

&.selected {
border: 1px $color-original-purple solid;
background-color: white;
}

&.disabled-content {
color: $color-text-gray;
color: $color-text-gray;
border: 1px solid $color-soft-gray;
background-color: white;
cursor: default;
}

.title-row {
Expand All @@ -31,13 +43,21 @@
width: 100%;
height: 3em;
justify-content: space-between;
align-items: center;
}
.title-section {
display: flex;
flex-direction: row;
gap: 1em;
align-items: center;
}
.scenario-name {
@include h4();
width: 200px;
white-space: nowrap;
text-overflow: ellipsis;
overflow-x: hidden;
}
.controls-section {
display: flex;
flex-direction: row;
Expand Down
Loading

0 comments on commit 43840b4

Please sign in to comment.