diff --git a/README.md b/README.md
index 8f32bcc..dcc44a1 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,7 @@ GitHub Burndown Chart as a service. Public repos are free, for private access au
### The 20%
+- [ ] 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
@@ -34,6 +35,7 @@ GitHub Burndown Chart as a service. Public repos are free, for private access au
- [ ] highlight for a moment recently changed milestone
- [ ] smooth animation when transitioning between icons and notifications
- [ ] show logged-in state only after it is known
+- [x] how does a message look like when we have an error and nothing to render?
- [x] format milestone titles prepending "Milestone" word if appropriate
- [x] Variable document.title on different pages
- [x] be able to go back to homepage
diff --git a/public/css/app.bundle.css b/public/css/app.bundle.css
index 47f58af..5764ebc 100644
--- a/public/css/app.bundle.css
+++ b/public/css/app.bundle.css
@@ -449,12 +449,13 @@ ul{list-style-type:none;margin:0;padding:0;}
ul li{display:inline-block}
.wrap{width:800px;margin:0 auto}
#notify{position:fixed;top:-68px;z-index:1;width:100%;background:#fcfcfc;color:#aaafbf;border-top:3px solid #aaafbf;border-bottom:1px solid #f3f4f8;}
+#notify.system{top:0%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);-moz-transform:translateX(-50%) translateY(-50%);-o-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);width:500px}
#notify.success{border-top-color:#00b361;color:#00b361}
#notify.warn{border-top-color:#ea9712;color:#ea9712}
#notify.alert{border-top-color:#c1041c;color:#c1041c}
-#notify .icon,#notify p{display:inline-block}
-#notify .icon{font-size:26px;padding:18px;width:38px}
-#notify p{margin-right:10px}
+#notify .icon,#notify p{display:block}
+#notify .icon{font-size:26px;padding:18px;width:38px;float:left}
+#notify p{padding:20px 20px 20px 74px;text-align:justify}
#head{background:#c1041c;height:64px;}
#head #icon{font-size:26px;margin:0;padding:10px 0;line-height:44px;height:44px;width:74px;background:#77000e;display:inline-block;color:#c1041c;margin:0;text-align:center}
#head .q{position:relative;display:inline-block;margin:13px 20px 0 20px;vertical-align:top;}
diff --git a/public/css/app.css b/public/css/app.css
index e1f2fea..21ab131 100644
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -42,12 +42,13 @@ ul{list-style-type:none;margin:0;padding:0;}
ul li{display:inline-block}
.wrap{width:800px;margin:0 auto}
#notify{position:fixed;top:-68px;z-index:1;width:100%;background:#fcfcfc;color:#aaafbf;border-top:3px solid #aaafbf;border-bottom:1px solid #f3f4f8;}
+#notify.system{top:0%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);-moz-transform:translateX(-50%) translateY(-50%);-o-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);width:500px}
#notify.success{border-top-color:#00b361;color:#00b361}
#notify.warn{border-top-color:#ea9712;color:#ea9712}
#notify.alert{border-top-color:#c1041c;color:#c1041c}
-#notify .icon,#notify p{display:inline-block}
-#notify .icon{font-size:26px;padding:18px;width:38px}
-#notify p{margin-right:10px}
+#notify .icon,#notify p{display:block}
+#notify .icon{font-size:26px;padding:18px;width:38px;float:left}
+#notify p{padding:20px 20px 20px 74px;text-align:justify}
#head{background:#c1041c;height:64px;}
#head #icon{font-size:26px;margin:0;padding:10px 0;line-height:44px;height:44px;width:74px;background:#77000e;display:inline-block;color:#c1041c;margin:0;text-align:center}
#head .q{position:relative;display:inline-block;margin:13px 20px 0 20px;vertical-align:top;}
diff --git a/public/js/app.bundle.js b/public/js/app.bundle.js
index f382941..b282a7d 100644
--- a/public/js/app.bundle.js
+++ b/public/js/app.bundle.js
@@ -40460,7 +40460,7 @@ Router.prototype.mount = function(routes, path) {
// app.coffee
root.require.register('burnchart/src/app.js', function(exports, require, module) {
- var App, Header, Notify, Router, key, _i, _len, _ref;
+ var App, Header, Notify, key, router, _i, _len, _ref;
_ref = ['utils/mixins', 'models/projects'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -40468,12 +40468,12 @@ Router.prototype.mount = function(routes, path) {
require("./" + key);
}
- Router = require('./modules/router');
-
Header = require('./views/header');
Notify = require('./views/notify');
+ router = require('./modules/router');
+
App = Ractive.extend({
'template': require('./templates/layout'),
'components': {
@@ -40481,7 +40481,7 @@ Router.prototype.mount = function(routes, path) {
Notify: Notify
},
init: function() {
- return new Router();
+ return router.init('/');
}
});
@@ -41197,7 +41197,7 @@ Router.prototype.mount = function(routes, path) {
});
};
- router = Router({
+ module.exports = window.router = router = Router({
'/': _.partial(route, 'index'),
'/new/project': _.partial(route, 'new'),
'/:owner/:name': _.partial(route, 'project'),
@@ -41208,16 +41208,14 @@ Router.prototype.mount = function(routes, path) {
},
'/notify': function() {
mediator.fire('!app/loading', true);
- mediator.fire('!app/notify', 'You did something real good', 'warn');
+ mediator.fire('!app/notify', {
+ 'text': 'You have some interesting news in your inbox. Go check it out now.',
+ 'type': 'warn'
+ });
return window.location.hash = '#';
}
});
- module.exports = function() {
- router.init('/');
- return router;
- };
-
});
// header.mustache
@@ -41244,10 +41242,16 @@ Router.prototype.mount = function(routes, path) {
module.exports = ["","","","
"," ","
","",""].join("\n");
});
+ // milestones.mustache
+ root.require.register('burnchart/src/templates/milestones.js', function(exports, require, module) {
+
+ module.exports = ["{{#milestones.length}}"," "," ","","
"," {{#milestones}}"," "," "," {{ title }}"," | "," "," "," {{Math.floor(format.progress(closed_issues, open_issues))}}%"," {{{ format.due(due_on) }}}"," "," "," | ","
"," {{/milestones}}","
",""," ","
","{{/milestones.length}}"].join("\n");
+ });
+
// notify.mustache
root.require.register('burnchart/src/templates/notify.js', function(exports, require, module) {
- module.exports = ["{{#text}}"," ","{{/text}}"].join("\n");
+ module.exports = ["{{#text}}"," {{#system}}"," "," {{else}}"," "," {{/system}}","{{/text}}"].join("\n");
});
// chart.mustache
@@ -41271,13 +41275,13 @@ Router.prototype.mount = function(routes, path) {
// project.mustache
root.require.register('burnchart/src/templates/pages/project.js', function(exports, require, module) {
- module.exports = ["","
","
radekstepan/disposable
"," ","
","",""," Project milestones go here","
"].join("\n");
+ module.exports = ["","
","
{{route.join('/')}}
"," ","
","",""," ","
"].join("\n");
});
// projects.mustache
root.require.register('burnchart/src/templates/projects.js', function(exports, require, module) {
- module.exports = ["{{#projects.list.length}}"," "," ","","
"," {{#projects.list}}"," {{#milestones}}"," "," "," {{owner}}/{{name}}"," | "," "," {{ title }}"," | "," "," "," {{Math.floor(format.progress(closed_issues, open_issues))}}%"," {{{ format.due(due_on) }}}"," "," "," | ","
"," {{/milestones}}"," {{/projects.list}}",""," ","
",""," ","
","{{/projects.list}}"].join("\n");
+ module.exports = ["{{#projects.list.length}}"," "," ","","
"," {{#projects.list}}"," {{#milestones}}"," "," "," {{owner}}/{{name}}"," | "," "," {{ title }}"," | "," "," "," {{Math.floor(format.progress(closed_issues, open_issues))}}%"," {{{ format.due(due_on) }}}"," "," "," | ","
"," {{/milestones}}"," {{/projects.list}}","
",""," ","
","{{/projects.list.length}}","",""].join("\n");
});
// date.coffee
@@ -41479,6 +41483,33 @@ Router.prototype.mount = function(routes, path) {
});
+ // milestones.coffee
+ root.require.register('burnchart/src/views/milestones.js', function(exports, require, module) {
+
+ var Icons, mediator, projects;
+
+ mediator = require('../modules/mediator');
+
+ projects = require('../models/projects');
+
+ Icons = require('./icons');
+
+ module.exports = Ractive.extend({
+ 'template': require('../templates/milestones'),
+ 'components': {
+ Icons: Icons
+ },
+ 'adapt': [Ractive.adaptors.Ractive],
+ init: function() {
+ return this.set('milestones', _.filter(projects.get('list'), {
+ 'owner': this.get('owner'),
+ 'name': this.get('name')
+ }));
+ }
+ });
+
+ });
+
// notify.coffee
root.require.register('burnchart/src/views/notify.js', function(exports, require, module) {
@@ -41496,16 +41527,20 @@ Router.prototype.mount = function(routes, path) {
'top': HEIGHT
},
init: function() {
- var _this = this;
- return mediator.on('!app/notify', function(text, type) {
- if (type == null) {
- type = '';
- }
- _this.set({
- text: text,
- type: type
- });
- _this.animate('top', 0, {
+ var defaults,
+ _this = this;
+ defaults = {
+ 'text': '',
+ 'type': '',
+ 'system': false,
+ 'icon': 'megaphone'
+ };
+ return mediator.on('!app/notify', function(opts) {
+ var pos;
+ opts = _.defaults(opts, defaults);
+ _this.set(opts);
+ pos = [0, 50][+opts.system];
+ _this.animate('top', pos, {
'easing': d3.ease('bounce'),
'duration': 800
});
@@ -41643,30 +41678,18 @@ Router.prototype.mount = function(routes, path) {
// project.coffee
root.require.register('burnchart/src/views/pages/project.js', function(exports, require, module) {
- var Hero, Projects, format;
+ var Milestones;
- Hero = require('../hero');
-
- Projects = require('../projects');
-
- format = require('../../utils/format');
+ Milestones = require('../milestones');
module.exports = Ractive.extend({
'template': require('../../templates/pages/project'),
'components': {
- Hero: Hero,
- Projects: Projects
- },
- 'data': {
- format: format
+ Milestones: Milestones
},
init: function() {
- var name, owner, route, _ref;
+ var name, owner, _ref;
_ref = this.get('route'), owner = _ref[0], name = _ref[1];
- route = {
- owner: owner,
- name: name
- };
return document.title = "" + owner + "/" + name;
}
});
diff --git a/public/js/app.js b/public/js/app.js
index 449dae1..8790e1d 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -7,7 +7,7 @@
// app.coffee
root.require.register('burnchart/src/app.js', function(exports, require, module) {
- var App, Header, Notify, Router, key, _i, _len, _ref;
+ var App, Header, Notify, key, router, _i, _len, _ref;
_ref = ['utils/mixins', 'models/projects'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -15,12 +15,12 @@
require("./" + key);
}
- Router = require('./modules/router');
-
Header = require('./views/header');
Notify = require('./views/notify');
+ router = require('./modules/router');
+
App = Ractive.extend({
'template': require('./templates/layout'),
'components': {
@@ -28,7 +28,7 @@
Notify: Notify
},
init: function() {
- return new Router();
+ return router.init('/');
}
});
@@ -744,7 +744,7 @@
});
};
- router = Router({
+ module.exports = window.router = router = Router({
'/': _.partial(route, 'index'),
'/new/project': _.partial(route, 'new'),
'/:owner/:name': _.partial(route, 'project'),
@@ -755,16 +755,14 @@
},
'/notify': function() {
mediator.fire('!app/loading', true);
- mediator.fire('!app/notify', 'You did something real good', 'warn');
+ mediator.fire('!app/notify', {
+ 'text': 'You have some interesting news in your inbox. Go check it out now.',
+ 'type': 'warn'
+ });
return window.location.hash = '#';
}
});
- module.exports = function() {
- router.init('/');
- return router;
- };
-
});
// header.mustache
@@ -791,10 +789,16 @@
module.exports = ["","","",""," ","
","",""].join("\n");
});
+ // milestones.mustache
+ root.require.register('burnchart/src/templates/milestones.js', function(exports, require, module) {
+
+ module.exports = ["{{#milestones.length}}"," "," ","","
"," {{#milestones}}"," "," "," {{ title }}"," | "," "," "," {{Math.floor(format.progress(closed_issues, open_issues))}}%"," {{{ format.due(due_on) }}}"," "," "," | ","
"," {{/milestones}}","
",""," ","
","{{/milestones.length}}"].join("\n");
+ });
+
// notify.mustache
root.require.register('burnchart/src/templates/notify.js', function(exports, require, module) {
- module.exports = ["{{#text}}"," ","{{/text}}"].join("\n");
+ module.exports = ["{{#text}}"," {{#system}}"," "," {{else}}"," "," {{/system}}","{{/text}}"].join("\n");
});
// chart.mustache
@@ -818,13 +822,13 @@
// project.mustache
root.require.register('burnchart/src/templates/pages/project.js', function(exports, require, module) {
- module.exports = ["","
","
radekstepan/disposable
"," ","
","",""," Project milestones go here","
"].join("\n");
+ module.exports = ["","
","
{{route.join('/')}}
"," ","
","",""," ","
"].join("\n");
});
// projects.mustache
root.require.register('burnchart/src/templates/projects.js', function(exports, require, module) {
- module.exports = ["{{#projects.list.length}}"," "," ","","
"," {{#projects.list}}"," {{#milestones}}"," "," "," {{owner}}/{{name}}"," | "," "," {{ title }}"," | "," "," "," {{Math.floor(format.progress(closed_issues, open_issues))}}%"," {{{ format.due(due_on) }}}"," "," "," | ","
"," {{/milestones}}"," {{/projects.list}}",""," ","
",""," ","
","{{/projects.list}}"].join("\n");
+ module.exports = ["{{#projects.list.length}}"," "," ","","
"," {{#projects.list}}"," {{#milestones}}"," "," "," {{owner}}/{{name}}"," | "," "," {{ title }}"," | "," "," "," {{Math.floor(format.progress(closed_issues, open_issues))}}%"," {{{ format.due(due_on) }}}"," "," "," | ","
"," {{/milestones}}"," {{/projects.list}}","
",""," ","
","{{/projects.list.length}}","",""].join("\n");
});
// date.coffee
@@ -1026,6 +1030,33 @@
});
+ // milestones.coffee
+ root.require.register('burnchart/src/views/milestones.js', function(exports, require, module) {
+
+ var Icons, mediator, projects;
+
+ mediator = require('../modules/mediator');
+
+ projects = require('../models/projects');
+
+ Icons = require('./icons');
+
+ module.exports = Ractive.extend({
+ 'template': require('../templates/milestones'),
+ 'components': {
+ Icons: Icons
+ },
+ 'adapt': [Ractive.adaptors.Ractive],
+ init: function() {
+ return this.set('milestones', _.filter(projects.get('list'), {
+ 'owner': this.get('owner'),
+ 'name': this.get('name')
+ }));
+ }
+ });
+
+ });
+
// notify.coffee
root.require.register('burnchart/src/views/notify.js', function(exports, require, module) {
@@ -1043,16 +1074,20 @@
'top': HEIGHT
},
init: function() {
- var _this = this;
- return mediator.on('!app/notify', function(text, type) {
- if (type == null) {
- type = '';
- }
- _this.set({
- text: text,
- type: type
- });
- _this.animate('top', 0, {
+ var defaults,
+ _this = this;
+ defaults = {
+ 'text': '',
+ 'type': '',
+ 'system': false,
+ 'icon': 'megaphone'
+ };
+ return mediator.on('!app/notify', function(opts) {
+ var pos;
+ opts = _.defaults(opts, defaults);
+ _this.set(opts);
+ pos = [0, 50][+opts.system];
+ _this.animate('top', pos, {
'easing': d3.ease('bounce'),
'duration': 800
});
@@ -1190,30 +1225,18 @@
// project.coffee
root.require.register('burnchart/src/views/pages/project.js', function(exports, require, module) {
- var Hero, Projects, format;
+ var Milestones;
- Hero = require('../hero');
-
- Projects = require('../projects');
-
- format = require('../../utils/format');
+ Milestones = require('../milestones');
module.exports = Ractive.extend({
'template': require('../../templates/pages/project'),
'components': {
- Hero: Hero,
- Projects: Projects
- },
- 'data': {
- format: format
+ Milestones: Milestones
},
init: function() {
- var name, owner, route, _ref;
+ var name, owner, _ref;
_ref = this.get('route'), owner = _ref[0], name = _ref[1];
- route = {
- owner: owner,
- name: name
- };
return document.title = "" + owner + "/" + name;
}
});
diff --git a/src/app.coffee b/src/app.coffee
index 832a300..5e2e69b 100644
--- a/src/app.coffee
+++ b/src/app.coffee
@@ -4,9 +4,9 @@
] )
-Router = require './modules/router'
Header = require './views/header'
Notify = require './views/notify'
+router = require './modules/router'
App = Ractive.extend
@@ -15,6 +15,6 @@ App = Ractive.extend
'components': { Header, Notify }
init: ->
- new Router()
+ router.init '/'
module.exports = new App()
\ No newline at end of file
diff --git a/src/modules/router.coffee b/src/modules/router.coffee
index 2abb928..b7489a1 100644
--- a/src/modules/router.coffee
+++ b/src/modules/router.coffee
@@ -6,7 +6,7 @@ route = (page, args...) ->
Page = require "../views/pages/#{page}"
new Page { el, 'data': { 'route': args } }
-router = Router
+module.exports = window.router = router = Router
'/': _.partial route, 'index'
'/new/project': _.partial route, 'new'
'/:owner/:name': _.partial route, 'project'
@@ -17,10 +17,7 @@ router = Router
window.location.hash = '#'
'/notify': ->
mediator.fire '!app/loading', yes
- mediator.fire '!app/notify', 'You did something real good', 'warn'
- window.location.hash = '#'
-
-module.exports = ->
- # Init the routes.
- router.init '/'
- router
\ No newline at end of file
+ mediator.fire '!app/notify',
+ 'text': 'You have some interesting news in your inbox. Go check it out now.'
+ 'type': 'warn'
+ window.location.hash = '#'
\ No newline at end of file
diff --git a/src/styles/app.styl b/src/styles/app.styl
index 250828a..4ea328e 100644
--- a/src/styles/app.styl
+++ b/src/styles/app.styl
@@ -40,6 +40,13 @@ ul
border-top: 3px solid #AAAFBF
border-bottom: 1px solid #F3F4F8
+ // system-wide notification
+ &.system
+ top: 0% // hide from view
+ left: 50%
+ transform: translateX(-50%) translateY(-50%)
+ width: 500px
+
&.success
border-top-color: #00B361
color: #00B361
@@ -53,15 +60,17 @@ ul
color: $strong_color
.icon, p
- display: inline-block
+ display: block
.icon
font-size: 26px
padding: 18px
width: 38px
+ float: left
p
- margin-right: 10px
+ padding: 20px 20px 20px 74px
+ text-align: justify
#head
background: $strong_color
diff --git a/src/templates/milestones.mustache b/src/templates/milestones.mustache
new file mode 100644
index 0000000..84cd6a7
--- /dev/null
+++ b/src/templates/milestones.mustache
@@ -0,0 +1,31 @@
+{{#milestones.length}}
+
+
+
+
+ {{#milestones}}
+
+
+ {{ title }}
+ |
+
+
+ {{Math.floor(format.progress(closed_issues, open_issues))}}%
+ {{{ format.due(due_on) }}}
+
+
+ |
+
+ {{/milestones}}
+
+
+
+
+{{/milestones.length}}
\ No newline at end of file
diff --git a/src/templates/notify.mustache b/src/templates/notify.mustache
index d38d846..c0fe1b5 100644
--- a/src/templates/notify.mustache
+++ b/src/templates/notify.mustache
@@ -1,6 +1,13 @@
{{#text}}
-
+ {{#system}}
+
+ {{else}}
+
+ {{/system}}
{{/text}}
\ No newline at end of file
diff --git a/src/templates/pages/project.mustache b/src/templates/pages/project.mustache
index bf37e56..efd7761 100644
--- a/src/templates/pages/project.mustache
+++ b/src/templates/pages/project.mustache
@@ -1,9 +1,9 @@
-
radekstepan/disposable
+ {{route.join('/')}}
- Project milestones go here
+
\ No newline at end of file
diff --git a/src/templates/projects.mustache b/src/templates/projects.mustache
index c2c55e4..e55e8cc 100644
--- a/src/templates/projects.mustache
+++ b/src/templates/projects.mustache
@@ -15,7 +15,7 @@
{{ title }}
|
-
+ |
{{Math.floor(format.progress(closed_issues, open_issues))}}%
{{{ format.due(due_on) }}}
@@ -27,65 +27,65 @@
{{/milestones}}
{{/projects.list}}
-
-
-{{/projects.list}}
\ No newline at end of file
+{{/projects.list.length}}
+
+
\ No newline at end of file
diff --git a/src/views/milestones.coffee b/src/views/milestones.coffee
new file mode 100644
index 0000000..8f3c999
--- /dev/null
+++ b/src/views/milestones.coffee
@@ -0,0 +1,16 @@
+mediator = require '../modules/mediator'
+projects = require '../models/projects'
+Icons = require './icons'
+
+module.exports = Ractive.extend
+
+ 'template': require '../templates/milestones'
+
+ 'components': { Icons }
+
+ 'adapt': [ Ractive.adaptors.Ractive ]
+
+ init: ->
+ @set 'milestones', _.filter projects.get('list'),
+ 'owner': @get 'owner'
+ 'name': @get 'name'
\ No newline at end of file
diff --git a/src/views/notify.coffee b/src/views/notify.coffee
index a05bd17..e654cf2 100644
--- a/src/views/notify.coffee
+++ b/src/views/notify.coffee
@@ -11,18 +11,35 @@ module.exports = Ractive.extend
'top': HEIGHT
init: ->
- # Save the notify text on us.
- mediator.on '!app/notify', (text, type='') =>
- @set { text, type }
- @animate 'top', 0, # slide to view
+ defaults =
+ 'text': ''
+ 'type': ''
+ 'system': no
+ 'icon': 'megaphone'
+
+ # Animate.
+ # type: alert/warn/success
+ # system: yes/no
+ mediator.on '!app/notify', (opts) =>
+ opts = _.defaults opts, defaults
+
+ # Set the text.
+ @set opts
+ # Which position to slide to?
+ pos = [ 0, 50 ][ +opts.system ] # 0px or 50% from top
+ # Slide into view.
+ @animate 'top', pos,
'easing': d3.ease('bounce')
'duration': 800
_.delay =>
- @animate 'top', HEIGHT, # slide out of view
+ # Slide out of the view.
+ @animate 'top', HEIGHT,
'easing': d3.ease('back')
'complete': =>
- @set 'text', null # reset
- , 5e3 # ttl
+ # Reset the text when all is done.
+ @set 'text', null
+ # Ttl.
+ , 5e3
'components': { Icons }
diff --git a/src/views/pages/project.coffee b/src/views/pages/project.coffee
index 5a48e9d..cc52706 100644
--- a/src/views/pages/project.coffee
+++ b/src/views/pages/project.coffee
@@ -1,17 +1,12 @@
-Hero = require '../hero'
-Projects = require '../projects'
-format = require '../../utils/format'
+Milestones = require '../milestones'
module.exports = Ractive.extend
'template': require '../../templates/pages/project'
- 'components': { Hero, Projects }
-
- 'data': { format }
+ 'components': { Milestones }
init: ->
[ owner, name ] = @get 'route'
- route = { owner, name }
document.title = "#{owner}/#{name}"
\ No newline at end of file
|