Skip to content

Commit c59073a

Browse files
committed
Added a widgetry to decide which packages will be traced.
1 parent a694400 commit c59073a

File tree

6 files changed

+187
-59
lines changed

6 files changed

+187
-59
lines changed

codepulse/src/main/resources/toserve/pages/traces/PackageController.js

Lines changed: 70 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
// build this into a Map[packageId -> packageWidget.selectedProp]
2727
var stateTemplate = {}
2828

29+
// build this into a Map[packageId -> packageWidget.instrumentationSelectedProp]
30+
var instrumentedTemplate = {}
31+
2932
var widgets = {}
3033

3134
// initialize the `stateTemplate` and `widgets` maps
@@ -43,6 +46,11 @@
4346
handleSelectionClick(node, pw)
4447
})
4548

49+
instrumentedTemplate[node.id] = pw.instrumentationSelectedProp
50+
pw.instrumentationSelectedClicks.onValue(function(){
51+
handleInstrumentationSelectionClick(node, pw)
52+
})
53+
4654
pw.uiParts.collapser.click(function(event){
4755
pw.collapseChildren('toggle', true)
4856
event.stopPropagation()
@@ -87,40 +95,64 @@
8795
return found
8896
}
8997

90-
function handleSelectionClick(node, widget){
91-
// selected may be one of [1, 0, undefined].
92-
// transition [1 -> 0], [0 -> 1], [undefined -> 1]
93-
var newSel = +!widget.selected()
94-
95-
// apply the new selection to this node and each of its children
96-
;(function bubbleDown(w){
97-
w.selected(newSel)
98-
w.children.forEach(bubbleDown)
99-
})(widget)
100-
101-
// climb the tree, re-checking the full/partial selection state of node's ancestors
102-
;(function bubbleUp(n){
103-
if(!n || n.kind == 'root') return
104-
var w = widgets[n.id]
105-
if(!w) return
106-
107-
var isFullSelected = true,
108-
isPartialSelected = false
109-
110-
w.children.forEach(function(c){
111-
var s = c.selected()
112-
if(!s) isFullSelected = false
113-
if(s == 1 || s == undefined) isPartialSelected = true
114-
})
115-
116-
var s = isFullSelected ? 1 : isPartialSelected ? undefined : 0
117-
w.selected(s)
98+
// checkSelected = function(widget){ return <is widget selected> }
99+
// setSelected = function(widget, sel){ <set widget.selected to sel> }
100+
// Returns a function(node, widget):
101+
// node is the starting point in the data tree
102+
// widget is the corresponding widget for the node
103+
//
104+
// The function applies partial selection logic as if the widget
105+
// had been clicked.
106+
function bubblePartialSelection(checkSelected, setSelected){
107+
return function(node, widget){
108+
// selected may be one of [1, 0, undefined].
109+
// transition [1 -> 0], [0 -> 1], [undefined -> 1]
110+
var newSel = +!checkSelected(widget)
111+
112+
// apply the new selection to this node and each of its children
113+
;(function bubbleDown(w){
114+
setSelected(w, newSel)
115+
w.children.forEach(bubbleDown)
116+
})(widget)
117+
118+
// climb the tree, re-checking the full/partial selection state of node's ancestors
119+
;(function bubbleUp(n){
120+
if(!n || n.kind == 'root') return
121+
var w = widgets[n.id]
122+
if(!w) return
123+
124+
var isFullSelected = true,
125+
isPartialSelected = false
126+
127+
w.children.forEach(function(c){
128+
var s = checkSelected(c)
129+
if(!s) isFullSelected = false
130+
if(s == 1 || s == undefined) isPartialSelected = true
131+
})
132+
133+
var s = isFullSelected ? 1 : isPartialSelected ? undefined : 0
134+
setSelected(w, s)
135+
136+
bubbleUp(n.parent)
137+
138+
})(node.parent)
139+
var p = node.parent, pw = p && widgets[p.id]
140+
}
141+
}
118142

119-
bubbleUp(n.parent)
143+
// a function(node,widget) that toggles the tri-state 'selected' property,
144+
// starting from the given node+widget
145+
var handleSelectionClick = bubblePartialSelection(
146+
/*get*/ function(w){ return w.selected() },
147+
/*set*/ function(w,s){ return w.selected(s) }
148+
)
120149

121-
})(node.parent)
122-
var p = node.parent, pw = p && widgets[p.id]
123-
}
150+
// a function(node, widget) that toggles the tri-state 'instrumentationSelected'
151+
// property, starting from the given node+widget
152+
var handleInstrumentationSelectionClick = bubblePartialSelection(
153+
/*get*/ function(w){ return w.instrumentationSelected() },
154+
/*set*/ function(w,s){ return w.instrumentationSelected(s) }
155+
)
124156

125157
// set the `methodCount` property for all widgets
126158
applyMethodCounts(treeData, widgets)
@@ -131,6 +163,12 @@
131163
*/
132164
this.selectedWidgets = Bacon.combineTemplate(stateTemplate).debounce(10)
133165

166+
/**
167+
* Exposes the 'instrumented' state of each of the widgets, as
168+
* a Map[package.id -> isInstrumented]
169+
*/
170+
this.instrumentedWidgets = Bacon.combineTemplate(instrumentedTemplate).debounce(10)
171+
134172
// Decide whether or not to show the "clear all selections" button
135173
// depending on whether or not there are selected widgets
136174
this.selectedWidgets

codepulse/src/main/resources/toserve/pages/traces/PackageWidget.css

Lines changed: 67 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
}
3535

3636
.packages-header .header-label,
37+
.packages-header .header-trace,
3738
.packages-header .header-method-count,
3839
.packages-header .header-barchart {
3940

@@ -48,18 +49,26 @@
4849
line-height: 40px;
4950
background-color: #7E7E7E;
5051
}
52+
53+
.packages-header .header-trace {
54+
width: 40px;
55+
text-align: center;
56+
font-size: small;
57+
line-height: 40px;
58+
background-color: #9C9C9C;
59+
}
5160

5261
.packages-header .header-method-count {
5362
width: 50px;
5463
text-align: center;
5564
font-size: small;
56-
background-color: #9C9C9C;
65+
background-color: #7E7E7E;
5766
}
5867

5968
.packages-header .header-barchart {
6069
background-color: #6D6D6D;
6170

62-
width: calc(100% - 250px);
71+
width: calc(100% - 290px);
6372
line-height: 40px;
6473
padding-left: 5px;
6574
}
@@ -211,10 +220,62 @@
211220
content: '\f0c8'; /* fa-minus-square */
212221
}
213222

223+
/*******************************\
224+
| Widget Tracing Toggler Styles |
225+
\*******************************/
226+
227+
.widget-trace-toggle {
228+
width: 40px;
229+
float: left;
230+
text-align: center;
231+
background-color: #9C9C9C;
232+
}
233+
234+
.tri-state-toggle {
235+
width: 20px;
236+
margin: auto;
237+
cursor: pointer;
238+
}
239+
240+
.tri-state-toggle:before {
241+
font-family: FontAwesome;
242+
-webkit-font-smoothing: antialiased;
243+
244+
width: 20px;
245+
text-align: center;
246+
font-size: 13px;
247+
248+
content: '\f096'; /* fa-square-o */
249+
color: #FFF;
250+
}
251+
252+
.tri-state-toggle.full-select:before {
253+
content: '\f00c'; /* fa-check */
254+
}
255+
256+
.tri-state-toggle.partial-select:before {
257+
content: '\f0c8'; /* fa-minus-square */
258+
}
259+
214260
/*****************************\
215261
| Widget Method Counts Styles |
216262
\*****************************/
217263

264+
.widget-method-count {
265+
background-color: #7E7E7E;
266+
width: 50px;
267+
display: inline-block;
268+
float: left;
269+
height: 20px;
270+
text-align: center;
271+
box-sizing: border-box;
272+
color: white;
273+
}
274+
275+
.widget-method-count .count-number {
276+
font-size: small;
277+
}
278+
218279
/* Some parts of the .widget-label will be highlighted, by showing a
219280
* .highlight div behind the regular content.
220281
*/
@@ -249,33 +310,12 @@
249310
opacity: 0; /* opacity should be set and transitioned with javascript */
250311
}
251312

252-
253-
/*****************************\
254-
| Widget Method Counts Styles |
255-
\*****************************/
256-
257-
.widget-method-count {
258-
background-color: #9C9C9C;
259-
width: 50px;
260-
display: inline-block;
261-
float: left;
262-
height: 20px;
263-
text-align: center;
264-
box-sizing: border-box;
265-
color: white;
266-
}
267-
268-
.widget-method-count .count-number {
269-
font-size: small;
270-
}
271-
272-
273313
/************************\
274314
| Widget Barchart Styles |
275315
\************************/
276316

277317
.widget-barchart {
278-
width: calc(100% - 250px);
318+
width: calc(100% - 290px);
279319
display: inline-block;
280320
height: 20px;
281321
}
@@ -357,6 +397,9 @@
357397
.package-totals .widget-label .content .label-text {
358398
line-height: 30px;
359399
}
400+
.package-totals .widget-trace-toggle {
401+
line-height: 30px;
402+
}
360403
.package-totals .widget-method-count {
361404
height: 30px;
362405
line-height: 30px;

codepulse/src/main/resources/toserve/pages/traces/PackageWidget.js

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,19 @@
6868
var self = this,
6969
_fullLabel = '',
7070
_abbreviatedLabel = '',
71-
_selectable = true,
7271
_indentation = 0,
7372
_methodCount = 0,
7473
_totalCoverage = 0,
7574
_displayCompact = false,
75+
7676
_selected = 0,
77+
_selectable = true,
7778
_selectedBus = new Bacon.Bus(),
79+
80+
_instrumentationSelected = 0,
81+
_instrumentationSelectable = true,
82+
_instrumentationSelectedBus = new Bacon.Bus(),
83+
7884
_collapseChildren = false,
7985
_childWidgets = []
8086

@@ -95,6 +101,7 @@
95101
'indent': e.find('.indent'),
96102
'contentContainer': e.find('.content'),
97103
'labelText': e.find('.label-text'),
104+
'instrumentationSelectedToggle': e.find('.tri-state-toggle'),
98105
'countNumber': e.find('.count-number'),
99106
'barFill': e.find('.bar-fill'),
100107
'barLabel': e.find('.bar-label'),
@@ -156,6 +163,13 @@
156163
return self
157164
}
158165

166+
this.instrumentationSelectable = function(newSel){
167+
if(!arguments.length) return _instrumentationSelectable
168+
169+
_instrumentationSelectable = newSel
170+
return self
171+
}
172+
159173
this.displayCompact = function(compactFlag){
160174
if(!arguments.length) return _displayCompact
161175

@@ -194,6 +208,19 @@
194208
return self
195209
}
196210

211+
this.instrumentationSelected = function(newSelect){
212+
if(!arguments.length) return _instrumentationSelected
213+
_instrumentationSelected = newSelect
214+
215+
self.uiParts.instrumentationSelectedToggle
216+
.toggleClass('full-select', _instrumentationSelected == 1)
217+
.toggleClass('partial-select', _instrumentationSelected == undefined)
218+
219+
_instrumentationSelectedBus.push(_instrumentationSelected)
220+
221+
return self
222+
}
223+
197224
this.collapseChildren = function(arg, animate){
198225
if(!arguments.length) return _collapseChildren
199226

@@ -233,6 +260,10 @@
233260

234261
this.selectionClicks = new Bacon.Bus()
235262

263+
this.instrumentationSelectedProp = _instrumentationSelectedBus.toProperty(_instrumentationSelected).skipDuplicates()
264+
265+
this.instrumentationSelectedClicks = new Bacon.Bus()
266+
236267
// ============================================================================
237268
// Helper Methods
238269
// ============================================================================
@@ -277,6 +308,11 @@
277308
self.selectionClicks.push(1)
278309
}
279310
})
311+
this.uiParts.instrumentationSelectedToggle.click(function(){
312+
if(_instrumentationSelectable){
313+
self.instrumentationSelectedClicks.push(1)
314+
}
315+
})
280316
}
281317

282318
$(document).ready(function(){

codepulse/src/main/resources/toserve/pages/traces/traces.css

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,13 @@ body > .overlay:before {
4444

4545
/* width = full screen minus:
4646
- 200px (the width of the .widget-label)
47+
- 40px (the width of the .widget-trace-toggle)
4748
- 50px (the width of the .widget-method-count)
4849
- 60px (the width of the percentage marker compact)
4950
- 241px (the width of the side bar)
5051
= 551px
5152
*/
52-
width: calc(100% - 551px);
53+
width: calc(100% - 591px);
5354

5455
transition: left .3s ease;
5556
background-color: #9C9C9C;
@@ -63,11 +64,12 @@ body > .overlay:before {
6364
.middle-column-alt.in-view {
6465
/* left =
6566
+ 200px (width of .widget-label)
67+
+ 40px (width of .widget-trace-toggle)
6668
+ 50px (width of .widget-method-count)
6769
+ 60px (width of percentage marker compact)
6870
= 310px
6971
*/
70-
left: 310px;
72+
left: 350px;
7173
border-left: none;
7274
}
7375

0 commit comments

Comments
 (0)