Skip to content

Commit 371bb1f

Browse files
committed
Merge pull request #204 from 10gen/INT-708-progress-bar
INT-708 progress bar
2 parents eb9d6b6 + 98512d4 commit 371bb1f

File tree

7 files changed

+136
-63
lines changed

7 files changed

+136
-63
lines changed

src/bugsnag.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,17 @@ var _ = require('lodash');
1414
var debug = require('debug')('scout:bugsnag');
1515

1616
var TOKEN = '0d11ab5f4d97452cc83d3365c21b491c';
17-
1817
// @todo (imlucas): use mongodb-redact
1918
function beforeNotify(d) {
2019
app.sendMessage('show bugsnag OS notification', d.message);
20+
app.statusbar.hide();
2121

2222
d.stacktrace = redact(d.stacktrace);
2323
d.context = redact(d.context);
2424
d.file = redact(d.file);
2525
d.message = redact(d.message);
2626
d.url = redact(d.url);
2727
d.name = redact(d.name);
28-
d.file = redact(d.file);
2928
d.metaData = redact(d.metaData);
3029
debug('redacted bugsnag report\n', JSON.stringify(d, null, 2));
3130
}

src/home/collection.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ var MongoDBCollectionView = View.extend({
6767
},
6868
initialize: function() {
6969
this.model = new MongoDBCollection();
70-
app.statusbar.watch(this, this.schema);
7170
this.listenTo(this.schema, 'sync', this.schemaIsSynced.bind(this));
7271
this.listenTo(this.schema, 'request', this.schemaIsRequested.bind(this));
7372
this.listenToAndRun(this.parent, 'change:ns', this.onCollectionChanged.bind(this));

src/models/sampled-schema.js

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -165,21 +165,23 @@ module.exports = Schema.extend({
165165
}
166166
model.documents.reset(docs);
167167
model.documents.trigger('sync');
168+
app.statusbar.hide(true);
168169

169170
// @note (imlucas): Any other metrics? Feedback on `Schema *`?
170171
var totalTime = new Date() - start;
171172
var timeToFirstDoc = timeAtFirstDoc - start;
172173

173174
metrics.track('Schema: Complete', {
174-
Duration: totalTime,
175-
'Total Document Count': model.total,
176-
'Sample Size': model.documents.length,
177-
'Errored Document Count': erroredOnDocs.length,
178-
'Time to First Doc': timeToFirstDoc,
179-
'Average Time Per Doc': (totalTime - timeToFirstDoc) / model.documents.length
180-
// 'Schema Height': model.height, // # of top level keys
181-
// 'Schema Width': model.width, // max nesting depth
182-
// 'Schema Sparsity': model.sparsity // lots of fields missing or consistent
175+
duration: totalTime,
176+
'total document count': model.total,
177+
'sample size': model.documents.length,
178+
'errored document count': erroredOnDocs.length,
179+
'total sample time': timeToFirstDoc,
180+
'total analysis time': totalTime - timeToFirstDoc,
181+
'average analysis time per doc': (totalTime - timeToFirstDoc) / model.documents.length
182+
// 'Schema Height': model.height, // # of top level keys
183+
// 'Schema Width': model.width, // max nesting depth
184+
// 'Schema Sparsity': model.sparsity // lots of fields missing or consistent
183185
});
184186
options.success({});
185187
};
@@ -199,9 +201,29 @@ module.exports = Schema.extend({
199201
return onEmpty();
200202
}
201203

202-
debug('creating sample stream');
204+
var status = 0;
205+
var counter = 0;
206+
var numSamples = Math.min(options.size, count.count);
207+
var stepSize = Math.ceil(Math.max(1, numSamples / 10));
208+
209+
app.statusbar.show('Sampling collection...');
210+
app.statusbar.width = 1;
211+
app.statusbar.trickle(true);
203212
app.client.sample(model.ns, options)
204213
.pipe(es.map(parse))
214+
.once('data', function() {
215+
status = app.statusbar.width;
216+
app.statusbar.message = 'Analyzing documents...';
217+
app.statusbar.trickle(false);
218+
})
219+
.on('data', function() {
220+
counter ++;
221+
if (counter % stepSize === 0) {
222+
var inc = (100 - status) * stepSize / numSamples;
223+
debug(inc);
224+
app.statusbar.width += inc;
225+
}
226+
})
205227
.pipe(es.map(addToDocuments))
206228
.pipe(es.wait(onEnd));
207229
});

src/statusbar/index.jade

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
.progress-bar.progress-bar-striped.active(data-hook='inner-bar')
44
ul.message-background.with-sidebar.centered(data-hook='message-container'): li
55
p(data-hook='message')
6-
.spinner-circles(data-hook='loading')
7-
.circle-1
8-
.circle-2
6+
.spinner(data-hook='loading')
7+
.rect1
8+
.rect2
9+
.rect3
10+
.rect4
11+
.rect5

src/statusbar/index.js

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
var View = require('ampersand-view');
2+
var _ = require('lodash');
3+
// var debug = require('debug')('scout:statusbar:index');
4+
25
var StatusbarView = View.extend({
36
props: {
7+
trickleTimer: 'any',
48
width: {
59
type: 'number',
610
default: 0
711
},
812
message: {
913
type: 'string'
1014
},
11-
loading: {
15+
loadingIndicator: {
1216
type: 'boolean',
1317
default: true
18+
},
19+
visible: {
20+
type: 'boolean',
21+
default: false
1422
}
1523
},
1624
template: require('./index.jade'),
1725
bindings: {
18-
loading: {
26+
loadingIndicator: {
1927
hook: 'loading',
2028
type: 'booleanClass',
2129
yes: 'visible',
@@ -46,9 +54,14 @@ var StatusbarView = View.extend({
4654
},
4755
{
4856
type: 'booleanClass',
57+
hook: 'outer-bar',
4958
no: 'hidden'
5059
}
51-
]
60+
],
61+
visible: {
62+
type: 'booleanClass',
63+
no: 'hidden'
64+
}
5265
},
5366
derived: {
5467
/**
@@ -79,19 +92,43 @@ var StatusbarView = View.extend({
7992
this.hide();
8093
},
8194
fatal: function(err) {
82-
this.loading = false;
95+
this.visible = true;
96+
this.loadingIndicator = false;
8397
this.message = 'Fatal Error: ' + err.message;
84-
this.width = 100;
98+
this.width = 0;
99+
this.trickle(false);
100+
clearInterval(this.trickleTimer);
101+
},
102+
trickle: function(bool) {
103+
if (bool) {
104+
this.trickleTimer = setInterval(function() {
105+
this.width = Math.min(98, this.width + _.random(1, 3));
106+
}.bind(this), 800);
107+
} else {
108+
clearInterval(this.trickleTimer);
109+
}
85110
},
86111
show: function(message) {
112+
this.visible = true;
87113
this.message = message || '';
88114
this.width = 100;
89-
this.loading = true;
115+
this.loadingIndicator = true;
90116
},
91-
hide: function() {
117+
hide: function(completed) {
92118
this.message = '';
93-
this.width = 0;
94-
this.loading = false;
119+
this.loadingIndicator = false;
120+
clearInterval(this.trickleTimer);
121+
if (completed) {
122+
this.width = 100;
123+
var model = this;
124+
_.delay(function() {
125+
model.width = 0;
126+
model.visible = false;
127+
}, 1000);
128+
} else {
129+
this.width = 0;
130+
this.visible = false;
131+
}
95132
}
96133
});
97134

src/statusbar/index.less

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -24,45 +24,58 @@
2424
}
2525
}
2626
.message-background {
27-
.spinner-circles {
28-
width: 40px;
29-
height: 40px;
30-
position: relative;
31-
margin: 40px auto;
27+
.spinner {
28+
margin: 50px auto;
29+
width: 65px;
30+
height: 60px;
31+
text-align: center;
32+
font-size: 10px;
33+
}
3234

33-
.circle-1, .circle-2 {
34-
width: 100%;
35-
height: 100%;
36-
border-radius: 50%;
37-
background-color: @mc-blue0;
38-
opacity: 0.6;
39-
position: absolute;
40-
top: 0;
41-
left: 0;
35+
.spinner > div {
36+
background-color: rgba(0, 0, 0, 0.2);;
37+
margin: 0 3px 0 0;
38+
height: 100%;
39+
width: 10px;
40+
display: inline-block;
4241

43-
-webkit-animation: bounce 2.0s infinite ease-in-out;
44-
animation: bounce 2.0s infinite ease-in-out;
45-
}
42+
-webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;
43+
animation: sk-stretchdelay 1.2s infinite ease-in-out;
44+
}
4645

47-
.circle-2 {
48-
-webkit-animation-delay: -1.0s;
49-
animation-delay: -1.0s;
50-
}
46+
.spinner .rect2 {
47+
-webkit-animation-delay: -1.1s;
48+
animation-delay: -1.1s;
49+
}
5150

52-
@-webkit-keyframes bounce {
53-
0%, 100% { -webkit-transform: scale(0.0) }
54-
50% { -webkit-transform: scale(1.0) }
55-
}
51+
.spinner .rect3 {
52+
-webkit-animation-delay: -1.0s;
53+
animation-delay: -1.0s;
54+
}
55+
56+
.spinner .rect4 {
57+
-webkit-animation-delay: -0.9s;
58+
animation-delay: -0.9s;
59+
}
60+
61+
.spinner .rect5 {
62+
-webkit-animation-delay: -0.8s;
63+
animation-delay: -0.8s;
64+
}
65+
66+
@-webkit-keyframes sk-stretchdelay {
67+
0%, 40%, 100% { -webkit-transform: scaleY(0.4) }
68+
20% { -webkit-transform: scaleY(1.0) }
69+
}
5670

57-
@keyframes bounce {
58-
0%, 100% {
59-
transform: scale(0.0);
60-
-webkit-transform: scale(0.0);
61-
} 50% {
62-
transform: scale(1.0);
63-
-webkit-transform: scale(1.0);
64-
}
71+
@keyframes sk-stretchdelay {
72+
0%, 40%, 100% {
73+
transform: scaleY(0.4);
74+
-webkit-transform: scaleY(0.4);
75+
} 20% {
76+
transform: scaleY(1.0);
77+
-webkit-transform: scaleY(1.0);
6578
}
6679
}
6780
}
68-
}
81+
}

styles/10strap.less

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -649,10 +649,10 @@ fieldset[disabled] .btn-link:focus {
649649
-webkit-box-sizing: border-box;
650650
-moz-box-sizing: border-box;
651651
box-sizing: border-box;
652-
-webkit-transition: width 0.6s ease;
653-
-moz-transition: width 0.6s ease;
654-
-o-transition: width 0.6s ease;
655-
transition: width 0.6s ease;
652+
-webkit-transition: width 0.8s ease;
653+
-moz-transition: width 0.8s ease;
654+
-o-transition: width 0.8s ease;
655+
transition: width 0.8s ease;
656656
}
657657
.progress.active .progress-bar {
658658
-webkit-animation: progress-bar-stripes 0.6s linear infinite;

0 commit comments

Comments
 (0)