PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 1.1.2
Visualizer – Tables & Charts Manager with Built-in AI Generator v1.1.2
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 3.10.4 All 148 releases
← All changes | js/frame.js +55 -949 4.0.41.1.2 View file →
@@ -1,855 +1,63 @@
1 -/* global prompt */
2 -/* global visualizer */
3 -/* global alert */
4 -/* global confirm */
5 -/* global ajaxurl */
6 -/* global CodeMirror */
7 -/* global vizHaveSettingsChanged */
1 +(function($) {
2 + $(document).ready(function() {
3 + $('.type-radio').change(function() {
4 + $('.type-label-selected').removeClass('type-label-selected');
5 + $(this).parent().addClass('type-label-selected');
6 + });
8 7
9 -(function ($) {
10 - $(window).on('load', function(){
11 - let chart_select = $('#chart-select');
12 - if(chart_select.length > 0){
13 - // scroll to the selected chart type.
14 - $('#chart-select')[0].scrollIntoView();
15 - }
16 - });
8 + $('.group-title').click(function() {
9 + var parent = $(this).parent();
17 10
18 - $(document).ready(function () {
19 - onReady();
20 - });
11 + if (parent.hasClass('open')) {
12 + parent.removeClass('open');
13 + } else {
14 + $('.group.open').removeClass('open');
15 + parent.addClass('open');
16 + }
17 + });
21 18
22 - function initTabs(){
23 - $( "#sidebar" ).lock();
24 - $( "#viz-tabs" ).tabs({
25 - create: function( event, ui ) {
26 - $(this).addClass('done');
27 - $( "#sidebar" ).unlock();
28 - },
29 - beforeActivate: function( event, ui ) {
30 - // if settings have changed in tab #2 and tab #1 is being activated, warn the user.
31 - if(vizHaveSettingsChanged() && ui.newTab.find( 'a' ).attr( 'id' ).includes('viz-tab-basic')){
32 - return confirm(visualizer.l10n.save_settings);
33 - }
34 - }
35 - });
36 - }
19 + $('#remote-file').click(function() {
20 + var url = $.trim(prompt(visualizer.l10n.remotecsv_prompt));
37 21
38 - function onReady() {
39 - initAccessibility();
40 - initTabs();
22 + if (url != '') {
23 + if(/^([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*|(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)){0})(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(url)) {
24 + $('#remote-data').val(url);
25 + $('#csv-file').val('');
26 + $('#canvas').lock();
27 + $('#csv-form').submit();
28 + } else {
29 + alert(visualizer.l10n.invalid_source);
30 + }
31 + }
32 + });
41 33
42 - // open the correct source tab/sub-tab.
43 - var source = $('#visualizer-chart-id').attr('data-chart-source');
44 - $('li.viz-group.' + source).addClass('open');
45 - $('li.viz-group.' + source + ' span.viz-section-title.' + source).addClass('open');
46 - $('li.viz-group.' + source + ' span.viz-section-title.' + source + '.open').parent().find('div.viz-section-items').show();
34 + $('#csv-file').change(function() {
35 + if ($.trim($(this).val()) != '') {
36 + $('#remote-data').val('');
37 + $('#canvas').lock();
38 + $('#csv-form').submit();
39 + }
40 + });
47 41
48 - init_permissions();
42 + $('#thehole').load(function() {
43 + $('#canvas').unlock();
44 + });
49 45
50 - if(typeof visualizer !== 'undefined' && visualizer.is_pro) {
51 - init_db_import();
52 - init_filter_import();
53 - }
46 + $('.section-title').click(function() {
47 + $(this).toggleClass('open').parent().find('.section-items').toggle();
48 + });
54 49
55 - init_json_import();
56 -
57 - init_editor_table();
58 -
59 - // update the manual configuation link to point to the correct chart type.
60 - var type = $('#visualizer-chart-id').attr('data-chart-type');
61 - var chart_type_in_api_link = type + 'chart';
62 - switch (type) {
63 - case "gauge":
64 - case "table":
65 - case "timeline":
66 - chart_type_in_api_link = type;
67 - break;
68 - }
69 -
70 - if($('span.viz-gvlink').length > 0) {
71 - $('span.viz-gvlink').html($('span.viz-gvlink').html().replace('?', chart_type_in_api_link));
72 - }
73 -
74 - $('.type-radio').change(function () {
75 - $('.type-label-selected').removeClass('type-label-selected');
76 - $(this).parent().addClass('type-label-selected');
77 - updateTypeAriaChecked();
78 - });
79 -
80 - // collapse other open sections of this group
81 - $(document).on('click', '.viz-group-title', function () {
82 - var parent = $(this).parent();
83 -
84 - if (parent.hasClass('open')) {
85 - parent.removeClass('open');
86 - } else {
87 - parent.parent().find('.viz-group.open').removeClass('open');
88 - parent.addClass('open');
89 - }
90 -
91 - /*
92 - * if the user wants to perform an action and click that tab to change the source
93 - * and the chart is no longer showing because that particular LHS screen is showing
94 - * e.g. create parameters, import json, db query box etc.
95 - * we need to make sure we cancel the current process WITHOUT saving
96 - * and then show the chart as it was
97 - * let's close the LHS window and show the chart that is hidden
98 - */
99 - $('body').trigger('visualizer:change:action');
100 - updateGroupAriaState($(this));
101 - });
102 -
103 - // collapse other open subsections of this section
104 - $(document).on('click', '.viz-section-title', function () {
105 - var grandparent = $(this).parent().parent();
106 - grandparent.find('.viz-section-title.open').not(this).each(function () {
107 - $(this).removeClass('open').siblings('.viz-section-items').hide();
108 - });
109 - updateSectionAriaState($(this));
110 - });
111 -
112 - $('#view-remote-file').click(function () {
113 - var url = $(this).parent().find('#vz-schedule-url').val();
114 -
115 - if (url !== '') {
116 - if (url.indexOf('localhost') !== -1 || /^([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*|(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)){0})(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(url)) {
117 - if (url.substr(url.length - 8) === '/pubhtml') {
118 - url = url.substring(0, url.length - 8) + '/export?format=csv';
119 - }
120 -
121 - $('#canvas').lock();
122 - $(this).parent().submit();
123 - } else {
124 - alert(visualizer.l10n.invalid_source);
125 - }
126 - }
127 - });
128 -
129 - $('#vz-import-file').click(function (e) {
130 - e.preventDefault();
131 - if ($.trim($(this).parent().find("#csv-file").val()) !== '') {
132 - $('#canvas').lock();
133 - $(this).parent().submit();
134 - }
135 - });
136 -
137 - $( window ).on( 'load', function() {
138 - $('#canvas').unlock();
139 - } );
140 -
141 - $(document).on('click', '.viz-section-title', function () {
142 - $(this).toggleClass('open').parent().find('.viz-section-items').toggle();
143 - });
144 -
145 - $(document).on('click', '.more-info', function () {
146 - $(this).parent().find('.viz-section-description:first').toggle();
147 - return false;
148 - });
149 -
150 - $('#cancel-button').click(function () {
151 - $('#cancel-form').submit();
152 - });
153 -
154 - init_available_chart_list();
155 -
156 - $('.viz-abort').on('click', function(e){
157 - e.preventDefault();
158 - window.parent.postMessage('visualizer:mediaframe:close', '*');
159 - });
160 -
161 - }
162 -
163 - function initAccessibility(){
164 - // Chart type picker: treat tiles as radios with keyboard support.
165 - var $typePicker = $('#type-picker');
166 - if($typePicker.length){
167 - $typePicker.attr('role', 'radiogroup');
168 - $('.type-label').each(function(){
169 - var $label = $(this);
170 - var $input = $label.find('input[type="radio"]');
171 - $label.attr('tabindex', '0').attr('role', 'radio');
172 - if($input.length){
173 - $label.attr('aria-checked', $input.is(':checked') ? 'true' : 'false');
174 - }else{
175 - $label.attr('aria-disabled', 'true');
176 - }
177 - });
178 - $(document).on('keydown', '.type-label', function(e){
179 - if(e.key === 'Enter' || e.key === ' '){
180 - e.preventDefault();
181 - var $label = $(this);
182 - var $input = $label.find('input[type="radio"]');
183 - if($input.length){
184 - $input.prop('checked', true).trigger('change');
185 - }
186 - }
187 - });
188 - }
189 -
190 - // Collapsible groups: add button roles + keyboard activation.
191 - $('.viz-group-title').each(function(index){
192 - var $title = $(this);
193 - $title.attr('role', 'button').attr('tabindex', '0');
194 - var $content = $title.siblings('.viz-group-content');
195 - if($content.length){
196 - if(!$content.attr('id')){
197 - $content.attr('id', 'viz-group-content-' + index);
198 - }
199 - $title.attr('aria-controls', $content.attr('id'));
200 - updateGroupAriaState($title);
201 - }
202 - });
203 - $(document).on('keydown', '.viz-group-title', function(e){
204 - if(e.key === 'Enter' || e.key === ' '){
205 - e.preventDefault();
206 - $(this).trigger('click');
207 - }
208 - });
209 -
210 - // Subsections in source panel.
211 - $('.viz-section-title').each(function(index){
212 - var $title = $(this);
213 - $title.attr('role', 'button').attr('tabindex', '0');
214 - var $items = $title.siblings('.viz-section-items');
215 - if($items.length){
216 - if(!$items.attr('id')){
217 - $items.attr('id', 'viz-section-items-' + index);
218 - }
219 - $title.attr('aria-controls', $items.attr('id'));
220 - updateSectionAriaState($title);
221 - }
222 - });
223 - $(document).on('keydown', '.viz-section-title', function(e){
224 - if(e.key === 'Enter' || e.key === ' '){
225 - e.preventDefault();
226 - $(this).trigger('click');
227 - }
228 - });
229 - }
230 -
231 - function updateTypeAriaChecked(){
232 - $('.type-label').each(function(){
233 - var $label = $(this);
234 - var $input = $label.find('input[type="radio"]');
235 - if($input.length){
236 - $label.attr('aria-checked', $input.is(':checked') ? 'true' : 'false');
237 - }
238 - });
239 - }
240 -
241 - function updateGroupAriaState($title){
242 - if(!$title || $title.length === 0){
243 - return;
244 - }
245 - var isOpen = $title.parent().hasClass('open');
246 - $title.attr('aria-expanded', isOpen ? 'true' : 'false');
247 - }
248 -
249 - function updateSectionAriaState($title){
250 - if(!$title || $title.length === 0){
251 - return;
252 - }
253 - var isOpen = $title.hasClass('open');
254 - $title.attr('aria-expanded', isOpen ? 'true' : 'false');
255 - }
256 -
257 - /**
258 - * Initialize/Update the available chart list based on their supported renderer libraries.
259 - *
260 - * @returns {void}
261 - */
262 - function init_available_chart_list() {
263 - const rendererSelect = document.querySelector('select.viz-select-library');
264 - if ( ! rendererSelect ) {
265 - return;
266 - }
267 -
268 - const rendererTypesMappingData = rendererSelect?.getAttribute('data-type-vs-library');
269 - if( ! rendererTypesMappingData ) {
270 - return;
271 - }
272 -
273 - /** @type {Record<string, ('GoogleCharts' | 'ChartJS' | 'DataTable')[]>} */
274 - const rendererTypesMapping = JSON.parse( rendererTypesMappingData );
275 -
276 - document.querySelectorAll('input.type-radio').forEach( chartTypeRadio => {
277 -
278 - // Init the lib based on the default selected chart type.
279 - if ( chartTypeRadio.checked ) {
280 - const chartType = chartTypeRadio.value;
281 - if ( ! chartType ) {
282 - return;
283 - }
284 -
285 - const selectedRenderer = rendererSelect.value;
286 - if ( ! rendererTypesMapping[chartType]?.includes( selectedRenderer ) ) {
287 - disable_renderer_select_placeholder();
288 - rendererSelect.value = rendererTypesMapping[chartType][0]
289 - }
290 - }
291 -
292 - chartTypeRadio.addEventListener('click', (event) => {
293 - // Check if the chart type is supported by the selected renderer. If not, select the first supported renderer.
294 - const chartType = event.target.value;
295 - if ( ! chartType ) {
296 - return;
297 - }
298 -
299 - const selectedRenderer = rendererSelect.value;
300 - if ( ! rendererTypesMapping[chartType]?.includes( selectedRenderer ) ) {
301 - disable_renderer_select_placeholder();
302 - rendererSelect.value = rendererTypesMapping[chartType][0]
303 - }
304 - });
305 - });
306 -
307 - // Update the chart list on user interaction.
308 - rendererSelect.addEventListener('change', (event) => {
309 - disable_renderer_select_placeholder();
310 - toggle_renderer_type( event.target.value );
311 - toggle_chart_types_by_render( event.target.value );
312 - });
313 -
314 - }
315 -
316 - /**
317 - * Disable the placeholder option in the renderer select.
318 - */
319 - function disable_renderer_select_placeholder() {
320 - const placeholderOption = document.querySelector('#library-select-placeholder');
321 - if ( placeholderOption && placeholderOption.disabled === false ) {
322 - placeholderOption.disabled = true;
323 - }
324 - }
325 -
326 - /**
327 - * Toggle the renderer type class based on the given renderer type.
328 - *
329 - * The class is used to style the chart type picker based on the given renderer library.
330 - *
331 - * @param {('GoogleCharts' | 'ChartJS' | 'DataTable')} rendererType The renderer type to toggle the class.
332 - */
333 - function toggle_renderer_type( rendererType ) {
334 - const typePicker = document.querySelector('#type-picker');
335 - if ( ! typePicker ) {
336 - return;
337 - }
338 -
339 - typePicker.classList.remove('lib-GoogleCharts', 'lib-ChartJS', 'lib-DataTable');
340 - typePicker.classList.add(`lib-${rendererType}`);
341 - }
342 -
343 - /**
344 - * Toggle chart types based on the given renderer type.
345 - *
346 - * @param {('GoogleCharts' | 'ChartJS' | 'DataTable')} rendererType The renderer type to filter the chart types.
347 - */
348 - function toggle_chart_types_by_render( rendererType ) {
349 - document.querySelectorAll('.type-box').forEach( typeBox => {
350 - const hasLib = typeBox.classList.contains(`type-lib-${rendererType}`);
351 - typeBox.classList.toggle('viz-hidden', ! hasLib );
352 -
353 - // Reset unavailable chart type selection.
354 - const chartOption = typeBox.querySelector('input[type="radio"]');
355 - if ( ! hasLib && chartOption?.checked ) {
356 - chartOption.checked = false;
357 - }
358 - });
359 -
360 - enable_libraries_for($('input.type-radio:checked').val(), $typeVsLibrary);
361 - }
362 -
363 - function enable_libraries_for($type, $typeVsLibrary) {
364 - $('select.viz-select-library option').addClass('disabled').attr('disabled', 'disabled');
365 - $('select.viz-select-library option .premium-label').remove();
366 - $('select.viz-select-library option').append('<span class="premium-label"> (PREMIUM)</span>');
367 - var $libs = $typeVsLibrary[$type];
368 - $.each($libs, function( i, $lib ) {
369 - $('select.viz-select-library option[value="' + $lib + '"]').removeClass('disabled').removeAttr('disabled');
370 - $('select.viz-select-library option[value="' + $lib + '"] .premium-label').remove();
371 - });
372 - $('select.viz-select-library').val( $('select.viz-select-library option:not(.disabled)').val() );
373 - }
374 -
375 - function init_permissions(){
376 - $('.visualizer-permission').chosen({
377 - width : '50%',
378 - search_contains : true
379 - });
380 -
381 - $('.visualizer-permission-type').each(function(x, y){
382 - var type = $(y).attr('data-visualizer-permission-type');
383 - var child = $('.visualizer-permission-' + type + '-specific');
384 - if($(y).val() === 'all'){
385 - child.next('div.chosen-container').hide();
386 - return;
387 - }
388 - });
389 -
390 - $('.visualizer-permission-type').on('change', function(evt, params) {
391 - var type = $(this).attr('data-visualizer-permission-type');
392 - var child = $('.visualizer-permission-' + type + '-specific');
393 - child.empty();
394 - if(params.selected === 'all'){
395 - child.next('div.chosen-container').hide();
396 - return;
397 - } else {
398 - child.next('div.chosen-container').show();
399 - }
400 - child.append('<option value="">' + visualizer.l10n['loading'] + '</option>').trigger('chosen:updated');
401 - $.ajax({
402 - url : visualizer.ajax['url'],
403 - method : 'post',
404 - data : {
405 - 'action' : visualizer.ajax['actions']['permissions'],
406 - 'nonce' : visualizer.ajax['nonces']['permissions'],
407 - 'type' : params.selected
408 - },
409 - success : function(d, textStatus, XMLHttpRequest){
410 - if(d.success) {
411 - child.empty();
412 - $.each(d.data, function(k, v){
413 - child.append('<option value="' + k + '">' + v + '</option>');
414 - });
415 - child.trigger('chosen:updated');
416 - }
417 - }
418 - });
419 - });
420 - }
421 -
422 - // https://codemirror.net/
423 - function init_db_import_component(){
424 - var table_columns = visualizer.db_query.tables;
425 - var code_mirror = wp.CodeMirror || CodeMirror;
426 - var cm = code_mirror.fromTextArea($('.visualizer-db-query').get(0), {
427 - value: $('.visualizer-db-query').val(),
428 - autofocus: true,
429 - mode: 'text/x-mysql',
430 - lineWrapping: true,
431 - dragDrop: false,
432 - matchBrackets: true,
433 - autoCloseBrackets: true,
434 - extraKeys: {"Shift-Space": "autocomplete"},
435 - hintOptions: { tables: table_columns }
436 - });
437 -
438 - // force refresh so that the query shows on first time load. Otherwise you have to click on the editor for it to show.
439 - $('body').on('visualizer:db:query:focus', function(event, data){
440 - cm.refresh();
441 - });
442 -
443 - cm.focus();
444 -
445 - // update text area.
446 - cm.on('inputRead', function(x, y){
447 - cm.save();
448 - });
449 -
450 - // backspace and delete do not register so the text box does not get empty if the entire query is deleted
451 - // from the editor. Let's force this.
452 - $('body').on('visualizer:db:query:update', function(event, data){
453 - cm.save();
454 - });
455 -
456 - // clear the editor.
457 - $('body').on('visualizer:db:query:setvalue', function(event, data){
458 - cm.setValue(data.value);
459 - cm.clearHistory();
460 - cm.refresh();
461 - });
462 -
463 - // set an option at runtime?
464 - $('body').on('visualizer:db:query:changeoption', function(event, data){
465 - cm.setOption(data.name, data.value);
466 - });
467 - }
468 -
469 - function init_filter_import() {
470 - $( '#db-filter-save-button' ).on( 'click', function(){
471 - $('#vz-filter-wizard').submit();
472 - $( '#vz-wp-sync-options' ).hide();
473 - $( '#vz-wp-sync-btn' ).attr( 'aria-expanded', false );
474 - });
475 - }
476 -
477 - function init_db_import(){
478 - $( '#visualizer-db-query' ).css("z-index", "-1").hide();
479 -
480 - init_db_import_component();
481 -
482 - $('#visualizer-query-fetch').on('click', function(e){
483 -
484 - $('body').trigger('visualizer:db:query:update', {});
485 - if($('.visualizer-db-query').val() === ''){
486 - return;
487 - }
488 -
489 - start_ajax($('#visualizer-db-query'));
490 - $('.db-wizard-results').empty();
491 - $('.db-wizard-error').empty();
492 - $.ajax({
493 - url : ajaxurl,
494 - method : 'post',
495 - data : {
496 - 'action' : visualizer.ajax['actions']['db_get_data'],
497 - 'security' : visualizer.ajax['nonces']['db_get_data'],
498 - 'params' : $('#db-query-form').serialize()
499 - },
500 - success : function(data){
501 - if(data.success){
502 - $('.db-wizard-results').html(data.data.table);
503 - $('#results').DataTable({
504 - "paging": false
505 - });
506 - }else{
507 - $('.db-wizard-error').html(data.data.msg);
508 - }
509 - },
510 - complete: function(){
511 - end_ajax($('#visualizer-db-query'));
512 - }
513 - });
514 - });
515 -
516 - $( '#db-chart-button' ).on( 'click', function(){
517 -
518 - $('body').off('visualizer:change:action').on('visualizer:change:action', function(e){
519 - var filter_button = $( '#db-chart-button' );
520 - $( '#visualizer-db-query' ).css("z-index", "-1").hide();
521 - filter_button.val( filter_button.attr( 'data-t-chart' ) );
522 - filter_button.html( filter_button.attr( 'data-t-chart' ) );
523 - filter_button.attr( 'data-current', 'chart' );
524 - $( '#canvas' ).css("z-index", "1").show();
525 - });
526 -
527 - $('#content').css('width', 'calc(100% - 350px)');
528 - if( $(this).attr( 'data-current' ) === 'chart'){
529 - $(this).val( $(this).attr( 'data-t-filter' ) );
530 - $(this).html( $(this).attr( 'data-t-filter' ) );
531 - $(this).attr( 'data-current', 'filter' );
532 - $( '.visualizer-editor-lhs' ).hide();
533 - $( '#visualizer-db-query' ).css("z-index", "9999").show();
534 - $('body').trigger('visualizer:db:query:focus', {});
535 - $( '#canvas' ).hide();
536 - }else{
537 - var filter_button = $(this);
538 - $( '#visualizer-db-query' ).css("z-index", "-1").hide();
539 - $('#canvas').lock();
540 - filter_button.val( filter_button.attr( 'data-t-chart' ) );
541 - filter_button.html( filter_button.attr( 'data-t-chart' ) );
542 - filter_button.attr( 'data-current', 'chart' );
543 - $( '#canvas' ).css("z-index", "1").show();
544 - $( '#db-chart-save-button' ).trigger('click');
545 - }
546 - } );
547 -
548 - $( document ).on( 'click', '#vz-db-sync-btn', function(){
549 - var $options = $( '#vz-db-sync-options' );
550 - var isOpen = $options.is( ':visible' );
551 - $options.toggle();
552 - $( this ).attr( 'aria-expanded', ! isOpen );
553 - } );
554 -
555 - $( document ).on( 'click', '#vz-wp-sync-btn', function(){
556 - var $options = $( '#vz-wp-sync-options' );
557 - var isOpen = $options.is( ':visible' );
558 - $options.toggle();
559 - $( this ).attr( 'aria-expanded', ! isOpen );
560 - } );
561 -
562 - $( '#db-chart-save-button' ).on( 'click', function(){
563 - // submit only if a query has been provided.
564 - if($('#db-query-form .visualizer-db-query').val().length > 0){
565 - $('#viz-db-wizard-params').val($('#db-query-form').serialize());
566 - $('#vz-db-wizard').submit();
567 - $( '#vz-db-sync-options' ).hide();
568 - $( '#vz-db-sync-btn' ).attr( 'aria-expanded', false );
569 - }else{
570 - $('#canvas').unlock();
571 - }
572 - });
573 - }
574 -
575 - function init_json_import(){
576 - if(typeof visualizer === 'undefined'){
577 - return;
578 - }
579 -
580 - var regex = new RegExp(visualizer.json_tag_separator, 'g');
581 -
582 - $( '#visualizer-json-screen' ).css("z-index", "-1").hide();
583 - $('.visualizer-json-form').accordion({
584 - heightStyle: 'content',
585 - active: 0
586 - });
587 - $('.visualizer-json-subform').accordion({
588 - heightStyle: 'content',
589 - active: false,
590 - collapsible: true
591 - });
592 -
593 - // open the accordions by default if they are indicated with the 'open' class.
594 - $('.visualizer-json-subform .viz-substep.open').each(function(i, e){
595 - $('.visualizer-json-subform').accordion( "option", "active", i );
596 - });
597 -
598 - // toggle between chart and create/modify parameters
599 - $( '#json-chart-button, #woo-chart-button' ).on( 'click', function(){
600 -
601 - $('body').off('visualizer:change:action').on('visualizer:change:action', function(e){
602 - var filter_button = $( '#json-chart-button, #woo-chart-button' );
603 - $( '#visualizer-json-screen' ).css("z-index", "-1").hide();
604 - filter_button.val( filter_button.attr( 'data-t-chart' ) );
605 - filter_button.html( filter_button.attr( 'data-t-chart' ) );
606 - filter_button.attr( 'data-current', 'chart' );
607 - $( '#canvas' ).css("z-index", "1").show();
608 - $( '#vz-import-woo-report' ).find( 'select, input' ).removeAttr( 'disabled' );
609 - });
610 -
611 - if ( 'json-chart-button' === $( this ).attr( 'id' ) ) {
612 - $( '#vz-import-woo-report' ).find( 'select, input' ).attr( 'disabled', true );
613 - } else {
614 - $( '#vz-import-woo-report' ).find( 'select, input' ).removeAttr( 'disabled' );
615 - }
616 - $('#content').css('width', 'calc(100% - 100px)');
617 - if( $(this).attr( 'data-current' ) === 'chart'){
618 - // toggle from chart to LHS form
619 - $(this).val( $(this).attr( 'data-t-filter' ) );
620 - $(this).html( $(this).attr( 'data-t-filter' ) );
621 - $(this).attr( 'data-current', 'filter' );
622 - $( '.visualizer-editor-lhs' ).hide();
623 - $( '#visualizer-json-screen' ).css("z-index", "9999").show();
624 - if ( 'woo-chart-button' === $( this ).attr( 'id' ) && '' !== $( '#vz-woo-source:visible' ).val() ) {
625 - $( '#vz-import-json-url' ).val( visualizer.rest_base + $( '#vz-woo-source' ).val() ).attr( 'readonly', true );
626 - } else {
627 - if ( 'undefined' !== $( '#vz-import-json-url' ).attr( 'readonly' ) ) {
628 - $( '#vz-import-json-url' ).val( '' ).removeAttr( 'readonly' ).removeAttr( 'value' );
629 - $('#json-endpoint-form')[0].reset();
630 - $('.visualizer-json-form h3.viz-step:not(.step1)').addClass('ui-state-disabled');
631 - }
632 - }
633 - $( '#canvas' ).hide();
634 - }else{
635 - // toggle from LHS form to chart
636 - $( '#json-conclude-form' ).trigger('submit');
637 - }
638 - } );
639 -
640 - $('body').on('visualizer:json:form:submit', function() {
641 - var filter_button = $( '#json-chart-button, #woo-chart-button' );
642 - $( '#visualizer-json-screen' ).css("z-index", "-1").hide();
643 - $('#canvas').lock();
644 - filter_button.val( filter_button.attr( 'data-t-chart' ) );
645 - filter_button.html( filter_button.attr( 'data-t-chart' ) );
646 - filter_button.attr( 'data-current', 'chart' );
647 - end_ajax( $( '#visualizer-json-screen' ) );
648 - $( '#canvas' ).removeClass('visualizer-chart-loaded').css("z-index", "1").show();
649 - });
650 -
651 -
652 - // fetch the roots for the provided endpoint
653 - $( '#visualizer-json-fetch' ).on( 'click', function(e){
654 - e.preventDefault();
655 - $('.visualizer-json-form').accordion( 'option', 'active', 0 );
656 - $('.visualizer-json-form h3.viz-step:not(.step1)').addClass('ui-state-disabled');
657 - $('.json-table').html('');
658 - start_ajax( $( '#visualizer-json-screen' ) );
659 - $.ajax({
660 - url : ajaxurl,
661 - method : 'post',
662 - data : {
663 - 'action' : visualizer.ajax['actions']['json_get_roots'],
664 - 'security' : visualizer.ajax['nonces']['json_get_roots'],
665 - 'params' : $('#json-endpoint-form').serialize()
666 - },
667 - success : function(data){
668 - if(data.success){
669 - $('#vz-import-json-root').empty();
670 - $.each(data.data.roots, function(i, name){
671 - $('#vz-import-json-root').append('<option value="' + name + '">' + name.replace(regex, visualizer.json_tag_separator_view) + '</option>');
672 - });
673 - $('#json-root-form').fadeIn('medium');
674 - json_accordion_activate(1, true);
675 - }else{
676 - alert(data.data.msg);
677 - }
678 - },
679 - complete: function(){
680 - end_ajax($('#visualizer-json-screen'));
681 - }
682 - });
683 - });
684 -
685 - // fetch the data for the chosen root
686 - $( '#visualizer-json-parse' ).on( 'click', function(e){
687 - e.preventDefault();
688 - $('.visualizer-json-form h3.viz-step:not(.step1):not(.step2)').addClass('ui-state-disabled');
689 - $('.json-table').html('');
690 - start_ajax( $( '#visualizer-json-screen' ) );
691 - $.ajax({
692 - url : ajaxurl,
693 - method : 'post',
694 - data : {
695 - 'action' : visualizer.ajax['actions']['json_get_data'],
696 - 'security' : visualizer.ajax['nonces']['json_get_data'],
697 - 'params' : $('#json-root-form, #json-endpoint-form').serialize()
698 - },
699 - success : function(data){
700 - if(data.success){
701 - $('#vz-import-json-paging option:not(.static)').remove();
702 - if(data.data.paging.length > 0){
703 - var $template = $('#vz-import-json-paging').attr('data-template');
704 - $.each(data.data.paging, function(i, name){
705 - var display = name.replace(regex, visualizer.json_tag_separator_view);
706 - display = $template.replace('?', display);
707 - $('#vz-import-json-paging').append('<option value="' + name + '">' + display + '</option>');
708 - });
709 - $('.json-pagination').show();
710 - }
711 - $('#json-conclude-form .json-table').html(data.data.table);
712 -
713 - var $table = create_editor_table( '#json-conclude-form' );
714 -
715 - json_accordion_activate(3, true);
716 - json_accordion_activate(2, false);
717 - $table.columns.adjust().draw();
718 - }else{
719 - alert(data.data.msg);
720 - }
721 - },
722 - complete: function(){
723 - end_ajax($('#visualizer-json-screen'));
724 - }
725 - });
726 - });
727 -
728 - // when the data is set and the chart is updated, toggle the screen so that the chart is shown
729 - $('#json-conclude-form').on( 'submit', function(e){
730 - // at least one column has to be selected as non-excluded.
731 - var count_selected = 0;
732 - $('select.viz-select-data-type').each(function(i, element){
733 - if($(element).prop('selectedIndex') > 0){
734 - count_selected++;
735 - }
736 - });
737 - if(count_selected === 0){
738 - alert(visualizer.l10n.select_columns);
739 - return false;
740 - }
741 -
742 - // populate the form elements that are in the other tabs.
743 - $('#json-conclude-form-helper .json-form-element, #json-endpoint-form .json-form-element, #json-root-form .json-form-element, #vz-import-json .json-form-element, #vz-import-woo-report .json-form-element:not(:disabled)').each(function(x, y){
744 - $('#json-conclude-form').append('<input type="hidden" name="' + y.name + '" value="' + y.value + '">');
745 - });
746 -
747 - $('body').trigger('visualizer:json:form:submit');
748 - });
749 -
750 - // update the schedule
751 - $('#json-chart-save-button, #woo-chart-save-button').on('click', function(e){
752 - e.preventDefault();
753 - $('#canvas').lock();
754 - var btnID = jQuery( this ).attr( 'id' );
755 - $.ajax({
756 - url : ajaxurl,
757 - method : 'post',
758 - data : {
759 - 'action' : visualizer.ajax['actions']['json_set_schedule'],
760 - 'security' : visualizer.ajax['nonces']['json_set_schedule'],
761 - 'chart' : $('#vz-json-time, #vz-woo-time').attr('data-chart'),
762 - 'time' : $('#vz-json-time, #vz-woo-time').val(),
763 - 'is_woocommerce_report': 'woo-chart-save-button' === btnID,
764 - },
765 - success : function(data){
766 - // do nothing.
767 - },
768 - complete: function(){
769 - $('#canvas').unlock();
770 - }
771 - });
772 - });
773 -
774 - // Select WooCommerce report endpoint.
775 - $( '#vz-woo-source' ).on( 'click', function( e ) {
776 - // Trigger change action.
777 - $( 'body' ).trigger( 'visualizer:change:action' );
778 -
779 - if ( '' !== $( this ).val() ) {
780 - $( '#woo-chart-button, #woo-chart-save-button' ).removeAttr( 'disabled' );
781 - } else {
782 - $( '#woo-chart-button, #woo-chart-save-button' ).attr( 'disabled', true );
783 - }
784 - } );
785 -
786 - }
787 -
788 - function init_editor_table() {
789 - $('body').on('visualizer:db:editor:table:init', function(event, data){
790 - var $table = create_editor_table('.viz-table-editor', data.config);
791 - $('body').on('visualizer:db:editor:table:redraw', function(event, data){
792 - $table.draw();
793 - });
794 - });
795 - }
796 -
797 - function create_editor_table(element, config) {
798 - var settings = {
799 - paging: false,
800 - searching: false,
801 - ordering: false,
802 - select: false,
803 - scrollX: "100%",
804 - scrollY: "400px",
805 - info: false,
806 - colReorder: {
807 - fixedColumnsLeft: 1
808 - }
809 - };
810 -
811 - // show column visibility button only when more than 6 columns are found (including the Label column)
812 - if($(element + ' table.viz-editor-table thead tr th').length > 6){
813 - $.extend( settings, {
814 - dom: 'Bt',
815 - buttons: [
816 - {
817 - extend: 'colvis',
818 - columns: ':gt(0)',
819 - collectionLayout: 'four-column'
820 - }
821 - ]
822 - } );
823 - }
824 - if(config){
825 - $.extend( settings, config );
826 - }
827 -
828 - var $table = $(element + ' .viz-editor-table').DataTable(settings);
829 - return $table;
830 - }
831 -
832 - function json_accordion_activate($step, $activate){
833 - $('.visualizer-json-form h3.viz-step.step' + ( $step + 1 )).removeClass('ui-state-disabled');
834 - if($activate){
835 - $('.visualizer-json-form').accordion( 'option', 'active', $step );
836 - }
837 - }
838 -
839 - function start_ajax(element){
840 - element.lock();
841 - }
842 -
843 - function end_ajax(element){
844 - element.unlock();
845 - }
846 -
50 + $('.more-info').click(function() {
51 + $(this).parent().find('.section-description:first').toggle();
52 + return false;
53 + });
54 + });
847 55 })(jQuery);
848 56
849 -(function ($) {
850 - $.fn.lock = function () {
851 - $(this).each(function () {
57 +(function($) {
58 + $.fn.lock = function() {
59 + $(this).each(function() {
852 60 var $this = $(this);
853 61 var position = $this.css('position');
854 62
855 63 if (!position) {
@@ -855,9 +63,9 @@
855 63 if (!position) {
856 64 position = 'static';
857 65 }
858 66
859 - switch (position) {
67 + switch(position) {
860 68 case 'absolute':
861 69 case 'relative':
862 70 break;
863 71 default:
@@ -876,123 +84,21 @@
876 84 loader.width(width).height(height);
877 85
878 86 locker.append(loader);
879 87 $this.append(locker);
880 - $(window).resize(function () {
88 + $(window).resize(function() {
881 89 $this.find('.locker,.locker-loader').width($this.width()).height($this.height());
882 90 });
883 91 });
884 92
885 93 return $(this);
886 - };
94 + }
887 95
888 - $.fn.unlock = function () {
889 - $(this).each(function () {
96 + $.fn.unlock = function() {
97 + $(this).each(function() {
890 98 $(this).find('.locker').remove();
891 99 $(this).css('position', $(this).data('position'));
892 100 });
893 101
894 102 return $(this);
895 - };
896 -
897 - // Telemetry
898 - function getChartID() {
899 - const urlParams = new URLSearchParams(window.location.search);
900 - return urlParams.get('chart') ?? '';
901 103 }
902 -
903 - const groupId = getChartID();
904 -
905 - const chartTypes = document.querySelector('#viz-types-form')
906 - if( chartTypes ) {
907 - document.querySelector('.push-right[type=submit]')?.addEventListener('click', async function (event) {
908 - if ( typeof window.tiTrk !== 'undefined' ) {
909 - event.preventDefault();
910 - try {
911 - const formData = new FormData(document.querySelector('#viz-types-form'));
912 - const savedData = Object.fromEntries(formData);
913 -
914 - tiTrk?.with('visualizer')?.add({
915 - feature: 'chart-create',
916 - featureComponent: 'saved-data',
917 - featureData: {
918 - type: savedData?.['type'],
919 - library: savedData?.['chart-library']
920 - },
921 - groupId
922 - });
923 -
924 - // Do not make the user to wait too long for the event to be uploaded.
925 - const timer = new Promise((resolve) => setTimeout(resolve, 500));
926 - await Promise.race([timer, tiTrk?.uploadEvents()]);
927 - } catch (e) {
928 - console.warn(e);
929 - }
930 - $('#viz-types-form').submit();
931 - }
932 - });
933 - }
934 -
935 - [
936 - {
937 - selector: '#editor-button',
938 - featureComponent: 'source-manual-data'
939 - },
940 - {
941 - selector: '#vz-import-file',
942 - featureComponent: 'source-import-csv-file'
943 - },
944 - {
945 - selector: '#vz-save-schedule',
946 - featureComponent: 'source-import-csv-remote'
947 - },
948 - {
949 - selector: '#visualizer-json-fetch',
950 - featureComponent: 'source-import-json-remote'
951 - },
952 - {
953 - selector: '#existing-chart',
954 - featureComponent: 'source-import-chart'
955 - },
956 - {
957 - selector: '#filter-chart-button',
958 - featureComponent: 'source-import-wordpress',
959 - },
960 - {
961 - selector: '#woo-chart-button',
962 - featureComponent: 'source-import-woocommerce'
963 - },
964 - {
965 - selector: '#db-chart-button',
966 - featureComponent: 'source-import-database'
967 - }
968 - ].forEach(({ selector, featureComponent }) => {
969 - document.querySelector(selector)?.addEventListener('click', function () {
970 - window?.tiTrk?.with('visualizer')?.set('used-source',{
971 - feature: 'chart-edit-used-source',
972 - featureComponent,
973 - groupId
974 - });
975 - });
976 - });
977 -})(jQuery);
978 -
979 -
980 -document.querySelector('#viz-copy-shortcode')?.addEventListener('click', function() {
981 - var copyText = document.querySelector('#viz-shortcode')?.value;
982 - if ( !copyText ) {
983 - return;
984 - }
985 -
986 - navigator.clipboard.writeText(copyText);
987 - alert(visualizer.l10n.copied);
988 -});
989 -
990 -// Connect Chart Backend Title Info Panel with the field from the settings form.
991 -const interactiveBackendTitleField = document.querySelector( '#viz-backend-name' );
992 -const backendTitleSave = document.querySelector( '#settings-form input[name="backend-title"]' );
993 -
994 -if ( interactiveBackendTitleField && backendTitleSave ) {
995 - interactiveBackendTitleField.addEventListener('input', function() {
996 - backendTitleSave.value = this.value;
997 - });
998 -}
104 +})(jQuery);