You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@climate.apache.org by jo...@apache.org on 2014/08/28 05:07:49 UTC
[05/28] CLIMATE-512 - Replace frontend with new Yeoman/Grunt/Bower
frontend
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/scripts/directives/onblur.js
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/scripts/directives/onblur.js b/ocw-ui/frontend/app/scripts/directives/onblur.js
new file mode 100644
index 0000000..313dbe0
--- /dev/null
+++ b/ocw-ui/frontend/app/scripts/directives/onblur.js
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http: *www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+/**
+ * @ngdoc directive
+ * @name ocwUiApp.directive:onBlur
+ * @description
+ * # onBlur
+ */
+angular.module('ocwUiApp')
+.directive('onBlur', function() {
+ return {
+ restrict: 'A',
+ link: function($scope, $elem, $attrs) {
+ $elem.bind('blur', function() {
+ $scope.$eval($attrs.onBlur);
+ });
+ },
+ };
+});
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/scripts/directives/predictivefilebrowserinput.js
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/scripts/directives/predictivefilebrowserinput.js b/ocw-ui/frontend/app/scripts/directives/predictivefilebrowserinput.js
new file mode 100644
index 0000000..7142c15
--- /dev/null
+++ b/ocw-ui/frontend/app/scripts/directives/predictivefilebrowserinput.js
@@ -0,0 +1,316 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http: *www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+/**
+ * @ngdoc directive
+ * @name ocwUiApp.directive:predictiveFileBrowserInput
+ * @description
+ * # predictiveFileBrowserInput
+ */
+angular.module('ocwUiApp')
+.directive('predictiveFileBrowserInput', function() {
+ var link = function($scope, $elem, $attrs) {
+ $scope.autocomplete = [];
+
+ // Set id to use this directive correctly in multiple places
+ $scope.id = 'autoCompletePath'+ $elem.context.id
+ /*
+ * We need a place to dump our auto-completion options
+ */
+ $($elem).parent().append('<ul id="' + $scope.id +'"><ul>');
+
+ // Handle user clicks on auto-complete path options
+ $(document).on('click', '#' +$scope.id+ ' li span', function(e) {
+ // Set the input text box's value to that of the user selected path
+ var val = $(e.target).text();
+ $($elem).val(val);
+ // Need to trigger the input box's "input" event so Angular updates the model!
+ $elem.trigger('input');
+
+ // If the user selected a directory, find more results..
+ if (val[val.length - 1] == '/') {
+ $scope.fetchFiles($($elem).val());
+ // Otherwise, remove the auto-complete options...
+ } else {
+ $('#' +$scope.id+ ' li').remove();
+ }
+ });
+
+ /*
+ * Handle key-down events on the input box
+ *
+ * We need to ignore <TAB> presses here so we can auto-complete with <TAB>.
+ * If we don't ignore here then <TAB> will move the user to the next field
+ * in the form and our common-prefix-fill won't work later.
+ */
+ $($elem).keydown(function(e) {
+ var code = e.keyCode || e.which;
+ var BACKSPACE = 8,
+ TAB = 9;
+
+ if (code == TAB)
+ return false;
+ });
+
+ /*
+ * Handle key-up events on the input box
+ */
+ $($elem).keyup(function(e) {
+ var code = e.keyCode || e.which;
+ var BACKSPACE = 8,
+ TAB = 9,
+ FORWARD_SLASH = 191;
+
+ if (code === FORWARD_SLASH) {
+ // Fetch new directory information from the server.
+ $scope.fetchFiles($(this).val());
+ } else if (code === TAB) {
+ // Attempt to auto-fill for the user.
+ $scope.handleTabPress();
+ } else if (code == BACKSPACE) {
+ // Need to properly handle the removal of directory information
+ // and the displaying of auto-complete options
+ $scope.handleBackSpace();
+ } else {
+ // Filter auto-complete options based on user input..
+ $scope.handleMiscKeyPress();
+ }
+
+ // This is being used so we can handle backspacing. The user might hold
+ // down the backspace key or select a section of text and delete. This allows
+ // us to compare the result to its prior state, which makes handling
+ // backspaces easier.
+ $scope.lastInputContents = $elem.val();
+ });
+
+ /*
+ * Grab additional path information from the web-server
+ *
+ * Params:
+ * path - The path to get a directory listing of.
+ */
+ // TODO Make this use $HTTP
+ $scope.fetchFiles = function(path) {
+ $.get($scope.baseURL + '/dir/list/' + path, {},
+ function(data) {
+ data = data['listing']
+ $scope.setNewData(data);
+ $scope.updateAutoComplete();
+ }, 'json');
+ };
+
+ /*
+ * Grab additional path information from the web-server and filter the
+ * results based on the current input text.
+ *
+ * Params:
+ * path - The path to get a directory listing of.
+ *
+ * This is needed to handle deletion of selected text. It is possible that
+ * the user will select text and delete only part of a word. The results
+ * need to be filtered based on this partial input.
+ */
+ // TODO Why isn't this using $http?!?!?! Because I copy and pasted!!!!
+ $scope.fetchFilesAndFilter = function(path) {
+ $.get($scope.baseURL + '/dir/list/' + path, {},
+ function(data) {
+ data = data['listing']
+ $scope.setNewData(data);
+ $scope.filterResults();
+ $scope.updateAutoComplete();
+ }, 'json');
+ };
+
+ /*
+ * Handle directory data from the server.
+ *
+ * We store the entire directory information along with the remaining
+ * possible options given the users current input. This lets us avoid
+ * unnecessary calls to the server for directory information every time
+ * the user deletes something.
+ */
+ $scope.setNewData = function(data) {
+ $scope.autocomplete = data.sort();
+ $scope.possibleCompletes = $scope.autocomplete;
+ };
+
+ /*
+ * Handle <TAB> presses.
+ *
+ * Attempt to auto-complete options when the user presses <TAB>.
+ */
+ $scope.handleTabPress = function() {
+ // If there's only one option available there's no points in trying to
+ // find a common prefix! Just set the value!
+ if ($scope.possibleCompletes.length === 1) {
+ $elem.val($scope.possibleCompletes[0]);
+
+ // Make sure more options are displayed if a directory was selected.
+ $scope.checkForMoreOptions();
+ $scope.updateAutoComplete();
+ return;
+ }
+
+ // Find the greatest common prefix amongst the remaining choices and set
+ // the input text to it.
+ var prefix = $scope.getLargestCommonPrefix($scope.possibleCompletes);
+ $elem.val(prefix);
+ $scope.updateAutoComplete();
+ };
+
+ /*
+ * Handle Backspacing and option displaying.
+ *
+ * The auto-complete options needs to be displayed correctly when the user
+ * removes directory information.
+ */
+ $scope.handleBackSpace = function() {
+ var curInputVal = $elem.val();
+
+ // If the user deletes everything in the input box all we need to do
+ // is make sure that the auto-complete options aren't displayed.
+ if (curInputVal.length === 0) {
+ $('#' +$scope.id+ ' li').remove();
+ return;
+ }
+
+ // Figure out how much text the user removed from the input box.
+ var lengthDiff = $scope.lastInputContents.length - curInputVal.length;
+ // Grab the removed text.
+ var removedText = $scope.lastInputContents.substr(-lengthDiff);
+
+ // If the user deleted over a directory we need to fetch information on the
+ // previous directory for auto-completion.
+ if (removedText.indexOf('/') !== -1) {
+ var lastSlashIndex = curInputVal.lastIndexOf('/');
+
+ // If the remaining path still contains a directory...
+ if (lastSlashIndex !== -1) {
+ // Grab the section of the path that points to a valid directory,
+ // fetch the listing, and update the results.
+ var pathToSearch = curInputVal.slice(0, lastSlashIndex + 1);
+ $scope.fetchFilesAndFilter(pathToSearch);
+ } else {
+ // Delete the old auto-complete information in the case where the user
+ // completely removed path information.
+ $('#' +$scope.id+ ' li').remove();
+ }
+ } else {
+ // Otherwise, we just need to filter results based on the remaining input.
+ $scope.filterResults();
+ $scope.updateAutoComplete();
+ }
+ };
+
+ /*
+ * Handle all other key presses in the input box
+ *
+ * Filter the auto-complete options as the user types to ensure that only options
+ * which are possible given the current input text are still displayed.
+ */
+ $scope.handleMiscKeyPress = function() {
+ // Safely exit when there are no options available.
+ if ($scope.autocomplete === [])
+ return;
+
+ // Otherwise, filter the results.
+ $scope.filterResults();
+ $scope.updateAutoComplete();
+ };
+
+ /*
+ * When a path is auto-completed with <TAB> we need to check to see if it points
+ * to a directory. If it does, we still need to fetch results!
+ */
+ $scope.checkForMoreOptions = function() {
+ var path = $elem.val();
+ if (path[path.length - 1] === '/') {
+ $scope.fetchFiles(path);
+ }
+ };
+
+ /*
+ * Calculate the greatest common prefix of the passed options.
+ *
+ * Params:
+ * Options - An array of strings in which the greatest common prefix
+ * should be found
+ *
+ * Returns:
+ * The greatest common prefix of the strings.
+ *
+ *
+ * Note - For us, there will always be a prefix of at least '/' since this can't
+ * possible be called without the users entering a starting directory. As a result,
+ * we don't explicitly handle the case where there is 0 length common prefix.
+ */
+ $scope.getLargestCommonPrefix = function(options) {
+ var index = 1;
+ var shortestString = options.reduce(function(a, b) { return a.length < b.length ? a : b; });
+ var longestString = options.reduce(function(a, b) { return a.length > b.length ? a : b; });
+ var substringToCheck = shortestString[0];
+
+ while (longestString.indexOf(substringToCheck) !== -1) {
+ substringToCheck = shortestString.slice(0, ++index);
+ }
+
+ return longestString.slice(0, index - 1);
+ };
+
+ /*
+ * Filter the auto-complete options based on the current input.
+ */
+ $scope.filterResults = function() {
+ $scope.possibleCompletes = $scope.autocomplete.filter(function(item, index, array) {
+ return (~item.indexOf($($elem).val()));
+ });
+
+ $scope.possibleCompletes.sort();
+ };
+
+ /*
+ * Update the display of auto-complete options.
+ */
+ $scope.updateAutoComplete = function() {
+ // Remove all the existing options
+ $('#' +$scope.id+ ' li').remove();
+
+ // We don't need to show anything if the user has completely selected
+ // the only existing option available.
+ if ($scope.possibleCompletes.length === 1) {
+ if ($scope.possibleCompletes[0] === $elem.val()) {
+ return;
+ }
+ }
+
+ // Display all the possible completes
+ $.each($scope.possibleCompletes, function(i, v) {
+ $('#' +$scope.id+ '').append($('<li>').html($('<span>').text(v)));
+ });
+ };
+ };
+
+ return {
+ link: link,
+ scope: true,
+ restrict: 'A'
+ };
+});
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/scripts/directives/previewmap.js
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/scripts/directives/previewmap.js b/ocw-ui/frontend/app/scripts/directives/previewmap.js
new file mode 100644
index 0000000..78aae8c
--- /dev/null
+++ b/ocw-ui/frontend/app/scripts/directives/previewmap.js
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http: *www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+/**
+ * @ngdoc directive
+ * @name ocwUiApp.directive:previewMap
+ * @description
+ * # previewMap
+ */
+angular.module('ocwUiApp')
+.directive('previewMap', function($rootScope) {
+ return {
+ restrict: 'A',
+ scope: {dataset: '=previewMap', index: '=index'},
+ template: '<div id="{{dataset.name}}" class="preview-map"></div>',
+ replace: true,
+ link: function(scope, element, attrs) {
+
+ // Any attribute that contains {{}} interpolation will be set to null in the attrs
+ // parameter during the link function since the first $digest since the compilation
+ // has yet to run to evaluate it! We can't run a $digest in the middle of compilation,
+ // so using an $observe (or $watch) is the best way to get the values.
+ attrs.$observe('id', function(newId) {
+ var map = L.map(attrs.id, {
+ zoom: 0,
+ scrollWheelZoom: false,
+ zoomControl: false,
+ attributionControl: false,
+ worldCopyJump: true,
+ });
+
+ L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {}).addTo(map);
+
+ // Zoom the map to the dataset bound regions (or at least try our best to do so)
+ var datasetBounds = [[scope.dataset.latlonVals.latMax, scope.dataset.latlonVals.lonMin],
+ [scope.dataset.latlonVals.latMin, scope.dataset.latlonVals.lonMax]];
+ map.fitBounds(datasetBounds, {});
+
+ // Draw a colored overlay on the region of the map
+ var maplatlon = scope.dataset.latlonVals;
+ var bounds = [[maplatlon.latMax, maplatlon.lonMin], [maplatlon.latMin, maplatlon.lonMax]];
+
+ var polygon = L.rectangle(bounds,{
+ stroke: false,
+ fillColor: $rootScope.fillColors[1],
+ fillOpacity: 0.6
+ });
+
+ // Add layer to Group
+ var rectangleGroup = L.layerGroup();
+ rectangleGroup.addLayer(polygon);
+
+ // Add the overlay to the map
+ rectangleGroup.addTo(map);
+ });
+ }
+ };
+});
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/scripts/directives/timeline.js
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/scripts/directives/timeline.js b/ocw-ui/frontend/app/scripts/directives/timeline.js
new file mode 100644
index 0000000..760a819
--- /dev/null
+++ b/ocw-ui/frontend/app/scripts/directives/timeline.js
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http: *www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+/**
+ * @ngdoc directive
+ * @name ocwUiApp.directive:timeline
+ * @description
+ * # timeline
+ */
+angular.module('ocwUiApp')
+.directive('timeline', function($rootScope, $window) {
+ return {
+ restrict: 'C',
+ replace: true,
+ transclude: true,
+ template: '<div id="OCWtimeline"></div>',
+ link: function(scope, element, attrs) {
+ // Instantiate timeline object.
+ $rootScope.timeline = new links.Timeline(document.getElementById('OCWtimeline'));
+
+ // Redraw the timeline whenever the window is resized
+ angular.element($window).bind('resize', function() {
+ $rootScope.timeline.checkResize();
+ });
+
+ var options = {
+ "width": "100%",
+ "showCurrentTime": false,
+ "moveable": false,
+ "zoomable": false
+ };
+
+ $rootScope.timeline.draw([], options);
+ }
+ }
+});
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/scripts/filters/isodatetomiddleendian.js
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/scripts/filters/isodatetomiddleendian.js b/ocw-ui/frontend/app/scripts/filters/isodatetomiddleendian.js
new file mode 100644
index 0000000..7fcd2a9
--- /dev/null
+++ b/ocw-ui/frontend/app/scripts/filters/isodatetomiddleendian.js
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http: *www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+/**
+ * @ngdoc filter
+ * @name ocwUiApp.filter:ISODateToMiddleEndian
+ * @function
+ * @description
+ * # ISODateToMiddleEndian
+ * Filter in the ocwUiApp.
+ */
+angular.module('ocwUiApp')
+.filter('ISODateToMiddleEndian', function() {
+ return function(input) {
+ var original = input;
+
+ // Strip whitespace from the start and end of the string
+ input = input.replace(/(^\s+|\s+$)/g, '');
+
+ // ISO Standard says time is separated from Date with a 'T'. Our timestamps
+ // slightly modify that and use a space. We'll check for both here and prefer
+ // to split on a 'T' if it's available.
+ if (input.indexOf('T') != -1 || input.indexOf(' ') != -1) {
+ input = (input.indexOf('T') != -1) ? input.split('T')[0] : input.split(' ')[0];
+ }
+
+ // The components of the date should be split with hyphens. If we can't find them
+ // then the string is poorly formed.
+ if (input.indexOf('-') == -1 || input.split('-').length - 1 != 2) {
+ return original;
+ }
+
+ // At this point the date is probably valid and we should try to convert it!
+ var components = input.split('-');
+ return (components[1] + "/" + components[2] + "/" + components[0]);
+ };
+});
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/scripts/services/evaluationsettings.js
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/scripts/services/evaluationsettings.js b/ocw-ui/frontend/app/scripts/services/evaluationsettings.js
new file mode 100644
index 0000000..b53842c
--- /dev/null
+++ b/ocw-ui/frontend/app/scripts/services/evaluationsettings.js
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http: *www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+/**
+ * @ngdoc service
+ * @name ocwUiApp.evaluationSettings
+ * @description
+ * # evaluationSettings
+ * Service in the ocwUiApp.
+ */
+angular.module('ocwUiApp')
+ .service('evaluationSettings', function($rootScope, $http) {
+ $http.get($rootScope.baseURL + '/processing/metrics/').then(function(data) {
+ var metrics_data = data['data']['metrics'];
+ var metrics = [];
+
+ for (var i = 0; i < metrics_data.length; ++i) {
+ metrics.push({'name': metrics_data[i], 'select': false});
+ }
+
+ settings['metrics'] = metrics;
+ });
+
+ var settings = {
+ 'metrics': [],
+ 'temporal': {
+ 'options': ['daily', 'monthly', 'yearly'],
+ 'selected': 'yearly',
+ },
+ 'spatialSelect': null,
+ };
+
+ return {
+ getSettings: function() {
+ return settings;
+ }
+ };
+ });
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/scripts/services/regionselectparams.js
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/scripts/services/regionselectparams.js b/ocw-ui/frontend/app/scripts/services/regionselectparams.js
new file mode 100644
index 0000000..cb3f4f8
--- /dev/null
+++ b/ocw-ui/frontend/app/scripts/services/regionselectparams.js
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http: *www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+/**
+ * @ngdoc service
+ * @name ocwUiApp.regionSelectParams
+ * @description
+ * # regionSelectParams
+ * Service in the ocwUiApp.
+ */
+angular.module('ocwUiApp')
+.service('regionSelectParams', function() {
+ var parameters = {
+ "areValid" : true,
+ "latMin" : "",
+ "latMax" : "",
+ "lonMin" : "",
+ "lonMax" : "",
+ "start" : "",
+ "end" : "",
+ };
+
+ return {
+ getParameters: function() {
+ return parameters;
+ },
+ };
+});
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/scripts/services/selecteddatasetinformation.js
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/scripts/services/selecteddatasetinformation.js b/ocw-ui/frontend/app/scripts/services/selecteddatasetinformation.js
new file mode 100644
index 0000000..613cfb8
--- /dev/null
+++ b/ocw-ui/frontend/app/scripts/services/selecteddatasetinformation.js
@@ -0,0 +1,57 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http: *www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+/**
+ * @ngdoc service
+ * @name ocwUiApp.selectedDatasetInformation
+ * @description
+ * # selectedDatasetInformation
+ * Service in the ocwUiApp.
+ */
+angular.module('ocwUiApp')
+.service('selectedDatasetInformation', function() {
+ var datasets = [];
+
+ return {
+ getDatasets: function() {
+ return datasets;
+ },
+ getDatasetCount: function() {
+ return datasets.length;
+ },
+ // TODO: Define the structure of the objects that are added with addDataset.
+ addDataset: function(dataset) {
+ // All datasets need a shouldDisplay attribute that is used when rendering
+ // the overlays on the map!
+ dataset.shouldDisplay = false;
+ // The regrid attribute indicates which dataset should be used for spatial regridding
+ dataset.regrid = false;
+
+ datasets.push(dataset);
+ },
+ removeDataset: function(index) {
+ datasets.splice(index, 1);
+ },
+ clearDatasets: function() {
+ datasets.length = 0;
+ },
+ };
+});
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/styles/main.css
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/styles/main.css b/ocw-ui/frontend/app/styles/main.css
new file mode 100644
index 0000000..fb42ccd
--- /dev/null
+++ b/ocw-ui/frontend/app/styles/main.css
@@ -0,0 +1,120 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http: *www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+body {
+
+}
+
+#header-img {
+
+}
+
+#header-title {
+
+}
+
+#OCW-powered {
+
+}
+
+#main-container {
+ margin-top: 20px;
+ min-height: 400px;
+ height: auto !important;
+ height: 400px;
+}
+
+#datasetDiv {
+ height: 750px;
+ overflow-y: auto;
+ overflow-x: hidden;
+}
+
+#ocw-navbar {
+ margin-bottom: 0;
+}
+
+#map { height: 500px; }
+
+/* Small preview map that is displayed alongside dataset information */
+.preview-map {
+ height: 100px;
+ width: 100px;
+}
+
+.small-alert {
+ font-size: 12px;
+ color: green;
+ margin-top: 4px;
+ margin-left: 10px;
+}
+
+.colorSquare {
+ margin-top: 3px;
+ height: 10px;
+ width: 10px;
+}
+
+ul { list-style-type: none; }
+
+.no-color-link { color: #000000; }
+.no-color-link:hover { color: #000000; text-decoration: none; }
+.no-color-link:visited { color: #000000; }
+.no-color-link:active { color: #000000; }
+
+/* Remove the grayed out close button in modal headers */
+.modal-header .close { opacity: 1; }
+
+/* Remove the grayed out close button in modal footers */
+.modal-footer .close { opacity: 1; }
+
+/**
+ * Timeline
+ */
+div#OCWtimeline {
+ margin-top: 20px;
+ padding-bottom: 20px;
+}
+
+div.timeline-event {
+ border: none;
+ background: none;
+}
+
+div.timeline-event-content { margin: 0; }
+
+div.ocw-bar { height: 5px; }
+
+/**
+ * Results
+ */
+#results-sidebar {
+ min-height: 400px;
+ height: auto !important;
+ height: 400px;
+}
+
+#results-sidebar-header { font-size: 14px; }
+
+/* Helpers for vertical offsets */
+.top3 { margin-top: 3%; }
+.top7 { margin-top: 7%; }
+.top14 { margin-top:14%; }
+.top21 { margin-top:21%; }
+.top42 { margin-top:42%; }
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/views/main.html
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/views/main.html b/ocw-ui/frontend/app/views/main.html
new file mode 100644
index 0000000..2f428e5
--- /dev/null
+++ b/ocw-ui/frontend/app/views/main.html
@@ -0,0 +1,274 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!-- Modal for evaluation settings -->
+<div class="modal fade" id="evaluationSettingsModal" role="dialog" aria-labelledby="datasetSelectModalLabel" aria-hidden="true">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button class="close" data-dismiss="modal">×</button>
+ <h3>Settings</h3>
+ </div>
+ <div class="modal-body" ng-controller="SettingsCtrl">
+ <h4>Select the metrics you would like to run.</h4>
+ <div ng-repeat="metric in settings.metrics">
+ <label><input type="checkbox" ng-model="metric.select"> {{metric.name}}</label>
+ </div>
+ <hr />
+ <h4>Select how you would like to temporally re-grid the datasets.</h4>
+ <select class="form-control" ng-model="settings.temporal.selected" ng-options="opt for opt in settings.temporal.options"></select>
+ <hr />
+ <h4>Select which dataset to use as the reference.</h4>
+ <select class="form-control" ng-model="settings.spatialSelect" ng-options="dataset as dataset.name for dataset in datasets"></select>
+ <hr />
+ <!-- Temporarily hidden for work on CLIMATE-365.-->
+ <div ng-hide=true>
+ <h4>Select a file which will define the bounds of subregions.</h4>
+ <form class="form-inline" autocomplete="off">
+ <input id="subregionFileInput" predictive-file-browser-input ng-model="settings.subregionFile" type="text" class="input-xlarge" autocomplete="off" />
+ </form>
+ </div>
+ <!--End hidden section for CLIMATE-365-->
+ </div>
+ <div class="modal-footer">
+ <button class="btn btn-warning cancel" data-dismiss="modal">Close</button>
+ </div>
+ </div>
+ </div>
+</div>
+<!-- END - Modal for evaluation settings -->
+
+<div class="row">
+ <div class="col-md-12">
+ <div class="row">
+ <!-- Dataset Select and Display Column -->
+ <div class="col-md-6">
+ <!--Dataset Select Controls-->
+ <div ng-controller="DatasetSelectCtrl">
+ <div class="row">
+ <div class="col-md-1 col-md-offset-10">
+ <button class="btn btn-link no-color-link" ng-click="clearDatasets()" ng-disabled="shouldDisableClearButton()">
+ <span tooltip-placement="left" tooltip-popup-delay="700" tooltip="Clear Datasets">
+ <i class="fa fa-trash-o fa-2x"></i>
+ </span>
+ </button>
+ </div>
+ <div class="col-md-1">
+ <button class="btn btn-link no-color-link" data-toggle="modal" data-target="#datasetSelect">
+ <span tooltip-placement="left" tooltip-popup-delay="700" tooltip="Add Dataset">
+ <i class="fa fa-plus fa-2x"></i>
+ </span>
+ </button>
+ </div>
+ </div>
+ <!-- Modal for dataset selection -->
+ <div class="modal fade" id="datasetSelect" role="dialog" aria-labelledby="datasetSelectModalLabel" aria-hidden="true">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h3>Dataset Select</h3>
+ </div>
+ <div class="modal-body">
+ <tabset>
+ <tab ng-repeat="tab in templates" heading="{{tab.title}}" active="tab.active" disabled="tab.disabled">
+ <div ng-include src="tab.url"></div>
+ </tab>
+ <li class="pull-right">Queued Datasets: {{datasetCount.length}}</li>
+ </tabset>
+ </div>
+ <div class="modal-footer">
+ <button class="btn btn-warning cancel" data-dismiss="modal">Close</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- END - Modal for dataset selection -->
+ <div class="row">
+ <div class="col-md-12">
+ <hr />
+ </div>
+ </div>
+ </div>
+ <!--Dataset display-->
+ <div ng-controller="DatasetDisplayCtrl" id="datasetDiv">
+ <div ng-repeat="dataset in datasets">
+ <div class="row">
+ <!--Data section-->
+ <div class="col-md-8 col-md-offset-1 muted">
+ {{dataset.name}}
+ </div>
+ <div class="col-md-1 col-md-offset-2">
+ <span tooltip-placement="left" tooltip-popup-delay="700" tooltip="Remove Dataset">
+ <a class="no-color-link" href="#" ng-click="removeDataset($index)">
+ <i class="fa fa-remove"></i>
+ </a>
+ </span>
+ </div>
+ </div>
+ <!--Time Values!-->
+ <div class="row">
+ <!--Dataset Info Section-->
+ <div class="col-md-9">
+ <div class="row">
+ <div class="col-md-2 col-md-offset-1 text-center">Start:</div>
+ <div class="col-md-2">
+ <div class="col-md-2 text-center">{{dataset.timeVals.start | ISODateToMiddleEndian}}</div>
+ </div>
+ <div class="col-md-2 text-center">End:</div>
+ <div class="col-md-2">
+ <div class="col-md-2 text-center">{{dataset.timeVals.end | ISODateToMiddleEndian}}</div>
+ </div>
+ </div>
+ <!--Lat/Long Values!-->
+ <div class="row">
+ <div class="col-md-2 col-md-offset-1 text-center">North:</div>
+ <div class="col-md-2 text-center">
+ {{dataset.latlonVals.latMax | number:2}}
+ </div>
+ <div class="col-md-2 text-center">West:</div>
+ <div class="col-md-2 text-center">
+ {{dataset.latlonVals.lonMin | number:2}}
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-2 col-md-offset-1 text-center">South:</div>
+ <div class="col-md-2 text-center">
+ {{dataset.latlonVals.latMin | number:2}}
+ </div>
+ <div class="col-md-2 text-center">East:</div>
+ <div class="col-md-2 text-center">
+ {{dataset.latlonVals.lonMax | number:2}}
+ </div>
+ </div>
+ </div>
+ <!--Preview Map Section-->
+ <div class="col-md-3">
+ <!--If the dataset is global we show a picture of a globe instead of the actual map-->
+ <div ng-hide="dataset.latlonVals.lonMin == -180 && dataset.latlonVals.lonMax == 180 &&
+ dataset.latlonVals.latMin == -90 && dataset.latlonVals.latMax == 90"
+ preview-map="dataset" index="$index"></div>
+ <div ng-show="dataset.latlonVals.lonMin == -180 && dataset.latlonVals.lonMax == 180 &&
+ dataset.latlonVals.latMin == -90 && dataset.latlonVals.latMax == 90">
+ <img src="img/globe.png" class="preview-map">
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6 col-md-offset-3"><hr /></div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- Map, Timeline, and Parameter Control Column -->
+ <div class="col-md-6">
+ <!--Map-->
+ <div class="row" ng-controller="WorldMapCtrl">
+ <div class="col-md-12">
+ <leaflet-map id="map"></leaflet-map>
+ </div>
+ </div>
+
+ <!--Timeline-->
+ <div class="row">
+ <div class="col-md-12" ng-controller="TimelineCtrl">
+ <div class="timeline"></div>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-12" ng-controller="ParameterSelectCtrl">
+ <div class="row top3">
+ <div class="col-md-2 text-center">Start Date:</div>
+ <div class="col-md-4">
+ <form>
+ <!--This styling HAD to be done inline. Using a class wouldn't work and for some -->
+ <!--reason the input boxes refused to be 100% wide when their span size was set.-->
+ <input ng-disabled="shouldDisableControls()" on-blur="checkParameters();" ng-model="displayParams.start" ui-date="datepickerSettings" ui-date-format="yy-mm-dd" type="text" class="col-md-4 text-center" style="width:100%" />
+ </form>
+ </div>
+ <div class="col-md-2 text-center">End Date:</div>
+ <div class="col-md-4">
+ <form>
+ <!--This styling HAD to be done inline. Using a class wouldn't work and for some -->
+ <!--reason the input boxes refused to be 100% wide when their span size was set.-->
+ <input ng-disabled="shouldDisableControls()" on-blur="checkParameters();" ng-model="displayParams.end" ui-date="datepickerSettings" ui-date-format="yy-mm-dd" type="text" class="col-md-4 text-center" style="width:100%"/>
+ </form>
+ </div>
+ </div>
+ <div class="row top3">
+ <div class="col-md-2 text-center">North:</div>
+ <div class="col-md-4">
+ <form action="">
+ <input ng-disabled="shouldDisableControls()" ng-model="displayParams.latMax" on-blur="checkParameters();" type="text" class="col-md-4 text-center" style="width:100%"/>
+ </form>
+ </div>
+ <div class="col-md-2 text-center">South:</div>
+ <div class="col-md-4">
+ <form action="">
+ <!--This styling HAD to be done inline. Using a class wouldn't work and for some -->
+ <!--reason the input boxes refused to be 100% wide when their span size was set.-->
+ <input ng-disabled="shouldDisableControls()" ng-model="displayParams.latMin" on-blur="checkParameters();" type="text" class="col-md-4 text-center" style="width:100%"/>
+ </form>
+ </div>
+ </div>
+ <div class="row top3">
+ <div class="col-md-2 text-center">East:</div>
+ <div class="col-md-4">
+ <form>
+ <!--This styling HAD to be done inline. Using a class wouldn't work and for some -->
+ <!--reason the input boxes refused to be 100% wide when their span size was set.-->
+ <input ng-disabled="shouldDisableControls()" ng-model="displayParams.lonMax" on-blur="checkParameters();" type="text" class="col-md-4 text-center" style="width:100%"/>
+ </form>
+ </div>
+ <div class="col-md-2 text-center">West:</div>
+ <div class="col-md-4">
+ <form>
+ <!--This styling HAD to be done inline. Using a class wouldn't work and for some -->
+ <!--reason the input boxes refused to be 100% wide when their span size was set.-->
+ <input ng-disabled="shouldDisableControls()" ng-model="displayParams.lonMin" on-blur="checkParameters();"; type="text" class="col-md-4 text-center" style="width:100%"/>
+ </form>
+ </div>
+ </div>
+ <div class="row top3">
+ <div class="col-md-2 col-md-offset-6">
+ <!--<button class="btn btn-link no-color-link pull-right" bootstrap-modal-open="evaluationSettings">-->
+ <button class="btn btn-link no-color-link pull-right" data-toggle="modal" data-target="#evaluationSettingsModal">
+ <span tooltip-placement="left" tooltip-popup-delay="700" tooltip="Settings">
+ <span class="fa-stack fa-lg">
+ <i class="fa fa-square-o fa-stack-2x"></i>
+ <i class="fa fa-cogs fa-stack-1x"></i>
+ </span>
+ </span>
+ </button>
+ </div>
+ <div class="col-md-4">
+ <button ng-click="runEvaluation()" ng-disabled="shouldDisableEvaluateButton()" class="btn btn-block btn-primary">
+ <div ng-hide="runningEval">Evaluate</div>
+ <div ng-show="runningEval"><i class="fa fa-spinner fa-spin"></i></div>
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/views/modelselect.html
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/views/modelselect.html b/ocw-ui/frontend/app/views/modelselect.html
new file mode 100644
index 0000000..9bc128f
--- /dev/null
+++ b/ocw-ui/frontend/app/views/modelselect.html
@@ -0,0 +1,87 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<div class="container">
+ <div class="row">
+ <div class="span10 offset1 columns">
+ <div class="row">
+ <div class="span10">
+ <center>
+ <form id="modelSelectorForm">
+ <input type="file" name="modelSelector">
+ </form>
+ </center>
+ </div>
+ </div>
+ <div class="row">
+ <div class="span10 offset2">
+ <form class="form-horizontal" id="parameterSelectorForm">
+ <div class="control-group">
+ <label class="control-label" for="paramSelect">Parameter Value</label>
+ <div class="controls">
+ <select id="paramSelect">
+ <option ng-repeat="param in modelParameters">
+ {{param.text}}
+ </option>
+ </select>
+ </div>
+ </div>
+ <div class="control-group">
+ <label class="control-label" for="latSelect">Latitude Variable</label>
+ <div class="controls">
+ <select id="latSelect">
+ <option ng-repeat="lat in latVariables">
+ {{lat.text}}
+ </option>
+ </select>
+ </div>
+ </div>
+ <div class="control-group">
+ <label class="control-label" for="lonSelect">Longitude Variable</label>
+ <div class"controls">
+ <select id="lonSelect">
+ <option ng-repeat="lon in lonVariables">
+ {{lon.text}}
+ </option>
+ </select>
+ </div>
+ </div>
+ <div class="control-group">
+ <label class="control-label" for="dateTimeSelect">Date/Time Variable</label>
+ <div class="controls">
+ <select id="dateTimeSelect">
+ <option ng-repeat="dateTime in dateTimeVariables">
+ {{dateTime.text}}
+ </option>
+ </select>
+ </div>
+ </div>
+ <div class="control-group">
+ <div class="controls">
+ <button type="submit" class="btn btn-warn">Cancel</button>
+ <button type="submit" class="btn">Add Model</button>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/views/results.html
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/views/results.html b/ocw-ui/frontend/app/views/results.html
new file mode 100644
index 0000000..432bba1
--- /dev/null
+++ b/ocw-ui/frontend/app/views/results.html
@@ -0,0 +1,34 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<div class="row">
+ <div class="col-md-3">
+ <div id="results-sidebar" class="pa-sidebar well well-small">
+ <ul class="nav nav-list">
+ <li id="results-sidebar-header" class="nav-header">Latest Run Results</li>
+ <li ng-repeat="result in results"
+ ng-class="{ active: $state.includes('results.detail') && $stateParams.resultId == result }">
+ <a href="#/results/{{result.replace('/', '')}}" >{{result}}</a>
+ </li>
+ </ul>
+ <div ui-view="menu"></div>
+ </div>
+ </div>
+ <div class="col-md-9" ui-view ng-animate="{enter:'fade-enter'}"></div>
+</div>
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/views/resultsdetail.html
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/views/resultsdetail.html b/ocw-ui/frontend/app/views/resultsdetail.html
new file mode 100644
index 0000000..4083ff3
--- /dev/null
+++ b/ocw-ui/frontend/app/views/resultsdetail.html
@@ -0,0 +1,30 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<div>
+ <h2>{{result}}</h2>
+ <div class="row text-center">
+ <div class="{{alertClass}}">{{alertMessage}}</div>
+ <ul>
+ <li ng-repeat="figure in figures">
+ <img class="img-responsive" ng-src="{{baseURL}}/static/eval_results/{{figure}}" alt="" />
+ </li>
+ </ul>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/views/resultslist.html
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/views/resultslist.html b/ocw-ui/frontend/app/views/resultslist.html
new file mode 100644
index 0000000..f4664c6
--- /dev/null
+++ b/ocw-ui/frontend/app/views/resultslist.html
@@ -0,0 +1,21 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<h4>Select one of your previous runs. If none are displayed, please return
+ to the main page and start one!</h4>
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/views/selectobservation.html
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/views/selectobservation.html b/ocw-ui/frontend/app/views/selectobservation.html
new file mode 100644
index 0000000..fd10ff8
--- /dev/null
+++ b/ocw-ui/frontend/app/views/selectobservation.html
@@ -0,0 +1,80 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<div ng-controller="ObservationSelectCtrl">
+ <div class="row">
+ <div class="col-md-12">
+ <div class="row">
+ <!--<form class="form-inline" autocomplete="off">-->
+ <form class="form" autocomplete="off">
+ <div class="form-group">
+ <div class="col-md-9">
+ <input id="observationFileInput" predictive-file-browser-input ng-model="filePathInput" type="text" class="form-control" autocomplete="off" placeholder="Navigate to a .nc file. Start by typing '/'" />
+ </div>
+ <div class="col-md-2">
+ <button class="btn" ng-click="uploadLocalFile()" ng-disabled="shouldDisableLoadButton()">
+ <div ng-hide="loadingFile">Parse File</div>
+ <div ng-show="loadingFile"><i class="icon-spinner icon-spin"></i></div>
+ </button>
+ </div>
+ </div>
+ </form>
+ </div>
+ <hr />
+ <div class="row top3">
+ <div class="col-md-5 text-center">
+ Evaluation Variable
+ </div>
+ <div class="col-md-6">
+ <select class="form-control" ng-model="paramSelect" ng-options="param for param in params"></select>
+ </div>
+ </div>
+ <div class="row top3">
+ <div class="col-md-5 text-center">
+ Latitude Variable
+ </div>
+ <div class="col-md-6">
+ <select class="form-control" ng-model="latsSelect" ng-options="lat for lat in lats"></select>
+ </div>
+ </div>
+ <div class="row top3">
+ <div class="col-md-5 text-center">
+ Longitude Variable
+ </div>
+ <div class="col-md-6">
+ <select class="form-control" ng-model="lonsSelect" ng-options="lon for lon in lons"></select>
+ </div>
+ </div>
+ <div class="row top3">
+ <div class="col-md-5 text-center">
+ Date/Time Variable
+ </div>
+ <div class="col-md-6">
+ <select class="form-control" ng-model="timeSelect" ng-options="time for time in times"></select>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="row top3">
+ <div class="col-md-3 col-md-offset-1">
+ <button class="btn btn-primary btn-block" ng-click="addDataSet()">Add Dataset</button>
+ </div>
+ <div class="pull-left small-alert" ng-show="fileAdded">Successfully added dataset...</div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/app/views/selectrcmed.html
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/app/views/selectrcmed.html b/ocw-ui/frontend/app/views/selectrcmed.html
new file mode 100644
index 0000000..6b09f48
--- /dev/null
+++ b/ocw-ui/frontend/app/views/selectrcmed.html
@@ -0,0 +1,40 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<div ng-controller="RcmedSelectionCtrl">
+ <div class="row">
+ <div class="col-md-10 col-md-offset-1">
+ <div class="row top3">Select the RCMED dataset that you would like use.</div>
+ <div class="row top3">
+ <select ng-change="dataSelectUpdated()" class="form-control" ng-model="datasetSelection" ng-options="obs as obs.longname for obs in availableObs"></select>
+ </div>
+ <div class="row top3">Select the dataset parameter that you would like to test.</div>
+ <div class="row top3">
+ <select class="form-control" ng-model="parameterSelection" ng-options="param as param.shortname for param in retrievedObsParams"></select>
+ </div>
+
+ <div class="row top3">
+ <div class="col-md-3">
+ <button class="btn btn-primary btn-block-left" ng-click="addObservation()">Add Observation</button>
+ </div>
+ <div class="pull-left small-alert" ng-show="fileAdded">Successfully added dataset...</div>
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/bower.json
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/bower.json b/ocw-ui/frontend/bower.json
new file mode 100644
index 0000000..d288a19
--- /dev/null
+++ b/ocw-ui/frontend/bower.json
@@ -0,0 +1,25 @@
+{
+ "name": "ocw-ui",
+ "version": "0.0.0",
+ "dependencies": {
+ "angular": "1.2.16",
+ "json3": "~3.3.1",
+ "es5-shim": "~3.1.0",
+ "bootstrap": "~3.2.0",
+ "angular-resource": "1.2.16",
+ "angular-cookies": "1.2.16",
+ "angular-animate": "1.2.16",
+ "angular-route": "1.2.16",
+ "angular-ui-router": "angular-ui/ui-router#~0.2.10",
+ "leaflet": "~0.7.3",
+ "chap-links-timeline": "~2.6.1",
+ "components-font-awesome": "~4.1.0",
+ "angular-bootstrap": "~0.11.0",
+ "angular-ui-date": "~0.0.3"
+ },
+ "devDependencies": {
+ "angular-mocks": "1.2.16",
+ "angular-scenario": "1.2.16"
+ },
+ "appPath": "app"
+}
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/config/karma-e2e.conf.js
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/config/karma-e2e.conf.js b/ocw-ui/frontend/config/karma-e2e.conf.js
deleted file mode 100755
index 746879e..0000000
--- a/ocw-ui/frontend/config/karma-e2e.conf.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
-**/
-basePath = '../';
-
-files = [
- ANGULAR_SCENARIO,
- ANGULAR_SCENARIO_ADAPTER,
- 'test/e2e/**/*.js'
-];
-
-autoWatch = false;
-
-browsers = ['Chrome'];
-
-singleRun = true;
-
-proxies = {
- '/': 'http://localhost:8000/'
-};
-
-junitReporter = {
- outputFile: 'test_out/e2e.xml',
- suite: 'e2e'
-};
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/config/karma.conf.js
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/config/karma.conf.js b/ocw-ui/frontend/config/karma.conf.js
deleted file mode 100755
index 65b5013..0000000
--- a/ocw-ui/frontend/config/karma.conf.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
-**/
-basePath = '../';
-
-files = [
- JASMINE,
- JASMINE_ADAPTER,
- 'app/js/lib/jquery/jquery-1.10.1.js',
- 'app/js/lib/jquery/jquery-ui/jquery-ui-1.10.3.min.js',
- 'app/js/lib/bootstrap/bootstrap.js',
- 'app/js/lib/angular/angular.js',
- 'app/js/lib/angular/angular-*.js',
- 'app/js/lib/angular-ui/*.js',
- 'test/lib/angular/angular-mocks.js',
- 'app/js/lib/jquery/jquery-ui/datepicker-wrapper/date.js',
- 'app/js/lib/leaflet/leaflet-0.5.js',
- 'app/js/app.js',
- 'app/js/controllers/*.js',
- 'app/js/directives/*.js',
- 'app/js/services/*.js',
- 'app/js/filters/*.js',
- 'test/unit/**/*.js'
-];
-
-autoWatch = true;
-
-browsers = ['Chrome'];
-
-junitReporter = {
- outputFile: 'test_out/unit.xml',
- suite: 'unit'
-};
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/package.json
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/package.json b/ocw-ui/frontend/package.json
new file mode 100644
index 0000000..be2f597
--- /dev/null
+++ b/ocw-ui/frontend/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "ocwui",
+ "version": "0.0.0",
+ "dependencies": {},
+ "devDependencies": {
+ "grunt": "^0.4.1",
+ "grunt-autoprefixer": "^0.7.3",
+ "grunt-concurrent": "^0.5.0",
+ "grunt-contrib-clean": "^0.5.0",
+ "grunt-contrib-concat": "^0.4.0",
+ "grunt-contrib-connect": "^0.7.1",
+ "grunt-contrib-copy": "^0.5.0",
+ "grunt-contrib-cssmin": "^0.9.0",
+ "grunt-contrib-htmlmin": "^0.3.0",
+ "grunt-contrib-imagemin": "^0.7.0",
+ "grunt-contrib-jshint": "^0.10.0",
+ "grunt-contrib-uglify": "^0.4.0",
+ "grunt-contrib-watch": "^0.6.1",
+ "grunt-filerev": "^0.2.1",
+ "grunt-google-cdn": "^0.4.0",
+ "grunt-karma": "^0.8.3",
+ "grunt-newer": "^0.7.0",
+ "grunt-ngmin": "^0.0.3",
+ "grunt-svgmin": "^0.4.0",
+ "grunt-usemin": "^2.1.1",
+ "grunt-wiredep": "^1.8.0",
+ "jshint-stylish": "^0.2.0",
+ "karma": "^0.12.17",
+ "karma-jasmine": "^0.1.5",
+ "karma-phantomjs-launcher": "^0.1.4",
+ "load-grunt-tasks": "^0.4.0",
+ "time-grunt": "^0.3.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "scripts": {
+ "test": "grunt test"
+ }
+}
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/scripts/e2e-test.sh
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/scripts/e2e-test.sh b/ocw-ui/frontend/scripts/e2e-test.sh
deleted file mode 100755
index dfca333..0000000
--- a/ocw-ui/frontend/scripts/e2e-test.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-BASE_DIR=`dirname $0`
-
-echo ""
-echo "Starting Karma Server"
-echo "-------------------------------------------------------------------"
-
-karma start $BASE_DIR/../config/karma-e2e.conf.js $*
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/scripts/test.sh
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/scripts/test.sh b/ocw-ui/frontend/scripts/test.sh
deleted file mode 100755
index 7094550..0000000
--- a/ocw-ui/frontend/scripts/test.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-BASE_DIR=`dirname $0`
-
-echo ""
-echo "Starting Karma Server"
-echo "-------------------------------------------------------------------"
-
-karma start $BASE_DIR/../config/karma.conf.js $*
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/scripts/web-server.js
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/scripts/web-server.js b/ocw-ui/frontend/scripts/web-server.js
deleted file mode 100755
index e137ad2..0000000
--- a/ocw-ui/frontend/scripts/web-server.js
+++ /dev/null
@@ -1,313 +0,0 @@
-#!/usr/bin/env node
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
-**/
-
-var util = require('util'),
- http = require('http'),
- fs = require('fs'),
- url = require('url'),
- events = require('events');
-
-var DEFAULT_PORT = 8000;
-
-function main(argv) {
- new HttpServer({
- 'GET': createServlet(StaticServlet),
- 'HEAD': createServlet(StaticServlet)
- }).start(Number(argv[2]) || DEFAULT_PORT);
-}
-
-function escapeHtml(value) {
- return value.toString().
- replace('<', '<').
- replace('>', '>').
- replace('"', '"');
-}
-
-function createServlet(Class) {
- var servlet = new Class();
- return servlet.handleRequest.bind(servlet);
-}
-
-/**
- * An Http server implementation that uses a map of methods to decide
- * action routing.
- *
- * @param {Object} Map of method => Handler function
- */
-function HttpServer(handlers) {
- this.handlers = handlers;
- this.server = http.createServer(this.handleRequest_.bind(this));
-}
-
-HttpServer.prototype.start = function(port) {
- this.port = port;
- this.server.listen(port);
- util.puts('Http Server running at http://localhost:' + port + '/');
-};
-
-HttpServer.prototype.parseUrl_ = function(urlString) {
- var parsed = url.parse(urlString);
- parsed.pathname = url.resolve('/', parsed.pathname);
- return url.parse(url.format(parsed), true);
-};
-
-HttpServer.prototype.handleRequest_ = function(req, res) {
- var logEntry = req.method + ' ' + req.url;
- if (req.headers['user-agent']) {
- logEntry += ' ' + req.headers['user-agent'];
- }
- util.puts(logEntry);
- req.url = this.parseUrl_(req.url);
- var handler = this.handlers[req.method];
- if (!handler) {
- res.writeHead(501);
- res.end();
- } else {
- handler.call(this, req, res);
- }
-};
-
-/**
- * Handles static content.
- */
-function StaticServlet() {}
-
-StaticServlet.MimeMap = {
- 'txt': 'text/plain',
- 'html': 'text/html',
- 'css': 'text/css',
- 'xml': 'application/xml',
- 'json': 'application/json',
- 'js': 'application/javascript',
- 'jpg': 'image/jpeg',
- 'jpeg': 'image/jpeg',
- 'gif': 'image/gif',
- 'png': 'image/png',
- 'svg': 'image/svg+xml'
-};
-
-StaticServlet.prototype.handleRequest = function(req, res) {
- var self = this;
- var path = ('./' + req.url.pathname).replace('//','/').replace(/%(..)/g, function(match, hex){
- return String.fromCharCode(parseInt(hex, 16));
- });
- var parts = path.split('/');
- if (parts[parts.length-1].charAt(0) === '.')
- return self.sendForbidden_(req, res, path);
- if (~path.indexOf("dirlist"))
- return self.getDirList_(req, res, path);
- fs.stat(path, function(err, stat) {
- if (err)
- return self.sendMissing_(req, res, path);
- if (stat.isDirectory())
- return self.sendDirectory_(req, res, path);
- return self.sendFile_(req, res, path);
- });
-}
-
-StaticServlet.prototype.sendError_ = function(req, res, error) {
- res.writeHead(500, {
- 'Content-Type': 'text/html'
- });
- res.write('<!doctype html>\n');
- res.write('<title>Internal Server Error</title>\n');
- res.write('<h1>Internal Server Error</h1>');
- res.write('<pre>' + escapeHtml(util.inspect(error)) + '</pre>');
- util.puts('500 Internal Server Error');
- util.puts(util.inspect(error));
-};
-
-StaticServlet.prototype.sendMissing_ = function(req, res, path) {
- path = path.substring(1);
- res.writeHead(404, {
- 'Content-Type': 'text/html'
- });
- res.write('<!doctype html>\n');
- res.write('<title>404 Not Found</title>\n');
- res.write('<h1>Not Found</h1>');
- res.write(
- '<p>The requested URL ' +
- escapeHtml(path) +
- ' was not found on this server.</p>'
- );
- res.end();
- util.puts('404 Not Found: ' + path);
-};
-
-StaticServlet.prototype.sendForbidden_ = function(req, res, path) {
- path = path.substring(1);
- res.writeHead(403, {
- 'Content-Type': 'text/html'
- });
- res.write('<!doctype html>\n');
- res.write('<title>403 Forbidden</title>\n');
- res.write('<h1>Forbidden</h1>');
- res.write(
- '<p>You do not have permission to access ' +
- escapeHtml(path) + ' on this server.</p>'
- );
- res.end();
- util.puts('403 Forbidden: ' + path);
-};
-
-StaticServlet.prototype.sendRedirect_ = function(req, res, redirectUrl) {
- res.writeHead(301, {
- 'Content-Type': 'text/html',
- 'Location': redirectUrl
- });
- res.write('<!doctype html>\n');
- res.write('<title>301 Moved Permanently</title>\n');
- res.write('<h1>Moved Permanently</h1>');
- res.write(
- '<p>The document has moved <a href="' +
- redirectUrl +
- '">here</a>.</p>'
- );
- res.end();
- util.puts('301 Moved Permanently: ' + redirectUrl);
-};
-
-StaticServlet.prototype.getDirList_ = function(req, res, path) {
- res.writeHead(200, {
- 'Content-Type': 'json'
- });
-
- // Grab the passed path value
- var pathQuery = url.parse(req.url, true).query.path
- // Using the supplied path, grab directory information
- var dirList = fs.readdirSync(pathQuery);
-
- // Filter out any hidden files or current/previous directory references
- dirList = dirList.filter(function(item, index, array) {
- return (item[0] !== ".");
- });
-
- // Generate the full path names for all the items found when 'ls'-ing
- // the passed directory.
- dirList = dirList.map(function(item, index, array) {
- var temp = item;
-
- // Make sure the path is joined properly. Sometimes there will be a trailing
- // '/' in the path and sometimes there won't. Don't want to end up with '//'.
- if (pathQuery[pathQuery.length - 1] === "/") {
- temp = pathQuery + item;
- } else {
- temp = pathQuery + "/" + item;
- }
-
- // We want the directories that are found to have a trailing '/'. Let's make sure
- // that we do that!
- var ret = temp;
- if (fs.existsSync(temp + "/")) {
- ret = temp + "/";
- }
-
- return ret;
- });
-
- // Sort all the results alphabetically ignoring case.
- dirList = dirList.sort(function(a, b) {
- if (a.toLowerCase() < b.toLowerCase()) return -1;
- if (a.toLowerCase() > b.toLowerCase()) return 1;
- return 0;
- });
-
- res.write(JSON.stringify(dirList));
- res.end();
-}
-
-StaticServlet.prototype.sendFile_ = function(req, res, path) {
- var self = this;
- var file = fs.createReadStream(path);
- res.writeHead(200, {
- 'Content-Type': StaticServlet.
- MimeMap[path.split('.').pop()] || 'text/plain'
- });
- if (req.method === 'HEAD') {
- res.end();
- } else {
- file.on('data', res.write.bind(res));
- file.on('close', function() {
- res.end();
- });
- file.on('error', function(error) {
- self.sendError_(req, res, error);
- });
- }
-};
-
-StaticServlet.prototype.sendDirectory_ = function(req, res, path) {
- var self = this;
- if (path.match(/[^\/]$/)) {
- req.url.pathname += '/';
- var redirectUrl = url.format(url.parse(url.format(req.url)));
- return self.sendRedirect_(req, res, redirectUrl);
- }
- fs.readdir(path, function(err, files) {
- if (err)
- return self.sendError_(req, res, error);
-
- if (!files.length)
- return self.writeDirectoryIndex_(req, res, path, []);
-
- var remaining = files.length;
- files.forEach(function(fileName, index) {
- fs.stat(path + '/' + fileName, function(err, stat) {
- if (err)
- return self.sendError_(req, res, err);
- if (stat.isDirectory()) {
- files[index] = fileName + '/';
- }
- if (!(--remaining))
- return self.writeDirectoryIndex_(req, res, path, files);
- });
- });
- });
-};
-
-StaticServlet.prototype.writeDirectoryIndex_ = function(req, res, path, files) {
- path = path.substring(1);
- res.writeHead(200, {
- 'Content-Type': 'text/html'
- });
- if (req.method === 'HEAD') {
- res.end();
- return;
- }
- res.write('<!doctype html>\n');
- res.write('<title>' + escapeHtml(path) + '</title>\n');
- res.write('<style>\n');
- res.write(' ol { list-style-type: none; font-size: 1.2em; }\n');
- res.write('</style>\n');
- res.write('<h1>Directory: ' + escapeHtml(path) + '</h1>');
- res.write('<ol>');
- files.forEach(function(fileName) {
- if (fileName.charAt(0) !== '.') {
- res.write('<li><a href="' +
- escapeHtml(fileName) + '">' +
- escapeHtml(fileName) + '</a></li>');
- }
- });
- res.write('</ol>');
- res.end();
-};
-
-// Must be last,
-main(process.argv);
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/test/.jshintrc
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/test/.jshintrc b/ocw-ui/frontend/test/.jshintrc
new file mode 100644
index 0000000..b1be025
--- /dev/null
+++ b/ocw-ui/frontend/test/.jshintrc
@@ -0,0 +1,36 @@
+{
+ "node": true,
+ "browser": true,
+ "esnext": true,
+ "bitwise": true,
+ "camelcase": true,
+ "curly": true,
+ "eqeqeq": true,
+ "immed": true,
+ "indent": 2,
+ "latedef": true,
+ "newcap": true,
+ "noarg": true,
+ "quotmark": "single",
+ "regexp": true,
+ "undef": true,
+ "unused": true,
+ "strict": true,
+ "trailing": true,
+ "smarttabs": true,
+ "globals": {
+ "after": false,
+ "afterEach": false,
+ "angular": false,
+ "before": false,
+ "beforeEach": false,
+ "browser": false,
+ "describe": false,
+ "expect": false,
+ "inject": false,
+ "it": false,
+ "jasmine": false,
+ "spyOn": false
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/test/e2e/runner.html
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/test/e2e/runner.html b/ocw-ui/frontend/test/e2e/runner.html
deleted file mode 100755
index 73c7733..0000000
--- a/ocw-ui/frontend/test/e2e/runner.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you under the Apache License, Version 2.0 (the
- ~ "License"); you may not use this file except in compliance
- ~ with the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing,
- ~ software distributed under the License is distributed on an
- ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- ~ KIND, either express or implied. See the License for the
- ~ specific language governing permissions and limitations
- ~ under the License.
- -->
-<!doctype html>
-<html lang="en">
- <head>
- <title>End2end Test Runner</title>
- <script src="../lib/angular/angular-scenario.js" ng-autotest></script>
- <script src="scenarios.js"></script>
- </head>
- <body>
- </body>
-</html>
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/test/e2e/scenarios.js
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/test/e2e/scenarios.js b/ocw-ui/frontend/test/e2e/scenarios.js
deleted file mode 100755
index c7c0e6c..0000000
--- a/ocw-ui/frontend/test/e2e/scenarios.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
-**/
-'use strict';
-
-/* http://docs.angularjs.org/guide/dev_guide.e2e-testing */
-
-describe('my app', function() {
-
- beforeEach(function() {
- browser().navigateTo('../../app/index.html');
- });
-
-
- it('should automatically redirect to /view1 when location hash/fragment is empty', function() {
- expect(browser().location().url()).toBe("/view1");
- });
-
-
- describe('view1', function() {
-
- beforeEach(function() {
- browser().navigateTo('#/view1');
- });
-
-
- it('should render view1 when user navigates to /view1', function() {
- expect(element('[ng-view] p:first').text()).
- toMatch(/partial for view 1/);
- });
-
- });
-
-
- describe('view2', function() {
-
- beforeEach(function() {
- browser().navigateTo('#/view2');
- });
-
-
- it('should render view2 when user navigates to /view2', function() {
- expect(element('[ng-view] p:first').text()).
- toMatch(/partial for view 2/);
- });
-
- });
-});
http://git-wip-us.apache.org/repos/asf/climate/blob/652ea657/ocw-ui/frontend/test/karma.conf.js
----------------------------------------------------------------------
diff --git a/ocw-ui/frontend/test/karma.conf.js b/ocw-ui/frontend/test/karma.conf.js
new file mode 100644
index 0000000..744d927
--- /dev/null
+++ b/ocw-ui/frontend/test/karma.conf.js
@@ -0,0 +1,86 @@
+// Karma configuration
+// http://karma-runner.github.io/0.12/config/configuration-file.html
+// Generated on 2014-07-15 using
+// generator-karma 0.8.3
+
+module.exports = function(config) {
+ 'use strict';
+
+ config.set({
+ // enable / disable watching file and executing tests whenever any file changes
+ autoWatch: true,
+
+ // base path, that will be used to resolve files and exclude
+ basePath: '../',
+
+ // testing framework to use (jasmine/mocha/qunit/...)
+ frameworks: ['jasmine'],
+
+ // list of files / patterns to load in the browser
+ files: [
+ 'bower_components/angular/angular.js',
+ 'bower_components/angular-mocks/angular-mocks.js',
+ 'bower_components/angular-animate/angular-animate.js',
+ 'bower_components/angular-cookies/angular-cookies.js',
+ 'bower_components/angular-resource/angular-resource.js',
+ 'bower_components/angular-route/angular-route.js',
+ 'bower_components/angular-animate/angular-animate.js',
+ 'bower_components/angular-bootstrap/ui-bootstrap.js',
+ // For some reason this causes the tests to completely fail to run
+ // if it is uncommented.
+ //'bower_components/angular-scenario/angular-scenario.js',
+ 'bower_components/angular-ui-date/src/date.js',
+ 'bower_components/angular-ui-router/release/angular-ui-router.js',
+ 'bower_components/chap-links-timeline/timeline.js',
+ 'bower_components/jquery/dist/jquery.js',
+ 'bower_components/jquery-ui/jquery-ui.js',
+ 'bower_components/leaflet/dist/leaflet.js',
+ 'app/scripts/**/*.js',
+ 'test/mock/**/*.js',
+ 'test/spec/**/*.js'
+ ],
+
+ // list of files / patterns to exclude
+ exclude: [],
+
+ // web server port
+ port: 8080,
+
+ // Start these browsers, currently available:
+ // - Chrome
+ // - ChromeCanary
+ // - Firefox
+ // - Opera
+ // - Safari (only Mac)
+ // - PhantomJS
+ // - IE (only Windows)
+ browsers: [
+ 'PhantomJS',
+ //'Chrome'
+ ],
+
+ // Which plugins to enable
+ plugins: [
+ 'karma-phantomjs-launcher',
+ 'karma-chrome-launcher',
+ 'karma-jasmine'
+ ],
+
+ // Continuous Integration mode
+ // if true, it capture browsers, run tests and exit
+ singleRun: false,
+
+ colors: true,
+
+ // level of logging
+ // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
+ logLevel: config.LOG_INFO,
+
+ // Uncomment the following lines if you are using grunt's server to run the tests
+ // proxies: {
+ // '/': 'http://localhost:9000/'
+ // },
+ // URL root prevent conflicts with the site root
+ // urlRoot: '_karma_'
+ });
+};