Skip to content

Commit

Permalink
Changes to put Results in a tab on the Details dialog.
Browse files Browse the repository at this point in the history
  • Loading branch information
longdogz committed Jul 14, 2016
1 parent 206656b commit 20ca966
Show file tree
Hide file tree
Showing 12 changed files with 248 additions and 12 deletions.
2 changes: 1 addition & 1 deletion modules/ui/Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ module.exports = function (grunt) {
development: {
constants: {
supportEmail: 'you@example.com',
apiHostBaseUrlValue: 'http://192.168.99.100:8080/api/v1'
apiHostBaseUrlValue: 'http://localhost:8080/api/v1'
}
}
},
Expand Down
1 change: 1 addition & 0 deletions modules/ui/app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ <h1></h1>
<script src="scripts/controllers/ChangeRapidExperimentCtrl.js"></script>
<script src="scripts/controllers/LogsCtrl.js"></script>
<script src="scripts/controllers/LogModalCtrl.js"></script>
<script src="scripts/controllers/ResultsModal.js"></script>
<script src="scripts/controllers/AnalysisGraphModal.js"></script>
<script src="scripts/controllers/UserCtrl.js"></script>
<script src="scripts/directives/ConvertPercentDirective.js"></script>
Expand Down
80 changes: 77 additions & 3 deletions modules/ui/app/scripts/controllers/ExperimentDetailsCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ angular.module('wasabi.controllers').
disableSimple: false,
disableAdvanced: false,
ruleWidgetsDisabled: false,
resultsWidgetsDisabled: true,
descriptionLength: 0
};

Expand All @@ -23,6 +24,7 @@ angular.module('wasabi.controllers').
$scope.simpleRuleEditing = $cookies['showAdvancedSegmentationEditor'] == undefined || $cookies['showAdvancedSegmentationEditor'] !== 'true';
$scope.downloadUrl = ConfigFactory.baseUrl() + '/experiments/' + $scope.experiment.id + '/assignments';
$scope.rulesChangedNotSaved = true;
$scope.resultsChangedNotSaved = true;
$scope.showingActionRates = true;
$scope.plugins = $rootScope.plugins;
$scope.supportEmail = supportEmail;
Expand Down Expand Up @@ -101,8 +103,20 @@ angular.module('wasabi.controllers').
return UtilitiesFactory.hasPermission(experiment.applicationName, PERMISSIONS.updatePerm);
};

$scope.afterPause = function() {
// Prompt the user for results then load the experiment after they have provided them.
UtilitiesFactory.openResultsModal($scope.experiment, $scope.readOnly, $scope.loadExperiment);
};

$scope.changeState = function (experiment, state) {
UtilitiesFactory.changeState(experiment, state, $scope.loadExperiment);
var afterChangeActions = {
// Transitioning to PAUSED, that is, stopping the experiment. Prompt the user to enter their results.
'PAUSED': $scope.afterPause,
// In other cases, just load the experiment.
'RUNNING': $scope.loadExperiment,
'TERMINATED': $scope.loadExperiment
};
UtilitiesFactory.changeState(experiment, state, afterChangeActions);
};

$scope.deleteExperiment = function (experiment) {
Expand Down Expand Up @@ -208,6 +222,10 @@ angular.module('wasabi.controllers').
ExperimentsFactory.show({id: $stateParams.experimentId}).$promise.then(function (experiment) {
$scope.experiment = experiment;

// TODO: Remove this when have fields in data model
$scope.experiment.results = 'My results.';
$scope.experiment.hypothesisCorrect = 'yes';

$scope.rulesChangedNotSaved = $scope.checkForRule();

$scope.readOnly = ($scope.readOnly || experiment.state.toLowerCase() === 'terminated');
Expand Down Expand Up @@ -790,6 +808,47 @@ angular.module('wasabi.controllers').
);
};

$scope.editResults = function() {
$scope.resultsChangedNotSaved = true;
$scope.data.resultsWidgetsDisabled = false;
$scope.$digest();
return {
results: $scope.experiment.results,
hypothesisCorrect: $scope.experiment.hypothesisCorrect
};
};

$scope.cancelResults = function(tempValue) {
$scope.resultsChangedNotSaved = false;
$scope.data.resultsWidgetsDisabled = true;
$scope.experiment.results = tempValue.results;
$scope.experiment.hypothesisCorrect = tempValue.hypothesisCorrect;
$scope.$digest();
};

$scope.saveResults = function(newValue) {
var experiment = $scope.experiment;
$scope.data.resultsWidgetsDisabled = true;
$scope.$digest();
/* TODO: enable this
ExperimentsFactory.update({
id: experiment.id,
results: experiment.results,
hypothesisCorrect: experiment.hypothesisCorrect
}).$promise.then(function () {
UtilitiesFactory.trackEvent('saveItemSuccess',
{key: 'dialog_name', value: 'saveResultsFromDetails'},
{key: 'application_name', value: experiment.applicationName},
{key: 'item_id', value: experiment.id},
{key: 'item_label', value: experiment.label});
},
function(response) {
UtilitiesFactory.handleGlobalError(response);
}
);
*/
};

$scope.onDescriptionChange = function() {
$scope.data.descriptionLength = $('#experimentDescription').text().length;
$scope.$digest();
Expand All @@ -810,8 +869,19 @@ angular.module('wasabi.controllers').

$scope.saveDescription = function(newValue) {
var newDesc = $.trim(newValue);
if (newDesc.length > 256) {
DialogsFactory.alertDialog('The description must be 256 characters or less.', 'Description Too Long', function() {});
if (newDesc.length > 256 || newDesc.length <= 0) {
if (newDesc.length <= 0) {
DialogsFactory.alertDialog('You must provide a hypothesis/description.', 'Missing Hypothesis/Description', function() {});
}
else {
DialogsFactory.alertDialog('The hypothesis/description must be 256 characters or less.', 'Hypothesis/Description Too Long', function() {});
}
// This will cause the dynamicEdit widget to go back into Edit mode.
$('#descriptionToolbar .dynamicEdit').click();
return false;
}
if (newDesc.length <= 0) {
DialogsFactory.alertDialog('You must provide a hypothesis/description.', 'Missing Hypothesis/Description', function() {});
// This will cause the dynamicEdit widget to go back into Edit mode.
$('#descriptionToolbar .dynamicEdit').click();
return false;
Expand Down Expand Up @@ -1042,6 +1112,10 @@ angular.module('wasabi.controllers').
};


$scope.openResultsModal = function () {
UtilitiesFactory.openResultsModal($scope.experiment, $scope.readOnly, $scope.loadExperiment);
};

$scope.openPluginModal = function(plugin) {
UtilitiesFactory.openPluginModal(plugin, $scope.experiment);
};
Expand Down
13 changes: 12 additions & 1 deletion modules/ui/app/scripts/controllers/ExperimentsCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,8 +472,19 @@ angular.module('wasabi.controllers').
UtilitiesFactory.deleteExperiment(experiment, $scope.loadExperiments);
};

$scope.openResultsModal = function (experiment) {
UtilitiesFactory.openResultsModal(experiment, false, $scope.loadExperiments);
};

$scope.changeState = function (experiment, state) {
UtilitiesFactory.changeState(experiment, state, $scope.loadExperiments);
var afterChangeActions = {
// Transitioning to PAUSED, that is, stopping the experiment. Prompt the user to enter their results.
'PAUSED': $scope.openResultsModal,
// In other cases, just load the experiment.
'RUNNING': $scope.loadExperiments,
'TERMINATED': $scope.loadExperiments
};
UtilitiesFactory.changeState(experiment, state, afterChangeActions);
};

$scope.stateImgUrl = function(state) {
Expand Down
13 changes: 12 additions & 1 deletion modules/ui/app/scripts/controllers/PrioritiesCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,19 @@ angular.module('wasabi.controllers').
return UtilitiesFactory.hasPermission(appName, PERMISSIONS.updatePerm);
};

$scope.openResultsModal = function (experiment) {
UtilitiesFactory.openResultsModal(experiment, false, $scope.loadPrioritiesAfterAction);
};

$scope.changeState = function (experiment, state) {
UtilitiesFactory.changeState(experiment, state, $scope.loadPrioritiesAfterAction);
var afterChangeActions = {
// Transitioning to PAUSED, that is, stopping the experiment. Prompt the user to enter their results.
'PAUSED': $scope.openResultsModal,
// In other cases, just load the experiment.
'RUNNING': $scope.loadPrioritiesAfterAction,
'TERMINATED': $scope.loadPrioritiesAfterAction
};
UtilitiesFactory.changeState(experiment, state, afterChangeActions);
};

$scope.deleteExperiment = function (experiment) {
Expand Down
41 changes: 41 additions & 0 deletions modules/ui/app/scripts/controllers/ResultsModal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict';

angular.module('wasabi.controllers')
.controller('ResultsModalCtrl',
['$scope', '$filter', '$modalInstance', 'ExperimentsFactory', 'experiment', 'readOnly', 'UtilitiesFactory', '$modal', 'ConfigFactory', 'DialogsFactory',
function ($scope, $filter, $modalInstance, ExperimentsFactory, experiment, readOnly, UtilitiesFactory, $modal, ConfigFactory, DialogsFactory) {

$scope.experiment = experiment;
$scope.tmpResults = '';
$scope.tmpHypothesisCorrect = '';

$scope.originalResults = $scope.experiment.results;
$scope.originalHypothesisCorrect = $scope.experiment.hypothesisCorrect;

$scope.help = ConfigFactory.help;
$scope.readOnly = readOnly;

$scope.doSaveResults = function () {
if ($scope.originalResults !== $scope.tmpResults ||
$scope.originalHypothesisCorrect !== $scope.tmpHypothesisCorrect) {
// Save the new results values.
$scope.experiment.results = $scope.tmpResults;
$scope.experiment.hypothesisCorrect = $scope.tmpHypothesisCorrect;
/*
ExperimentsFactory.update({id: $scope.experiment.id, results: $scope.experiment.results, hypothesisCorrect: $scope.experiment.hypothesisCorrect }).$promise.then(function () {
UtilitiesFactory.trackEvent('updateItemSuccess',
{key: 'dialog_name', value: 'updateExperimentResults'},
{key: 'experiment_id', value: $scope.experiment.id},
{key: 'item_value', value: $scope.experiment.results + '|' + $scope.experiment.hypothesisCorrect});
}, function(response) {
UtilitiesFactory.handleGlobalError(response, 'Your experiment results could not be changed.');
});
*/
}
$modalInstance.close();
};

$scope.cancel = function () {
$modalInstance.close('cancel');
};
}]);
37 changes: 36 additions & 1 deletion modules/ui/app/scripts/services/UtilitiesFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,19 @@ angular.module('wasabi.services').factory('UtilitiesFactory', ['Session', '$stat
{key: 'experiment_id', value: experiment.id},
{key: 'item_id', value: state});

afterUpdateFunction();
if (afterUpdateFunction && afterUpdateFunction === Object(afterUpdateFunction) &&
typeof afterUpdateFunction !== 'function') {
// afterUpdateFunction is actually an object where the properties should be the
// name of a state. We should call the function associated with that property
// only after we make a change to that state.
if (afterUpdateFunction.hasOwnProperty(state)) {
afterUpdateFunction[state](experiment);
}
}
else {
// Otherwise, it is a function to be called for all state changes.
afterUpdateFunction();
}
}, function(response) {
that.handleGlobalError(response, 'The state of your experiment could not be changed.');
});
Expand Down Expand Up @@ -983,6 +995,29 @@ angular.module('wasabi.services').factory('UtilitiesFactory', ['Session', '$stat
});

return false;
},

openResultsModal: function (experiment, readOnly, afterResultsFunc) {
var modalInstance = $modal.open({
templateUrl: 'views/ResultsModal.html',
controller: 'ResultsModalCtrl',
windowClass: 'xxx-dialog',
backdrop: 'static',
resolve: {
experiment: function () {
return experiment;
},
readOnly: function() {
return readOnly;
}
}
});

modalInstance.result.then(function () {
if (afterResultsFunc) {
afterResultsFunc();
}
});
}

};
Expand Down
17 changes: 17 additions & 0 deletions modules/ui/app/styles/wasabi.scss
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ header {
margin: 0 auto 20px auto;
}

.truncateDiv {
width: 790px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
}

.pageError {
display: none;
position: fixed;
Expand Down Expand Up @@ -1102,6 +1110,10 @@ header {
right: 44px;
top: 4px;
}
#resultsToolbar {
right: 4px;
top: 4px;
}
.descriptionLabel {
padding-bottom: 3px;
font-size: 12px;
Expand Down Expand Up @@ -2994,6 +3006,11 @@ form input.ng-dirty.ng-invalid:not(.ng-focused) {
left: -50px;
}

#resultsModal {
width: 700px;
left: 0;
}

#bucketAssignmentModal {
width: 800px;
left: -50px;
Expand Down
20 changes: 19 additions & 1 deletion modules/ui/app/views/ExperimentDetails.html
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ <h2><div style="margin-bottom: 10px;">{{experiment.applicationName}}</div><div>{
</table>

<div>
<div style="float: left; margin-right: 862px;"><label class="descriptionLabel">Description</label></div>
<div style="float: left; margin-right: 862px;"><label class="descriptionLabel">Hypothesis/Description</label></div>
<pre id="experimentDescription" spellcheck="false" class="readOnly"></pre>
<div id="descriptionToolbar" ng-show="!readOnly" dynamic-edit input-tag="experimentDescription" select-function="saveDescription" edit-function="editDescription" cancel-function="cancelDescription" ng-model="experiment.description" class="dynamicToolbar"></div>
<div style="margin-top: 5px; margin-bottom: 10px; font-size: 12px;"><label ng-class="{tooMany: data.descriptionLength > 256}">{{(256 - data.descriptionLength) >= 0 ? 256 - data.descriptionLength : 'NO'}} characters left</label></div>
Expand Down Expand Up @@ -163,6 +163,24 @@ <h2><div style="margin-bottom: 10px;">{{experiment.applicationName}}</div><div>{
</div>
</div>
</tab>
<tab heading="Results">
<div class="resultsTab">
<div id="resultsToolbar" ng-show="!readOnly" dynamic-edit input-tag="rule" select-function="saveResults" edit-function="editResults" cancel-function="cancelResults" ng-model="experiment.rule" class="dynamicToolbar"></div>
<form name="resultsForm" novalidate>
<div>
<div>
<label>Results</label>
<textarea ng-show="!readOnly && !data.resultsWidgetsDisabled" name="experimentResults" id="experimentResults" class="form-control" required ng-model="experiment.results" style="width: 99%; height: 55px" ng-maxlength="256" placeholder="Enter Experiment Results"></textarea>
<textarea ng-show="readOnly || data.resultsWidgetsDisabled" disabled="true" name="experimentResults" class="form-control readOnly" ng-model="experiment.results" style="width: 99%; height: 55px"></textarea>
</div>
<div style="margin-top: 10px;">
<label>Hypothesis Correct?</label>
<select ng-class="{disabled: readOnly || data.resultsWidgetsDisabled}" ng-disabled="readOnly || data.resultsWidgetsDisabled" name="experimentHypothesisCorrect" id="experimentHypothesisCorrect" ng-model="experiment.hypothesisCorrect"><option value="">Select answer</option><option value="yes">Yes, my hypothesis was correct</option><option value="no">No, my hypothesis was incorrect</option><option value="indeterminate">Indeterminate</option></select>
</div>
</div>
</form>
</div>
</tab>
<tab heading="Mutual Exclusion" ng-controller="MutualExclusionsCtrl">
<a ng-show="!readOnly" href="#" id="newExpAddExclusion" class="listAction add" onclick="return false;" ng-click="openMutualExclusionModal(experiment.id)"><span></span>Add Experiment</a>
<span class="info newHelp" help help-content="{{help.mutualExclusion}}"></span>
Expand Down
Loading

0 comments on commit 20ca966

Please sign in to comment.