add project ui

This commit is contained in:
Radek Stepan 2014-09-01 21:54:20 -07:00
parent 3115872d4b
commit 0a355c690d
9 changed files with 110 additions and 65 deletions

View File

@ -1,5 +1,57 @@
# burnchart # burnchart
1. Do not show login/logged-in state when we are still fetching that information from Firebase ## Concept
1. Handle 404 on routes; from catch all check if '/' or go 404 controller
1. Variable document.title on different pages GitHub Burndown Chart as a service. Public repos are free, for private access auth via GitHub and pay.
## Name
charcoal, charriot
- gurndown [.com/.io] github burndown
- bithubchart [.com/.io] burndown github chart
- burnchart [.io]
## Tasks
### MVP
[ ] landing page allows you to immediately jump into action
[ ] past repos are cached remotely or in localStorage
[ ] show chart for the current milestone or choose a custom one
[ ] be able to config options through UI that currently have to be hardcoded in config
[ ] embed user tracking
[ ] sort projects based on their closest due dates
[ ] show only repo name if all projects are under our name
[ ] rotate between percentage progress and points left
[ ] Send notifications to people like Codeship or have our own delivery system perhaps like Github or just show a notification icon and onclick ask people to upgrade
### Extras
[ ] choose your own strategy for naming issues, e.g. all issues are one size
[ ] choose your own theme
[ ] custom milestone start dates
[ ] show burndown chart for all milestones
[ ] handle Enterprise editions of GH
[ ] auto-update the chart (with delay when no activity) when logged-in
[ ] show a countdown clock towards the end of the milestone or show overdue
[ ] add weekly velocity across all projects and a bar chart to that effect
[ ] show a little lightning and a number for today's velocity
[ ] show burnchart only for your tasks; this would be a second category of projects & tasks in the dashboard
[ ] show an overall text-based status like: all projects on time etc.
[ ] until GH fix milestone start date then provide an option to specify it (either do that on GH server or locally)
[ ] work on mobile devices
[ ] show velocity number for each member of the team in the corner of the layout
[ ] show velocity for all team members and how it progresses through time
[ ] points collector - give medals for 1st 3 spots in terms of velocity
[ ] Do not show login/logged-in state when we are still fetching that information from Firebase
[ ] Handle 404 on routes; from catch all check if '/' or go 404 controller
[ ] Variable document.title on different pages
[ ] In add a project form autocomplete on my username, orgs I am member of and repos I have access to
[ ] Someone might create a public repo, add it to the system and switch it to private; need to check repo priviledges at runtime; or when asking for auth, one would choose either public OR public/private, but this could get confusign.
## Notes
- *payment gateways* in Canada: http://www.shopify.com/payment-gateways/canada
- start people on a *Startup* plan showing them a comparison table to upgrade to a better offering
- Startup, small business and enterprise plans

View File

@ -437,7 +437,7 @@ table {
100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)} 100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}
} }
body{color:#3e4457;font-family:'MuseoSans500Regular',sans-serif} body{color:#3e4457;font-family:'MuseoSans500Regular',sans-serif}
a{text-decoration:none;color:#aaafbf} a{text-decoration:none;color:#aaafbf;cursor:pointer}
h1,h2,h3,p{margin:0} h1,h2,h3,p{margin:0}
ul{list-style-type:none;margin:0;padding:0;} ul{list-style-type:none;margin:0;padding:0;}
ul li{display:inline-block} ul li{display:inline-block}
@ -471,20 +471,14 @@ ul li{display:inline-block}
#content #hero .content .cta a{font-family:'MuseoSlab500Regular',serif;padding:11px 20px;-webkit-border-radius:2px;border-radius:2px;display:inline-block;margin:0 4px;} #content #hero .content .cta a{font-family:'MuseoSlab500Regular',serif;padding:11px 20px;-webkit-border-radius:2px;border-radius:2px;display:inline-block;margin:0 4px;}
#content #hero .content .cta a.primary{font-weight:bold;background:#c1041c;color:#fff} #content #hero .content .cta a.primary{font-weight:bold;background:#c1041c;color:#fff}
#content #hero .content .cta a.secondary{background:#fff;color:#c1041c} #content #hero .content .cta a.secondary{background:#fff;color:#c1041c}
#content #add{border:1px solid #cdcecf;-webkit-border-radius:2px;border-radius:2px;background:#fff;width:400px;}
#content #add h2{color:#3e4457} #content #add h2{color:#3e4457}
#content #add p{font-family:'MuseoSlab500Regular',serif;color:#b1b6c4;margin-top:10px;line-height:20px;text-align:justify;text-justify:inter-word;} #content #add p{font-family:'MuseoSlab500Regular',serif;color:#b1b6c4;margin-top:10px;line-height:20px;text-align:justify;text-justify:inter-word;}
#content #add p a{color:#3e4457} #content #add p a{color:#3e4457}
#content #add .form{padding:20px;} #content #add .form{margin-top:20px;}
#content #add .form table{width:100%;} #content #add .form table{width:100%;}
#content #add .form table tr td:first-child{width:100%} #content #add .form table tr td:first-child{width:100%}
#content #add .form input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:10px;width:100%;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px;border:1px solid #dde1ed;border-right:0;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.2);box-shadow:inset 0 1px 2px rgba(0,0,0,0.2)} #content #add .form input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:10px;width:100%;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px;border:1px solid #dde1ed;border-right:0;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.2);box-shadow:inset 0 1px 2px rgba(0,0,0,0.2)}
#content #add .form a{margin-left:-2px;font-family:'MuseoSlab500Regular',serif;padding:11px 20px;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;display:inline-block;font-weight:bold;background:#c1041c;color:#fff} #content #add .form a{margin-left:-2px;font-family:'MuseoSlab500Regular',serif;padding:11px 20px;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;display:inline-block;font-weight:bold;background:#c1041c;color:#fff}
#content #add .header,#content #add .footer{padding:20px 30px}
#content #add .header{-webkit-box-shadow:0 1px 2px rgba(221,225,237,0.5);box-shadow:0 1px 2px rgba(221,225,237,0.5);margin-bottom:2px;border-bottom:1px solid #dde1ed;}
#content #add .header a{font-family:'MuseoSlab500Regular',serif}
#content #add .footer{background:#f9fafb;color:#aaafbf;-webkit-box-shadow:inset 0 1px 2px rgba(221,225,237,0.2);box-shadow:inset 0 1px 2px rgba(221,225,237,0.2);border-top:1px solid #dde1ed;text-align:center;font-family:'MuseoSlab500Regular',serif;}
#content #add .footer .icon{display:inline-block;color:#aaafbf}
#content #repos{border:1px solid #cdcecf;-webkit-border-radius:2px;border-radius:2px;} #content #repos{border:1px solid #cdcecf;-webkit-border-radius:2px;border-radius:2px;}
#content #repos h2{color:#3e4457;display:inline-block} #content #repos h2{color:#3e4457;display:inline-block}
#content #repos .sort{float:right;line-height:30px} #content #repos .sort{float:right;line-height:30px}

View File

@ -30,7 +30,7 @@
100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)} 100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}
} }
body{color:#3e4457;font-family:'MuseoSans500Regular',sans-serif} body{color:#3e4457;font-family:'MuseoSans500Regular',sans-serif}
a{text-decoration:none;color:#aaafbf} a{text-decoration:none;color:#aaafbf;cursor:pointer}
h1,h2,h3,p{margin:0} h1,h2,h3,p{margin:0}
ul{list-style-type:none;margin:0;padding:0;} ul{list-style-type:none;margin:0;padding:0;}
ul li{display:inline-block} ul li{display:inline-block}
@ -64,20 +64,14 @@ ul li{display:inline-block}
#content #hero .content .cta a{font-family:'MuseoSlab500Regular',serif;padding:11px 20px;-webkit-border-radius:2px;border-radius:2px;display:inline-block;margin:0 4px;} #content #hero .content .cta a{font-family:'MuseoSlab500Regular',serif;padding:11px 20px;-webkit-border-radius:2px;border-radius:2px;display:inline-block;margin:0 4px;}
#content #hero .content .cta a.primary{font-weight:bold;background:#c1041c;color:#fff} #content #hero .content .cta a.primary{font-weight:bold;background:#c1041c;color:#fff}
#content #hero .content .cta a.secondary{background:#fff;color:#c1041c} #content #hero .content .cta a.secondary{background:#fff;color:#c1041c}
#content #add{border:1px solid #cdcecf;-webkit-border-radius:2px;border-radius:2px;background:#fff;width:400px;}
#content #add h2{color:#3e4457} #content #add h2{color:#3e4457}
#content #add p{font-family:'MuseoSlab500Regular',serif;color:#b1b6c4;margin-top:10px;line-height:20px;text-align:justify;text-justify:inter-word;} #content #add p{font-family:'MuseoSlab500Regular',serif;color:#b1b6c4;margin-top:10px;line-height:20px;text-align:justify;text-justify:inter-word;}
#content #add p a{color:#3e4457} #content #add p a{color:#3e4457}
#content #add .form{padding:20px;} #content #add .form{margin-top:20px;}
#content #add .form table{width:100%;} #content #add .form table{width:100%;}
#content #add .form table tr td:first-child{width:100%} #content #add .form table tr td:first-child{width:100%}
#content #add .form input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:10px;width:100%;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px;border:1px solid #dde1ed;border-right:0;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.2);box-shadow:inset 0 1px 2px rgba(0,0,0,0.2)} #content #add .form input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:10px;width:100%;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px;border:1px solid #dde1ed;border-right:0;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.2);box-shadow:inset 0 1px 2px rgba(0,0,0,0.2)}
#content #add .form a{margin-left:-2px;font-family:'MuseoSlab500Regular',serif;padding:11px 20px;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;display:inline-block;font-weight:bold;background:#c1041c;color:#fff} #content #add .form a{margin-left:-2px;font-family:'MuseoSlab500Regular',serif;padding:11px 20px;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;display:inline-block;font-weight:bold;background:#c1041c;color:#fff}
#content #add .header,#content #add .footer{padding:20px 30px}
#content #add .header{-webkit-box-shadow:0 1px 2px rgba(221,225,237,0.5);box-shadow:0 1px 2px rgba(221,225,237,0.5);margin-bottom:2px;border-bottom:1px solid #dde1ed;}
#content #add .header a{font-family:'MuseoSlab500Regular',serif}
#content #add .footer{background:#f9fafb;color:#aaafbf;-webkit-box-shadow:inset 0 1px 2px rgba(221,225,237,0.2);box-shadow:inset 0 1px 2px rgba(221,225,237,0.2);border-top:1px solid #dde1ed;text-align:center;font-family:'MuseoSlab500Regular',serif;}
#content #add .footer .icon{display:inline-block;color:#aaafbf}
#content #repos{border:1px solid #cdcecf;-webkit-border-radius:2px;border-radius:2px;} #content #repos{border:1px solid #cdcecf;-webkit-border-radius:2px;border-radius:2px;}
#content #repos h2{color:#3e4457;display:inline-block} #content #repos h2{color:#3e4457;display:inline-block}
#content #repos .sort{float:right;line-height:30px} #content #repos .sort{float:right;line-height:30px}

View File

@ -21536,9 +21536,22 @@ goog.exportProperty(FirebaseSimpleLogin,"onOpen",FirebaseSimpleLogin.onOpen);Fir
module.exports = Ractive.extend({ module.exports = Ractive.extend({
'template': require('../templates/addProjectForm'), 'template': require('../templates/addProjectForm'),
'data': { 'data': {
'user': user 'user': user,
'value': null
}, },
'adapt': [Ractive.adaptors.Ractive] 'adapt': [Ractive.adaptors.Ractive],
init: function() {
var autocomplete;
autocomplete = function(value) {
return console.log('Autocomplete', value);
};
this.observe('value', _.debounce(autocomplete, 200), {
'init': false
});
return this.on('submit', function() {
return console.log('Submit the form with', this.get('value'));
});
}
}); });
}); });
@ -21679,13 +21692,13 @@ goog.exportProperty(FirebaseSimpleLogin,"onOpen",FirebaseSimpleLogin.onOpen);Fir
// addProjectForm.mustache // addProjectForm.mustache
root.require.register('burnchart/src/templates/addProjectForm.js', function(exports, require, module) { root.require.register('burnchart/src/templates/addProjectForm.js', function(exports, require, module) {
module.exports = ["<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\">"," </td>"," <td>"," <a href=\"#\">Add</a>"," </td>"," </tr>"," </table>"," </div>",""," <div class=\"footer\">"," <span class=\"icon spin6\"></span> Connecting to your repo."," </div>","</div>"].join("\n"); module.exports = ["<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>"].join("\n");
}); });
// header.mustache // header.mustache
root.require.register('burnchart/src/templates/header.js', function(exports, require, module) { root.require.register('burnchart/src/templates/header.js', function(exports, require, module) {
module.exports = ["<div id=\"head\">"," <div class=\"right\">"," {{#user.displayName}}"," {{user.displayName}} logged in"," {{else}}"," <a href=\"#\" class=\"github\" on-click=\"!login\"><span class=\"icon github\"></span> Sign In</a>"," {{/user.displayName}}"," </div>",""," <h1><span class=\"icon fire-station\"></span></h1>",""," <div class=\"q\">"," <span class=\"icon search\"></span>"," <span class=\"icon down-open\"></span>"," <input type=\"text\" placeholder=\"Jump to...\">"," </div>",""," <ul>"," <li><a href=\"#project/add\" class=\"add\"><span class=\"icon plus-circled\"></span> Add a Project</a></li>"," <li><a href=\"#\" class=\"faq\">FAQ</a></li>"," </ul>","</div>"].join("\n"); module.exports = ["<div id=\"head\">"," <div class=\"right\">"," {{#user.displayName}}"," {{user.displayName}} logged in"," {{else}}"," <a class=\"github\" on-click=\"!login\"><span class=\"icon github\"></span> Sign In</a>"," {{/user.displayName}}"," </div>",""," <h1><span class=\"icon fire-station\"></span></h1>",""," <div class=\"q\">"," <span class=\"icon search\"></span>"," <span class=\"icon down-open\"></span>"," <input type=\"text\" placeholder=\"Jump to...\">"," </div>",""," <ul>"," <li><a href=\"#project/add\" class=\"add\"><span class=\"icon plus-circled\"></span> Add a Project</a></li>"," <li><a href=\"#\" class=\"faq\">FAQ</a></li>"," </ul>","</div>"].join("\n");
}); });
// layout.mustache // layout.mustache

View File

@ -57,9 +57,22 @@
module.exports = Ractive.extend({ module.exports = Ractive.extend({
'template': require('../templates/addProjectForm'), 'template': require('../templates/addProjectForm'),
'data': { 'data': {
'user': user 'user': user,
'value': null
}, },
'adapt': [Ractive.adaptors.Ractive] 'adapt': [Ractive.adaptors.Ractive],
init: function() {
var autocomplete;
autocomplete = function(value) {
return console.log('Autocomplete', value);
};
this.observe('value', _.debounce(autocomplete, 200), {
'init': false
});
return this.on('submit', function() {
return console.log('Submit the form with', this.get('value'));
});
}
}); });
}); });
@ -200,13 +213,13 @@
// addProjectForm.mustache // addProjectForm.mustache
root.require.register('burnchart/src/templates/addProjectForm.js', function(exports, require, module) { root.require.register('burnchart/src/templates/addProjectForm.js', function(exports, require, module) {
module.exports = ["<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\">"," </td>"," <td>"," <a href=\"#\">Add</a>"," </td>"," </tr>"," </table>"," </div>",""," <div class=\"footer\">"," <span class=\"icon spin6\"></span> Connecting to your repo."," </div>","</div>"].join("\n"); module.exports = ["<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>"].join("\n");
}); });
// header.mustache // header.mustache
root.require.register('burnchart/src/templates/header.js', function(exports, require, module) { root.require.register('burnchart/src/templates/header.js', function(exports, require, module) {
module.exports = ["<div id=\"head\">"," <div class=\"right\">"," {{#user.displayName}}"," {{user.displayName}} logged in"," {{else}}"," <a href=\"#\" class=\"github\" on-click=\"!login\"><span class=\"icon github\"></span> Sign In</a>"," {{/user.displayName}}"," </div>",""," <h1><span class=\"icon fire-station\"></span></h1>",""," <div class=\"q\">"," <span class=\"icon search\"></span>"," <span class=\"icon down-open\"></span>"," <input type=\"text\" placeholder=\"Jump to...\">"," </div>",""," <ul>"," <li><a href=\"#project/add\" class=\"add\"><span class=\"icon plus-circled\"></span> Add a Project</a></li>"," <li><a href=\"#\" class=\"faq\">FAQ</a></li>"," </ul>","</div>"].join("\n"); module.exports = ["<div id=\"head\">"," <div class=\"right\">"," {{#user.displayName}}"," {{user.displayName}} logged in"," {{else}}"," <a class=\"github\" on-click=\"!login\"><span class=\"icon github\"></span> Sign In</a>"," {{/user.displayName}}"," </div>",""," <h1><span class=\"icon fire-station\"></span></h1>",""," <div class=\"q\">"," <span class=\"icon search\"></span>"," <span class=\"icon down-open\"></span>"," <input type=\"text\" placeholder=\"Jump to...\">"," </div>",""," <ul>"," <li><a href=\"#project/add\" class=\"add\"><span class=\"icon plus-circled\"></span> Add a Project</a></li>"," <li><a href=\"#\" class=\"faq\">FAQ</a></li>"," </ul>","</div>"].join("\n");
}); });
// layout.mustache // layout.mustache

View File

@ -8,5 +8,15 @@ module.exports = Ractive.extend
'data': 'data':
'user': user 'user': user
'value': null
'adapt': [ Ractive.adaptors.Ractive ] 'adapt': [ Ractive.adaptors.Ractive ]
init: ->
autocomplete = (value) ->
console.log 'Autocomplete', value
@observe 'value', _.debounce(autocomplete, 200), { 'init': no }
@on 'submit', ->
console.log 'Submit the form with', @get('value')

View File

@ -13,6 +13,7 @@ body
a a
text-decoration: none text-decoration: none
color: #AAAFBF color: #AAAFBF
cursor: pointer
h1, h2, h3, p h1, h2, h3, p
margin: 0 margin: 0
@ -173,11 +174,6 @@ ul
color: $strong_color color: $strong_color
#add #add
border: 1px solid #CDCECF
border-radius: 2px
background: #FFF
width: 400px
h2 h2
color: #3E4457 color: #3E4457
@ -193,8 +189,8 @@ ul
color: #3E4457 color: #3E4457
.form .form
padding: 20px margin-top: 20px
table table
width: 100% width: 100%
@ -222,29 +218,6 @@ ul
background: $strong_color background: $strong_color
color: #FFF color: #FFF
.header, .footer
padding: 20px 30px
.header
box-shadow: 0 1px 2px rgba(#DDE1ED, 50%)
margin-bottom: 2px
border-bottom: 1px solid #DDE1ED
a
font-family: $serif_font
.footer
background: #F9FAFB
color: #AAAFBF
box-shadow: inset 0 1px 2px rgba(#DDE1ED, 20%)
border-top: 1px solid #DDE1ED
text-align: center
font-family: $serif_font
.icon
display: inline-block
color: #AAAFBF
#repos #repos
border: 1px solid #CDCECF border: 1px solid #CDCECF
border-radius: 2px border-radius: 2px

View File

@ -8,16 +8,12 @@
<table> <table>
<tr> <tr>
<td> <td>
<input type="text" placeholder="user/repo" autocomplete="off"> <input type="text" placeholder="user/repo" autocomplete="off" value="{{value}}">
</td> </td>
<td> <td>
<a href="#">Add</a> <a on-click="submit">Add</a>
</td> </td>
</tr> </tr>
</table> </table>
</div> </div>
<div class="footer">
<span class="icon spin6"></span> Connecting to your repo.
</div>
</div> </div>

View File

@ -3,7 +3,7 @@
{{#user.displayName}} {{#user.displayName}}
{{user.displayName}} logged in {{user.displayName}} logged in
{{else}} {{else}}
<a href="#" class="github" on-click="!login"><span class="icon github"></span> Sign In</a> <a class="github" on-click="!login"><span class="icon github"></span> Sign In</a>
{{/user.displayName}} {{/user.displayName}}
</div> </div>