Skip to content

Commit 0e502f2

Browse files
committed
Merge branch 'release/1.9.10'
2 parents d55fd55 + cdbdc5f commit 0e502f2

File tree

19 files changed

+859
-115
lines changed

19 files changed

+859
-115
lines changed

Dashboard/app/css/main.scss

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ html {
147147
height: 100%;
148148
overflow-y: scroll;
149149
border-top: 3px solid rgb(38, 8, 89);
150+
box-sizing: border-box;
150151
background: white;
151152
}
152153

@@ -6290,16 +6291,27 @@ li.disable {
62906291
}
62916292
}
62926293

6293-
/* Custom styling for navMaps tab */
6294+
/* Non-scrollable map views */
62946295

6295-
html.navMaps {
6296-
border-top: 0px;
6296+
html.navMaps, .public {
62976297
header {
62986298
position: initial;
62996299
}
6300-
#flowMap, #pointDetails {
6301-
height: 600px;
6302-
height: 75vh;
6300+
#selected-media {
6301+
z-index: 999;
6302+
position: absolute;
6303+
padding: 5px;
6304+
bottom: 130px;
6305+
left: 20%;
6306+
background-color: white;
6307+
img {
6308+
float: left;
6309+
height: 70px;
6310+
}
6311+
label {
6312+
float: left;
6313+
margin-left: 10px
6314+
}
63036315
}
63046316
.mapFlow.middleSection {
63056317
padding: 0;
@@ -6308,3 +6320,21 @@ html.navMaps {
63086320
padding-bottom: 15px;
63096321
}
63106322
}
6323+
6324+
.public {
6325+
#dropdown-holder {
6326+
margin-top: 30px;
6327+
z-index:9999;
6328+
}
6329+
footer {
6330+
height: 60px;
6331+
}
6332+
6333+
#flowMap {
6334+
height: calc(100vh - (3px + 83px + 53px + 60px));
6335+
}
6336+
6337+
#pointDetails {
6338+
height: calc(100vh - (3px + 83px + 53px + 60px + 5px));
6339+
}
6340+
}

Dashboard/app/js/lib/controllers/general-controllers-common.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ FLOW.dashboardLanguageControl = Ember.Object.create({
44
content: [{ label: "English (Default)", value: "en"},
55
{ label: "Español", value: "es" },
66
{ label: "Français", value: "fr" },
7+
{ label: "Bahasa Indonesia", value: "id"},
78
{ label: "Português", value: "pt" },
8-
{ label: "Bahasa Indonesia", value: "id"}],
9+
{ label: "Tiếng Việt", value: "vi"}],
910

1011
languageChanged: function () {
1112
var localeUrl = '/ui-strings.js?locale=' + this.dashboardLanguage;

Dashboard/app/js/lib/views/maps/map-views-common.js

Lines changed: 117 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ FLOW.NavMapsView = FLOW.View.extend({
1010
polygons: [],
1111
mapZoomLevel: 0,
1212
mapCenter: null,
13+
clickedPointCoordinates: [],
14+
mediaMarkers: {},
15+
selectedMediaMarker: {},
16+
mediaMarkerSelected: {},
1317
hierarchyObject: [],
1418
lastSelectedElement: 0,
1519
geomodel: null,
@@ -183,21 +187,7 @@ FLOW.NavMapsView = FLOW.View.extend({
183187
this.map = map;
184188

185189
map.on('click', function(e) {
186-
if(self.marker != null){
187-
self.map.removeLayer(self.marker);
188-
self.hideDetailsPane();
189-
$('#pointDetails').html('<p class="noDetails">'+Ember.String.loc('_no_details') +'</p>');
190-
}
191-
192-
if(self.polygons.length > 0){
193-
for(var i=0; i<self.polygons.length; i++){
194-
self.map.removeLayer(self.polygons[i]);
195-
}
196-
//restore the previous zoom level and map center
197-
self.map.setZoom(self.mapZoomLevel);
198-
self.map.panTo(self.mapCenter);
199-
self.polygons = [];
200-
}
190+
self.clearMap(); //remove any previously loaded point data
201191
});
202192

203193
map.on('zoomend', function() {
@@ -208,11 +198,10 @@ FLOW.NavMapsView = FLOW.View.extend({
208198
self.checkHierarchy(0);
209199

210200
$(document).off('change', '.folder_survey_selector').on('change', '.folder_survey_selector',function(e) {
211-
201+
self.clearMap(); //remove any previously loaded point data
212202
$('#form_selector option[value!=""]').remove();
213203

214-
//remove all 'folder_survey_selector's after current
215-
self.cleanHierarchy($(this));
204+
self.cleanHierarchy($(this)); //remove all 'folder_survey_selector's after current
216205

217206
//first remove previously created form selector elements
218207
$(".form_selector").remove();
@@ -281,8 +270,8 @@ FLOW.NavMapsView = FLOW.View.extend({
281270
});
282271

283272
$(document).off('change', '.form_selector').on('change', '.form_selector',function(e) {
284-
//remove all 'folder_survey_selector's after current
285-
self.cleanHierarchy($(this));
273+
self.clearMap(); //remove any previously loaded point data
274+
self.cleanHierarchy($(this)); //remove all 'folder_survey_selector's after current
286275

287276
if ($(this).val() !== "") {
288277
var formId = $(this).val();
@@ -310,7 +299,7 @@ FLOW.NavMapsView = FLOW.View.extend({
310299

311300
$(document.body).on('click', '.project-geoshape', function(){
312301
if(self.polygons.length > 0){
313-
$(this).html(Ember.String.loc('_project_geoshape_onto_main_map'));
302+
$(this).html(Ember.String.loc('_project_onto_main_map'));
314303
for(var i=0; i<self.polygons.length; i++){
315304
self.map.removeLayer(self.polygons[i]);
316305
}
@@ -323,6 +312,62 @@ FLOW.NavMapsView = FLOW.View.extend({
323312
self.projectGeoshape($(this).data('geoshape-object'));
324313
}
325314
});
315+
316+
$(document.body).on('mouseover', '.media', function(){
317+
var mediaObject = $(this).data('coordinates');
318+
var mediaMarkerIcon = new L.Icon({
319+
iconUrl: 'images/media-marker.png',
320+
iconSize: [11, 11]
321+
}), selectedMediaMarkerIcon = new L.Icon({
322+
iconUrl: 'images/media-marker-selected.png',
323+
iconSize: [11, 11]
324+
});
325+
if(mediaObject !== '') {
326+
var filename = mediaObject.filename.substring(mediaObject.filename.lastIndexOf("/")+1).split(".")[0];
327+
var mediaCoordinates = [mediaObject['location']['latitude'], mediaObject['location']['longitude']];
328+
if(!(filename in self.mediaMarkers)) {
329+
self.mediaMarkers[filename] = new L.marker(mediaCoordinates, {icon: mediaMarkerIcon}).addTo(self.map);
330+
} else {
331+
self.selectedMediaMarker[filename] = new L.marker(mediaCoordinates, {icon: selectedMediaMarkerIcon}).addTo(self.map);
332+
}
333+
}
334+
});
335+
336+
$(document.body).on('mouseout', '.media', function(){
337+
var mediaObject = $(this).data('coordinates');
338+
if(mediaObject !== '') {
339+
var filename = mediaObject.filename.substring(mediaObject.filename.lastIndexOf("/")+1).split(".")[0];
340+
if(filename in self.mediaMarkers && !(filename in self.mediaMarkerSelected)) {
341+
self.map.removeLayer(self.mediaMarkers[filename]);
342+
delete self.mediaMarkers[filename];
343+
} else {
344+
self.map.removeLayer(self.selectedMediaMarker[filename]);
345+
delete self.selectedMediaMarker[filename];
346+
}
347+
}
348+
});
349+
350+
$(document.body).on('click', '.media-location', function(){
351+
var mediaObject = $(this).data('coordinates');
352+
var mediaMarkerIcon = new L.Icon({
353+
iconUrl: 'images/media-marker.png',
354+
iconSize: [11, 11]
355+
});
356+
if(mediaObject !== '') {
357+
var filename = mediaObject.filename.substring(mediaObject.filename.lastIndexOf("/")+1).split(".")[0];
358+
var mediaCoordinates = [mediaObject['location']['latitude'], mediaObject['location']['longitude']];
359+
if(!(filename in self.mediaMarkerSelected)) {
360+
$(this).html(Ember.String.loc('_hide_photo_on_map'));
361+
self.mediaMarkers[filename] = new L.marker(mediaCoordinates, {icon: mediaMarkerIcon}).addTo(self.map);
362+
self.mediaMarkerSelected[filename] = true;
363+
} else {
364+
$(this).html(Ember.String.loc('_show_photo_on_map'));
365+
self.map.removeLayer(self.mediaMarkers[filename]);
366+
delete self.mediaMarkers[filename];
367+
delete self.mediaMarkerSelected[filename];
368+
}
369+
}
370+
});
326371
},
327372

328373
/*Check if a named map exists. If one exists, call function to overlay it
@@ -545,6 +590,7 @@ FLOW.NavMapsView = FLOW.View.extend({
545590
if(self.marker != null){
546591
self.map.removeLayer(self.marker);
547592
}
593+
self.clickedPointCoordinates = [data.lat, data.lon];
548594
self.placeMarker([data.lat, data.lon]);
549595

550596
self.showDetailsPane();
@@ -610,7 +656,7 @@ FLOW.NavMapsView = FLOW.View.extend({
610656

611657
$.get(url, function(pointData, status){
612658
if (pointData['answers'] != null) {
613-
var geoshapeObject, geoshapeQuestionsCount = 0;
659+
var geoshapeObject, geoshapeQuestionsCount = 0, mediaResponses = [];
614660

615661
var dataCollectionDate = pointData['answers']['created_at'];
616662
var date = new Date(dataCollectionDate);
@@ -649,7 +695,7 @@ FLOW.NavMapsView = FLOW.View.extend({
649695
clickedPointContent += '<h4><div style="float: left">'
650696
+self.questions[i].text
651697
+'</div>&nbsp;<a style="float: right" class="project-geoshape" data-geoshape-object=\''+questionAnswer+'\'>'
652-
+Ember.String.loc('_project_geoshape_onto_main_map')+'</a></h4>';
698+
+Ember.String.loc('_project_onto_main_map')+'</a></h4>';
653699
}
654700
} else {
655701
clickedPointContent += '<h4>'+self.questions[i].text+'&nbsp;</h4>';
@@ -660,21 +706,31 @@ FLOW.NavMapsView = FLOW.View.extend({
660706
if(questionAnswer !== "" && questionAnswer !== null && questionAnswer !== "null"){
661707
switch (self.questions[i].questionType) {
662708
case "PHOTO":
663-
var imageString = "", imageJson;
709+
case "VIDEO":
710+
var mediaString = "", mediaJson, mediaFilename = "", mediaObject = {};
664711
if (questionAnswer.charAt(0) === '{') {
665-
imageJson = JSON.parse(questionAnswer);
666-
imageString = imageJson.filename
712+
mediaJson = JSON.parse(questionAnswer);
713+
mediaString = mediaJson.filename;
667714
} else {
668-
imageString = questionAnswer;
715+
mediaString = questionAnswer;
669716
}
670717

671-
var image = '<div class=":imgContainer photoUrl:shown:hidden">';
672-
var imageFilename = FLOW.Env.photo_url_root+imageString.substring(imageString.lastIndexOf("/")+1);
673-
image += '<a href="'+imageFilename+'" target="_blank">'
674-
+'<img src="'+imageFilename+'" alt=""/></a>';
675-
676-
image += '</div>';
677-
clickedPointContent += image;
718+
var mediaFileURL = FLOW.Env.photo_url_root+mediaString.substring(mediaString.lastIndexOf("/")+1);
719+
if(self.questions[i].questionType == "PHOTO") {
720+
mediaOutput = '<div class=":imgContainer photoUrl:shown:hidden">'
721+
+'<a class="media" data-coordinates=\''
722+
+((mediaJson.location) ? questionAnswer : '' )+'\' href="'
723+
+mediaFileURL+'" target="_blank"><img src="'+mediaFileURL+'" alt=""/></a><br>'
724+
+((mediaJson.location) ? '<a class="media-location" data-coordinates=\''+questionAnswer+'\'>'+Ember.String.loc('_show_photo_on_map')+'</a>' : '')
725+
+'</div>';
726+
} else if (self.questions[i].questionType == "VIDEO") {
727+
mediaOutput = '<div><div class="media" data-coordinates=\''
728+
+((mediaJson.location) ? questionAnswer : '' )+'\'>'+mediaFileURL+'</div><br>'
729+
+'<a href="'+mediaFileURL+'" target="_blank">'+Ember.String.loc('_open_video')+'</a>'
730+
+((mediaJson.location) ? '&nbsp;|&nbsp;<a class="media-location" data-coordinates=\''+questionAnswer+'\'>'+Ember.String.loc('_show_photo_on_map')+'</a>' : '')
731+
+'</div>';
732+
}
733+
clickedPointContent += mediaOutput;
678734
break;
679735
case "GEOSHAPE":
680736
geoshapeObject = FLOW.parseGeoshape(questionAnswer);
@@ -711,20 +767,6 @@ FLOW.NavMapsView = FLOW.View.extend({
711767
clickedPointContent += srcAttr + signatureJson.image +'"/></div>';
712768
clickedPointContent += '<div class="signedBySection">'+Ember.String.loc('_signed_by') +': '+signatureJson.name+'</div>';
713769
break;
714-
case "VIDEO":
715-
var videoString = "", videoJson;
716-
if (questionAnswer.charAt(0) === '{') {
717-
videoJson = JSON.parse(questionAnswer);
718-
videoString = videoJson.filename
719-
} else {
720-
videoString = questionAnswer;
721-
}
722-
723-
var videoFileUrl = FLOW.Env.photo_url_root+videoString.substring(videoString.lastIndexOf("/")+1);
724-
var videoContent = videoFileUrl+' <a href="'+videoFileUrl+'" target="_blank">'+Ember.String.loc('_open_video')+'</a>';
725-
726-
clickedPointContent += videoContent;
727-
break;
728770
case "CASCADE":
729771
case "OPTION":
730772
var cascadeString = "", cascadeJson;
@@ -741,14 +783,14 @@ FLOW.NavMapsView = FLOW.View.extend({
741783
default:
742784
clickedPointContent += questionAnswer
743785
}
786+
clickedPointContent += "&nbsp;</div><hr>";
744787
}
745-
clickedPointContent += "&nbsp;</div><hr>";
746788
}
747789
}
748790
}
749791
clickedPointContent += '</div>';
750-
751-
$("#pointDetails").append(clickedPointContent);
792+
$('#pointDetails').append(clickedPointContent);
793+
$('hr').show();
752794

753795
//if there's geoshape, draw it
754796
if(geoshapeQuestionsCount > 0){
@@ -890,6 +932,30 @@ FLOW.NavMapsView = FLOW.View.extend({
890932
}
891933
},
892934

935+
clearMap: function() {
936+
var self = this;
937+
if(self.marker != null){
938+
self.map.removeLayer(self.marker);
939+
self.hideDetailsPane();
940+
$('#pointDetails').html('<p class="noDetails">'+Ember.String.loc('_no_details') +'</p>');
941+
}
942+
943+
if(!$.isEmptyObject(self.mediaMarkers)) {
944+
for(mediaMarker in self.mediaMarkers) {
945+
self.map.removeLayer(self.mediaMarkers[mediaMarker]);
946+
}
947+
}
948+
949+
if(self.polygons.length > 0){
950+
for(var i=0; i<self.polygons.length; i++){
951+
self.map.removeLayer(self.polygons[i])
952+
}
953+
//restore the previous zoom level and map center
954+
self.map.setView(self.mapCenter, self.mapZoomLevel);
955+
self.polygons = [];
956+
}
957+
},
958+
893959
formatDate: function(date) {
894960
if (date && !isNaN(date.getTime())) {
895961
return date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();

Dashboard/app/js/lib/views/views-public.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,6 @@ Ember.Select.reopen({
171171
attributeBindings: ['size']
172172
});
173173

174-
175-
FLOW.HeaderView = FLOW.View.extend({
176-
templateName: 'application/header-common'
177-
});
178-
179174
FLOW.FooterView = FLOW.View.extend({
180175
templateName: 'application/footer-public'
181176
});

Dashboard/app/js/templates/application/application-public.handlebars

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@
99
<div class="widthConstraint">
1010
<h1>Akvo
1111
<abbr title="field level operations watch">Flow</abbr></h1>
12-
13-
{{view FLOW.HeaderView}}
1412
</div>
1513
</header>
16-
<div id="pageWrap" class="widthConstraint belowHeader">
14+
<div id="pageWrap" class="widthConstraint belowHeader public">
1715
{{outlet}}
1816
</div>
1917

172 Bytes
Loading
172 Bytes
Loading

GAE/src/com/gallatinsystems/survey/dao/DeviceSurveyJobQueueDAO.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ public List<DeviceSurveyJobQueue> get(String devicePhoneNumber, String imei, Str
6161
query.declareParameters("String imeiParam");
6262
legacy = (List<DeviceSurveyJobQueue>) query.execute(imei);
6363
}
64-
if ((legacy == null || legacy.isEmpty()) && devicePhoneNumber != null) {
64+
if ((legacy == null || legacy.isEmpty())
65+
&& devicePhoneNumber != null && !devicePhoneNumber.isEmpty()) {
6566
// Fall back to phone number
6667
query = pm.newQuery(DeviceSurveyJobQueue.class);
6768
query.setFilter("devicePhoneNumber == devicePhoneNumberParam");

GAE/src/locale/en.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ Group = Group
210210
Group\ smaller\ items = Group smaller items
211211
Hide = Hide
212212
Hide\ from\ map = Hide from map
213+
Hide\ photo\ location\ on\ map = Hide photo location on map
213214
Hide\ questions = Hide questions
214215
Home = Home
215216
Horizontal\ bar\ chart = Horizontal bar chart
@@ -423,6 +424,7 @@ Settings = Settings
423424
Show = Show
424425
Show\ advanced\ settings = Show advanced settings
425426
Show\ on\ map = Show on map
427+
Show\ photo\ location\ on\ map = Show photo location on map
426428
Show\ questions = Show questions
427429
Signature = Signature
428430
Signed\ by = Signed by

0 commit comments

Comments
 (0)