dash_creator 0.1.2
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +170 -0
- data/Rakefile +36 -0
- data/app/assets/config/dash_creator_manifest.js +2 -0
- data/app/assets/javascripts/dash_creator/application.js +24 -0
- data/app/assets/javascripts/dash_creator/chart.js +2 -0
- data/app/assets/javascripts/dash_creator/dashboard.js +2 -0
- data/app/assets/javascripts/dash_creator/dashboard_object.js +2 -0
- data/app/assets/javascripts/dash_creator/filter.js +2 -0
- data/app/assets/javascripts/dash_creator/libs/Chart.js +12269 -0
- data/app/assets/javascripts/dash_creator/libs/bootstrap.js +3535 -0
- data/app/assets/javascripts/dash_creator/libs/chartCreator.js +1582 -0
- data/app/assets/javascripts/dash_creator/libs/dashboardCreator.js +531 -0
- data/app/assets/javascripts/dash_creator/libs/daterangepicker.js +1626 -0
- data/app/assets/javascripts/dash_creator/libs/filterCreator.js +733 -0
- data/app/assets/javascripts/dash_creator/libs/jquery-ui.js +18706 -0
- data/app/assets/javascripts/dash_creator/libs/jquery.minicolors.js +1108 -0
- data/app/assets/javascripts/dash_creator/libs/moment.js +4301 -0
- data/app/assets/javascripts/dash_creator/libs/tether.js +1811 -0
- data/app/assets/javascripts/dash_creator/user.js +2 -0
- data/app/assets/stylesheets/dash_creator/application.css +16 -0
- data/app/assets/stylesheets/dash_creator/chart.css +4 -0
- data/app/assets/stylesheets/dash_creator/dashboard.css +4 -0
- data/app/assets/stylesheets/dash_creator/dashboard_object.css +4 -0
- data/app/assets/stylesheets/dash_creator/filter.css +4 -0
- data/app/assets/stylesheets/dash_creator/fonts/FontAwesome.otf +0 -0
- data/app/assets/stylesheets/dash_creator/fonts/fontawesome-webfont.eot +0 -0
- data/app/assets/stylesheets/dash_creator/fonts/fontawesome-webfont.svg +2671 -0
- data/app/assets/stylesheets/dash_creator/fonts/fontawesome-webfont.ttf +0 -0
- data/app/assets/stylesheets/dash_creator/fonts/fontawesome-webfont.woff +0 -0
- data/app/assets/stylesheets/dash_creator/fonts/fontawesome-webfont.woff2 +0 -0
- data/app/assets/stylesheets/dash_creator/libs/font-awesome.css +2199 -0
- data/app/assets/stylesheets/dash_creator/libs/jquery.minicolors.css +319 -0
- data/app/assets/stylesheets/dash_creator/libs/jquery.minicolors.png +0 -0
- data/app/assets/stylesheets/dash_creator/libs/style.css +13714 -0
- data/app/assets/stylesheets/dash_creator/user.css +4 -0
- data/app/controllers/dash_creator/application_controller.rb +3 -0
- data/app/controllers/dash_creator/chart_controller.rb +81 -0
- data/app/controllers/dash_creator/dashboard_controller.rb +37 -0
- data/app/controllers/dash_creator/dashboard_object_controller.rb +34 -0
- data/app/controllers/dash_creator/filter_controller.rb +60 -0
- data/app/controllers/dash_creator/user_controller.rb +82 -0
- data/app/helpers/dash_creator/application_helper.rb +4 -0
- data/app/helpers/dash_creator/chart_helper.rb +829 -0
- data/app/helpers/dash_creator/dashboard_helper.rb +4 -0
- data/app/helpers/dash_creator/dashboard_object_helper.rb +4 -0
- data/app/helpers/dash_creator/filter_helper.rb +237 -0
- data/app/helpers/dash_creator/user_helper.rb +4 -0
- data/app/jobs/dash_creator/application_job.rb +4 -0
- data/app/mailers/dash_creator/application_mailer.rb +6 -0
- data/app/models/dash_creator/application_record.rb +5 -0
- data/app/models/dash_creator/chart.rb +21 -0
- data/app/models/dash_creator/dashboard.rb +13 -0
- data/app/models/dash_creator/dashboard_object.rb +7 -0
- data/app/models/dash_creator/filter.rb +22 -0
- data/app/views/dash_creator/chart/_chart_creator.html.erb +230 -0
- data/app/views/dash_creator/chart/_modals.html.erb +74 -0
- data/app/views/dash_creator/chart/_plot_chart.html.erb +45 -0
- data/app/views/dash_creator/chart/create_chart.js.erb +53 -0
- data/app/views/dash_creator/dashboard/_dashboard_creator.html.erb +182 -0
- data/app/views/dash_creator/dashboard/_modals.html.erb +74 -0
- data/app/views/dash_creator/dashboard_object/_chart.html.erb +9 -0
- data/app/views/dash_creator/dashboard_object/_stat.html.erb +24 -0
- data/app/views/dash_creator/dashboard_object/_table.html.erb +16 -0
- data/app/views/dash_creator/filter/_filtering_card.html.erb +132 -0
- data/app/views/dash_creator/filter/_modals.html.erb +51 -0
- data/app/views/dash_creator/filter/_result_tables.html.erb +55 -0
- data/app/views/dash_creator/filter/apply_filtering.js.erb +46 -0
- data/app/views/dash_creator/filter/create_stat.js.erb +20 -0
- data/app/views/dash_creator/layouts/application.html.erb +64 -0
- data/app/views/dash_creator/layouts/menu/_left_menu.html.erb +12 -0
- data/app/views/dash_creator/user/_section_card.html.erb +17 -0
- data/app/views/dash_creator/user/creator.html.erb +11 -0
- data/app/views/dash_creator/user/dashboard.html.erb +10 -0
- data/config/initializers/dash_creator.rb +0 -0
- data/config/routes.rb +30 -0
- data/lib/dash_creator.rb +87 -0
- data/lib/dash_creator/acts_as_dash_creator.rb +16 -0
- data/lib/dash_creator/acts_as_dashboard_object.rb +19 -0
- data/lib/dash_creator/engine.rb +11 -0
- data/lib/dash_creator/version.rb +3 -0
- data/lib/generators/dash_creator/install/install_generator.rb +70 -0
- data/lib/generators/dash_creator/install/templates/_chart.html.erb +9 -0
- data/lib/generators/dash_creator/install/templates/_section_card.html.erb +17 -0
- data/lib/generators/dash_creator/install/templates/_stat.html.erb +24 -0
- data/lib/generators/dash_creator/install/templates/_table.html.erb +16 -0
- data/lib/generators/dash_creator/install/templates/add_indexes_to_dash_creator_tables.rb +15 -0
- data/lib/generators/dash_creator/install/templates/create_dash_creator_charts.rb +25 -0
- data/lib/generators/dash_creator/install/templates/create_dash_creator_dashboard_objects.rb +36 -0
- data/lib/generators/dash_creator/install/templates/create_dash_creator_dashboards.rb +28 -0
- data/lib/generators/dash_creator/install/templates/create_dash_creator_filters.rb +22 -0
- data/lib/generators/dash_creator/install/templates/dashboard.html.erb +10 -0
- data/lib/generators/dash_creator/install/templates/initializer.rb +48 -0
- data/lib/tasks/dash_creator_tasks.rake +4 -0
- metadata +196 -0
@@ -0,0 +1,531 @@
|
|
1
|
+
/*!
|
2
|
+
* Dashboard Creator v1.0
|
3
|
+
* 2017 Elie Oriol
|
4
|
+
*/
|
5
|
+
|
6
|
+
(function(factory) {
|
7
|
+
if (typeof define === 'function' && define.amd) {
|
8
|
+
define([ 'jquery' ], factory);
|
9
|
+
}
|
10
|
+
else if (typeof exports === 'object') { // Node/CommonJS
|
11
|
+
module.exports = factory(require('jquery'));
|
12
|
+
}
|
13
|
+
else {
|
14
|
+
factory(jQuery);
|
15
|
+
}
|
16
|
+
})(function($) {
|
17
|
+
var DashboardCreator = function(element, options, callback) {
|
18
|
+
this.parentEl = $(element);
|
19
|
+
|
20
|
+
// Objects data format:
|
21
|
+
// 'object.code': {
|
22
|
+
// 'related_model': object.related_model,
|
23
|
+
// 'name': object.name,
|
24
|
+
// 'objects': [model_objects]
|
25
|
+
// }
|
26
|
+
|
27
|
+
// Model object format:
|
28
|
+
// {
|
29
|
+
// 'id': object.id,
|
30
|
+
// 'name': object.name
|
31
|
+
// }
|
32
|
+
|
33
|
+
if (typeof options !== 'object' || options === null)
|
34
|
+
options = {};
|
35
|
+
|
36
|
+
this.objects_data = typeof options.objects_data === 'object' ? options.objects_data : {};
|
37
|
+
|
38
|
+
this.callback = (typeof callback === 'function') ? callback : function() { };
|
39
|
+
|
40
|
+
if (typeof options.template !== 'string' && !(options.template instanceof $)) {
|
41
|
+
options.template = '<div class="row">' +
|
42
|
+
'<div class="col-md-12 px-2" style="background-color: #eee; border-radius: 10px; padding: 20px 10px;">' +
|
43
|
+
'<h3>Dashboard Preview</h3>' +
|
44
|
+
'<div class="row" id="dashboard-preview" style="margin: 30px; padding: 20px; border: 1px dashed black; border-radius: 10px;">' +
|
45
|
+
'</div>' +
|
46
|
+
'</div>' +
|
47
|
+
'<div class="col-md-12 px-2">' +
|
48
|
+
'<div class="row" id="sections-container">' +
|
49
|
+
'<div class="col-sm-12" style="margin-top:50px;" id="add-section-btn-container">' +
|
50
|
+
'<button id="add-section-btn" class="btn btn-primary">+</button>' +
|
51
|
+
'</div>' +
|
52
|
+
'</div>' +
|
53
|
+
'</div>' +
|
54
|
+
'</div>';
|
55
|
+
}
|
56
|
+
|
57
|
+
this.container = $(options.template).appendTo(this.parentEl);
|
58
|
+
this.sections_container = this.container.find('div#sections-container');
|
59
|
+
this.dashboard_preview = this.container.find('div#dashboard-preview');
|
60
|
+
|
61
|
+
this.sections_container
|
62
|
+
.on('click', '#add-section-btn', $.proxy(this.addSection, this))
|
63
|
+
.on('click', '.remove-section-btn', $.proxy(this.removeSection, this))
|
64
|
+
.on('change', 'input[name="section-name"]', $.proxy(this.changeSectionName, this))
|
65
|
+
.on('click', '.add-object-btn', $.proxy(this.addObject, this))
|
66
|
+
.on('click', '.remove-object-btn', $.proxy(this.removeObject, this))
|
67
|
+
.on('change', 'select[name="object_type"]', $.proxy(this.displayObjectSelect, this))
|
68
|
+
.on('blur', 'select[name="object_select"]', $.proxy(this.selectObjectResponse, this))
|
69
|
+
.on('change', 'select[name="object_select"]', $.proxy(this.selectObjectResponse, this));
|
70
|
+
|
71
|
+
this.dashboard_preview
|
72
|
+
.on('change', 'input[name="section-size"]', $.proxy(this.changeSectionSize, this))
|
73
|
+
.on('change', 'input[name="section-offset"]', $.proxy(this.changeSectionOffset, this))
|
74
|
+
.on('change', 'input[name="object-size"]', $.proxy(this.changeObjectSize, this))
|
75
|
+
.on('change', 'input[name="object-offset"]', $.proxy(this.changeObjectOffset, this))
|
76
|
+
// Event 'build' to avoid wrong dashboard display
|
77
|
+
.on('build', 'input[name="section-size"]', $.proxy(this.changeSectionSize, this))
|
78
|
+
.on('build', 'input[name="section-offset"]', $.proxy(this.changeSectionOffset, this))
|
79
|
+
.on('build', 'input[name="object-size"]', $.proxy(this.changeObjectSize, this))
|
80
|
+
.on('build', 'input[name="object-offset"]', $.proxy(this.changeObjectOffset, this));
|
81
|
+
};
|
82
|
+
|
83
|
+
DashboardCreator.prototype = {
|
84
|
+
|
85
|
+
constructor: DashboardCreator,
|
86
|
+
|
87
|
+
// --------------- Sections handling ---------------
|
88
|
+
// Add section
|
89
|
+
addSection: function() {
|
90
|
+
var last_section = this.sections_container.find('.section:last');
|
91
|
+
var section_id = last_section.length === 0 ? 1 : parseInt(last_section.attr('data-section-id')) + 1;
|
92
|
+
|
93
|
+
this.addCreatorSection(section_id);
|
94
|
+
this.addPreviewSection(section_id);
|
95
|
+
},
|
96
|
+
|
97
|
+
// Add section to creator
|
98
|
+
addCreatorSection: function(section_id) {
|
99
|
+
var section_string = '<div class="col-sm-12 section" data-section-id="' + section_id + '" style="margin-top: 50px;">'
|
100
|
+
+ '<div class="row">'
|
101
|
+
+ '<div class="col-sm-1">'
|
102
|
+
+ '<button type="button" class="close remove-section-btn" aria-label="Close">'
|
103
|
+
+ '<span aria-hidden="true">×</span>'
|
104
|
+
+ '</button>'
|
105
|
+
+ '</div>'
|
106
|
+
+ '<div class="col-sm-2">'
|
107
|
+
+ '<h5 class="section-name">Section ' + section_id + '</h5>'
|
108
|
+
+ '</div>'
|
109
|
+
+ '<div class="form-group col-sm-9">'
|
110
|
+
+ '<input type="text" name="section-name" value="Section ' + section_id + '" class="form-control">'
|
111
|
+
+ '</div>'
|
112
|
+
+ '<div class="col-sm-11 offset-sm-1">'
|
113
|
+
+ '<ul class="section-objects-list"></ul>'
|
114
|
+
+ '<button class="btn-sm btn-primary add-object-btn">+</button>'
|
115
|
+
+ '</div></div></div>';
|
116
|
+
|
117
|
+
$(section_string).appendTo(this.sections_container);
|
118
|
+
},
|
119
|
+
|
120
|
+
// Add section to preview
|
121
|
+
addPreviewSection: function(section_id) {
|
122
|
+
var preview_section_string = '<div class="col-sm-12 preview-section" data-section-id="' + section_id + '" style="padding: 20px; overflow: auto;">'
|
123
|
+
+ '<div style="padding: 15px 30px; background-color: #2d8ac7; border: 1px solid #0e6498; border-radius: 5px;">'
|
124
|
+
+ '<div class="row" style="margin-bottom: 20px;">'
|
125
|
+
+ '<div class="col-sm-6">'
|
126
|
+
+ '<h5 class="section-name">Section ' + section_id + '</h5>'
|
127
|
+
+ '</div>'
|
128
|
+
+ '<div class="col-sm-3">'
|
129
|
+
+ '<input type="number" name="section-size" min="1" max="12" step="1" value="12" class="form-control">'
|
130
|
+
+ '</div>'
|
131
|
+
+ '<div class="col-sm-3">'
|
132
|
+
+ '<input type="number" name="section-offset" min="0" max="11" step="1" value="0" class="form-control">'
|
133
|
+
+ '</div></div>'
|
134
|
+
+ '<div class="row preview-objects-container"></div>'
|
135
|
+
+ '</div></div>';
|
136
|
+
|
137
|
+
$(preview_section_string).appendTo(this.dashboard_preview);
|
138
|
+
},
|
139
|
+
|
140
|
+
removeSection: function(e) {
|
141
|
+
var target = $(e.target);
|
142
|
+
|
143
|
+
var section_id = target.closest('.section').attr("data-section-id");
|
144
|
+
this.removeCreatorSection(section_id);
|
145
|
+
this.removePreviewSection(section_id);
|
146
|
+
},
|
147
|
+
|
148
|
+
// Remove section from creator
|
149
|
+
removeCreatorSection: function(section_id) {
|
150
|
+
this.sections_container.find('.section[data-section-id="' + section_id + '"]').remove();
|
151
|
+
},
|
152
|
+
|
153
|
+
// Remove section from preview
|
154
|
+
removePreviewSection: function(section_id) {
|
155
|
+
this.dashboard_preview.find('.preview-section[data-section-id="' + section_id + '"]').remove();
|
156
|
+
},
|
157
|
+
|
158
|
+
changeSectionName: function(e) {
|
159
|
+
var target = $(e.target);
|
160
|
+
|
161
|
+
var section_id = target.closest('.section').attr('data-section-id');
|
162
|
+
var preview_section = this.dashboard_preview.find('.preview-section[data-section-id="' + section_id + '"]');
|
163
|
+
var section_name = target.val();
|
164
|
+
preview_section.find('.section-name').text(section_name);
|
165
|
+
},
|
166
|
+
|
167
|
+
|
168
|
+
// --------------- Objects handling ---------------
|
169
|
+
// Add an object to section
|
170
|
+
addObject: function(e) {
|
171
|
+
var target = $(e.target);
|
172
|
+
|
173
|
+
var objects_list = target.siblings('.section-objects-list');
|
174
|
+
var section_id = target.closest('.section').attr("data-section-id");
|
175
|
+
|
176
|
+
var last_object = objects_list.find('.object:last');
|
177
|
+
var new_object_id = last_object.length === 0 ? 1 : parseInt(last_object.attr("data-id")) + 1;
|
178
|
+
|
179
|
+
var object_string = '<li class="object" data-section-id="' + section_id + '" data-id="' + new_object_id + '">'
|
180
|
+
+ '<div class="row">'
|
181
|
+
+ '<div class="col-sm-1">'
|
182
|
+
+ '<button type="button" class="close remove-object-btn" aria-label="Close">'
|
183
|
+
+ '<span aria-hidden="true">×</span>'
|
184
|
+
+ '</button>'
|
185
|
+
+ '</div>'
|
186
|
+
+ '<div class="form-group col-sm-5">'
|
187
|
+
+ '<select name="object_type" class="form-control"></select>'
|
188
|
+
+ '</div>'
|
189
|
+
+ '<div class="form-group col-sm-5 offset-sm-1 select-object">'
|
190
|
+
+ '</div>'
|
191
|
+
+ '</div></li>';
|
192
|
+
|
193
|
+
var li_object = $(object_string).appendTo(objects_list);
|
194
|
+
|
195
|
+
var options_string = '<option value="">Choose object type</option>';
|
196
|
+
$.each(this.objects_data, function(type, data) {
|
197
|
+
var name = data['name'];
|
198
|
+
options_string += '<option value="' + type + '">' + name + '</option>';
|
199
|
+
});
|
200
|
+
|
201
|
+
$(options_string).appendTo(li_object.find('[name="object_type"]'));
|
202
|
+
},
|
203
|
+
|
204
|
+
// Remove an object from section
|
205
|
+
removeObject: function(e) {
|
206
|
+
var target = $(e.target);
|
207
|
+
|
208
|
+
// Remove from creator and preview
|
209
|
+
var object_div = target.closest('.object');
|
210
|
+
var section_id = object_div.attr("data-section-id"), object_id = object_div.attr("data-id");
|
211
|
+
var preview_object = this.dashboard_preview.find('.preview-object[data-section-id="' + section_id + '"][data-id="' + object_id + '"]');
|
212
|
+
object_div.remove();
|
213
|
+
preview_object.remove();
|
214
|
+
},
|
215
|
+
|
216
|
+
// Display select according to object type selected
|
217
|
+
displayObjectSelect: function(e) {
|
218
|
+
var target = $(e.target);
|
219
|
+
|
220
|
+
// Remove select if already one
|
221
|
+
var select_object_div = target.closest('.object').find('.select-object');
|
222
|
+
select_object_div.children().remove();
|
223
|
+
|
224
|
+
// Return if type is empty (value of select prompt)
|
225
|
+
var object_type = target.val();
|
226
|
+
if (object_type === '') return;
|
227
|
+
|
228
|
+
// Retrieve object type info
|
229
|
+
var object_model_name = this.objects_data[object_type]['related_model'];
|
230
|
+
|
231
|
+
// Add select if associated to model
|
232
|
+
if (object_model_name !== '') {
|
233
|
+
var select_string = '<select name="object_select" class="form-control">'
|
234
|
+
+ '<option value="">Choose a ' + object_type + '</option>'
|
235
|
+
+ '</select>';
|
236
|
+
|
237
|
+
var select = $(select_string).appendTo(select_object_div);
|
238
|
+
|
239
|
+
// Add options to select
|
240
|
+
var objects = this.objects_data[object_type]['objects'];
|
241
|
+
var options_string = '';
|
242
|
+
for (var i = 0; i < objects.length; i++) {
|
243
|
+
var name = objects[i]['name'], id = objects[i]['id'];
|
244
|
+
options_string += '<option value="' + id + '">' + name + '</option>';
|
245
|
+
}
|
246
|
+
|
247
|
+
$(options_string).appendTo(select);
|
248
|
+
}
|
249
|
+
},
|
250
|
+
|
251
|
+
// Respond to object select change
|
252
|
+
selectObjectResponse: function(e) {
|
253
|
+
var target = $(e.target);
|
254
|
+
|
255
|
+
var option_value = target.val();
|
256
|
+
|
257
|
+
var object_div = target.closest('.object');
|
258
|
+
var id = object_div.attr("data-id"), section_id = object_div.attr("data-section-id");
|
259
|
+
|
260
|
+
if (option_value === '') return this.removeObjectPreview(id, section_id);
|
261
|
+
|
262
|
+
this.addObjectPreview(id, section_id);
|
263
|
+
},
|
264
|
+
|
265
|
+
// Add object to preview
|
266
|
+
addObjectPreview: function(id, section_id) {
|
267
|
+
var object_div = this.sections_container.find('[data-id="' + id + '"][data-section-id="' + section_id + '"]');
|
268
|
+
var object_type = object_div.find('[name="object_type"] option:selected').text();
|
269
|
+
var object_name = object_div.find('[name="object_select"] option:selected').text();
|
270
|
+
|
271
|
+
var object_preview_string = '<div class="col-sm-6 preview-object" data-section-id="' + section_id + '" data-id="' + id + '" style="padding: 20px;">'
|
272
|
+
+ '<div class="row" style="height: 100px; padding: 10px; background-color: #00bf8f; border: 1px solid #00a67c; border-radius: 5px;">'
|
273
|
+
+ '<div class="col-sm-12" style="margin-bottom: 10px;">'
|
274
|
+
+ '<strong>' + object_type + ' ' + object_name + '</strong>'
|
275
|
+
+ '</div>'
|
276
|
+
+ '<div class="col-sm-6">'
|
277
|
+
+ '<input type="number" name="object-size" min="1" max="12" step="1" value="6" class="form-control">'
|
278
|
+
+ '</div>'
|
279
|
+
+ '<div class="col-sm-6">'
|
280
|
+
+ '<input type="number" name="object-offset" min="0" max="11" step="1" value="0" class="form-control">'
|
281
|
+
+ '</div></div></div>';
|
282
|
+
|
283
|
+
var preview_objects_container = this.dashboard_preview.find('.preview-section[data-section-id="' + section_id + '"] .preview-objects-container');
|
284
|
+
var preview_section_objects = preview_objects_container.find('.preview-object');
|
285
|
+
|
286
|
+
if (preview_section_objects.length === 0) return $(object_preview_string).appendTo(preview_objects_container);
|
287
|
+
if (preview_objects_container.find('.preview-object[data-id="' + id +'"]').length !== 0) return;
|
288
|
+
|
289
|
+
var to_append = true;
|
290
|
+
preview_section_objects.each(function() {
|
291
|
+
if (parseInt($(this).attr("data-id")) > id) {
|
292
|
+
to_append = false;
|
293
|
+
return $(object_preview_string).insertBefore($(this));
|
294
|
+
}
|
295
|
+
});
|
296
|
+
if (to_append) $(object_preview_string).appendTo(preview_objects_container);
|
297
|
+
},
|
298
|
+
|
299
|
+
// Remove object from preview
|
300
|
+
removeObjectPreview: function(id, section_id) {
|
301
|
+
this.dashboard_preview.find('[data-id="' + id + '"][data-section-id="' + section_id + '"]').remove();
|
302
|
+
},
|
303
|
+
|
304
|
+
// Change section preview on size change
|
305
|
+
changeSectionSize: function(e) {
|
306
|
+
var target = $(e.target);
|
307
|
+
|
308
|
+
var size = target.val();
|
309
|
+
var preview_section = target.closest('.preview-section');
|
310
|
+
|
311
|
+
var new_class = 'col-sm-' + size, old_class = 'col-sm-12';
|
312
|
+
|
313
|
+
$.each(preview_section.attr("class").split(' '), function(index, c) {
|
314
|
+
if (c.indexOf('col-sm-') !== -1)
|
315
|
+
return old_class = c;
|
316
|
+
});
|
317
|
+
|
318
|
+
if (new_class !== old_class) {
|
319
|
+
var duration = e.type === 'change' ? 400 : 0;
|
320
|
+
preview_section.switchClass(old_class, new_class, duration);
|
321
|
+
}
|
322
|
+
},
|
323
|
+
|
324
|
+
// Change section preview on offset change
|
325
|
+
changeSectionOffset: function(e) {
|
326
|
+
var target = $(e.target);
|
327
|
+
|
328
|
+
var offset = target.val();
|
329
|
+
var preview_section = target.closest('.preview-section');
|
330
|
+
|
331
|
+
var new_class = 'offset-sm-' + offset, old_class = '';
|
332
|
+
|
333
|
+
$.each(preview_section.attr("class").split(' '), function(index, c) {
|
334
|
+
if (c.indexOf('offset-sm-') !== -1)
|
335
|
+
return old_class = c;
|
336
|
+
});
|
337
|
+
|
338
|
+
if (new_class !== old_class) {
|
339
|
+
var duration = e.type === 'change' ? 400 : 0;
|
340
|
+
preview_section.switchClass(old_class, new_class, duration);
|
341
|
+
}
|
342
|
+
},
|
343
|
+
|
344
|
+
// Change object preview on size change
|
345
|
+
changeObjectSize: function(e) {
|
346
|
+
var target = $(e.target);
|
347
|
+
|
348
|
+
var size = target.val();
|
349
|
+
var preview_object = target.closest('.preview-object');
|
350
|
+
|
351
|
+
var new_class = 'col-sm-' + size, old_class = 'col-sm-6';
|
352
|
+
|
353
|
+
$.each(preview_object.attr("class").split(' '), function(index, c) {
|
354
|
+
if (c.indexOf('col-sm-') !== -1)
|
355
|
+
return old_class = c;
|
356
|
+
});
|
357
|
+
|
358
|
+
if (new_class !== old_class) {
|
359
|
+
var duration = e.type === 'change' ? 400 : 0;
|
360
|
+
preview_object.switchClass(old_class, new_class, duration);
|
361
|
+
}
|
362
|
+
},
|
363
|
+
|
364
|
+
// Change object preview on offset change
|
365
|
+
changeObjectOffset: function(e) {
|
366
|
+
var target = $(e.target);
|
367
|
+
|
368
|
+
var offset = target.val();
|
369
|
+
var preview_object = target.closest('.preview-object');
|
370
|
+
|
371
|
+
var new_class = 'offset-sm-' + offset, old_class = '';
|
372
|
+
|
373
|
+
$.each(preview_object.attr("class").split(' '), function(index, c) {
|
374
|
+
if (c.indexOf('offset-sm-') !== -1)
|
375
|
+
return old_class = c;
|
376
|
+
});
|
377
|
+
|
378
|
+
if (new_class !== old_class) {
|
379
|
+
var duration = e.type === 'change' ? 400 : 0;
|
380
|
+
preview_object.switchClass(old_class, new_class, duration);
|
381
|
+
}
|
382
|
+
},
|
383
|
+
|
384
|
+
|
385
|
+
// --------------- Prepare data ---------------
|
386
|
+
// Get the dashboard data
|
387
|
+
getDashboardData: function() {
|
388
|
+
var dashboard_data = [];
|
389
|
+
this.getSectionsData(dashboard_data);
|
390
|
+
|
391
|
+
return JSON.parse(JSON.stringify(dashboard_data));
|
392
|
+
},
|
393
|
+
|
394
|
+
// Get sections data
|
395
|
+
getSectionsData: function(dashboard_data) {
|
396
|
+
var creator = this;
|
397
|
+
creator.sections_container.find('.section').each(function() {
|
398
|
+
var section_data = dashboard_data[dashboard_data.push({}) - 1];
|
399
|
+
creator.getSectionData(section_data, $(this));
|
400
|
+
});
|
401
|
+
},
|
402
|
+
|
403
|
+
// Get a section data
|
404
|
+
getSectionData: function(section_data, section_div) {
|
405
|
+
// Get size & offset in preview
|
406
|
+
var section_id = section_div.attr("data-section-id");
|
407
|
+
var preview_section = this.dashboard_preview.find('.preview-section[data-section-id="' + section_id + '"]');
|
408
|
+
var section_size = preview_section.find('[name="section-size"]').val();
|
409
|
+
var section_offset = preview_section.find('[name="section-offset"]').val();
|
410
|
+
|
411
|
+
// Get name
|
412
|
+
var section_name = section_div.find('[name="section-name"]').val();
|
413
|
+
|
414
|
+
// Fill section data in hash
|
415
|
+
|
416
|
+
section_data['name'] = section_name;
|
417
|
+
section_data['size'] = section_size;
|
418
|
+
section_data['offset'] = section_offset;
|
419
|
+
section_data['objects'] = [];
|
420
|
+
|
421
|
+
// Add objects
|
422
|
+
var objects_list = section_div.find('.section-objects-list');
|
423
|
+
this.getObjectsData(section_data['objects'], objects_list);
|
424
|
+
},
|
425
|
+
|
426
|
+
// Get objects data of a section
|
427
|
+
getObjectsData: function(objects_data, objects_list) {
|
428
|
+
var creator = this;
|
429
|
+
objects_list.find('.object').each(function() {
|
430
|
+
var object_data = objects_data[objects_data.push({}) - 1];
|
431
|
+
creator.getObjectData(object_data, $(this));
|
432
|
+
});
|
433
|
+
},
|
434
|
+
|
435
|
+
// Get an object data
|
436
|
+
getObjectData: function(object_data, object_div) {
|
437
|
+
// Get object type and return if empty (don't add to hash)
|
438
|
+
var type = object_div.find('[name="object_type"]').val();
|
439
|
+
if (type === '') return true;
|
440
|
+
|
441
|
+
// Get size & offset in preview
|
442
|
+
var object_id = object_div.attr("data-id"), section_id = object_div.attr("data-section-id");
|
443
|
+
var preview_object = this.dashboard_preview.find('.preview-object[data-section-id="' + section_id + '"][data-id="' + object_id + '"]');
|
444
|
+
var object_size = preview_object.find('[name="object-size"]').val();
|
445
|
+
var object_offset = preview_object.find('[name="object-offset"]').val();
|
446
|
+
|
447
|
+
// Fill object data in hash
|
448
|
+
|
449
|
+
object_data['type'] = type;
|
450
|
+
object_data['size'] = object_size;
|
451
|
+
object_data['offset'] = object_offset;
|
452
|
+
|
453
|
+
var object_select = object_div.find('[name="object_select"]');
|
454
|
+
if (object_select.length !== 0) object_data['id'] = object_select.val();
|
455
|
+
},
|
456
|
+
|
457
|
+
|
458
|
+
// --------------- Build dashboard from data ---------------
|
459
|
+
// Build dashboard from data
|
460
|
+
buildDashboard: function(dashboard_data) {
|
461
|
+
this.sections_container.children().not('#add-section-btn-container').remove();
|
462
|
+
this.dashboard_preview.children().remove();
|
463
|
+
|
464
|
+
this.buildSections(dashboard_data);
|
465
|
+
},
|
466
|
+
|
467
|
+
// Build sections from data
|
468
|
+
buildSections: function(dashboard_data) {
|
469
|
+
var creator = this;
|
470
|
+
// For each section data in dashboard data
|
471
|
+
$.each(dashboard_data, function(index, section_data) {
|
472
|
+
creator.buildSection(section_data);
|
473
|
+
});
|
474
|
+
},
|
475
|
+
|
476
|
+
// Build a section from data
|
477
|
+
buildSection: function(section_data) {
|
478
|
+
// Add new section
|
479
|
+
this.sections_container.find('#add-section-btn').click();
|
480
|
+
|
481
|
+
// Fill section name, size & offset
|
482
|
+
this.sections_container.find('[name="section-name"]:last').val(section_data['name']);
|
483
|
+
this.dashboard_preview.find('[name="section-size"]:last').val(section_data['size']).trigger('build');
|
484
|
+
this.dashboard_preview.find('[name="section-offset"]:last').val(section_data['offset']).trigger('build');
|
485
|
+
|
486
|
+
// Rebuild objects of section
|
487
|
+
this.buildObjects(section_data['objects']);
|
488
|
+
},
|
489
|
+
|
490
|
+
// Build objects of a section from data
|
491
|
+
buildObjects: function(objects_data) {
|
492
|
+
var creator = this;
|
493
|
+
// For each object data in objects array
|
494
|
+
$.each(objects_data, function(index, object_data) {
|
495
|
+
creator.buildObject(object_data);
|
496
|
+
});
|
497
|
+
},
|
498
|
+
|
499
|
+
// Build an object from data
|
500
|
+
buildObject: function(object_data) {
|
501
|
+
// Add new object to section
|
502
|
+
this.sections_container.find('.add-object-btn:last').click();
|
503
|
+
|
504
|
+
// Fill object type
|
505
|
+
var type = object_data['type'];
|
506
|
+
this.sections_container.find('[name="object_type"]:last').val(type).change();
|
507
|
+
|
508
|
+
// Select object
|
509
|
+
var object_select = this.sections_container.find('[name="object_select"]:last');
|
510
|
+
if (object_select.length !== 0) object_select.val(object_data['id']).change();
|
511
|
+
|
512
|
+
// Fill object size & offset
|
513
|
+
this.dashboard_preview.find('[name="object-size"]:last').val(object_data['size']).trigger('build');
|
514
|
+
this.dashboard_preview.find('[name="object-offset"]:last').val(object_data['offset']).trigger('build');
|
515
|
+
}
|
516
|
+
|
517
|
+
};
|
518
|
+
|
519
|
+
$.fn.dashboardCreator = function(options, callback) {
|
520
|
+
this.each(function(i, _element) {
|
521
|
+
var el = $(_element);
|
522
|
+
if (el.data('dashboardCreator'))
|
523
|
+
el.data('dashboardCreator').remove();
|
524
|
+
el.data('dashboardCreator', new DashboardCreator(el, options, callback));
|
525
|
+
});
|
526
|
+
return this;
|
527
|
+
};
|
528
|
+
|
529
|
+
return DashboardCreator;
|
530
|
+
});
|
531
|
+
|