This repository was archived by the owner on Jun 16, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 19
Added the ability to control how score gets exported #262
Open
ThinkRedstone
wants to merge
12
commits into
FirstLegoLeague:master
Choose a base branch
from
ThinkRedstone:export-score
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
f4b8fe2
Changed sorting icons to a material-icons versions in ranking
ThinkRedstone fe8f09a
added sorting icons to scores.html
ThinkRedstone 2800b81
changed test for ranking to use the new material-icons
ThinkRedstone 588bd38
changed score.index to $index in scores.html
ThinkRedstone 9efa240
Moved css properties of sortable fields to elements.css under sortabl…
ThinkRedstone b5e75f5
Removed broken export dialog
ThinkRedstone b779a51
Added settings for formatting exported scores
ThinkRedstone 5a0d236
Changed export function to abide user settings
ThinkRedstone fb41f47
Merge branch 'sorting-icons' into export-score
ThinkRedstone 4b92580
made array encoding notepad-friendly
ThinkRedstone e1cae74
Replaces undefined or null fields with an empty string in exported files
ThinkRedstone a3c4b78
Changed test in accordance with the new export file format and expand…
ThinkRedstone File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,13 +5,13 @@ define('views/ranking',[ | |
| 'services/ng-scores', | ||
| 'services/ng-handshake', | ||
| 'services/ng-message', | ||
| 'controllers/ExportRankingDialogController', | ||
| 'services/ng-settings', | ||
| 'angular' | ||
| ],function(log) { | ||
| var moduleName = 'ranking'; | ||
| return angular.module(moduleName,['ExportRankingDialog']).controller(moduleName+'Ctrl', [ | ||
| '$scope', '$scores', '$stages','$handshake','$message', | ||
| function($scope, $scores, $stages, $handshake, $message) { | ||
| return angular.module(moduleName,[]).controller(moduleName+'Ctrl', [ | ||
| '$scope', '$scores', '$stages','$handshake','$message', '$settings', | ||
| function($scope, $scores, $stages, $handshake, $message, $settings) { | ||
| log('init ranking ctrl'); | ||
|
|
||
| // temporary default sort values | ||
|
|
@@ -70,15 +70,15 @@ define('views/ranking',[ | |
| var icon = ''; | ||
| if (stage.sort == col) { | ||
| if (stage.rev){ | ||
| icon = 'icon-sort-down'; | ||
| icon = 'arrow_drop_down'; | ||
| } else { | ||
| icon = 'icon-sort-up'; | ||
| icon = 'arrow_drop_up'; | ||
| } | ||
| } else if (stage.sort === undefined && col == $scope.sort) { | ||
| if (stage.rev === undefined && $scope.rev) { | ||
| icon = 'icon-sort-down'; | ||
| icon = 'arrow_drop_down'; | ||
| } else { | ||
| icon = 'icon-sort-up'; | ||
| icon = 'arrow_drop_up'; | ||
| } | ||
| } else { | ||
| icon = ''; // no icon if column is not sorted | ||
|
|
@@ -102,64 +102,60 @@ define('views/ranking',[ | |
| return new Array($scope.maxRounds() - stage.$rounds.length); | ||
| }; | ||
|
|
||
| // Data for CSV export links, indexed by stage ID | ||
| $scope.csvdata = {}; // CSV data itself | ||
| $scope.csvname = {}; // Filenames suggested to user | ||
|
|
||
| // Convert a 2D matrix to a CSV string. | ||
| // All cells are converted to strings and fully quoted, | ||
| // except null or undefined cells, which are passed as empty | ||
| // values (without quotes). | ||
| function toCSV(rows) { | ||
| return rows.map(function(row) { | ||
| return row.map(function(col) { | ||
| // Escape quotes, and wrap in quotes | ||
| if (col === undefined || col === null) { | ||
| col = ""; | ||
| } | ||
| return '"' + String(col).replace(/"/gi, '""') + '"'; | ||
| }).join(","); | ||
| }).join("\r\n"); // Use Windows line-endings, to make it Notepad-friendly | ||
| } | ||
| /** | ||
| * encodes a two dimensional array as a string according to the settings | ||
| * specified by the user as reported by the ng-settings.$settings service | ||
| * | ||
| * @param array the array to be encoded | ||
| * @returns {string} the encoded string form of the array | ||
| */ | ||
| $scope.encodeArray = function (array) { | ||
| var string = ""; | ||
| var settings = $settings.settings; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. encodeArray now 'depends' on $settings, making it harder to refactor out of here and re-use elsewhere, and harder to unit-test. |
||
| array.forEach(function (row) { | ||
| row = row.map((elem) => elem || elem === 0 ? String(elem) : ""); | ||
| string = string.concat(settings.lineStartString ? String(settings.lineStartString) : ""); | ||
| string = string.concat(row.join(settings.separatorString ? String(settings.separatorString) : "")); | ||
| string = string.concat((settings.lineEndString ? String(settings.lineEndString) : "") + "\r\n"); | ||
| }); | ||
| return string; | ||
| }; | ||
|
|
||
| $scope.exportFiles = {}; | ||
|
|
||
| /** | ||
| * Rebuild CSV data (contents and filenames) of given scoreboard. | ||
| * @param scoreboard Per-stage ranking as present in e.g. $scores.scoreboard. | ||
| * Builds the .csv file for exporting score for each stage and assigns it | ||
| * to exportFiles in the field corresponding to that stage's id | ||
| */ | ||
| $scope.rebuildCSV = function(scoreboard) { | ||
| $scope.csvdata = {}; | ||
| $scope.csvname = {}; | ||
| Object.keys(scoreboard).forEach(function(stageId) { | ||
| var ranking = scoreboard[stageId]; | ||
| var rows = ranking.map(function(entry) { | ||
| return [ | ||
| entry.rank, | ||
| entry.team.number, | ||
| entry.team.name, | ||
| entry.highest, | ||
| ].concat(entry.scores); | ||
| $scope.buildExportFiles= function () { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(It did directly tweak things on $scope, which is bad, so probably it should have returned an object containing these items instead.) |
||
| Object.keys($scope.scoreboard).forEach(function (stageID) { | ||
| var teams = $scope.scoreboard[stageID]; | ||
| teams = teams.map(function (teamEntry) { | ||
| return [teamEntry.rank, teamEntry.team.number, | ||
| teamEntry.team.name, teamEntry.highest].concat(teamEntry.scores); | ||
| }); | ||
| var header = ["Rank", "Team Number", "Team Name", "Highest"]; | ||
| var stage = $stages.get(stageId); | ||
| header = header.concat(stage.$rounds.map(function(round) { return "Round " + round; })); | ||
| rows.unshift(header); | ||
| $scope.csvname[stageId] = encodeURIComponent("ranking_" + stageId + ".csv"); | ||
| $scope.csvdata[stageId] = "data:text/csv;charset=utf-8," + encodeURIComponent(toCSV(rows)); | ||
| $scope.exportFiles[stageID] = "data:text/csv;charset=utf-8,"+encodeURIComponent($scope.encodeArray(teams)); | ||
| }); | ||
| }; | ||
|
|
||
| // Rebuild CSV data and filenames when scoreboard is updated | ||
| $scope.$watch("scoreboard", function() { | ||
| $scope.rebuildCSV($scores.scoreboard); | ||
| $scope.$watch("scoreboard", function () { | ||
| $scope.buildExportFiles(); | ||
| }, true); | ||
|
|
||
| $scope.$watchCollection("settings", function () {//we need to rebuild the files if the user changes his export format | ||
| $scope.buildExportFiles(); | ||
| }); | ||
|
|
||
| $settings.init().then(function () {//we have to wait for settings to initialize otherwise $scope.settings gets set to undefined | ||
| $scope.settings = $settings.settings; | ||
| }); | ||
| $scope.stages = $stages.stages; | ||
| $scope.scoreboard = $scores.scoreboard; | ||
|
|
||
| $scope.getRoundLabel = function(round){ | ||
| return "Round " + round; | ||
| }; | ||
|
|
||
|
|
||
| } | ||
| ]); | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not ideal to have to pass the promise implementation to the mock.
Just use
Promiseinside of it, and/or the 'normal'qpackage.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is legacy from our side. Not sure how to fix that as the stages services used $q to resolve promises in an "angular aware" fashion.
The other option would be to not use $q at all in the service, but wrap its use in $q.when() everywhere, but that seems even less ideal