diff --git a/src/app/citizenScience/bristlebird/bristlebird.js b/src/app/citizenScience/bristlebird/bristlebird.js index e9d13cd5..aa7bd908 100644 --- a/src/app/citizenScience/bristlebird/bristlebird.js +++ b/src/app/citizenScience/bristlebird/bristlebird.js @@ -103,15 +103,15 @@ class BristlebirdController { } else if (studies.length > 1) { console.warn("More than one study found. Using the first one"); } + $scope.study = studies[0]; - $scope.study_id = $scope.study.id; - Question.questions($scope.study_id).then(x => { + Question.questions($scope.study.id).then(x => { console.log("questions loaded", x); //TODO: update to allow multiple questions $scope.questionData = x.data.data[0].questionData; - SampleLabels.init(x.data.data[0], $scope.study_id); + SampleLabels.init(x.data.data[0], $scope.study.id); }); }); diff --git a/src/app/citizenScience/bristlebird/listen.tpl.html b/src/app/citizenScience/bristlebird/listen.tpl.html index 1f852100..6fa1b300 100644 --- a/src/app/citizenScience/bristlebird/listen.tpl.html +++ b/src/app/citizenScience/bristlebird/listen.tpl.html @@ -42,18 +42,13 @@

Eastern Bristlebird Search - + - - - - - - \ No newline at end of file + diff --git a/src/app/citizenScience/datasetProgress/citizenScienceSamples.js b/src/app/citizenScience/datasetProgress/citizenScienceSamples.js index 28e3c3d9..1adc9e3f 100644 --- a/src/app/citizenScience/datasetProgress/citizenScienceSamples.js +++ b/src/app/citizenScience/datasetProgress/citizenScienceSamples.js @@ -12,10 +12,6 @@ csSamples.factory("CsSamples", [ var self = this; - // the dataset id for this citizen science project - // todo: integrate with settings for cs project - self.datasetId = 3; - self.resetlist = function () { self.currentIndex = { page: -1, item: -1}; self.pages = []; @@ -138,7 +134,8 @@ csSamples.factory("CsSamples", [ }); }, - init : function () { + init : function (datasetId) { + self.datasetId = datasetId; self.requestPageOfItems(true); }, diff --git a/src/app/citizenScience/datasetProgress/datasetProgress.js b/src/app/citizenScience/datasetProgress/datasetProgress.js index 7c3b1060..2e9c4802 100644 --- a/src/app/citizenScience/datasetProgress/datasetProgress.js +++ b/src/app/citizenScience/datasetProgress/datasetProgress.js @@ -12,27 +12,32 @@ angular.module("bawApp.components.progress", ["bawApp.citizenScience.csSamples"] controller: ["$scope", "$routeParams", "CsSamples", "SampleLabels", function ($scope, $routeParams, CsSamples, SampleLabels) { - if ($routeParams.sampleNum) { - CsSamples.selectById($routeParams.sampleNum); - $scope.nextItem = function () { - SampleLabels.sendResponse("using_routed"); - return true; - }; - $scope.isRoutedSample = true; - } else { - CsSamples.init(); - $scope.nextItem = function () { - SampleLabels.sendResponse(); - CsSamples.nextItem(); - }; - $scope.isRoutedSample = false; - } + var self = this; + // need to wait for the study's dataset_id before initialising + $scope.$watch(function () { return self.datasetId; }, function (newVal, oldVal){ + if (newVal > 0) { + if ($routeParams.sampleNum) { + CsSamples.selectById($routeParams.sampleNum); + $scope.nextItem = function () { + SampleLabels.sendResponse("using_routed"); + return true; + }; + $scope.isRoutedSample = true; + } else { + CsSamples.init(self.datasetId); + $scope.nextItem = function () { + SampleLabels.sendResponse(); + CsSamples.nextItem(); + }; + $scope.isRoutedSample = false; + } + } + }); $scope.$watch(() => CsSamples.currentItem(), (newVal, oldVal) => { - var newDatasetItemId = newVal.id; - SampleLabels.reset(newDatasetItemId); + SampleLabels.reset(newVal.id); }); $scope.$on("autoNextTrigger", function (x) { @@ -58,5 +63,6 @@ angular.module("bawApp.components.progress", ["bawApp.citizenScience.csSamples"] }], bindings: { + datasetId: "=" } }); \ No newline at end of file diff --git a/src/app/citizenScience/labels/citizenScienceLabels.js b/src/app/citizenScience/labels/citizenScienceLabels.js index d6a306f7..e5d11fbb 100644 --- a/src/app/citizenScience/labels/citizenScienceLabels.js +++ b/src/app/citizenScience/labels/citizenScienceLabels.js @@ -2,6 +2,7 @@ var csLabels = angular.module("bawApp.citizenScience.csLabels", [ "bawApp.citizenScience.common", "bawApp.components.citizenScienceYesnoLabels", "bawApp.components.citizenScienceThumbLabels", + "bawApp.components.citizenScienceTextLabels", "bawApp.citizenScience.sampleLabels" ]); diff --git a/src/app/citizenScience/labels/labels.tpl.html b/src/app/citizenScience/labels/labels.tpl.html index c9e74f75..d93c1573 100644 --- a/src/app/citizenScience/labels/labels.tpl.html +++ b/src/app/citizenScience/labels/labels.tpl.html @@ -2,11 +2,11 @@ - + + + diff --git a/src/app/citizenScience/labels/textLabels/label.js b/src/app/citizenScience/labels/textLabels/label.js new file mode 100644 index 00000000..a8739c03 --- /dev/null +++ b/src/app/citizenScience/labels/textLabels/label.js @@ -0,0 +1,30 @@ +angular.module("bawApp.components.citizenScienceTextLabels.label", + [ + "bawApp.citizenScience.sampleLabels" + ]) + .component("citizenScienceTextLabel", { + templateUrl: "citizenScience/labels/textLabels/label.tpl.html", + controller: [ + "$scope", + "SampleLabels", + function ($scope, SampleLabels) { + + var self = this; + + $scope.isSelected = function() { + return SampleLabels.getValue(self.label.id); + }; + + /** + * callback when this label is either attached or detached from the current sample + * @param isSelected Boolean + */ + self.onToggleSelected = function (isSelected) { + SampleLabels.setValue(isSelected, self.label.id); + }; + + }], + bindings: { + label: "=", + } + }); \ No newline at end of file diff --git a/src/app/citizenScience/labels/textLabels/label.tpl.html b/src/app/citizenScience/labels/textLabels/label.tpl.html new file mode 100644 index 00000000..efbc2136 --- /dev/null +++ b/src/app/citizenScience/labels/textLabels/label.tpl.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/src/app/citizenScience/labels/textLabels/labels.js b/src/app/citizenScience/labels/textLabels/labels.js index f802fcf0..0c0a45d8 100644 --- a/src/app/citizenScience/labels/textLabels/labels.js +++ b/src/app/citizenScience/labels/textLabels/labels.js @@ -1,88 +1,80 @@ -angular.module("bawApp.components.citizenScienceTextLabels", ["bawApp.citizenScience.common"]) +angular.module("bawApp.components.citizenScienceTextLabels", + [ + "bawApp.components.citizenScienceTextLabels.label", + "bawApp.citizenScience.sampleLabels" + ]) .component("citizenScienceTextLabels", { templateUrl: "citizenScience/labels/textLabels/labels.tpl.html", controller: [ "$scope", - "$http", - "CitizenScienceCommon", - function ($scope, $http, CitizenScienceCommon) { + "SampleLabels", + function ($scope, SampleLabels) { //console.log("dataset progress component scope");console.log($scope); var self = this; - /** - * Add or remove the lable num to the list of selected labels for this sample - * Send the new set of labels to the dataset - * Note, we can't guarantee the order that the api calls will reach the google sheet. - * if the user adds and removes a label in quick succession, they might arrive out of order - * resulting in the wrong labels being applied. - * @param label string - */ - $scope.toggleLabel = function (labelNum) { + console.log(self); - var currentSample = self.samples[self.currentSampleNum]; + //////////////// - currentSample.labels[labelNum] = !currentSample.labels[labelNum]; - currentSample.done = true; - var tags = self.labels.filter(function (value, index) { - return currentSample.labels[index]; - }).map(function (value) { - return value.tags; - }); - var url = CitizenScienceCommon.apiUrl("setLabels", - self.csProject, - currentSample.name, - currentSample.recordingId, - currentSample.startOffset, - CitizenScienceCommon.labelsAsString(tags)); - $http.get(url).then(function (response) { - console.log(response.data); - }); + //////////////// - }; - - /** - * Whether the label has been attached to the current sample - * @param label Object - * @returns Boolean - */ - $scope.labelSelected = function (labelNum) { - if(self.currentSampleNum === -1) { - return false; - } - var currentSample = self.samples[self.currentSampleNum]; - - return currentSample.labels[labelNum]; - - }; - - /** - * Toggles whether the examples are showing for the given label number - * hides examples from other labels. - * TODO: move this into examples component - * @param key int - */ - $scope.toggleShowExamples = function (key) { - self.labels.forEach(function (el, index) { - if (index !== key) { - el.showExamples = false; - } else if (el.hasOwnProperty("showExamples")) { - el.showExamples = !el.showExamples; - } else { - el.showExamples = true; - } - }); - }; + // /** + // * Add or remove the lable num to the list of selected labels for this sample + // * Send the new set of labels to the dataset + // * Note, we can't guarantee the order that the api calls will reach the google sheet. + // * if the user adds and removes a label in quick succession, they might arrive out of order + // * resulting in the wrong labels being applied. + // * @param label string + // */ + // $scope.toggleLabel = function (labelNum) { + // + // var currentSample = self.samples[self.currentSampleNum]; + // + // currentSample.labels[labelNum] = !currentSample.labels[labelNum]; + // + // currentSample.done = true; + // + // var tags = self.labels.filter(function (value, index) { + // return currentSample.labels[index]; + // }).map(function (value) { + // return value.tags; + // }); + // + // var url = CitizenScienceCommon.apiUrl("setLabels", + // self.csProject, + // currentSample.name, + // currentSample.recordingId, + // currentSample.startOffset, + // CitizenScienceCommon.labelsAsString(tags)); + // $http.get(url).then(function (response) { + // console.log(response.data); + // }); + // + // }; + // + // /** + // * Whether the label has been attached to the current sample + // * @param label Object + // * @returns Boolean + // */ + // $scope.labelSelected = function (labelNum) { + // if(self.currentSampleNum === -1) { + // return false; + // } + // var currentSample = self.samples[self.currentSampleNum]; + // + // return currentSample.labels[labelNum]; + // + // }; + // }], bindings: { - labels: "=labels", - samples: "=samples", - currentSampleNum: "=currentSampleNum", - csProject: "=csProject" + labels: "=labels" } }); \ No newline at end of file diff --git a/src/app/citizenScience/labels/textLabels/labels.tpl.html b/src/app/citizenScience/labels/textLabels/labels.tpl.html index 900fdbb4..190376ac 100644 --- a/src/app/citizenScience/labels/textLabels/labels.tpl.html +++ b/src/app/citizenScience/labels/textLabels/labels.tpl.html @@ -1,9 +1,6 @@
- - - {{label.label}} - - +
\ No newline at end of file diff --git a/src/app/citizenScience/labels/thumbLabels/label.js b/src/app/citizenScience/labels/thumbLabels/label.js index c1040a8a..b7af707c 100644 --- a/src/app/citizenScience/labels/thumbLabels/label.js +++ b/src/app/citizenScience/labels/thumbLabels/label.js @@ -3,7 +3,7 @@ angular.module("bawApp.components.citizenScienceThumbLabels.label", "bawApp.components.citizenScienceThumbLabels.examples", "bawApp.citizenScience.sampleLabels" ]) - .component("citizenScienceLabel", { + .component("citizenScienceThumbLabel", { templateUrl: "citizenScience/labels/thumbLabels/label.tpl.html", controller: [ "$scope", @@ -43,7 +43,7 @@ angular.module("bawApp.components.citizenScienceThumbLabels.label", * @param isSelected Boolean */ self.onToggleSelected = function (isSelected) { - SampleLabels.setValue(self.label.id, isSelected); + SampleLabels.setValue(isSelected, self.label.id); }; }], diff --git a/src/app/citizenScience/labels/thumbLabels/labels.js b/src/app/citizenScience/labels/thumbLabels/labels.js index be5fa8d7..14872158 100644 --- a/src/app/citizenScience/labels/thumbLabels/labels.js +++ b/src/app/citizenScience/labels/thumbLabels/labels.js @@ -37,6 +37,9 @@ angular.module("bawApp.components.citizenScienceThumbLabels", $scope.examplesPosition = "0px"; + /** + * Watch for labels to be updated so that the examples etc can be loaded + */ $scope.$watch(function () { return self.labels; }, function (newVal, oldVal) { diff --git a/src/app/citizenScience/labels/thumbLabels/labels.tpl.html b/src/app/citizenScience/labels/thumbLabels/labels.tpl.html index 4efbc89a..b0d6e65e 100644 --- a/src/app/citizenScience/labels/thumbLabels/labels.tpl.html +++ b/src/app/citizenScience/labels/thumbLabels/labels.tpl.html @@ -1,13 +1,13 @@
- + >
diff --git a/src/app/citizenScience/labels/yesnoLabels/labels.js b/src/app/citizenScience/labels/yesnoLabels/labels.js index 5152a602..8d436eca 100644 --- a/src/app/citizenScience/labels/yesnoLabels/labels.js +++ b/src/app/citizenScience/labels/yesnoLabels/labels.js @@ -10,25 +10,22 @@ angular.module("bawApp.components.citizenScienceYesnoLabels", var self = this; // yesno questions only have one label - $scope.label = self.questionData.labels[0].name; + $scope.label = self.labels[0].name; - // binary can have 3 statuses: selected yes, selected no or not selected - - $scope.isSelected = function() { - return SampleLabels.getValue(self.label.id); + $scope.isSelectedPositive = function() { + return SampleLabels.getValue() === 1; }; /** * callback when this label is either attached or detached from the current sample - * @param isSelected Boolean + * @param value Boolean */ - self.onToggleSelected = function (isSelected) { - SampleLabels.setValue(self.label.id, isSelected); + $scope.setValue = function (value) { + SampleLabels.setValue(value); }; - }], bindings: { - questionData: "=", + labels: "=", } }); \ No newline at end of file diff --git a/src/app/citizenScience/labels/yesnoLabels/labels.tpl.html b/src/app/citizenScience/labels/yesnoLabels/labels.tpl.html index 9afd9189..375c9af1 100644 --- a/src/app/citizenScience/labels/yesnoLabels/labels.tpl.html +++ b/src/app/citizenScience/labels/yesnoLabels/labels.tpl.html @@ -1,5 +1,9 @@
- +
diff --git a/src/app/citizenScience/responses/citizenScienceSampleLabels.js b/src/app/citizenScience/responses/citizenScienceSampleLabels.js index 785f7732..4b2016f2 100644 --- a/src/app/citizenScience/responses/citizenScienceSampleLabels.js +++ b/src/app/citizenScience/responses/citizenScienceSampleLabels.js @@ -46,62 +46,100 @@ sampleLabels.factory("SampleLabels", [ self.allowMulti = false; } + // if label ids are not supplied, add them in. + if (!self.labels.every(l => l.hasOwnProperty("id"))) { + + // if only some but not all label ids are supplied, error + if (self.labels.some(l => l.hasOwnProperty("id"))) { + console.error("Invalid question data: Some but not all labels have ids"); + } + + self.labels = self.labels.map((l,i) => { + l.id = i+1; + return(l); + }); + + } + } return self.data; }; - self.functions = { - init : self.init, + /** + * updates the value of a labelId applied to a sampleId as either true or false + * @param labelId int; may be omitted if it is a binary (only one label) task. + * @param value int [0,1] + */ + self.setValue = function (value, labelId) { - /** - * Looks up the data to see if there is a boolean value stored for a given sampleId and labelId - * and if so, returns it. - * @param sampleId. If omitted, will use the current sample if available - * @param labelId - * @returns {boolean} - */ - getValue : function (labelId) { + if (labelId === undefined && self.labels.length === 1) { + labelId = 1; + } - return self.data.labels.has(labelId); + if (labelId !== undefined) { + self.hasResponse = true; + if (value) { + if (!self.allowMulti) { + self.data.labels.clear(); + } + self.data.labels.add(labelId); + } else { + self.data.labels.delete(labelId); + } + } else { + console.warn("Label id not defined"); + } - }, + }; - /** - * updates the value of a labelId applied to a sampleId as either true or false - * @param sampleId int; if null, will use the current sample id - * @param labelId int; if omitted, we are not applying a label but noting that the sample has been viewed - * @param value int [0,1] - */ - setValue : function (labelId, value) { - if (labelId !== undefined) { - self.hasResponse = true; - if (value) { - if (!self.allowMulti) { - self.data.labels.clear(); - } - self.data.labels.add(labelId); - } else { - self.data.labels.delete(labelId); - } - } + /** + * Looks up the data to see if there is a boolean value stored for a given sampleId and labelId + * and if so, returns it. + * @param sampleId. If omitted, will use the current sample if available + * @param labelId + * @returns {boolean} + */ + self.getValue = function (labelId) { - }, + if (labelId === undefined && self.labels.length === 1) { + labelId = 1; + } + return self.data.labels.has(labelId); + }; + + self.functions = { + + init : self.init, + getValue : self.getValue, + setValue : self.setValue, + setValueBinary : self.setValueBinary, /** * sends the response to the server using the questionResponse service */ - sendResponse : function (notes) { + sendResponse : function (notes, userNotes) { if (self.data.datasetItemId) { // convert labels to data json - self.data.data = {"labels": [...self.data.labels]}; + // just an array of label ids + self.data.data = {"labelIds": [...self.data.labels]}; + // json object with status for all positive labels + self.data.data.labels = self.labels.reduce(function (map, obj, idx, src) { + if (self.data.labels.has(obj.id)) { + map.push(obj.name); + } + return map; + },[]); if (notes) { self.data.data.notes = notes; } + if (userNotes) { + self.data.data.userNotes = userNotes; + } QuestionResponse.createQuestionResponse(self.data.questionId, self.data.datasetItemId, self.data.studyId, self.data.data); }