seemingly working adding of errors and stats
This commit is contained in:
parent
5d6bed2759
commit
367f26e517
4
Makefile
4
Makefile
|
@ -6,10 +6,6 @@ build:
|
|||
./node_modules/.bin/browserify -e ./src/app.coffee -o public/js/app.js -d
|
||||
grunt
|
||||
|
||||
watch:
|
||||
grunt
|
||||
grunt watchify
|
||||
|
||||
serve:
|
||||
cd public; python -m SimpleHTTPServer 8000
|
||||
|
||||
|
|
2
TODO.md
2
TODO.md
|
@ -3,7 +3,7 @@
|
|||
##Release: Assembly
|
||||
|
||||
- [ ] use Browserify as an app build pipeline
|
||||
- [ ] sort milestones on index and project page based on priority (most delayed first); Trend - actual = different in days and those overdue come first
|
||||
- [ ] sort milestones on index and project page based on priority (most delayed first); Trend - actual = difference in days and those overdue come first
|
||||
|
||||
1. in a projects collection observe the list prop and resort index; already sorted flag passed in as yes)
|
||||
1. The index is not already sorted when sort order changes
|
||||
|
|
322
public/js/app.js
322
public/js/app.js
File diff suppressed because one or more lines are too long
|
@ -2,6 +2,7 @@
|
|||
|
||||
config = require '../models/config.coffee'
|
||||
mediator = require '../modules/mediator.coffee'
|
||||
stats = require '../modules/stats.coffee'
|
||||
Model = require '../utils/model.coffee'
|
||||
date = require '../utils/date.coffee'
|
||||
search = require '../utils/search.coffee'
|
||||
|
@ -12,7 +13,7 @@ module.exports = new Model
|
|||
'name': 'models/projects'
|
||||
|
||||
'data':
|
||||
'sortKey': 'priority'
|
||||
'sortBy': 'priority'
|
||||
|
||||
find: (project) ->
|
||||
_.find @data.list, project
|
||||
|
@ -24,15 +25,34 @@ module.exports = new Model
|
|||
add: (project) ->
|
||||
@push 'list', project unless @exists project
|
||||
|
||||
# Find index of a project.
|
||||
findIndex: ({ owner, name }) ->
|
||||
_.findIndex @data.list, { owner, name }
|
||||
|
||||
addMilestone: (project, milestone) ->
|
||||
if (idx = _.findIndex(@data.list, project)) > -1
|
||||
# Add in the stats.
|
||||
_.extend milestone, { 'stats': stats(milestone) }
|
||||
|
||||
if (idx = @findIndex(project)) > -1
|
||||
if project.milestones?
|
||||
@push "list.#{idx}.milestones", milestone
|
||||
else
|
||||
@set "list.#{idx}.milestones", [ milestone ]
|
||||
else
|
||||
# We are supposed to exist already.
|
||||
throw 500
|
||||
|
||||
# Save an error from loading milestones or issues
|
||||
saveError: (project, err) ->
|
||||
if (idx = @findIndex(project)) > -1
|
||||
if project.errors?
|
||||
@push "list.#{idx}.errors", err
|
||||
else
|
||||
@set "list.#{idx}.errors", [ err ]
|
||||
else
|
||||
# We are supposed to exist already.
|
||||
throw 500
|
||||
|
||||
clear: ->
|
||||
@set 'list', []
|
||||
|
||||
|
@ -42,9 +62,10 @@ module.exports = new Model
|
|||
index = @data.index or []
|
||||
|
||||
for p in @data.list
|
||||
continue unless p.milestones?
|
||||
for m in p.milestones
|
||||
# Run a comparator here inserting into index.
|
||||
@data.sortKey
|
||||
console.log @data.sortBy, m
|
||||
|
||||
# Save the index.
|
||||
@set 'index', index
|
||||
|
@ -67,6 +88,6 @@ module.exports = new Model
|
|||
# Reset our index and re-sort.
|
||||
@observe 'sortKey', ->
|
||||
# Use pop as Ractive is glitchy.
|
||||
@pop 'index' while @data.index.length
|
||||
( @pop 'index' while @data.index.length ) if @data.index?
|
||||
# Run the sort again.
|
||||
do @sort
|
|
@ -116,10 +116,10 @@ module.exports =
|
|||
|
||||
[
|
||||
{
|
||||
date: created_at
|
||||
points: fn(a)
|
||||
'date': created_at
|
||||
'points': fn(a)
|
||||
}, {
|
||||
date: due_on
|
||||
points: fn(b)
|
||||
'date': due_on
|
||||
'points': fn(b)
|
||||
}
|
||||
]
|
|
@ -0,0 +1,25 @@
|
|||
# Progress in %.
|
||||
progress = (a, b) -> 100 * (a / (b + a))
|
||||
|
||||
# Calculate the stats for a milestone.
|
||||
# Is it on time? What is the progress?
|
||||
module.exports = (milestone) ->
|
||||
# Progress in points.
|
||||
points = progress milestone.issues.closed.size, milestone.issues.open.size
|
||||
|
||||
# Milestones with no due date are always on track.
|
||||
return { 'isOnTime': yes, 'progress': { points } } unless milestone.due_on
|
||||
|
||||
a = +new Date milestone.created_at
|
||||
b = +new Date
|
||||
c = +new Date milestone.due_on
|
||||
|
||||
# Progress in time.
|
||||
time = progress b - a, c - b
|
||||
|
||||
isOnTime = points > time
|
||||
|
||||
{
|
||||
'isOnTime': isOnTime
|
||||
'progress': { points, time }
|
||||
}
|
|
@ -12,10 +12,10 @@
|
|||
</td>
|
||||
<td style="width:1%">
|
||||
<div class="progress">
|
||||
<span class="percent">{{Math.floor(format.progress(issues.closed.size, issues.open.size))}}%</span>
|
||||
<span class="percent">{{Math.floor(stats.progress.points)}}%</span>
|
||||
<span class="due">{{{ format.due(due_on) }}}</span>
|
||||
<div class="outer bar">
|
||||
<div class="inner bar {{format.onTime(number, due_on, created_at, issues.closed.size, issues.open.size)}}" style="width:{{format.progress(issues.closed.size, issues.open.size)}}%"></div>
|
||||
<div class="inner bar {{(stats.isOnTime) ? 'green' : 'red'}}" style="width:{{stats.progress.points}}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
<table>
|
||||
{{#projects.list}}
|
||||
{{#if error}}
|
||||
{{#if errors}}
|
||||
<tr>
|
||||
<td colspan="3" class="repo">
|
||||
<div class="project">{{owner}}/{{name}} <span class="error" title="{{error}}"><Icons icon="attention"/></span></div>
|
||||
<div class="project">{{owner}}/{{name}} <span class="error" title="{{errors.join('\n')}}"><Icons icon="attention"/></span></div>
|
||||
</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
|
@ -23,10 +23,10 @@
|
|||
</td>
|
||||
<td style="width:1%">
|
||||
<div class="progress">
|
||||
<span class="percent">{{Math.floor(format.progress(issues.closed.size, issues.open.size))}}%</span>
|
||||
<span class="percent">{{Math.floor(stats.progress.points)}}%</span>
|
||||
<span class="due">{{{ format.due(due_on) }}}</span>
|
||||
<div class="outer bar">
|
||||
<div class="inner bar {{format.onTime(number, due_on, created_at, issues.closed.size, issues.open.size)}}" style="width:{{format.progress(issues.closed.size, issues.open.size)}}%"></div>
|
||||
<div class="inner bar {{(stats.isOnTime) ? 'green' : 'red'}}" style="width:{{stats.progress.points}}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
|
|
@ -2,48 +2,26 @@
|
|||
|
||||
module.exports =
|
||||
|
||||
# Progress in percentages.
|
||||
'progress': _.memoize (a, b) ->
|
||||
100 * (a / (b + a))
|
||||
|
||||
# Is a milestone on time?
|
||||
'onTime': _.memoize (number, due_on, created_at, closed_size, open_size) ->
|
||||
# Milestones with no due date are always on track.
|
||||
return 'green' unless due_on
|
||||
|
||||
# Calculate the progress in days.
|
||||
a = +new Date created_at
|
||||
b = +new Date
|
||||
c = +new Date due_on
|
||||
|
||||
# Progress in time.
|
||||
time = @progress b - a, c - b
|
||||
|
||||
# Progress in size.
|
||||
[ 'red', 'green' ][ +(@progress(closed_size, open_size) > time) ]
|
||||
, (args...) -> # resolver
|
||||
args.join '/'
|
||||
|
||||
# Time from now.
|
||||
'fromNow': _.memoize (jsonDate) ->
|
||||
fromNow: _.memoize (jsonDate) ->
|
||||
moment(new Date(jsonDate)).fromNow()
|
||||
|
||||
# When is a milestone due?
|
||||
'due': (jsonDate) ->
|
||||
due: (jsonDate) ->
|
||||
return ' ' unless jsonDate
|
||||
[ 'due', @fromNow jsonDate ].join(' ')
|
||||
|
||||
# Markdown formatting.
|
||||
'markdown': (markup) ->
|
||||
markdown: (markup) ->
|
||||
marked markup
|
||||
|
||||
# Format milestone title.
|
||||
'title': (text) ->
|
||||
title: (text) ->
|
||||
if text.toLowerCase().indexOf('milestone') > -1
|
||||
text
|
||||
else
|
||||
[ 'Milestone', text ].join(' ')
|
||||
|
||||
# Hex to decimal.
|
||||
hexToDecimal: (hex) ->
|
||||
hexToDec: (hex) ->
|
||||
parseInt hex, 16
|
|
@ -29,6 +29,6 @@ module.exports = Ractive.extend
|
|||
onrender: ->
|
||||
@observe 'icon', (icon) ->
|
||||
if icon and hex = codes[icon]
|
||||
@set 'code', format.hexToDecimal hex
|
||||
@set 'code', format.hexToDec hex
|
||||
else
|
||||
@set 'code', null
|
|
@ -9,7 +9,6 @@ milestones = require '../../modules/github/milestones.coffee'
|
|||
issues = require '../../modules/github/issues.coffee'
|
||||
mediator = require '../../modules/mediator.coffee'
|
||||
|
||||
|
||||
module.exports = Ractive.extend
|
||||
|
||||
'name': 'views/pages/index'
|
||||
|
@ -32,28 +31,41 @@ module.exports = Ractive.extend
|
|||
|
||||
done = do system.async
|
||||
|
||||
# For all projects.
|
||||
async.map projects.data.list, (project, cb) ->
|
||||
# Skip if we have milestones already.
|
||||
return cb null, project if project.milestones
|
||||
# Otherwise fetch them.
|
||||
milestones.fetchAll project, (error, list) ->
|
||||
# Fetch their milestones.
|
||||
milestones.fetchAll project, (err, list) ->
|
||||
# Save the error if project does not exist.
|
||||
return cb null, _.extend project, { error } if error
|
||||
# Now map in the issues.
|
||||
async.map list, (milestone, cb) ->
|
||||
issues.fetchAll _.extend(project, { 'milestone': milestone.number }), (err, obj) ->
|
||||
cb err, _.extend milestone, { 'issues': obj }
|
||||
, (error, list) ->
|
||||
delete project.milestone # from fetchAll or do deep clone
|
||||
# Save any errors.
|
||||
return cb null, _.extend project, { error } if error
|
||||
# Otherwise add the milestones.
|
||||
cb null, _.extend project, { 'milestones': list }
|
||||
if err
|
||||
projects.saveError project, err
|
||||
return do cb
|
||||
|
||||
, (err, data) =>
|
||||
# TODO: Errors are saved on projects. Show them as a notification here too.
|
||||
# Save the projects.
|
||||
# Now add in the issues.
|
||||
async.each list, (milestone, cb) ->
|
||||
# Do we have this milestone already?
|
||||
return cb null if _.find project.milestones, ({ number }) ->
|
||||
milestone.number is number
|
||||
|
||||
# OK fetch all the issues for this milestone then.
|
||||
issues.fetchAll
|
||||
'owner': project.owner
|
||||
'name': project.name
|
||||
'milestone': milestone.number
|
||||
, (err, obj) ->
|
||||
# Save any errors on the project.
|
||||
if err
|
||||
projects.saveError project, err
|
||||
return do cb
|
||||
|
||||
# Add in the issues to the milestone.
|
||||
_.extend milestone, { 'issues': obj }
|
||||
# Save the milestone.
|
||||
projects.addMilestone project, milestone
|
||||
# Done
|
||||
do cb
|
||||
|
||||
, cb
|
||||
|
||||
, =>
|
||||
do done
|
||||
@set
|
||||
'projects.list': data
|
||||
'ready': yes
|
||||
@set 'ready', yes
|
|
@ -48,7 +48,8 @@ module.exports = Ractive.extend
|
|||
return cb err if err
|
||||
# Save the milestone with issues.
|
||||
projects.addMilestone project, _.extend milestone, { 'issues': obj }
|
||||
cb null
|
||||
# Next.
|
||||
do cb
|
||||
, cb
|
||||
|
||||
# Run it.
|
||||
|
|
Loading…
Reference in New Issue