PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.10.8
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.10.8
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 | classes/Visualizer/Gutenberg/src/Editor.js +214 -42 3.1.23.10.8 View file →
@@ -28,8 +28,9 @@
28 28 Button,
29 29 ButtonGroup,
30 30 Dashicon,
31 31 Placeholder,
32 + Notice,
32 33 Spinner
33 34 } = wp.components;
34 35
35 36 class Editor extends Component {
@@ -42,8 +43,16 @@
42 43 this.editPermissions = this.editPermissions.bind( this );
43 44 this.readUploadedFile = this.readUploadedFile.bind( this );
44 45 this.editURL = this.editURL.bind( this );
45 46 this.editSchedule = this.editSchedule.bind( this );
47 + this.editJSONSchedule = this.editJSONSchedule.bind( this );
48 + this.editJSONURL = this.editJSONURL.bind( this );
49 + this.editJSONHeaders = this.editJSONHeaders.bind( this );
50 + this.editJSONRoot = this.editJSONRoot.bind( this );
51 + this.editJSONPaging = this.editJSONPaging.bind( this );
52 + this.JSONImportData = this.JSONImportData.bind( this );
53 + this.editDatabaseSchedule = this.editDatabaseSchedule.bind( this );
54 + this.databaseImportData = this.databaseImportData.bind( this );
46 55 this.uploadData = this.uploadData.bind( this );
47 56 this.getChartData = this.getChartData.bind( this );
48 57 this.editChartData = this.editChartData.bind( this );
49 58 this.updateChart = this.updateChart.bind( this );
@@ -69,13 +78,22 @@
69 78 async componentDidMount() {
70 79
71 80 // Fetch review again if block loaded after saving.
72 81 if ( this.props.attributes.id ) {
73 - let result = await apiFetch({ path: `wp/v2/visualizer/${this.props.attributes.id}` });
82 + let result = await apiFetch({ path: `wp/v2/visualizer/${this.props.attributes.id}` }).catch( function( error ) {
83 + });
74 84
75 - this.setState({
76 - chart: result['chart_data']
77 - });
85 + if ( result ) {
86 + this.setState({
87 + chart: result['chart_data']
88 + });
89 + } else {
90 +
91 + // if the chart is not found.
92 + this.setState({
93 + route: 'error'
94 + });
95 + }
78 96 }
79 97 }
80 98
81 99 async getChart( id ) {
@@ -87,14 +105,16 @@
87 105
88 106 this.setState({
89 107 route: 'chartSelect',
90 108 chart: result['chart_data'],
91 - isLoading: false
109 + isLoading: true,
110 + isModified: true
92 111 });
93 112
94 113 this.props.setAttributes({
95 114 id,
96 - route: 'chartSelect'
115 + route: 'chartSelect',
116 + lazy: -1
97 117 });
98 118 }
99 119
100 120 editChart() {
@@ -103,8 +123,11 @@
103 123 }
104 124
105 125 editSettings( settings ) {
106 126 let chart = { ...this.state.chart };
127 + if ( '1' !== settings.pagination ) {
128 + delete settings.pageSize;
129 + }
107 130 chart['visualizer-settings'] = settings;
108 131 this.setState({
109 132 chart,
110 133 isModified: true
@@ -138,11 +161,83 @@
138 161
139 162 editSchedule( schedule ) {
140 163 let chart = { ...this.state.chart };
141 164 chart['visualizer-chart-schedule'] = schedule;
165 + this.setState({
166 + chart,
167 + isModified: true
168 + });
169 + }
170 +
171 + editJSONSchedule( schedule ) {
172 + let chart = { ...this.state.chart };
173 + chart['visualizer-json-schedule'] = schedule;
174 + this.setState({
175 + chart,
176 + isModified: true
177 + });
178 + }
179 +
180 + editJSONURL( url ) {
181 + let chart = { ...this.state.chart };
182 + chart['visualizer-json-url'] = url;
142 183 this.setState({ chart });
143 184 }
144 185
186 + editJSONHeaders( headers ) {
187 + let chart = { ...this.state.chart };
188 + delete headers.username;
189 + delete headers.password;
190 + chart['visualizer-json-headers'] = headers;
191 + this.setState({ chart });
192 + }
193 +
194 + editJSONRoot( root ) {
195 + let chart = { ...this.state.chart };
196 + chart['visualizer-json-root'] = root;
197 + this.setState({ chart });
198 + }
199 +
200 + editJSONPaging( root ) {
201 + let chart = { ...this.state.chart };
202 + chart['visualizer-json-paging'] = root;
203 + this.setState({ chart });
204 + }
205 +
206 + JSONImportData( name, series, data ) {
207 + let chart = { ...this.state.chart };
208 + chart['visualizer-source'] = name;
209 + chart['visualizer-default-data'] = 0;
210 + chart['visualizer-series'] = series;
211 + chart['visualizer-data'] = data;
212 + this.setState({
213 + chart,
214 + isModified: true
215 + });
216 + }
217 +
218 + editDatabaseSchedule( schedule ) {
219 + let chart = { ...this.state.chart };
220 + chart['visualizer-db-schedule'] = schedule;
221 + this.setState({
222 + chart,
223 + isModified: true
224 + });
225 + }
226 +
227 + databaseImportData( query, name, series, data ) {
228 + let chart = { ...this.state.chart };
229 + chart['visualizer-source'] = name;
230 + chart['visualizer-default-data'] = 0;
231 + chart['visualizer-series'] = series;
232 + chart['visualizer-data'] = data;
233 + chart['visualizer-db-query'] = query;
234 + this.setState({
235 + chart,
236 + isModified: true
237 + });
238 + }
239 +
145 240 uploadData( scheduled = false ) {
146 241 this.setState({
147 242 isLoading: 'uploadData',
148 243 isScheduled: scheduled
@@ -230,13 +325,13 @@
230 325 chart
231 326 });
232 327 }
233 328
234 - editChartData( chartData, type ) {
329 + editChartData( chartData, source ) {
235 330 let chart = { ...this.state.chart };
236 331 let series = [];
237 332 let settings = { ...chart['visualizer-settings'] };
238 -
333 + let type = chart['visualizer-chart-type'];
239 334 chartData[0].map( ( i, index ) => {
240 335 series[index] = {
241 336 label: i,
242 337 type: chartData[1][index]
@@ -247,32 +342,64 @@
247 342
248 343 let map = series;
249 344 let fieldName = 'series';
250 345
251 - if ( 'pie' === chart['visualizer-chart-type']) {
252 - map = chartData;
253 - fieldName = 'slices';
254 - }
346 + switch ( type ) {
347 + case 'pie':
348 + map = chartData;
349 + fieldName = 'slices';
255 350
351 + // pie charts are finicky about a number being a number
352 + // and editing a number makes it a string
353 + // so let's convert it back into a number.
354 + chartData.map( ( i, index ) => {
355 + switch ( series[1].type ) {
356 + case 'number':
357 + i[1] = parseFloat( i[1]);
358 + break;
359 + }
360 + });
361 + break;
362 + case 'tabular':
363 +
364 + // table charts are finicky about a boolean being a boolean
365 + // and editing a boolean makes it a string
366 + // so let's convert it back into a boolean.
367 + chartData.map( ( i, index ) => {
368 + series.map( ( seriesObject, seriesIndex ) => {
369 + switch ( seriesObject.type ) {
370 + case 'boolean':
371 + if ( 'string' === typeof i[seriesIndex]) {
372 + i[seriesIndex] = 'true' === i[seriesIndex];
373 + }
374 + break;
375 + }
376 + });
377 + });
378 + break;
379 + }
380 +
256 381 map.map( ( i, index ) => {
257 - if ( 'pie' !== chart['visualizer-chart-type'] && 0 === index ) {
258 - return;
382 + if ( 'pie' !== type && 0 === index ) {
383 + return;
259 384 }
260 385
261 - const seriesIndex = 'pie' !== chart['visualizer-chart-type'] ? index - 1 : index;
386 + const seriesIndex = 'pie' !== type ? index - 1 : index;
262 387
263 - if ( settings[fieldName][seriesIndex] === undefined ) {
264 - settings[fieldName][seriesIndex] = {};
388 + if ( Array.isArray( settings[fieldName]) && settings[fieldName][seriesIndex] === undefined ) {
389 + settings[fieldName][seriesIndex] = {};
265 390 settings[fieldName][seriesIndex].temp = 1;
266 - }
391 + }
267 392 });
268 393
269 - settings[fieldName] = settings[fieldName].filter( ( i, index ) => {
270 - const length = 'pie' !== chart['visualizer-chart-type'] ? map.length - 1 : map.length;
271 - return index < length;
272 - });
394 + if ( Array.isArray( settings[fieldName]) ) {
395 + settings[fieldName] = settings[fieldName].filter( ( i, index ) => {
396 + const length = -1 >= [ 'pie', 'tabular', 'dataTable' ].indexOf( type ) ? map.length - 1 : map.length;
397 + return index < length;
398 + });
399 + }
273 400
274 - chart['visualizer-source'] = type;
401 + chart['visualizer-source'] = source;
275 402 chart['visualizer-default-data'] = 0;
276 403 chart['visualizer-data'] = chartData;
277 404 chart['visualizer-series'] = series;
278 405 chart['visualizer-settings'] = settings;
@@ -299,19 +426,22 @@
299 426 if ( 'pie' === data['visualizer-chart-type']) {
300 427 fieldName = 'slices';
301 428 }
302 429
303 - Object.keys( data['visualizer-settings'][fieldName])
304 - .map( i => {
305 - if ( data['visualizer-settings'][fieldName][i] !== undefined ) {
306 - if ( data['visualizer-settings'][fieldName][i].temp !== undefined ) {
307 - delete data['visualizer-settings'][fieldName][i].temp;
308 - }
309 - }
310 - }
311 - );
430 + // no series for bubble and timeline charts.
431 + if ( -1 >= [ 'bubble', 'timeline' ].indexOf( data['visualizer-chart-type']) ) {
432 + Object.keys( data['visualizer-settings'][fieldName])
433 + .map( i => {
434 + if ( data['visualizer-settings'][fieldName][i] !== undefined ) {
435 + if ( data['visualizer-settings'][fieldName][i].temp !== undefined ) {
436 + delete data['visualizer-settings'][fieldName][i].temp;
437 + }
438 + }
439 + }
440 + );
441 + }
312 442
313 - apiRequest({ path: `/visualizer/v1/update-chart?id=${this.props.attributes.id}`, method: 'POST', data: data }).then(
443 + apiRequest({ path: `/visualizer/v1/update-chart?id=${ this.props.attributes.id }`, method: 'POST', data: data }).then(
314 444 ( data ) => {
315 445
316 446 this.setState({
317 447 isLoading: false,
@@ -326,11 +456,36 @@
326 456 );
327 457 }
328 458
329 459 render() {
460 + if ( 'error' === this.state.route ) {
461 + return (
462 + <Notice
463 + status="error"
464 + isDismissible={ false }
465 + >
466 + <Dashicon icon="chart-pie" />
467 + { __( 'This chart is not available; it might have been deleted. Please delete this block and resubmit your chart.' ) }
468 + </Notice>
469 + );
470 + }
471 +
472 + if ( '1' === visualizerLocalize.isFullSiteEditor ) {
473 + return (
474 + <Notice
475 + status="error"
476 + isDismissible={ false }
477 + >
478 + <Dashicon icon="chart-pie" />
479 + { __( 'Visualizer block charts are currently not available for selection here, you must visit the library, get the shortcode, and add the chart here in a shortcode tag.' ) }
480 + </Notice>
481 + );
482 + }
483 +
330 484 if ( 'renderChart' === this.state.route && null !== this.state.chart ) {
331 485 return (
332 486 <ChartRender
487 + id={ this.props.attributes.id }
333 488 chart={ this.state.chart }
334 489 className={ this.props.className }
335 490 editChart={ this.editChart }
336 491 />
@@ -348,24 +503,29 @@
348 503 </div>
349 504
350 505 { 'home' === this.state.route && (
351 506 <div className="visualizer-settings__content">
352 -
353 507 <div className="visualizer-settings__content-description">
354 508 { __( 'Make a new chart or display an existing one?' ) }
355 509 </div>
356 510
357 - <div className="visualizer-settings__content-option locked">
511 + { /* You can apply "locked" class to lock any of the following list items. */ }
358 512
513 + <a
514 + href={ visualizerLocalize.adminPage }
515 + target="_blank"
516 + className="visualizer-settings__content-option"
517 + >
518 +
359 519 <span className="visualizer-settings__content-option-title">
360 - { __( 'Create a new chart (coming soon)' ) }
520 + { __( 'Create a new chart' ) }
361 521 </span>
362 522
363 523 <div className="visualizer-settings__content-option-icon">
364 - <Dashicon icon="lock" />
524 + <Dashicon icon="arrow-right-alt2" />
365 525 </div>
366 526
367 - </div>
527 + </a>
368 528
369 529 <div
370 530 className="visualizer-settings__content-option"
371 531 onClick={ () => {
@@ -396,8 +556,10 @@
396 556 { ( 'showCharts' === this.state.route && false === this.state.isLoading ) && <Charts getChart={ this.getChart }/> }
397 557
398 558 { ( 'chartSelect' === this.state.route && null !== this.state.chart ) &&
399 559 <ChartSelect
560 + id={ this.props.attributes.id }
561 + attributes={ this.props.attributes }
400 562 chart={ this.state.chart }
401 563 editSettings={ this.editSettings }
402 564 editPermissions={ this.editPermissions }
403 565 url={ this.state.url }
@@ -403,8 +565,16 @@
403 565 url={ this.state.url }
404 566 readUploadedFile={ this.readUploadedFile }
405 567 editURL={ this.editURL }
406 568 editSchedule={ this.editSchedule }
569 + editJSONURL={ this.editJSONURL }
570 + editJSONHeaders={ this.editJSONHeaders }
571 + editJSONSchedule={ this.editJSONSchedule }
572 + editJSONRoot={ this.editJSONRoot }
573 + editJSONPaging={ this.editJSONPaging }
574 + JSONImportData={ this.JSONImportData }
575 + editDatabaseSchedule={ this.editDatabaseSchedule }
576 + databaseImportData={ this.databaseImportData }
407 577 uploadData={ this.uploadData }
408 578 getChartData={ this.getChartData }
409 579 editChartData={ this.editChartData }
410 580 isLoading={ this.state.isLoading }
@@ -416,9 +586,9 @@
416 586 { ( 'showCharts' === this.state.route || 'chartSelect' === this.state.route ) &&
417 587 <ButtonGroup>
418 588
419 589 <Button
420 - isDefault
590 + variant="secondary"
421 591 isLarge
422 592 onClick={ () => {
423 593 let route;
424 594 if ( 'showCharts' === this.state.route ) {
@@ -425,9 +595,9 @@
425 595 route = 'home';
426 596 } else if ( 'chartSelect' === this.state.route ) {
427 597 route = 'showCharts';
428 598 }
429 - this.setState({ route });
599 + this.setState({ route, isLoading: false });
430 600 this.props.setAttributes({ route });
431 601 } }
432 602 >
433 603 { __( 'Back' ) }
@@ -437,12 +607,13 @@
437 607 <Fragment>
438 608
439 609 { false === this.state.isModified ?
440 610 <Button
441 - isDefault
611 + variant="secondary"
442 612 isLarge
613 + className="visualizer-bttn-done"
443 614 onClick={ () => {
444 - this.setState({ route: 'renderChart' });
615 + this.setState({ route: 'renderChart', isModified: true });
445 616 this.props.setAttributes({ route: 'renderChart' });
446 617 } }
447 618 >
448 619 { __( 'Done' ) }
@@ -449,8 +620,9 @@
449 620 </Button> :
450 621 <Button
451 622 isPrimary
452 623 isLarge
624 + className="visualizer-bttn-save"
453 625 isBusy={ 'updateChart' === this.state.isLoading }
454 626 disabled={ 'updateChart' === this.state.isLoading }
455 627 onClick={ this.updateChart }
456 628 >