Skip to content

Commit

Permalink
Merge pull request inasafe#6 from kartoza/upload-form
Browse files Browse the repository at this point in the history
update upload form to receive any hazard
lucernae authored Jul 22, 2020
2 parents 9a6e07f + 68f653c commit 0f4523c
Showing 18 changed files with 332 additions and 57 deletions.
39 changes: 39 additions & 0 deletions frontend/app-dashboard/css/side-panel.css
Original file line number Diff line number Diff line change
@@ -429,3 +429,42 @@ form label {
.panel-chart, .panel-chart-road, .panel-chart-primary {
margin-top: 15px
}

form input[type=file] {
height: 37px !important;
}

form label {
font-weight: 600;
margin-top: 5px;
}

.hazard-input {
border: 1px solid #ccc;
padding: 10px 20px;
margin-bottom: 10px;
}

.hazard-input select {
cursor: pointer;
}

.hazard-input-guide {
font-size: 12px;
}

.hazard-input-guide .fa {
color: green;
cursor: pointer;
margin-left: 5px;
}

.hazard-input-guide table {
margin-top: 10px;
}

.hazard-input-guide td, .hazard-input-guide th {
text-align: left;
border: 1px solid #ddd;
padding: 3px;
}
51 changes: 28 additions & 23 deletions frontend/app-dashboard/dashboard.html
Original file line number Diff line number Diff line change
@@ -47,10 +47,10 @@
forecast dashboard to trigger Early Action.</p>

<p>To get started, use the green flood selector icon below to
select a historical or forecast flood event (valid
select a historical or forecast flood event (valid
dates have circles around them).</p>
<p>This site is developed in collaboration with the

<p>This site is developed in collaboration with the
<a href="https://www.climatecentre.org">Red
Cross Red Crescent Climate Centre</a> with funding from the
World Bank GFDRR Challenge Fund and contributing to the
@@ -86,8 +86,8 @@
</div>
<div class="col-lg-10 text-justify">
<span>
Click the Browse Flood button on the bottom
right of InaSAFE FBA to browse flood forecasts.
Click the Browse Hazard button on the bottom
right of InaSAFE FBA to browse hazard forecasts.
</span>
</div>
</div>
@@ -96,11 +96,11 @@
<div class="panel-body-wrapper panel-body panel-flood-scenario" style="display: none">
<button class="btn btn-back pull-left"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></button>
<div class="panel-title">
Add Flood Forecast
Add Hazard Forecast
</div>
<div class="panel-body">
<button class="btn btn-warning btn-primary-1 btn-full-width" id="draw-flood" style="display: none;">Draw Flood Forecast</button>
<button class="btn btn-warning btn-primary-1 btn-full-width" id="upload-flood">Upload Flood Forecast</button>
<button class="btn btn-warning btn-primary-1 btn-full-width" id="upload-flood">Upload Hazard Forecast</button>
<button class="btn btn-warning btn-primary-1 btn-full-width" id="glofas" disabled>Latest GloFAS Forecast</button>
<button class="btn btn-warning btn-primary-1 btn-full-width" id="signature-flood" disabled>Latest Signature Flood Event</button>
<button class="btn btn-warning btn-primary-1 btn-full-width" id="existing-scenario-flood" disabled>Use Existing Scenario</button>
@@ -115,6 +115,9 @@
<div id="draw-flood-form">
<form role="form" id="draw-form" enctype="multipart/form-data" class="form-horizontal">
<div class="form-group">
<label for="draw_hazard_type">Hazard type</label>
<select class="form-control" name="hazard_type" id="draw_hazard_type" required></select>

<label for="draw_place_name">Place name</label>
<input class="form-control" name="place_name" id="draw_place_name" type="text">
<label for="draw_event_notes">Event notes</label>
@@ -158,27 +161,29 @@
<div id="upload-flood-form-wrapper">
<form role="form" method="post" id="upload-flood-form" enctype="multipart/form-data" class="form-horizontal" action="javascript:void(0)">
<div class="form-group">
<label for="upload_place_name">Place name</label>
<label for="upload_geojson">Geojson</label>
<input class="form-control" name="geojson" id="upload_geojson" type="file">
<div class="hazard-input">
<label for="hazard_type">Hazard type</label>
<select class="form-control" name="hazard_type" id="hazard_type" required></select>
<div class="hazard-input-guide">
Geojson need <b>class</b> attribute, which values range from : <i class="fa fa-caret-square-o-down" aria-hidden="true"></i>
<div class="hazard-input-guide-content" style="display: none">
</div>
</div>
</div>
<label for="upload_place_name">Hazard/Place name</label>
<input class="form-control" name="place_name" id="upload_place_name" type="text">
<label for="upload_source">Source</label>
<input class="form-control" name="source" id="upload_source" type="text">
<label for="upload_event_notes">Event notes</label>
<input class="form-control" name="event_notes" id="upload_event_notes" type="text">
<label for="upload_flood_model_notes">Flood model notes</label>
<label for="upload_flood_model_notes">Model notes</label>
<input class="form-control" name="flood_model_notes" id="upload_flood_model_notes" type="text">
<label for="upload_source_url">Source url</label>
<input class="form-control" name="source_url" id="upload_source_url" type="text">
<label for="upload_geojson">Geojson</label>
<input class="form-control" name="geojson" id="upload_geojson" type="file">
<label for="upload_return_period">Return period</label>
<select class="form-control" name="return_period" id="upload_return_period">
<option value="0">Unspecified</option>
<option value="1">1 year</option>
<option value="5">5 years</option>
<option value="10">10 years</option>
<option value="20">20 years</option>
<option value="100">100 years</option>
</select>
<div id="extra-info">
</div>
<div class="row">
<div class="col-lg-6" style="padding-right: 5px">
<label for="upload_acquisition_date">Acquisition date </label>
@@ -191,7 +196,7 @@
</div>
<br/>
<div id="upload-progress-bar" class="progress-status row">
<div class="alert-info" style="text-align: center;">Uploading Flood Forecast Map</div>
<div class="alert-info" style="text-align: center;">Uploading Hazard Layer</div>
<div class="progress">
<div class="progress-bar progress-bar-striped bg-info"></div>
</div>
@@ -212,7 +217,7 @@
</div>
<div class="col-lg-6" style="padding: 0 !important;">
<div style="text-align: center; line-height: 26px; color: white">
Browse Flood Forecasts
Browse Hazard Forecasts
</div>
</div>
<div class="col-lg-3 text-right">
@@ -352,7 +357,7 @@
</div>
</div>
<div class="col-lg-4 pull-right" style="text-align: right; padding-right: 35px; padding-top: 7px">
<button class="btn btn-warning btn-primary-1 add-flood-scenario"><img src="images/add-flood-icon.svg"><span>ADD FLOOD FORECAST</span></button>
<button class="btn btn-warning btn-primary-1 add-flood-scenario"><img src="images/add-flood-icon.svg"><span>ADD HAZARD FORECAST</span></button>
</div>
</div>
</nav>
9 changes: 9 additions & 0 deletions frontend/app-dashboard/forms/upload-extra-info/flood.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<label for="upload_return_period">Return period</label>
<select class="form-control" name="return_period" id="upload_return_period">
<option value="0">Unspecified</option>
<option value="1">1 year</option>
<option value="5">5 years</option>
<option value="10">10 years</option>
<option value="20">20 years</option>
<option value="100">100 years</option>
</select>
Empty file.
15 changes: 12 additions & 3 deletions frontend/app-dashboard/js/config.js
Original file line number Diff line number Diff line change
@@ -75,9 +75,18 @@ require([
'js/view/map.js',
'js/request.js',
'js/view/flood-collection.js',
], function ($, bootstrap, Backbone, _, moment, L, LDraw, AirDatepicker, AirDatepickerEN, utils, MAP, RequestView, FloodCollectionView) {
'js/model/hazard_type.js',
], function ($, bootstrap, Backbone, _, moment, L, LDraw, AirDatepicker, AirDatepickerEN, utils, MAP, RequestView, FloodCollectionView, HazardTypeCollection) {
AppRequest = new RequestView();
dispatcher = _.extend({}, Backbone.Events);
mapView = new MAP();
floodCollectionView = new FloodCollectionView();

// we get the hazardTypeCollection
hazardTypeCollection = new HazardTypeCollection()
hazardTypeCollection.fetch().then(function (data) {
mapView = new MAP();
floodCollectionView = new FloodCollectionView();
}).catch(function (data) {
console.log('Hazard type request failed');
console.log(data);
});
});
2 changes: 1 addition & 1 deletion frontend/app-dashboard/js/model/depth_class.js
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ define([

return Backbone.Collection.extend({
model: DepthClass,
urlRoot: postgresUrl + 'hazard_class',
urlRoot: postgresUrl + 'hazard_class?order=id',
url: function () {
return this.urlRoot
}
24 changes: 19 additions & 5 deletions frontend/app-dashboard/js/model/flood.js
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ define([
_geojson_attrs: {
flood_class_field: "class"
},

initialize: function (){
this._uploaded_features = 0;
this.on('feature-uploaded', this.featureUploaded, this);
@@ -66,7 +66,7 @@ define([
}
return 0;
},

featureUploaded: function(feature){
if(feature) {
this._uploaded_features++;
@@ -256,7 +256,7 @@ define([
}
return false;
},

_validateDepthClassAttribute: function () {
const geojson = this.get('geojson');
const areas = geojson.features;
@@ -283,7 +283,10 @@ define([

function _process_geojson(geojson){
try {
const layer = FloodLayer.fromGeoJSON(JSON.parse(geojson));
const layer = FloodLayer.fromGeoJSON(
JSON.parse(geojson),
{classes :flood_map_attributes.hazard_classes}
);
layer.set({
place_name: place_name,
return_period: return_period,
@@ -360,8 +363,19 @@ define([
const validated_geojson = layer.get('geojson');

const areas = validated_geojson.features.map(function(value){
// check the class based on the
let hazardClass = value.properties[layer._geojson_attrs.flood_class_field]
if (attributes && attributes['classes']) {
if (!attributes['classes'].includes(hazardClass)){
let e = {
'layer': layer,
'message': `Class "${hazardClass}" is not valid for selected hazard`
}
throw e
}
}
return {
depth_class: value.properties[layer._geojson_attrs.flood_class_field],
depth_class: hazardClass,
geometry: value.geometry
}
})
2 changes: 1 addition & 1 deletion frontend/app-dashboard/js/model/forecast_event.js
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ define([
const _flood_event_forecast_list_f_url = postgresUrl + 'rpc/flood_event_forecast_list_f';
const _flood_event_historical_forecast_list_f_url = postgresUrl + 'rpc/flood_event_historical_forecast_list_f';
// We define which column to take because we don't want to fetch the whole spreadsheet blob.
const _select_query_param = 'select=id,flood_map_id,acquisition_date,forecast_date,source,notes,link,trigger_status';
const _select_query_param = 'select=id,flood_map_id,acquisition_date,forecast_date,source,notes,link,trigger_status,hazard_type_id';
const ForecastEvent = Backbone.Model.extend({
// attribute placeholder
_url: {
25 changes: 25 additions & 0 deletions frontend/app-dashboard/js/model/hazard_type.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Hazard type model
* - id
* - name
*/
define([
'backbone',
'moment'
], function (Backbone) {

const HazardType = Backbone.Model.extend({
urlRoot: postgresUrl + 'hazard_type',
url: function () {
return `${this.urlRoot}?id=eq.${this.id}`
}
});

return Backbone.Collection.extend({
model: HazardType,
urlRoot: postgresUrl + 'hazard_type?order=name',
url: function () {
return this.urlRoot;
}
});
});
1 change: 1 addition & 0 deletions frontend/app-dashboard/js/shared.js
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ var dispatcher;
var mapView;
var AppRequest;
var floodCollectionView;
var hazardTypeCollection;
var resetView = true;

String.prototype.replaceAll = function (search, replacement) {
11 changes: 8 additions & 3 deletions frontend/app-dashboard/js/view/flood-collection.js
Original file line number Diff line number Diff line change
@@ -327,6 +327,11 @@ define([
selectForecast: function (forecast) {
let that = this;
this.selected_forecast = forecast;
hazardTypeCollection.models.forEach(function (model) {
if (that.selected_forecast.get('hazard_type_id') === model.get('id')){
that.selected_forecast.set('hazard_type', model.get('name'));
}
});
dispatcher.trigger('map:draw-forecast-layer', forecast, function () {
dispatcher.trigger('side-panel:open-dashboard', function () {
that.fetchVillageData(that.selected_forecast.id);
@@ -500,7 +505,7 @@ define([
overall['region'] = region;
}
dispatcher.trigger('dashboard:render-chart-building', overall, 'building');
dispatcher.trigger('dashboard:render-region-summary', overall, buildings, main_panel, region_render, that.keyStats[region_render], 'building');
dispatcher.trigger('dashboard:render-region-summary', overall, buildings, main_panel, region_render, that.keyStats[region_render], 'building', this.selected_forecast.get('hazard_type'));
},
fetchVillageData: function (flood_event_id) {
let that = this;
@@ -661,7 +666,7 @@ define([
overall['region'] = region;
}
dispatcher.trigger('dashboard:render-chart-road', overall, 'road');
dispatcher.trigger('dashboard:render-region-summary', overall, roads, main_panel, region_render, that.keyStats[region_render], 'road');
dispatcher.trigger('dashboard:render-region-summary', overall, roads, main_panel, region_render, that.keyStats[region_render], 'road', this.selected_forecast.get('hazard_type'));
},
fetchRoadDistrictData: function (flood_event_id) {
let that = this;
@@ -787,7 +792,7 @@ define([
overall['region'] = region;
}
dispatcher.trigger('dashboard:render-chart-population', overall, 'population');
dispatcher.trigger('dashboard:render-region-summary', overall, population, main_panel, region_render, that.keyStats[region_render], 'population');
dispatcher.trigger('dashboard:render-region-summary', overall, population, main_panel, region_render, that.keyStats[region_render], 'population', this.selected_forecast.get('hazard_type'));
},
_merge_population_stats: function(flood_event_id, stats_data, stats_collections, region){
let that = this;
Loading

0 comments on commit 0f4523c

Please sign in to comment.