From 51be190aeaa25c727d61569f9369f1727c5f1189 Mon Sep 17 00:00:00 2001 From: Radek Stepan Date: Fri, 3 Oct 2014 20:11:40 -0700 Subject: [PATCH] save project with a loading sign and a notification --- TODO.md | 61 +++++++++++++++++++++----------- public/js/app.bundle.js | 56 ++++++++++++++++++++++------- public/js/app.js | 56 ++++++++++++++++++++++------- src/models/projects.coffee | 2 +- src/templates/pages/new.mustache | 4 +-- src/views/notify.coffee | 5 ++- src/views/pages/new.coffee | 35 ++++++++++++------ 7 files changed, 157 insertions(+), 62 deletions(-) diff --git a/TODO.md b/TODO.md index 00893a1..b3a45ce 100644 --- a/TODO.md +++ b/TODO.md @@ -2,36 +2,57 @@ ##Release: MVP -- [ ] create a 500/400/loading system messages -- [ ] deal with Firebase timing out, are we still logged-in? -- [ ] mediator `!app/notify/edit` will edit the current notification -- [ ] verify that project exists on project page when fetching it remotely (add behind the scenes) -- [ ] need to show status (receiving information etc.) per repo -- [ ] provide a documentation site -- [ ] visiting a chart page saves the project if it isn't saved already -- [ ] landing page for the project and put message on my repo -- [ ] Handle [404](https://www.firebase.com/docs/hosting/guide/url-redirects-rewrites.html#section-404) on routes; from catch all check if '/' or go 404 controller -- [ ] allow `pushState` when [Firebase hosted](https://www.firebase.com/docs/hosting/guide/url-redirects-rewrites.html#section-rewrites) +###GitHub + - [ ] progress needs to be calculated based on strategy even on homepage, then sort the milestones based on priority -- [ ] calculate left margin based on the total number of points text width -- [ ] Do not show login/logged-in state when we are still fetching that information from Firebase + +###Notifications + +- [ ] create a 500/400/loading system messages +- [ ] mediator `!app/notify/edit` will edit the current notification +- [ ] need to show status (receiving information etc.) per repo + +###Error Handling + +- [ ] verify that project exists on project page when fetching it remotely (add behind the scenes) +- [ ] deal with Firebase timing out, are we still logged-in? +- [ ] visiting a chart page saves the project if it isn't saved already +- [ ] Check that we have not run out of requests to make +- [ ] can we get more than 1 notification at a time? +- [x] Validate repo input and show a loading sign of sorts + +###Bugs + - [ ] local storage is getting reset - [ ] a bit of a freeze when fetching `mbostock/d3` -- [ ] Validate repo input and show a loading sign of sorts -- [ ] Check that we have not run out of requests to make -- [ ] Show loading sign on top of [browser window](https://github.com/buunguyen/topbar) which is unobtrusive enough we can show it immediately. + +###Docs + +- [ ] landing page for the project and put message on my repo +- [ ] provide a documentation site + +###Routing + +- [ ] Handle [404](https://www.firebase.com/docs/hosting/guide/url-redirects-rewrites.html#section-404) on routes; from catch all check if '/' or go 404 controller +- [ ] allow `pushState` when [Firebase hosted](https://www.firebase.com/docs/hosting/guide/url-redirects-rewrites.html#section-rewrites) + +###Style + +- [ ] focus on form fields style +- [ ] switch off user select on buttons + +###Misc + +- [ ] show hero box or projects with a fade in and only when known +- [ ] calculate left margin based on the total number of points text width - [ ] show a countdown clock towards the end of the milestone or show overdue -- [ ] highlight for a moment recently changed milestone -- [ ] smooth animation when transitioning between icons and notifications -- [ ] show logged-in state only after it is known - [ ] trigger success topbar when we have completed a milestone on chart page; show plain when we are behind - [ ] on chart page show a little progress bar in the title - [ ] use tap plugin for Ractive -- [x] logged-in state fade into view independent of page loading -- [x] upgrade to Ractive [0.6.0](https://github.com/ractivejs/ractive/blob/dev/CHANGELOG.md) ##Future Releases +- [ ] smooth animation when transitioning between icons and notifications - [ ] show animated lines when drawing the chart - [ ] highlight changes from past fetch - [ ] In add a project form autocomplete on my username, orgs I am member of and repos I have access to diff --git a/public/js/app.bundle.js b/public/js/app.bundle.js index 628b60f..7e232d0 100644 --- a/public/js/app.bundle.js +++ b/public/js/app.bundle.js @@ -41004,7 +41004,7 @@ Router.prototype.mount = function(routes, path) { } }); }, - add: function(repo, add) { + add: function(repo, done) { var _this = this; return request.allMilestones(repo, function(err, res) { var milestones; @@ -41772,7 +41772,7 @@ Router.prototype.mount = function(routes, path) { // new.mustache root.require.register('burnchart/src/templates/pages/new.js', function(exports, require, module) { - module.exports = ["
","
","
","

Add a Project

","

Type in the name of the repository as you would normally. If you'd like to add a private GitHub project, Sign In first.

","
","","
"," "," "," "," "," ","
"," "," "," Add","
","
","
","
"].join("\n"); + module.exports = ["
","
","
","

Add a Project

","

Type in the name of the repository as you would normally. If you'd like to add a private GitHub project, Sign In first.

","
","","
"," "," "," "," "," ","
"," "," "," Add","
","
","
","
"].join("\n"); }); // project.mustache @@ -41849,6 +41849,21 @@ Router.prototype.mount = function(routes, path) { }); + // key.coffee + root.require.register('burnchart/src/utils/key.js', function(exports, require, module) { + + module.exports = { + is: function(evt) { + var _ref; + return (_ref = evt.original.type) === 'keyup' || _ref === 'keydown'; + }, + isEnter: function(evt) { + return evt.original.which === 13; + } + }; + + }); + // mixins.coffee root.require.register('burnchart/src/utils/mixins.js', function(exports, require, module) { @@ -42158,12 +42173,16 @@ Router.prototype.mount = function(routes, path) { // new.coffee root.require.register('burnchart/src/views/pages/new.js', function(exports, require, module) { - var mediator, user; + var key, mediator, system, user; mediator = require('../../modules/mediator'); + system = require('../../models/system'); + user = require('../../models/user'); + key = require('../../utils/key'); + module.exports = Ractive.extend({ 'template': require('../../templates/pages/new'), 'data': { @@ -42171,6 +42190,25 @@ Router.prototype.mount = function(routes, path) { user: user }, 'adapt': [Ractive.adaptors.Ractive], + submit: function(evt, value) { + var done, name, owner, _ref; + if (key.is(evt) && !key.isEnter(evt)) { + return; + } + _ref = value.split('/'), owner = _ref[0], name = _ref[1]; + done = system.async(); + return mediator.fire('!projects/add', { + owner: owner, + name: name + }, function(err) { + done(); + mediator.fire('!app/notify', { + 'text': err || ("Project " + value + " saved."), + 'type': err ? 'error' : 'success' + }); + return window.location.hash = '#'; + }); + }, onrender: function() { var autocomplete; document.title = 'Add a new project'; @@ -42178,16 +42216,8 @@ Router.prototype.mount = function(routes, path) { this.observe('value', _.debounce(autocomplete, 200), { 'init': false }); - return this.on('submit', function() { - var name, owner, _ref; - _ref = this.get('value').split('/'), owner = _ref[0], name = _ref[1]; - return mediator.fire('!projects/add', { - owner: owner, - name: name - }, function() { - return window.location.hash = '#'; - }); - }); + this.el.querySelector('input').focus(); + return this.on('submit', this.submit); } }); diff --git a/public/js/app.js b/public/js/app.js index b0f7ec8..dc9e01e 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -95,7 +95,7 @@ } }); }, - add: function(repo, add) { + add: function(repo, done) { var _this = this; return request.allMilestones(repo, function(err, res) { var milestones; @@ -863,7 +863,7 @@ // new.mustache root.require.register('burnchart/src/templates/pages/new.js', function(exports, require, module) { - module.exports = ["
","
","
","

Add a Project

","

Type in the name of the repository as you would normally. If you'd like to add a private GitHub project, Sign In first.

","
","","
"," "," "," "," "," ","
"," "," "," Add","
","
","
","
"].join("\n"); + module.exports = ["
","
","
","

Add a Project

","

Type in the name of the repository as you would normally. If you'd like to add a private GitHub project, Sign In first.

","
","","
"," "," "," "," "," ","
"," "," "," Add","
","
","
","
"].join("\n"); }); // project.mustache @@ -940,6 +940,21 @@ }); + // key.coffee + root.require.register('burnchart/src/utils/key.js', function(exports, require, module) { + + module.exports = { + is: function(evt) { + var _ref; + return (_ref = evt.original.type) === 'keyup' || _ref === 'keydown'; + }, + isEnter: function(evt) { + return evt.original.which === 13; + } + }; + + }); + // mixins.coffee root.require.register('burnchart/src/utils/mixins.js', function(exports, require, module) { @@ -1249,12 +1264,16 @@ // new.coffee root.require.register('burnchart/src/views/pages/new.js', function(exports, require, module) { - var mediator, user; + var key, mediator, system, user; mediator = require('../../modules/mediator'); + system = require('../../models/system'); + user = require('../../models/user'); + key = require('../../utils/key'); + module.exports = Ractive.extend({ 'template': require('../../templates/pages/new'), 'data': { @@ -1262,6 +1281,25 @@ user: user }, 'adapt': [Ractive.adaptors.Ractive], + submit: function(evt, value) { + var done, name, owner, _ref; + if (key.is(evt) && !key.isEnter(evt)) { + return; + } + _ref = value.split('/'), owner = _ref[0], name = _ref[1]; + done = system.async(); + return mediator.fire('!projects/add', { + owner: owner, + name: name + }, function(err) { + done(); + mediator.fire('!app/notify', { + 'text': err || ("Project " + value + " saved."), + 'type': err ? 'error' : 'success' + }); + return window.location.hash = '#'; + }); + }, onrender: function() { var autocomplete; document.title = 'Add a new project'; @@ -1269,16 +1307,8 @@ this.observe('value', _.debounce(autocomplete, 200), { 'init': false }); - return this.on('submit', function() { - var name, owner, _ref; - _ref = this.get('value').split('/'), owner = _ref[0], name = _ref[1]; - return mediator.fire('!projects/add', { - owner: owner, - name: name - }, function() { - return window.location.hash = '#'; - }); - }); + this.el.querySelector('input').focus(); + return this.on('submit', this.submit); } }); diff --git a/src/models/projects.coffee b/src/models/projects.coffee index 2219055..d591c2b 100644 --- a/src/models/projects.coffee +++ b/src/models/projects.coffee @@ -17,7 +17,7 @@ module.exports = new Model , (err) -> throw err if err - add: (repo, add) -> + add: (repo, done) -> # TODO: warn when we are adding an existing repo (or # silently go to index again). diff --git a/src/templates/pages/new.mustache b/src/templates/pages/new.mustache index 36acdaa..2e98c28 100644 --- a/src/templates/pages/new.mustache +++ b/src/templates/pages/new.mustache @@ -9,10 +9,10 @@
- + - Add + Add
diff --git a/src/views/notify.coffee b/src/views/notify.coffee index e5b398b..7334f36 100644 --- a/src/views/notify.coffee +++ b/src/views/notify.coffee @@ -12,15 +12,14 @@ module.exports = Ractive.extend 'hidden': yes 'defaults': 'text': '' - 'type': '' + 'type': '' # bland grey style 'system': no 'icon': 'megaphone' 'ttl': 5e3 # Show a notification. show: (opts) -> - @set 'hidden', no - + @set 'hidden', no # Set the opts. @set opts = _.defaults opts, @data.defaults # Which position to slide to? diff --git a/src/views/pages/new.coffee b/src/views/pages/new.coffee index d7fbf7b..d8d20bc 100644 --- a/src/views/pages/new.coffee +++ b/src/views/pages/new.coffee @@ -1,5 +1,7 @@ mediator = require '../../modules/mediator' +system = require '../../models/system' user = require '../../models/user' +key = require '../../utils/key' module.exports = Ractive.extend @@ -9,6 +11,26 @@ module.exports = Ractive.extend 'adapt': [ Ractive.adaptors.Ractive ] + # Listen to Enter keypress or Submit button click. + submit: (evt, value) -> + return if key.is(evt) and not key.isEnter(evt) + + [ owner, name ] = value.split('/') + + done = do system.async + + # Save repo. + mediator.fire '!projects/add', { owner, name }, (err) -> + do done + + mediator.fire '!app/notify', + 'text': err or "Project #{value} saved." + 'type': if err then 'error' else 'success' + + # Redirect to the dashboard. + # TODO: trigger a named route + window.location.hash = '#' + onrender: -> document.title = 'Add a new project' @@ -18,14 +40,7 @@ module.exports = Ractive.extend @observe 'value', _.debounce(autocomplete, 200), { 'init': no } - # TODO: focus on the input field + # Focus on the input field. + do @el.querySelector('input').focus - # TODO: listen to Enter keypress. - @on 'submit', -> - [ owner, name ] = @get('value').split('/') - - # TODO: save repo & persist. - mediator.fire '!projects/add', { owner, name }, -> - # Redirect to the dashboard. - # TODO: trigger a named route - window.location.hash = '#' \ No newline at end of file + @on 'submit', @submit \ No newline at end of file