Skip to content
This repository was archived by the owner on Aug 28, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/angular/planit/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { WeatherEventService } from './core/services/weather-event.service';

import {
BsDropdownModule,
ButtonsModule,
CollapseModule,
PopoverModule,
TooltipModule,
Expand All @@ -57,6 +58,7 @@ const appRoutes: Routes = [
HttpModule,
// 3rd party
BsDropdownModule.forRoot(),
ButtonsModule.forRoot(),
CollapseModule.forRoot(),
ModalModule.forRoot(),
PopoverModule.forRoot(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ export class AssessmentOverviewComponent implements OnInit {
constructor (private riskService: RiskService) {}

ngOnInit() {

this.riskService.list().subscribe(risks => {
this.risks = risks;
});
}
}

53 changes: 29 additions & 24 deletions src/angular/planit/src/app/risk-wizard/risk-wizard.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,42 @@
navigationMode="free"
navBarLocation="left"
navBarLayout="large-empty-symbols">
<app-risk-step-identify #identifyStep
wizardStep
stepTitle="{{ identifyStep.title }}"
navigationSymbol="{{ identifyStep.navigationSymbol }}">
<app-risk-step-identify class="wizard-step"
#identifyStep
wizardStep
stepTitle="{{ identifyStep.title }}"
navigationSymbol="{{ identifyStep.navigationSymbol }}">
</app-risk-step-identify>

<app-risk-step-hazard #hazardStep
wizardStep
optionalStep
stepTitle="{{ hazardStep.title }}"
navigationSymbol="{{ hazardStep.navigationSymbol }}">
<app-risk-step-hazard class="wizard-step"
#hazardStep
wizardStep
optionalStep
stepTitle="{{ hazardStep.title }}"
navigationSymbol="{{ hazardStep.navigationSymbol }}">
</app-risk-step-hazard>

<app-risk-step-impact #impactStep
wizardStep
optionalStep
stepTitle="{{ impactStep.title }}"
navigationSymbol="{{ impactStep.navigationSymbol }}">
<app-risk-step-impact class="wizard-step"
#impactStep
wizardStep
optionalStep
stepTitle="{{ impactStep.title }}"
navigationSymbol="{{ impactStep.navigationSymbol }}">
</app-risk-step-impact>

<app-risk-step-capacity #capacityStep
wizardStep
optionalStep
stepTitle="{{ capacityStep.title }}"
navigationSymbol="{{ capacityStep.navigationSymbol }}">
<app-risk-step-capacity class="wizard-step"
#capacityStep
wizardStep
optionalStep
stepTitle="{{ capacityStep.title }}"
navigationSymbol="{{ capacityStep.navigationSymbol }}">
</app-risk-step-capacity>

<app-risk-step-review #reviewStep
wizardCompletionStep
enableBackLinks
stepTitle="{{ reviewStep.title }}"
navigationSymbol="{{ reviewStep.navigationSymbol }}">
<app-risk-step-review class="wizard-step"
#reviewStep
wizardCompletionStep
enableBackLinks
stepTitle="{{ reviewStep.title }}"
navigationSymbol="{{ reviewStep.navigationSymbol }}">
</app-risk-step-review>
</wizard>
10 changes: 7 additions & 3 deletions src/angular/planit/src/app/risk-wizard/risk-wizard.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@ export class RiskWizardComponent implements AfterViewInit, OnDestroy, OnInit {
constructor(private session: WizardSessionService<Risk>) {}

ngOnInit() {
// TODO: Set initial risk from API
this.session.setData(new Risk({}));
this.session.data.subscribe(risk => this.riskModelChanged(risk));
// TODO (#324): Set initial risk from API
const risk = new Risk({
communitySystem: { name: '' },
weatherEvent: { name: '' }
});
this.session.setData(risk);
this.session.data.subscribe(r => this.riskModelChanged(r));
}

ngOnDestroy() {
Expand Down
6 changes: 5 additions & 1 deletion src/angular/planit/src/app/risk-wizard/risk-wizard.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';

import { ArchwizardModule } from 'ng2-archwizard';
import { BsDropdownModule, ButtonsModule, TooltipModule } from 'ngx-bootstrap';

import { Risk } from '../shared/models/risk.model';

Expand All @@ -19,7 +20,10 @@ import { SharedModule } from '../shared/shared.module';
BrowserModule,
ReactiveFormsModule,
ArchwizardModule,
SharedModule
SharedModule,
BsDropdownModule,
ButtonsModule,
TooltipModule
],
exports: [RiskWizardComponent],
declarations: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,40 @@
<h3>Hazard</h3>

<button type="button" nextStep>Continue</button>
<button type="button" previousStep>Back</button>
<div class="step-header">
<h3>Hazard</h3>
<h5>{{ risk.weatherEvent?.name }}</h5>
</div>
<div class="step-content">
<form [formGroup]="form">
<div class="step-form-control">
<h5>Probability</h5>
<app-option-dropdown [control]="form.controls['probability']"
[options]="relativeOptions">
</app-option-dropdown>
</div>
<div class="step-form-control">
<h5>Frequency <span class="icon icon-question-circle-o" tooltip="{{ tooltipText.frequency }}"></span></h5>
<div class="btn-group">
<button class="btn btn-primary"
[ngClass]="{active: form.controls.frequency.value === opt}"
*ngFor="let opt of directionalOptionsKeys"
(click)="updateDirectionalControl(form.controls.frequency, opt)">
{{ directionalOptions.get(opt)?.label }}
</button>
</div>
</div>
<div class="step-form-control">
<h5>Intensity <span class="icon icon-question-circle-o" tooltip="{{ tooltipText.intensity }}"></span></h5>
<div class="btn-group">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think buttons are what we're looking for rather than btn-group. The behavior is off too. If I change my selection, the buttons don't always respond. It would be nice to be able to select "unsure" again, and that is not possible. I'm on Chrome.
screen shot 2017-12-22 at 1 41 20 pm

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoa. Weird. The actual issue is that you can't select a button to the left of one you've already selected. That's new. Will fix.

I don't think the implementation of button vs button group really matters aside from button group is more semantically correct (since it enforces only one selected at a time) and we can separate the buttons with CSS. I'll play with it either way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well look what I found: valor-software/ngx-bootstrap#2581

Guess I'll switch to a standard button implementation real quick.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't address button spacing. That's fairly straightforward and can be addressed later in a styling pass.

<button class="btn btn-primary"
[ngClass]="{active: form.controls.intensity.value === opt}"
*ngFor="let opt of directionalOptionsKeys"
(click)="updateDirectionalControl(form.controls.intensity, opt)">
{{ directionalOptions.get(opt)?.label }}
</button>
</div>
</div>
</form>
</div>
<div class="step-footer">
<button type="button" nextStep>Skip Step</button>
<button type="button" [disabled]="form.pristine" nextStep (finalize)="save()">Continue</button>
</div>
Original file line number Diff line number Diff line change
@@ -1,16 +1,92 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';

import {
OrgRiskDirectionalOption,
OrgRiskDirectionalOptions,
OrgRiskRelativeOption,
OrgRiskRelativeOptions,
Risk
} from '../../shared/';
import { RiskStepKey } from '../risk-step-key';
import { WizardStepComponent } from '../wizard-step.component';
import { WizardSessionService } from '../wizard-session.service';

interface HazardStepFormModel {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put in it's own file? the identify step form model is in it's own file. It's exceptionally unlikely that this model will be used anywhere else independently so fundamentally I'm not opposed to this being here, but we should be consistent either way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch and good point. Given that this is for now a private interface on both components, I'll probably move the one in identify back to the component and remove the exports on these.

frequency: OrgRiskDirectionalOption;
intensity: OrgRiskDirectionalOption;
probability: OrgRiskRelativeOption;
}

@Component({
selector: 'app-risk-step-hazard',
templateUrl: 'hazard-step.component.html'
})

export class HazardStepComponent implements OnInit {
export class HazardStepComponent extends WizardStepComponent<Risk> implements OnInit {

public form: FormGroup;
public key = RiskStepKey.Hazard;
public navigationSymbol = '2';
public risk: Risk;
public title = 'Hazard';
public tooltipText = {
frequency: 'Estimation of the change in how often this hazard will occur in the future',
intensity: 'Estimation of the change in strength of this hazard in the future'
};

public directionalOptions = OrgRiskDirectionalOptions;
public relativeOptions = OrgRiskRelativeOptions;
// Can't *ngFor a map type or iterable, so instead we realize the iterable and use that in *ngFors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stanks but useful comment

public directionalOptionsKeys = Array.from(OrgRiskDirectionalOptions.keys());
public relativeOptionsKeys = Array.from(OrgRiskRelativeOptions.keys());

constructor(private fb: FormBuilder,
protected session: WizardSessionService<Risk>) {
super(session);
}

ngOnInit() {
super.ngOnInit();
this.risk = this.session.getData() || new Risk({});
this.setupForm(this.fromModel(this.risk));
this.form.get('intensity').valueChanges.subscribe(v => console.log('intensity: ', v));
}

save() {
const data: HazardStepFormModel = {
frequency: this.form.controls.frequency.value,
intensity: this.form.controls.intensity.value,
probability: this.form.controls.probability.value
};
this.session.setDataForKey(this.key, data);
}

updateDirectionalControl(control: FormControl, value: OrgRiskDirectionalOption) {
control.setValue(value);
control.markAsDirty();
}

setupForm(data: HazardStepFormModel) {
this.form = this.fb.group({
'frequency': [data.frequency, []],
'intensity': [data.intensity, []],
'probability': [data.probability, []],
});
}

constructor() { }
fromModel(model: Risk): HazardStepFormModel {
return {
frequency: model.frequency,
intensity: model.intensity,
probability: model.probability
};
}

ngOnInit() { }
toModel(data: HazardStepFormModel, model: Risk) {
model.frequency = data.frequency;
model.intensity = data.intensity;
model.probability = data.probability;
return model;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
<h3>Identify risk</h3>

<p>Match a hazard to a subset of people, strucutres or assets (sometimes referred to as a "community system") that the selected hazard may impact</p>

<form [formGroup]="form">
<div>
<label for="">Hazard</label>
<input type="text" formControlName="hazard">
<span *ngIf="form.controls.hazard.errors">*Required</span>
</div>
<div>
<label for="">Community System</label>
<input type="text" formControlName="communitySystem">
<span *ngIf="form.controls.communitySystem.errors">*Required</span>
</div>
<div class="step-header">
<h3>Identify risk</h3>
</div>
<div class="step-content">
<p>Match a hazard to a subset of people, structures or assets (sometimes referred to as a "community system") that the selected hazard may impact</p>
<form [formGroup]="form">
<div class="step-form-control">
<label for="">Hazard</label>
<input type="text" formControlName="hazard">
<span *ngIf="form.controls.hazard.errors">*Required</span>
</div>
<div class="step-form-control">
<label for="">Community System</label>
<input type="text" formControlName="communitySystem">
<span *ngIf="form.controls.communitySystem.errors">*Required</span>
</div>
</form>
</div>
<div class="step-footer">
<button type="button" [disabled]="!form.valid" nextStep (finalize)="save()">Continue</button>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think the buttons are generally considered part of the <form>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally yes, if they directly interact with form events, like a form submit button. That's not the case here though, these buttons are a part of wizard navigation not the form itself.

<button type="button" (click)="cancel()">Cancel</button>
</form>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';

import { Risk } from '../../shared/';
import { IdentifyStepFormModel } from './identify-step-form.model';
import { WizardStepComponent } from '../wizard-step.component';
import { RiskStepKey } from '../risk-step-key';
import { WizardSessionService } from '../wizard-session.service';

interface IdentifyStepFormModel {
hazard: string;
communitySystem: string;
}

@Component({
selector: 'app-risk-step-identify',
templateUrl: 'identify-step.component.html'
})

export class IdentifyStepComponent extends WizardStepComponent<Risk> implements OnInit {

public form: FormGroup;
Expand All @@ -29,23 +32,23 @@ export class IdentifyStepComponent extends WizardStepComponent<Risk> implements

ngOnInit() {
super.ngOnInit();
const risk = this.session.getData() || new Risk({});
this.setupForm(this.fromData(risk));
const risk = this.session.getData();
this.setupForm(this.fromModel(risk));
}

cancel() {
this.router.navigate(['assessment']);
}

fromData(risk: Risk): IdentifyStepFormModel {
fromModel(risk: Risk): IdentifyStepFormModel {
return {
hazard: risk.impactDescription,
hazard: risk.weatherEvent.name,
communitySystem: risk.communitySystem.name
};
}

save() {
const data = {
const data: IdentifyStepFormModel = {
hazard: this.form.controls.hazard.value,
communitySystem: this.form.controls.communitySystem.value
};
Expand All @@ -59,8 +62,8 @@ export class IdentifyStepComponent extends WizardStepComponent<Risk> implements
});
}

toData(data: IdentifyStepFormModel, risk: Risk) {
risk.impactDescription = data.hazard;
toModel(data: IdentifyStepFormModel, risk: Risk) {
risk.weatherEvent.name = data.hazard;
risk.communitySystem.name = data.communitySystem;
return risk;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ import { Injectable } from '@angular/core';

import { Subject } from 'rxjs/Rx';

import { RiskStepKey } from './risk-step-key';
import { Risk } from '../shared/';

interface DataHandler<T> {
toData: (any, T) => T;
fromData: (T) => any;
Expand Down
Loading