datavis-glide 4.0.0-PRE.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +45 -0
- package/README.md +129 -0
- package/datavis.js +101 -0
- package/dist/wcdatavis.css +1957 -0
- package/dist/wcdatavis.min.js +1 -0
- package/global-jquery.js +4 -0
- package/ie-fixes.js +13 -0
- package/index.js +70 -0
- package/meteor.js +1 -0
- package/package.json +102 -0
- package/src/flags.js +6 -0
- package/src/graph.js +1079 -0
- package/src/graph_renderer.js +85 -0
- package/src/grid.js +2777 -0
- package/src/grid_control.js +1957 -0
- package/src/grid_filter.js +1073 -0
- package/src/grid_renderer.js +276 -0
- package/src/group_fun_win.js +121 -0
- package/src/lang/en-US.js +188 -0
- package/src/lang/es-MX.js +188 -0
- package/src/lang/fr-FR.js +188 -0
- package/src/lang/id-ID.js +188 -0
- package/src/lang/nl-NL.js +188 -0
- package/src/lang/pt-BR.js +188 -0
- package/src/lang/ru-RU.js +188 -0
- package/src/lang/th-TH.js +188 -0
- package/src/lang/vi-VN.js +188 -0
- package/src/lang/zh-Hans-CN.js +188 -0
- package/src/operations_palette.js +176 -0
- package/src/prefs_modules.js +132 -0
- package/src/reg/graph_renderer.js +17 -0
- package/src/renderers/graph/chartjs.js +457 -0
- package/src/renderers/graph/google.js +584 -0
- package/src/renderers/graph/jit.js +61 -0
- package/src/renderers/graph/svelte-gantt.js +168 -0
- package/src/renderers/grid/dummy.js +79 -0
- package/src/renderers/grid/handlebars.js +217 -0
- package/src/renderers/grid/squirrelly.js +215 -0
- package/src/renderers/grid/table/group_detail.js +1404 -0
- package/src/renderers/grid/table/group_summary.js +380 -0
- package/src/renderers/grid/table/pivot.js +915 -0
- package/src/renderers/grid/table/plain.js +1592 -0
- package/src/renderers/grid/table.js +2510 -0
- package/src/trans.js +101 -0
- package/src/ui/collapsible.js +234 -0
- package/src/ui/filters/date.js +283 -0
- package/src/ui/grid_filter.js +398 -0
- package/src/ui/popup_menu.js +224 -0
- package/src/ui/popup_window.js +572 -0
- package/src/ui/slider.js +156 -0
- package/src/ui/tabs.js +202 -0
- package/src/ui/templates.js +131 -0
- package/src/ui/toolbar.js +63 -0
- package/src/ui/toolbars/grid.js +873 -0
- package/src/ui/windows/col_config.js +341 -0
- package/src/ui/windows/debug.js +164 -0
- package/src/ui/windows/grid_table_opts.js +139 -0
- package/src/util/handlebars.js +158 -0
- package/src/util/jquery.js +630 -0
- package/src/util/misc.js +1058 -0
- package/src/util/squirrelly.js +155 -0
- package/wcdatavis.css +1601 -0
|
@@ -0,0 +1,873 @@
|
|
|
1
|
+
import _ from 'underscore';
|
|
2
|
+
import sprintf from 'sprintf-js';
|
|
3
|
+
|
|
4
|
+
import jQuery from 'jquery';
|
|
5
|
+
|
|
6
|
+
import {trans} from '../../trans.js';
|
|
7
|
+
import {
|
|
8
|
+
deepCopy,
|
|
9
|
+
icon,
|
|
10
|
+
makeRadioButtons,
|
|
11
|
+
makeSubclass,
|
|
12
|
+
makeToggleCheckbox,
|
|
13
|
+
} from '../../util/misc.js';
|
|
14
|
+
|
|
15
|
+
import {ToolbarSection} from '../toolbar.js';
|
|
16
|
+
import {PREFS_BACKEND_REGISTRY, ComputedView} from 'datavis-ace';
|
|
17
|
+
import {GridTableOptsWin} from '../windows/grid_table_opts.js';
|
|
18
|
+
|
|
19
|
+
// PlainToolbar {{{1
|
|
20
|
+
|
|
21
|
+
var PlainToolbar = makeSubclass('PlainToolbar', ToolbarSection, function (grid) {
|
|
22
|
+
var self = this;
|
|
23
|
+
|
|
24
|
+
self.super['ToolbarSection'].ctor.apply(self, []);
|
|
25
|
+
self.ui.root.addClass('wcdv_toolbar_section');
|
|
26
|
+
|
|
27
|
+
self.grid = grid;
|
|
28
|
+
|
|
29
|
+
grid.ui.limit_div = jQuery('<div>').css({'display': 'inline-block'}).appendTo(self.ui.root);
|
|
30
|
+
|
|
31
|
+
// Create a checkbox that will toggle the "automatically show more" feature for the grid table.
|
|
32
|
+
|
|
33
|
+
self.ui.autoShowMore = makeToggleCheckbox(
|
|
34
|
+
grid.defn,
|
|
35
|
+
['table', 'limit', 'autoShowMore'],
|
|
36
|
+
true,
|
|
37
|
+
trans('GRID_TOOLBAR.PLAIN.SHOW_MORE_ON_SCROLL'),
|
|
38
|
+
grid.ui.limit_div
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// Create a button that will show all the rows when clicked. We fake this a little bit by just
|
|
42
|
+
// turning off the "limit" feature and letting the grid table be redrawn (changing the features
|
|
43
|
+
// causes it to be redrawn).
|
|
44
|
+
//
|
|
45
|
+
// TODO: This should disable the "automatically show more" checkbox (need to make sure it gets
|
|
46
|
+
// re-enabled if we switch grid tables and come back - as "limit" feature will be reset to its
|
|
47
|
+
// default value).
|
|
48
|
+
|
|
49
|
+
jQuery('<button>', {'type': 'button'})
|
|
50
|
+
.on('click', function (evt) {
|
|
51
|
+
grid.renderer.updateFeatures({
|
|
52
|
+
'block': true,
|
|
53
|
+
'progress': true,
|
|
54
|
+
'limit': false
|
|
55
|
+
});
|
|
56
|
+
})
|
|
57
|
+
.text(trans('GRID_TOOLBAR.PLAIN.SHOW_ALL_ROWS'))
|
|
58
|
+
.appendTo(grid.ui.limit_div)
|
|
59
|
+
;
|
|
60
|
+
|
|
61
|
+
self.ui.columnConfig = jQuery('<button>', {
|
|
62
|
+
'type': 'button',
|
|
63
|
+
'title': trans('GRID_TOOLBAR.PLAIN.COLUMNS')
|
|
64
|
+
})
|
|
65
|
+
.append(icon('columns-3'))
|
|
66
|
+
.append(trans('GRID_TOOLBAR.PLAIN.COLUMNS'))
|
|
67
|
+
.on('click', function (evt) {
|
|
68
|
+
grid.colConfigWin.show(grid.ui.controls, function (colConfig, opts) {
|
|
69
|
+
if (opts.clearRenderCache) {
|
|
70
|
+
grid.clearRenderCache(opts.clearRenderCache);
|
|
71
|
+
}
|
|
72
|
+
grid.setColConfig(colConfig, {
|
|
73
|
+
from: 'ui'
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
})
|
|
77
|
+
.appendTo(self.ui.root)
|
|
78
|
+
;
|
|
79
|
+
|
|
80
|
+
self.ui.TemplatesEditor = jQuery('<button>', {
|
|
81
|
+
'type': 'button'
|
|
82
|
+
})
|
|
83
|
+
.append(icon('pencil'))
|
|
84
|
+
.append(trans('GRID_TOOLBAR.PLAIN.TEMPLATES_EDITOR'))
|
|
85
|
+
.on('click', function (evt) {
|
|
86
|
+
grid.TemplatesEditor.show();
|
|
87
|
+
})
|
|
88
|
+
.appendTo(self.ui.root)
|
|
89
|
+
;
|
|
90
|
+
|
|
91
|
+
// Row Mode toggle (Clipped vs Wrapped)
|
|
92
|
+
self.ui.rowMode = makeRadioButtons(
|
|
93
|
+
grid.defn
|
|
94
|
+
, ['table', 'rowMode']
|
|
95
|
+
, 'wrapped'
|
|
96
|
+
, null
|
|
97
|
+
, 'rowMode'
|
|
98
|
+
, [{label: trans('GRID_TOOLBAR.PLAIN.ROW_MODE.WRAPPED'), value: 'wrapped'}
|
|
99
|
+
, {label: trans('GRID_TOOLBAR.PLAIN.ROW_MODE.CLIPPED'), value: 'clipped'}]
|
|
100
|
+
, trans('GRID_TOOLBAR.PLAIN.ROW_MODE')
|
|
101
|
+
, function (selected) {
|
|
102
|
+
grid.setRowMode(selected);
|
|
103
|
+
}
|
|
104
|
+
, self.ui.root
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
self.ui.autoResizeColumns = jQuery('<button>', {
|
|
108
|
+
'type': 'button',
|
|
109
|
+
'title': trans('GRID_TOOLBAR.PLAIN.AUTO_RESIZE_COLUMNS')
|
|
110
|
+
})
|
|
111
|
+
.append(icon('move-horizontal'))
|
|
112
|
+
.append(trans('GRID_TOOLBAR.PLAIN.AUTO_RESIZE_COLUMNS'))
|
|
113
|
+
.on('click', function (evt) {
|
|
114
|
+
var colConfig = grid.colConfig.clone();
|
|
115
|
+
colConfig.each(function (fcc) {
|
|
116
|
+
delete fcc.width;
|
|
117
|
+
});
|
|
118
|
+
grid.setColConfig(colConfig, {from: 'ui'});
|
|
119
|
+
if (grid.renderer.autoResizeColumns != null) {
|
|
120
|
+
grid.renderer.autoResizeColumns();
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
.appendTo(self.ui.root)
|
|
124
|
+
;
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// #update {{{2
|
|
128
|
+
|
|
129
|
+
PlainToolbar.prototype.update = function () {
|
|
130
|
+
var self = this;
|
|
131
|
+
|
|
132
|
+
if (self.grid.renderer.features.limit) {
|
|
133
|
+
self.grid.ui.limit_div.show();
|
|
134
|
+
self.ui.autoShowMore.show();
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
self.grid.ui.limit_div.hide();
|
|
138
|
+
self.ui.autoShowMore.hide();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
switch (self.grid.rendererName) {
|
|
142
|
+
case 'table':
|
|
143
|
+
self.ui.columnConfig.show();
|
|
144
|
+
self.ui.TemplatesEditor.hide();
|
|
145
|
+
self.ui.rowMode.show();
|
|
146
|
+
break;
|
|
147
|
+
case 'handlebars':
|
|
148
|
+
self.ui.columnConfig.hide();
|
|
149
|
+
self.ui.TemplatesEditor.show();
|
|
150
|
+
self.ui.rowMode.hide();
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// GroupToolbar {{{1
|
|
156
|
+
|
|
157
|
+
var GroupToolbar = makeSubclass('GroupToolbar', ToolbarSection, function (grid) {
|
|
158
|
+
var self = this;
|
|
159
|
+
|
|
160
|
+
self.super['ToolbarSection'].ctor.apply(self, []);
|
|
161
|
+
self.ui.root.addClass('wcdv_toolbar_section');
|
|
162
|
+
|
|
163
|
+
self.grid = grid;
|
|
164
|
+
|
|
165
|
+
var aggSpec;
|
|
166
|
+
|
|
167
|
+
grid.view.on('aggregateSet', function (a) {
|
|
168
|
+
aggSpec = deepCopy(a);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
var enableDisable = function (selected) {
|
|
172
|
+
switch (selected) {
|
|
173
|
+
case 'summary':
|
|
174
|
+
self.ui.showTotalRow.prop('disabled', false);
|
|
175
|
+
self.ui.pinRowVals.prop('disabled', false);
|
|
176
|
+
self.ui.columnConfig.prop('disabled', true);
|
|
177
|
+
self.ui.showExpandedGroups.prop('disabled', true);
|
|
178
|
+
break;
|
|
179
|
+
case 'detail':
|
|
180
|
+
self.ui.showTotalRow.prop('disabled', true);
|
|
181
|
+
self.ui.pinRowVals.prop('disabled', true);
|
|
182
|
+
self.ui.columnConfig.prop('disabled', false);
|
|
183
|
+
self.ui.showExpandedGroups.prop('disabled', false);
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// Create radio buttons to switch between summary and detail group grid tables.
|
|
189
|
+
|
|
190
|
+
self.ui.groupMode = makeRadioButtons(
|
|
191
|
+
grid.defn
|
|
192
|
+
, ['table', 'groupMode']
|
|
193
|
+
, 'detail'
|
|
194
|
+
, null
|
|
195
|
+
, 'groupOutput'
|
|
196
|
+
, [{label: trans('GRID_TOOLBAR.GROUP.MODE.SUMMARY'), value: 'summary'}
|
|
197
|
+
, {label: trans('GRID_TOOLBAR.GROUP.MODE.DETAIL'), value: 'detail'}]
|
|
198
|
+
, null
|
|
199
|
+
, function (selected) {
|
|
200
|
+
enableDisable(selected);
|
|
201
|
+
grid.redraw();
|
|
202
|
+
}
|
|
203
|
+
, self.ui.root
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
self.ui.showTotalRow = makeToggleCheckbox(
|
|
207
|
+
grid.defn,
|
|
208
|
+
['table', 'whenGroup', 'showTotalRow'],
|
|
209
|
+
true,
|
|
210
|
+
trans('GRID_TOOLBAR.GROUP.TOTAL_ROW'),
|
|
211
|
+
self.ui.root,
|
|
212
|
+
function (isChecked) {
|
|
213
|
+
var agg = grid.view.getAggregate();
|
|
214
|
+
|
|
215
|
+
if (!isChecked) {
|
|
216
|
+
aggSpec = deepCopy(agg);
|
|
217
|
+
delete agg.all;
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
agg.all = aggSpec.all;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
grid.view.setAggregate(agg, {
|
|
224
|
+
sendEvent: false
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
self.ui.showExpandedGroups = makeToggleCheckbox(
|
|
230
|
+
grid.defn,
|
|
231
|
+
['table', 'whenGroup', 'showExpandedGroups'],
|
|
232
|
+
false,
|
|
233
|
+
trans('GRID_TOOLBAR.GROUP.EXPAND_ALL'),
|
|
234
|
+
self.ui.root,
|
|
235
|
+
function (isChecked) {
|
|
236
|
+
grid.redraw();
|
|
237
|
+
}
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
self.ui.pinRowVals = makeToggleCheckbox(
|
|
241
|
+
grid.defn,
|
|
242
|
+
['table', 'whenGroup', 'pinRowvals'],
|
|
243
|
+
false,
|
|
244
|
+
trans('GRID_TOOLBAR.GROUP.PIN_GROUPS'),
|
|
245
|
+
self.ui.root,
|
|
246
|
+
function (isChecked) {
|
|
247
|
+
grid.redraw();
|
|
248
|
+
}
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
//make a toggle for expanded groups
|
|
252
|
+
|
|
253
|
+
self.ui.columnConfig = jQuery('<button>', {
|
|
254
|
+
'type': 'button'
|
|
255
|
+
})
|
|
256
|
+
.append(icon('columns-3'))
|
|
257
|
+
.append(trans('GRID_TOOLBAR.PLAIN.COLUMNS'))
|
|
258
|
+
.on('click', function (evt) {
|
|
259
|
+
grid.colConfigWin.show(grid.ui.controls, function (colConfig) {
|
|
260
|
+
grid.setColConfig(colConfig, {
|
|
261
|
+
from: 'ui'
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
})
|
|
265
|
+
.appendTo(self.ui.root)
|
|
266
|
+
;
|
|
267
|
+
|
|
268
|
+
self.ui.TemplatesEditor = jQuery('<button>', {
|
|
269
|
+
'type': 'button'
|
|
270
|
+
})
|
|
271
|
+
.append(icon('pencil'))
|
|
272
|
+
.append(trans('GRID_TOOLBAR.PLAIN.TEMPLATES_EDITOR'))
|
|
273
|
+
.on('click', function (evt) {
|
|
274
|
+
grid.TemplatesEditor.show();
|
|
275
|
+
})
|
|
276
|
+
.appendTo(self.ui.root)
|
|
277
|
+
;
|
|
278
|
+
|
|
279
|
+
enableDisable(grid.defn.table.groupMode);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// #update {{{2
|
|
283
|
+
|
|
284
|
+
GroupToolbar.prototype.update = function () {
|
|
285
|
+
var self = this;
|
|
286
|
+
|
|
287
|
+
switch (self.grid.rendererName) {
|
|
288
|
+
case 'table':
|
|
289
|
+
self.ui.groupMode.show();
|
|
290
|
+
self.ui.showTotalRow.show();
|
|
291
|
+
self.ui.pinRowVals.show();
|
|
292
|
+
self.ui.columnConfig.show();
|
|
293
|
+
self.ui.TemplatesEditor.hide();
|
|
294
|
+
break;
|
|
295
|
+
case 'handlebars':
|
|
296
|
+
self.ui.groupMode.hide();
|
|
297
|
+
self.ui.showTotalRow.hide();
|
|
298
|
+
self.ui.pinRowVals.hide();
|
|
299
|
+
self.ui.columnConfig.hide();
|
|
300
|
+
self.ui.TemplatesEditor.show();
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
// PivotToolbar {{{1
|
|
306
|
+
|
|
307
|
+
var PivotToolbar = makeSubclass('PivotToolbar', ToolbarSection, function (grid) {
|
|
308
|
+
var self = this;
|
|
309
|
+
|
|
310
|
+
self.super['ToolbarSection'].ctor.apply(self, []);
|
|
311
|
+
self.ui.root.addClass('wcdv_toolbar_section');
|
|
312
|
+
|
|
313
|
+
self.grid = grid;
|
|
314
|
+
|
|
315
|
+
var aggSpec;
|
|
316
|
+
|
|
317
|
+
grid.view.on('aggregateSet', function (a) {
|
|
318
|
+
aggSpec = deepCopy(a);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
self.ui.showTotals = makeToggleCheckbox(
|
|
322
|
+
grid.defn,
|
|
323
|
+
['table', 'whenPivot', 'showTotalCol'],
|
|
324
|
+
true,
|
|
325
|
+
trans('GRID_TOOLBAR.PIVOT.TOTAL_ROW_COLUMN'),
|
|
326
|
+
self.ui.root,
|
|
327
|
+
function (isChecked) {
|
|
328
|
+
var agg = grid.view.getAggregate();
|
|
329
|
+
|
|
330
|
+
if (!isChecked) {
|
|
331
|
+
aggSpec = deepCopy(agg);
|
|
332
|
+
delete agg.group;
|
|
333
|
+
delete agg.pivot;
|
|
334
|
+
delete agg.all;
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
agg.group = aggSpec.group;
|
|
338
|
+
agg.pivot = aggSpec.pivot;
|
|
339
|
+
agg.all = aggSpec.all;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
grid.view.setAggregate(agg, {
|
|
343
|
+
sendEvent: false
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
self.ui.pinRowVals = makeToggleCheckbox(
|
|
349
|
+
grid.defn,
|
|
350
|
+
['table', 'whenGroup', 'pinRowvals'],
|
|
351
|
+
false,
|
|
352
|
+
trans('GRID_TOOLBAR.GROUP.PIN_GROUPS'),
|
|
353
|
+
self.ui.root,
|
|
354
|
+
function (isChecked) {
|
|
355
|
+
grid.redraw();
|
|
356
|
+
}
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
self.ui.hideBottomValueAggResults = makeToggleCheckbox(
|
|
360
|
+
grid.defn,
|
|
361
|
+
['table', 'whenPivot', 'hideBottomValueAggResults'],
|
|
362
|
+
false,
|
|
363
|
+
trans('GRID_TOOLBAR.PIVOT.HIDE_ZERO_VALUES'),
|
|
364
|
+
self.ui.root,
|
|
365
|
+
function (isChecked) {
|
|
366
|
+
grid.redraw();
|
|
367
|
+
}
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
self.ui.TemplatesEditor = jQuery('<button>', {
|
|
371
|
+
'type': 'button'
|
|
372
|
+
})
|
|
373
|
+
.append(icon('pencil'))
|
|
374
|
+
.append(trans('GRID_TOOLBAR.PLAIN.TEMPLATES_EDITOR'))
|
|
375
|
+
.on('click', function (evt) {
|
|
376
|
+
grid.TemplatesEditor.show();
|
|
377
|
+
})
|
|
378
|
+
.appendTo(self.ui.root)
|
|
379
|
+
;
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
// #update {{{2
|
|
383
|
+
|
|
384
|
+
PivotToolbar.prototype.update = function () {
|
|
385
|
+
var self = this;
|
|
386
|
+
|
|
387
|
+
switch (self.grid.rendererName) {
|
|
388
|
+
case 'table':
|
|
389
|
+
self.ui.showTotals.show();
|
|
390
|
+
self.ui.pinRowVals.show();
|
|
391
|
+
self.ui.TemplatesEditor.hide();
|
|
392
|
+
break;
|
|
393
|
+
case 'handlebars':
|
|
394
|
+
self.ui.showTotals.hide();
|
|
395
|
+
self.ui.pinRowVals.hide();
|
|
396
|
+
self.ui.TemplatesEditor.show();
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
// PrefsToolbar {{{1
|
|
402
|
+
|
|
403
|
+
var PrefsToolbar = makeSubclass('PrefsToolbar', ToolbarSection, function (grid) {
|
|
404
|
+
var self = this;
|
|
405
|
+
|
|
406
|
+
self.super['ToolbarSection'].ctor.apply(self, []);
|
|
407
|
+
self.ui.root.addClass('wcdv_toolbar_section');
|
|
408
|
+
|
|
409
|
+
self.grid = grid;
|
|
410
|
+
|
|
411
|
+
var div = jQuery('<div>')
|
|
412
|
+
.addClass('wcdv_toolbar_view')
|
|
413
|
+
.css({'display': 'inline-block'})
|
|
414
|
+
.appendTo(self.ui.root)
|
|
415
|
+
;
|
|
416
|
+
|
|
417
|
+
var options = {};
|
|
418
|
+
|
|
419
|
+
var showHideBtns = function () {
|
|
420
|
+
var p = grid.prefs.getPerspective({ id: dropdown.val() });
|
|
421
|
+
|
|
422
|
+
if (p == null) {
|
|
423
|
+
throw new Error('No such perspective: ' + dropdown.val());
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (p.opts.isTemporary) {
|
|
427
|
+
saveAsBtn.show();
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
saveAsBtn.hide();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (p.opts.isEssential) {
|
|
434
|
+
renameBtn.hide();
|
|
435
|
+
deleteBtn.hide();
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
renameBtn.show();
|
|
439
|
+
deleteBtn.show();
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
var removePerspectiveFromDropdown = function (name) {
|
|
444
|
+
options[name].remove();
|
|
445
|
+
delete options[name];
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
// Clicking this button will reset all preferences back to the initial set (i.e. just "Main
|
|
449
|
+
// Perspective" and no changes in the view from its default). Perhaps useful when you have too
|
|
450
|
+
// many different perspectives set, but I feel better having it as a safety in case your prefs
|
|
451
|
+
// somehow get really messed up and don't work at all anymore. This button is always shown.
|
|
452
|
+
|
|
453
|
+
var resetBtn = jQuery('<button>', {'type': 'button', 'title': trans('GRID_TOOLBAR.PREFS.RESET.TOOLTIP')})
|
|
454
|
+
.addClass('wcdv_icon_button wcdv_text-primary')
|
|
455
|
+
.append(icon('brush-cleaning'))
|
|
456
|
+
.on('click', function (evt) {
|
|
457
|
+
evt.stopPropagation();
|
|
458
|
+
if (confirm(trans('GRID_TOOLBAR.PREFS.RESET.CONFIRM'))) {
|
|
459
|
+
grid.prefs.reset();
|
|
460
|
+
}
|
|
461
|
+
})
|
|
462
|
+
.appendTo(div)
|
|
463
|
+
;
|
|
464
|
+
|
|
465
|
+
var backBtn = jQuery('<button>', {'type': 'button'})
|
|
466
|
+
.append(icon('circle-chevron-left'))
|
|
467
|
+
.attr('title', trans('GRID_TOOLBAR.PREFS.BACK.TOOLTIP'))
|
|
468
|
+
.attr('disabled', true)
|
|
469
|
+
.addClass('wcdv_icon_button wcdv_text-primary')
|
|
470
|
+
.on('click', function (evt) {
|
|
471
|
+
evt.stopPropagation();
|
|
472
|
+
grid.prefs.back();
|
|
473
|
+
})
|
|
474
|
+
.appendTo(div)
|
|
475
|
+
;
|
|
476
|
+
|
|
477
|
+
var forwardBtn = jQuery('<button>', {'type': 'button'})
|
|
478
|
+
.append(icon('circle-chevron-right'))
|
|
479
|
+
.attr('title', trans('GRID_TOOLBAR.PREFS.FORWARD.TOOLTIP'))
|
|
480
|
+
.attr('disabled', true)
|
|
481
|
+
.addClass('wcdv_icon_button wcdv_text-primary')
|
|
482
|
+
.on('click', function (evt) {
|
|
483
|
+
evt.stopPropagation();
|
|
484
|
+
grid.prefs.forward();
|
|
485
|
+
})
|
|
486
|
+
.appendTo(div)
|
|
487
|
+
;
|
|
488
|
+
|
|
489
|
+
/*
|
|
490
|
+
var historyBtn = jQuery(icon('clock', 'wcdv_button', 'History'))
|
|
491
|
+
.on('click', function () {
|
|
492
|
+
grid.prefs._historyDebug();
|
|
493
|
+
})
|
|
494
|
+
.appendTo(div)
|
|
495
|
+
;
|
|
496
|
+
*/
|
|
497
|
+
|
|
498
|
+
// Dropdown of all the available perspectives, plus an entry that (when selected) prompts for the
|
|
499
|
+
// name of a new perspective.
|
|
500
|
+
|
|
501
|
+
var dropdown = jQuery('<select>')
|
|
502
|
+
.append(jQuery('<option>', { value: 'NEW' }).text(trans('GRID_TOOLBAR.PREFS.NEW_PERSPECTIVE')))
|
|
503
|
+
.on('click', function (evt) {
|
|
504
|
+
// After moving the perspective toolbar section into the titlebar, clicking
|
|
505
|
+
// the dropdown was toggling the grid; we need to add a click event handler
|
|
506
|
+
// here so we can explicitly prevent that from happening.
|
|
507
|
+
evt.stopPropagation();
|
|
508
|
+
})
|
|
509
|
+
.on('change', function () {
|
|
510
|
+
if (dropdown.val() === 'NEW') {
|
|
511
|
+
var name = prompt(trans('GRID_TOOLBAR.PREFS.NEW_PERSPECTIVE.PROMPT'), grid.prefs.currentPerspective.name);
|
|
512
|
+
if (name) {
|
|
513
|
+
grid.prefs.addPerspective(null, name);
|
|
514
|
+
grid.prefs.save();
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
// User cancelled the dialog, so just put the dropdown back to whatever the current
|
|
518
|
+
// perspective is.
|
|
519
|
+
dropdown.val(grid.prefs.currentPerspective.id);
|
|
520
|
+
}
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
grid.prefs.setCurrentPerspective(dropdown.val());
|
|
525
|
+
showHideBtns();
|
|
526
|
+
})
|
|
527
|
+
.appendTo(div)
|
|
528
|
+
;
|
|
529
|
+
|
|
530
|
+
var warnMsgText = jQuery('<span>');
|
|
531
|
+
|
|
532
|
+
var warnMsgContent = jQuery('<div>')
|
|
533
|
+
.append(icon('info').css('padding-right', '0.25em').addClass('wcdv_text-primary'))
|
|
534
|
+
.append(warnMsgText);
|
|
535
|
+
|
|
536
|
+
var warnMsg = icon('info', ['wcdv_info_icon'])
|
|
537
|
+
.attr({
|
|
538
|
+
'title': trans('GRID_TOOLBAR.PREFS.INFO.TOOLTIP'),
|
|
539
|
+
'data-tooltip': warnMsgContent
|
|
540
|
+
})
|
|
541
|
+
.hide()
|
|
542
|
+
.appendTo(div)
|
|
543
|
+
;
|
|
544
|
+
|
|
545
|
+
if (grid.prefs.backend instanceof PREFS_BACKEND_REGISTRY.get('temporary')) {
|
|
546
|
+
warnMsgText.text(trans('GRID_TOOLBAR.PREFS.BACKEND_DOES_NOT_SAVE'));
|
|
547
|
+
warnMsg.show();
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// Save As {{{2
|
|
551
|
+
|
|
552
|
+
var saveAsBtnTooltipContent = jQuery('<div>')
|
|
553
|
+
.append(icon('info').css('padding-right', '0.25em').addClass('wcdv_text-primary'))
|
|
554
|
+
.append(trans('GRID_TOOLBAR.PREFS.SAVE_AS.HELP'));
|
|
555
|
+
|
|
556
|
+
var saveAsBtn = jQuery('<button>', {
|
|
557
|
+
'type': 'button',
|
|
558
|
+
'title': trans('GRID_TOOLBAR.PREFS.SAVE_AS.TOOLTIP'),
|
|
559
|
+
'data-tooltip': saveAsBtnTooltipContent
|
|
560
|
+
})
|
|
561
|
+
.append(icon('save'))
|
|
562
|
+
.addClass('wcdv_icon_button wcdv_text-primary')
|
|
563
|
+
.on('click', function (evt) {
|
|
564
|
+
evt.stopPropagation();
|
|
565
|
+
grid.prefs.clonePerspective();
|
|
566
|
+
})
|
|
567
|
+
.appendTo(div)
|
|
568
|
+
;
|
|
569
|
+
|
|
570
|
+
// Save {{{2
|
|
571
|
+
|
|
572
|
+
var saveBtnTooltipContent = jQuery('<div>')
|
|
573
|
+
.append(icon('info').css('padding-right', '0.25em').addClass('wcdv_text-primary'))
|
|
574
|
+
.append(trans('GRID_TOOLBAR.PREFS.SAVE.HELP'));
|
|
575
|
+
|
|
576
|
+
var saveBtn = jQuery('<button>', {'type': 'button', 'title': trans('GRID_TOOLBAR.PREFS.SAVE.TOOLTIP')})
|
|
577
|
+
.append(icon('save'))
|
|
578
|
+
.addClass('wcdv_icon_button wcdv_text-primary')
|
|
579
|
+
.hide()
|
|
580
|
+
// .tooltip({
|
|
581
|
+
// classes: {
|
|
582
|
+
// 'ui-tooltip': 'ui-corner-all ui-widget-shadow wcdv_info_tooltip wcdv_border-primary'
|
|
583
|
+
// },
|
|
584
|
+
// show: { delay: 1000 },
|
|
585
|
+
// content: saveBtnTooltipContent
|
|
586
|
+
// })
|
|
587
|
+
.on('click', function (evt) {
|
|
588
|
+
evt.stopPropagation();
|
|
589
|
+
grid.prefs.reallySave();
|
|
590
|
+
})
|
|
591
|
+
.appendTo(div)
|
|
592
|
+
;
|
|
593
|
+
|
|
594
|
+
// Rename {{{2
|
|
595
|
+
|
|
596
|
+
// Clicking this button will show a prompt to rename the currently selected perspective. If you
|
|
597
|
+
// cancel the prompt, nothing will happen. This button is only shown when the currently selected
|
|
598
|
+
// perspective is not "Main Perspective" as it cannot be renamed.
|
|
599
|
+
//
|
|
600
|
+
// XXX: What if the user types in the name of an existing perspective?
|
|
601
|
+
// XXX: What if the user types in "Main Perspective" ?
|
|
602
|
+
// XXX: What if the user types in "NEW" ?
|
|
603
|
+
|
|
604
|
+
var renameBtn = jQuery('<button>', {'type': 'button', 'title': trans('GRID_TOOLBAR.PREFS.RENAME.TOOLTIP')})
|
|
605
|
+
.addClass('wcdv_icon_button wcdv_text-primary')
|
|
606
|
+
.append(icon('pencil'))
|
|
607
|
+
.on('click', function (evt) {
|
|
608
|
+
evt.stopPropagation();
|
|
609
|
+
var id = dropdown.val();
|
|
610
|
+
var p = grid.prefs.getPerspective({ id: id });
|
|
611
|
+
|
|
612
|
+
if (p.opts.isEssential) {
|
|
613
|
+
alert('Cannot rename essential perspective!');
|
|
614
|
+
}
|
|
615
|
+
else {
|
|
616
|
+
var newName = prompt(trans('GRID_TOOLBAR.PREFS.RENAME_PERSPECTIVE.PROMPT', p.name));
|
|
617
|
+
if (newName) {
|
|
618
|
+
grid.prefs.renamePerspective(id, newName);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
})
|
|
622
|
+
.appendTo(div)
|
|
623
|
+
;
|
|
624
|
+
|
|
625
|
+
// Delete {{{2
|
|
626
|
+
|
|
627
|
+
// Clicking this button will delete the currently selected perspective and switch back to "Main
|
|
628
|
+
// Perspective". It is only shown when the currently selected perspective is not "Main
|
|
629
|
+
// Perspective" as it cannot be deleted.
|
|
630
|
+
|
|
631
|
+
var deleteBtn = jQuery('<button>', {'type': 'button', 'title': trans('GRID_TOOLBAR.PREFS.DELETE.TOOLTIP')})
|
|
632
|
+
.addClass('wcdv_icon_button wcdv_text-primary')
|
|
633
|
+
.append(icon('trash-2'))
|
|
634
|
+
.on('click', function (evt) {
|
|
635
|
+
evt.stopPropagation();
|
|
636
|
+
if (confirm(trans('GRID_TOOLBAR.PREFS.DELETE_PERSPECTIVE.CONFIRM'))) {
|
|
637
|
+
grid.prefs.deletePerspective(dropdown.val());
|
|
638
|
+
}
|
|
639
|
+
})
|
|
640
|
+
.appendTo(div)
|
|
641
|
+
;
|
|
642
|
+
|
|
643
|
+
// }}}2
|
|
644
|
+
|
|
645
|
+
// Get the list of available perspectives from the Prefs instance and put them into the dropdown.
|
|
646
|
+
// The initial perspective will be selected by default. This DOES NOT actually load that
|
|
647
|
+
// perspective, it's just for the UI.
|
|
648
|
+
//
|
|
649
|
+
// XXX: Is it possible for perspectives to change by some other route so that we need to know
|
|
650
|
+
// about it to update the UI?
|
|
651
|
+
|
|
652
|
+
setTimeout(function () {
|
|
653
|
+
grid.prefs.prime(function () {
|
|
654
|
+
grid.prefs.getPerspectives(function (ids) {
|
|
655
|
+
_.each(_.sortBy(_.map(ids, function (id) {
|
|
656
|
+
return grid.prefs.getPerspective({ id: id });
|
|
657
|
+
}), 'name'), function (o) {
|
|
658
|
+
if (options[o.id] == null) {
|
|
659
|
+
options[o.id] = jQuery('<option>', { 'value': o.id })
|
|
660
|
+
.text(o.name)
|
|
661
|
+
.appendTo(dropdown);
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
dropdown.val(grid.prefs.currentPerspective.id);
|
|
666
|
+
showHideBtns();
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
grid.prefs.on('perspectiveAdded', function (id) {
|
|
670
|
+
if (options[id] == null) {
|
|
671
|
+
var p = grid.prefs.getPerspective({ id: id });
|
|
672
|
+
options[id] = jQuery('<option>', { value: id })
|
|
673
|
+
.text(p.name)
|
|
674
|
+
.appendTo(dropdown);
|
|
675
|
+
}
|
|
676
|
+
}, {
|
|
677
|
+
info: 'Adding new perspective to dropdown'
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
grid.prefs.on('perspectiveDeleted', function (id) {
|
|
681
|
+
if (options[id] == null) {
|
|
682
|
+
throw new Error(sprintf.sprintf('Received `perspectiveDeleted` event that references unknown perspective: id = "%s"', id));
|
|
683
|
+
}
|
|
684
|
+
options[id].remove();
|
|
685
|
+
delete options[id];
|
|
686
|
+
}, {
|
|
687
|
+
info: 'Removing perspective from dropdown'
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
grid.prefs.on('perspectiveRenamed', function (id, newName) {
|
|
691
|
+
if (options[id] == null) {
|
|
692
|
+
throw new Error(sprintf.sprintf('Received `perspectiveRenamed` event that references unknown perspective: id = "%s"', id));
|
|
693
|
+
}
|
|
694
|
+
options[id].text(newName);
|
|
695
|
+
}, {
|
|
696
|
+
info: 'Changing perspective name in dropdown'
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
grid.prefs.on('perspectiveChanged', function (id, p) {
|
|
700
|
+
if (options[id] == null) {
|
|
701
|
+
throw new Error(sprintf.sprintf('Received `perspectiveChanged` event that references unknown perspective: id = "%s"', id));
|
|
702
|
+
}
|
|
703
|
+
if (p.isUnsaved) {
|
|
704
|
+
saveBtn.show();
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
saveBtn.hide();
|
|
708
|
+
}
|
|
709
|
+
dropdown.val(id);
|
|
710
|
+
showHideBtns();
|
|
711
|
+
}, {
|
|
712
|
+
info: 'Changing dropdown to reflect new current perspective'
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
grid.prefs.on('prefsReset', function () {
|
|
716
|
+
_.each(options, function (elt) {
|
|
717
|
+
elt.remove();
|
|
718
|
+
});
|
|
719
|
+
options = {};
|
|
720
|
+
}, {
|
|
721
|
+
info: 'Deleting all perspectives from the dropdown'
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
grid.prefs.on('prefsChanged', function () {
|
|
725
|
+
var cp = grid.prefs.currentPerspective;
|
|
726
|
+
var o = options[cp.id];
|
|
727
|
+
o.text('[*] ' + cp.name);
|
|
728
|
+
saveBtn.show();
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
grid.prefs.on('prefsSaved', function () {
|
|
732
|
+
var cp = grid.prefs.currentPerspective;
|
|
733
|
+
var o = options[cp.id];
|
|
734
|
+
o.text(cp.name);
|
|
735
|
+
saveBtn.hide();
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
grid.prefs.on('prefsHistoryStatus', function (back, forward) {
|
|
739
|
+
backBtn.attr('disabled', !back);
|
|
740
|
+
forwardBtn.attr('disabled', !forward);
|
|
741
|
+
});
|
|
742
|
+
});
|
|
743
|
+
});
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
// RendererToolbar {{{1
|
|
747
|
+
|
|
748
|
+
var RendererToolbar = makeSubclass('RendererToolbar', ToolbarSection, function (grid) {
|
|
749
|
+
var self = this;
|
|
750
|
+
|
|
751
|
+
self.super['ToolbarSection'].ctor.apply(self, []);
|
|
752
|
+
self.ui.root.addClass('wcdv_toolbar_section');
|
|
753
|
+
|
|
754
|
+
self.grid = grid;
|
|
755
|
+
|
|
756
|
+
var div = jQuery('<div>')
|
|
757
|
+
.addClass('wcdv_toolbar_view')
|
|
758
|
+
.css({'display': 'inline-block'})
|
|
759
|
+
.appendTo(self.ui.root)
|
|
760
|
+
;
|
|
761
|
+
|
|
762
|
+
var configBtn = jQuery('<button>', {'type': 'button', 'title': trans('GRID_TOOLBAR.RENDERER.DISPLAY_OPTIONS')})
|
|
763
|
+
.append(icon('table'))
|
|
764
|
+
.append(trans('GRID_TOOLBAR.RENDERER.DISPLAY_OPTIONS'))
|
|
765
|
+
.on('click', function () {
|
|
766
|
+
var gridTableOptsWin = new GridTableOptsWin(grid.renderer);
|
|
767
|
+
gridTableOptsWin.show(function (newOpts) {
|
|
768
|
+
if (grid.renderer.canRender('plain')) {
|
|
769
|
+
grid.defn.table.whenPlain = newOpts;
|
|
770
|
+
}
|
|
771
|
+
else if (grid.renderer.canRender('group')) {
|
|
772
|
+
grid.defn.table.whenGroup = newOpts;
|
|
773
|
+
}
|
|
774
|
+
else if (grid.renderer.canRender('pivot')) {
|
|
775
|
+
grid.defn.table.whenPivot = newOpts;
|
|
776
|
+
}
|
|
777
|
+
grid.redraw();
|
|
778
|
+
});
|
|
779
|
+
})
|
|
780
|
+
.appendTo(div)
|
|
781
|
+
;
|
|
782
|
+
|
|
783
|
+
grid.on('renderEnd', function () {
|
|
784
|
+
configBtn.prop('disabled', grid.renderer.canRender('plain'));
|
|
785
|
+
});
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
// ComputedViewToolbar {{{1
|
|
789
|
+
|
|
790
|
+
var ComputedViewToolbar = makeSubclass('ComputedViewToolbar', ToolbarSection, function (grid) {
|
|
791
|
+
var self = this;
|
|
792
|
+
|
|
793
|
+
self.super['ToolbarSection'].ctor.apply(self, []);
|
|
794
|
+
self.ui.root.addClass('wcdv_toolbar_section');
|
|
795
|
+
|
|
796
|
+
self.grid = grid;
|
|
797
|
+
|
|
798
|
+
var div = jQuery('<div>')
|
|
799
|
+
.addClass('wcdv_toolbar_view')
|
|
800
|
+
.css({'display': 'inline-block'})
|
|
801
|
+
.appendTo(self.ui.root)
|
|
802
|
+
;
|
|
803
|
+
|
|
804
|
+
// Store {{{2
|
|
805
|
+
|
|
806
|
+
// This button creates a MirageView from the current view, and switches my grid's view to the new
|
|
807
|
+
// MirageView. If an error occurs, it should abort and leave things the way they are.
|
|
808
|
+
|
|
809
|
+
self.ui.storeMirageBtn = jQuery('<button>', {'type': 'button', 'title': trans('GRID_TOOLBAR.MIRAGE.STORE_DISPLAYED_DATA')})
|
|
810
|
+
.append(icon('save'))
|
|
811
|
+
.append(trans('GRID_TOOLBAR.MIRAGE.STORE_DISPLAYED_DATA'))
|
|
812
|
+
.on('click', function () {
|
|
813
|
+
var perspectiveName = prompt(trans('GRID_TOOLBAR.PREFS.NEW_PERSPECTIVE.PROMPT'), grid.prefs.currentPerspective.name);
|
|
814
|
+
if (perspectiveName != null) {
|
|
815
|
+
grid.mirageView.initFromView(grid.view.prefs, grid.view, grid.view.source, function () {
|
|
816
|
+
// XXX Clone the new perspective, redraw the grid, then switch to the mirage and save it?
|
|
817
|
+
// Or make the mirage first and lie to it about the perspective name, then clone it?
|
|
818
|
+
grid.mirageView.setPerspectiveName(perspectiveName);
|
|
819
|
+
grid.mirageView.save(function () {
|
|
820
|
+
// FIXME Needs to be a better way of doing this. Either reuse the existing mirageView
|
|
821
|
+
// or provide an API to switch the target of a prefs module.
|
|
822
|
+
// grid.prefs.modules.mirageView.target = grid.mirageView;
|
|
823
|
+
|
|
824
|
+
// Cloning the current perspective will cause it to be added and switched to, which
|
|
825
|
+
// causes the grid to change to the mirage view we just made, and redraw.
|
|
826
|
+
|
|
827
|
+
grid.prefs.clonePerspective(null, perspectiveName, function (config) {
|
|
828
|
+
config.mirageView = deepCopy(config.computedView);
|
|
829
|
+
config.isMirage = true;
|
|
830
|
+
|
|
831
|
+
return config;
|
|
832
|
+
}, function () {
|
|
833
|
+
}, function (errMsg) {
|
|
834
|
+
if (errMsg != null) {
|
|
835
|
+
alert(errMsg);
|
|
836
|
+
}
|
|
837
|
+
});
|
|
838
|
+
}, function (msg) {
|
|
839
|
+
self.logError(self.makeLogTag() + ' Failed to save mirage view: ' + msg);
|
|
840
|
+
});
|
|
841
|
+
}, function (msg) {
|
|
842
|
+
self.logError(self.makeLogTag() + ' Failed to initialize mirage view: ' + msg);
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
})
|
|
846
|
+
.appendTo(div)
|
|
847
|
+
;
|
|
848
|
+
|
|
849
|
+
// }}}2
|
|
850
|
+
|
|
851
|
+
// Control my own visibility by only showing myself when the view in use by my grid is a
|
|
852
|
+
// ComputedView. Other types of views have their own toolbars.
|
|
853
|
+
|
|
854
|
+
self.grid.on('renderEnd', function () {
|
|
855
|
+
if (self.grid.view instanceof ComputedView) {
|
|
856
|
+
self.show();
|
|
857
|
+
}
|
|
858
|
+
else {
|
|
859
|
+
self.hide();
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
// Exports {{{1
|
|
865
|
+
|
|
866
|
+
export {
|
|
867
|
+
PlainToolbar,
|
|
868
|
+
GroupToolbar,
|
|
869
|
+
PivotToolbar,
|
|
870
|
+
PrefsToolbar,
|
|
871
|
+
RendererToolbar,
|
|
872
|
+
ComputedViewToolbar,
|
|
873
|
+
};
|