requirejs [
'backbone', 'backbone.marionette'
+ 'analysis-reports/router'
'analysis-reports/layout'
'analysis-reports/models/reports'
'analysis-reports/views/reports-view'
'common/handlebars-extensions'
], (
Backbone, Marionette
+ Router
Layout
Reports
ReportsView
App.fetchReports = ->
+ process = window.process.addBackgroundProcess()
fetch = if @state.get 'active' then @reports.fetchActive() else @reports.fetchHistory()
@layout.showSpinner 'actionsRegion'
@layout.resultsRegion.reset()
fetch.done =>
+ @state.set page: @reports.paging.page
@reportsView = new ReportsView
app: @
collection: @reports
@layout.resultsRegion.show @reportsView
+ @reportsView.bindScrollEvents() unless @state.get 'active'
@actionsView = new ActionsView
app: @
collection: @reports
@layout.actionsRegion.show @actionsView
+ @layout.onResize()
+
+ window.process.finishBackgroundProcess process
+
+
+ App.fetchNextPage = ->
+ process = window.process.addBackgroundProcess()
+ @reports.fetchHistory
+ data:
+ p: @state.get('page') + 1
+ remove: false
+ .done =>
+ @state.set page: @reports.paging.page
+ window.process.finishBackgroundProcess process
+
App.addInitializer ->
- @state = new Backbone.Model active: true
+ @state = new Backbone.Model()
@state.on 'change:active', => @fetchReports()
App.addInitializer ->
@layout = new Layout app: @
jQuery('#analysis-reports').empty().append @layout.render().el
- @layout.onResize()
-
-
- App.addInitializer ->
- @reports = new Reports()
- @fetchReports()
- setInterval (=> @fetchReports()), 30000 # Once every 30s
App.addInitializer ->
@layout.headerRegion.show @headerView
+ App.addInitializer ->
+ @reports = new Reports()
+ @router = new Router app: @
+ Backbone.history.start()
+
l10nXHR = window.requestMessages()
jQuery.when(l10nXHR).done -> App.start()
footerHeight = footerEl.outerHeight true
resultsEl = @ui.results
- resultsHeight = jQuery(window).height() - resultsEl.offset().top -
- parseInt(resultsEl.css('margin-bottom'), 10) - footerHeight
+ resultsHeight = jQuery(window).height() - resultsEl.offset().top - footerHeight
resultsEl.height resultsHeight
parse: (r) ->
- @paging = r.paging
+ @paging =
+ page: r.p
+ pageSize: r.ps
+ total: r.total
+ maxResultsReached: r.p * r.ps >= r.total
r.reports
@fetch { url: "#{baseUrl}/api/analysis_reports/active" }, { reset: true }
- fetchHistory: ->
- @fetch { url: "#{baseUrl}/api/analysis_reports/history" }, { reset: true }
+ fetchHistory: (options = { }) ->
+ _.extend options,
+ url: "#{baseUrl}/api/analysis_reports/history"
+ @fetch options, { reset: true }
--- /dev/null
+define [
+ 'backbone',
+], (
+ Backbone,
+) ->
+
+ class AppRouter extends Backbone.Router
+
+ routes:
+ '': 'showCurrent'
+ 'current': 'showCurrent'
+ 'past': 'showPast'
+
+
+ initialize: (options) ->
+ @options = options
+
+
+ showCurrent: ->
+ @navigate 'current'
+ @options.app.state.set active: true
+
+
+ showPast: ->
+ @navigate 'past'
+ @options.app.state.set active: false
showPastReports: ->
- @options.app.state.set active: false
+ @options.app.router.navigate 'past', trigger: true
showCurrentActivity: ->
- @options.app.state.set active: true
+ @options.app.router.navigate 'current', trigger: true
serializeData: ->
_.extend super,
state: @options.app.state.toJSON()
- total: if @collection.paging then @collection.paging.total else @collection.length
+ total: @collection.paging.total || 0
@$el.addClass 'analysis-reports-report-working' if status is 'WORKING'
@$el.addClass 'analysis-reports-report-done' if status is 'SUCCESS'
@$el.addClass 'analysis-reports-report-failed' if status is 'FAIL'
+
+
+ serializeData: ->
+ duration = null
+ if @model.has('startedAt') && @model.has('finishedAt')
+ startedAtMoment = moment @model.get 'startedAt'
+ finishedAtMoment = moment @model.get 'finishedAt'
+ duration = finishedAtMoment.diff startedAtMoment
+ duration =
+ seconds: Math.floor (duration / 1000) % 60
+ minutes: Math.floor (duration / (1000 * 60)) % 60
+ hours: Math.floor (duration / (1000 * 60 * 60)) % 24
+ _.extend super,
+ duration: duration
--- /dev/null
+define [
+ 'backbone.marionette'
+ 'templates/analysis-reports'
+], (
+ Marionette
+ Templates
+) ->
+
+ class extends Marionette.ItemView
+ tagName: 'li'
+ template: Templates['analysis-reports-empty']
define [
'backbone.marionette'
'analysis-reports/views/report-view'
+ 'analysis-reports/views/reports-empty-view'
], (
Marionette
ReportView
+ EmptyView
) ->
+ $ = jQuery
+
+
class extends Marionette.CollectionView
tagName: 'ol'
className: 'navigator-results-list'
itemView: ReportView
+ emptyView: EmptyView
itemViewOptions: ->
listView: @, app: @options.app
+
+
+ initialize: ->
+ @loadMoreThrottled = _.throttle @loadMore, 200
+
+
+ onClose: ->
+ @unbindScrollEvents()
+
+
+ bindScrollEvents: ->
+ $('.navigator-results').on 'scroll', (=> @loadMoreThrottled())
+
+
+ unbindScrollEvents: ->
+ $('.navigator-results').off 'scroll'
+
+
+ loadMore: ->
+ if $('.navigator-results').scrollTop() + $('.navigator-results').outerHeight() >= $('.navigator-results-list').outerHeight() - 40
+ @unbindScrollEvents()
+ @options.app.fetchNextPage().done =>
+ @bindScrollEvents() unless @collection.paging.maxResultsReached
--- /dev/null
+<li>No reports to show</li>
<h1 class="navigator-header-title">{{t 'analysis_reports.page'}}</h1>
+<div class="navigator-header-description">The server is in charge to process reports submitted by batch analyses. This page allows to monitor the queue of pending reports to process, and gives access to the history of past analyses.</div>
<a href="{{dashboardUrl projectKey}}">{{projectName}}</a>
</span>
- {{#if submittedAt}}
- <span class="analysis-reports-timestamp line-small">
- Submitted: {{dt submittedAt}}
- </span>
- {{/if}}
+ <span class="analysis-reports-timestamp line-small">
+ {{#if submittedAt}}Submitted: {{dt submittedAt}}<br>{{/if}}
+ {{#if startedAt}}Started: {{dt startedAt}}<br>{{/if}}
+ {{#if finishedAt}}Finished: {{dt finishedAt}}<br>{{/if}}
+ </span>
- {{#if startedAt}}
+ {{#if duration}}
<span class="analysis-reports-timestamp line-small">
- Started: {{dt startedAt}}
+ Duration:
+ {{#gt duration.hours 0}}{{duration.hours}}h{{/gt}}
+ {{#gt duration.minutes 0}}{{duration.minutes}}m{{/gt}}
+ {{duration.seconds}}s
</span>
{{/if}}
- {{#if finishedAt}}
- <span class="analysis-reports-timestamp line-small">
- Finished: {{dt finishedAt}}
- </span>
- {{/if}}
</div>
<div class="analysis-reports-report-id">{{id}} {{status}}</div>
.navigator-header-description {
display: inline-block;
vertical-align: middle;
+ max-width: 70%;
margin-left: 16px;
font-size: @smallFontSize;
font-style: italic;