save project with a loading sign and a notification
This commit is contained in:
parent
f108813d29
commit
51be190aea
61
TODO.md
61
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
|
||||
|
|
|
@ -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 = ["<div id=\"content\" class=\"wrap\">"," <div id=\"add\">"," <div class=\"header\">"," <h2>Add a Project</h2>"," <p>Type in the name of the repository as you would normally. If you'd like to add a private GitHub project, <a href=\"#\">Sign In</a> first.</p>"," </div>",""," <div class=\"form\">"," <table>"," <tr>"," <td>"," <input type=\"text\" placeholder=\"user/repo\" autocomplete=\"off\" value=\"{{value}}\">"," </td>"," <td>"," <a on-click=\"submit\">Add</a>"," </td>"," </tr>"," </table>"," </div>"," </div>","</div>"].join("\n");
|
||||
module.exports = ["<div id=\"content\" class=\"wrap\">"," <div id=\"add\">"," <div class=\"header\">"," <h2>Add a Project</h2>"," <p>Type in the name of the repository as you would normally. If you'd like to add a private GitHub project, <a href=\"#\">Sign In</a> first.</p>"," </div>",""," <div class=\"form\">"," <table>"," <tr>"," <td>"," <input type=\"text\" placeholder=\"user/repo\" autocomplete=\"off\" value=\"{{value}}\" on-keyup=\"submit:{{value}}\">"," </td>"," <td>"," <a on-click=\"submit:{{value}}\">Add</a>"," </td>"," </tr>"," </table>"," </div>"," </div>","</div>"].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);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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 = ["<div id=\"content\" class=\"wrap\">"," <div id=\"add\">"," <div class=\"header\">"," <h2>Add a Project</h2>"," <p>Type in the name of the repository as you would normally. If you'd like to add a private GitHub project, <a href=\"#\">Sign In</a> first.</p>"," </div>",""," <div class=\"form\">"," <table>"," <tr>"," <td>"," <input type=\"text\" placeholder=\"user/repo\" autocomplete=\"off\" value=\"{{value}}\">"," </td>"," <td>"," <a on-click=\"submit\">Add</a>"," </td>"," </tr>"," </table>"," </div>"," </div>","</div>"].join("\n");
|
||||
module.exports = ["<div id=\"content\" class=\"wrap\">"," <div id=\"add\">"," <div class=\"header\">"," <h2>Add a Project</h2>"," <p>Type in the name of the repository as you would normally. If you'd like to add a private GitHub project, <a href=\"#\">Sign In</a> first.</p>"," </div>",""," <div class=\"form\">"," <table>"," <tr>"," <td>"," <input type=\"text\" placeholder=\"user/repo\" autocomplete=\"off\" value=\"{{value}}\" on-keyup=\"submit:{{value}}\">"," </td>"," <td>"," <a on-click=\"submit:{{value}}\">Add</a>"," </td>"," </tr>"," </table>"," </div>"," </div>","</div>"].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);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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).
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="text" placeholder="user/repo" autocomplete="off" value="{{value}}">
|
||||
<input type="text" placeholder="user/repo" autocomplete="off" value="{{value}}" on-keyup="submit:{{value}}">
|
||||
</td>
|
||||
<td>
|
||||
<a on-click="submit">Add</a>
|
||||
<a on-click="submit:{{value}}">Add</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
@ -12,7 +12,7 @@ module.exports = Ractive.extend
|
|||
'hidden': yes
|
||||
'defaults':
|
||||
'text': ''
|
||||
'type': ''
|
||||
'type': '' # bland grey style
|
||||
'system': no
|
||||
'icon': 'megaphone'
|
||||
'ttl': 5e3
|
||||
|
@ -20,7 +20,6 @@ module.exports = Ractive.extend
|
|||
# Show a notification.
|
||||
show: (opts) ->
|
||||
@set 'hidden', no
|
||||
|
||||
# Set the opts.
|
||||
@set opts = _.defaults opts, @data.defaults
|
||||
# Which position to slide to?
|
||||
|
|
|
@ -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 = '#'
|
||||
@on 'submit', @submit
|
Loading…
Reference in New Issue