PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.4.0
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.4.0
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
visualizer / classes / Visualizer / Gutenberg / src / Editor.js

Editor.js in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.4.0, at classes/Visualizer/Gutenberg/src/Editor.js

568 lines 13.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * External dependencies
3 */
4 import Charts from './Components/Charts.js';
5
6 import ChartSelect from './Components/ChartSelect.js';
7
8 import ChartRender from './Components/ChartRender.js';
9
10 import { CSVToArray } from './utils.js';
11
12 /**
13 * WordPress dependencies
14 */
15 const { __ } = wp.i18n;
16
17 const {
18 apiFetch,
19 apiRequest
20 } = wp;
21
22 const {
23 Component,
24 Fragment
25 } = wp.element;
26
27 const {
28 Button,
29 ButtonGroup,
30 Dashicon,
31 Placeholder,
32 Spinner
33 } = wp.components;
34
35 class Editor extends Component {
36 constructor() {
37 super( ...arguments );
38
39 this.getChart = this.getChart.bind( this );
40 this.editChart = this.editChart.bind( this );
41 this.editSettings = this.editSettings.bind( this );
42 this.editPermissions = this.editPermissions.bind( this );
43 this.readUploadedFile = this.readUploadedFile.bind( this );
44 this.editURL = this.editURL.bind( this );
45 this.editSchedule = this.editSchedule.bind( this );
46 this.editJSONSchedule = this.editJSONSchedule.bind( this );
47 this.editJSONURL = this.editJSONURL.bind( this );
48 this.editJSONHeaders = this.editJSONHeaders.bind( this );
49 this.editJSONRoot = this.editJSONRoot.bind( this );
50 this.editJSONPaging = this.editJSONPaging.bind( this );
51 this.JSONImportData = this.JSONImportData.bind( this );
52 this.editDatabaseSchedule = this.editDatabaseSchedule.bind( this );
53 this.databaseImportData = this.databaseImportData.bind( this );
54 this.uploadData = this.uploadData.bind( this );
55 this.getChartData = this.getChartData.bind( this );
56 this.editChartData = this.editChartData.bind( this );
57 this.updateChart = this.updateChart.bind( this );
58
59 this.state = {
60
61 /**
62 * Block Route Status
63 *
64 * home - Initial screen.
65 * showCharts - Display list of charts to pick.
66 * chartSelect - Chart selected.
67 * renderChart - Chart render.
68 */
69 route: ( this.props.attributes.route ? this.props.attributes.route : 'home' ),
70 chart: null,
71 isModified: false,
72 isLoading: false,
73 isScheduled: false
74 };
75 }
76
77 async componentDidMount() {
78
79 // Fetch review again if block loaded after saving.
80 if ( this.props.attributes.id ) {
81 let result = await apiFetch({ path: `wp/v2/visualizer/${this.props.attributes.id}` });
82
83 this.setState({
84 chart: result['chart_data']
85 });
86 }
87 }
88
89 async getChart( id ) {
90 await this.setState({
91 isLoading: 'getChart'
92 });
93
94 let result = await apiFetch({ path: `wp/v2/visualizer/${id}` });
95
96 this.setState({
97 route: 'chartSelect',
98 chart: result['chart_data'],
99 isLoading: false
100 });
101
102 this.props.setAttributes({
103 id,
104 route: 'chartSelect'
105 });
106 }
107
108 editChart() {
109 this.setState({ route: 'chartSelect' });
110 this.props.setAttributes({ route: 'chartSelect' });
111 }
112
113 editSettings( settings ) {
114 let chart = { ...this.state.chart };
115 chart['visualizer-settings'] = settings;
116 this.setState({
117 chart,
118 isModified: true
119 });
120 }
121
122 editPermissions( permissions ) {
123 let chart = { ...this.state.chart };
124 chart['visualizer-permissions'] = permissions;
125 this.setState({
126 chart,
127 isModified: true
128 });
129 }
130
131 readUploadedFile( e ) {
132 const fileTobeRead = e.current.files[0];
133 const fileReader = new FileReader();
134 fileReader.onload = () => {
135 const data = CSVToArray( fileReader.result );
136 this.editChartData( data, 'Visualizer_Source_Csv' );
137 };
138 fileReader.readAsText( fileTobeRead );
139 }
140
141 editURL( url ) {
142 let chart = { ...this.state.chart };
143 chart['visualizer-chart-url'] = url;
144 this.setState({ chart });
145 }
146
147 editSchedule( schedule ) {
148 let chart = { ...this.state.chart };
149 chart['visualizer-chart-schedule'] = schedule;
150 this.setState({
151 chart,
152 isModified: true
153 });
154 }
155
156 editJSONSchedule( schedule ) {
157 let chart = { ...this.state.chart };
158 chart['visualizer-json-schedule'] = schedule;
159 this.setState({
160 chart,
161 isModified: true
162 });
163 }
164
165 editJSONURL( url ) {
166 let chart = { ...this.state.chart };
167 chart['visualizer-json-url'] = url;
168 this.setState({ chart });
169 }
170
171 editJSONHeaders( headers ) {
172 let chart = { ...this.state.chart };
173 delete headers.username;
174 delete headers.password;
175 chart['visualizer-json-headers'] = headers;
176 this.setState({ chart });
177 }
178
179 editJSONRoot( root ) {
180 let chart = { ...this.state.chart };
181 chart['visualizer-json-root'] = root;
182 this.setState({ chart });
183 }
184
185 editJSONPaging( root ) {
186 let chart = { ...this.state.chart };
187 chart['visualizer-json-paging'] = root;
188 this.setState({ chart });
189 }
190
191 JSONImportData( name, series, data ) {
192 let chart = { ...this.state.chart };
193 chart['visualizer-source'] = name;
194 chart['visualizer-default-data'] = 0;
195 chart['visualizer-series'] = series;
196 chart['visualizer-data'] = data;
197 this.setState({
198 chart,
199 isModified: true
200 });
201 }
202
203 editDatabaseSchedule( schedule ) {
204 let chart = { ...this.state.chart };
205 chart['visualizer-db-schedule'] = schedule;
206 this.setState({
207 chart,
208 isModified: true
209 });
210 }
211
212 databaseImportData( query, name, series, data ) {
213 let chart = { ...this.state.chart };
214 chart['visualizer-source'] = name;
215 chart['visualizer-default-data'] = 0;
216 chart['visualizer-series'] = series;
217 chart['visualizer-data'] = data;
218 chart['visualizer-db-query'] = query;
219 this.setState({
220 chart,
221 isModified: true
222 });
223 }
224
225 uploadData( scheduled = false ) {
226 this.setState({
227 isLoading: 'uploadData',
228 isScheduled: scheduled
229 });
230
231 apiRequest({ path: `/visualizer/v1/upload-data?url=${this.state.chart['visualizer-chart-url']}`, method: 'POST' }).then(
232 ( data ) => {
233 if ( 2 <= Object.keys( data ).length ) {
234 let chart = { ...this.state.chart };
235
236 chart['visualizer-source'] = 'Visualizer_Source_Csv_Remote';
237 chart['visualizer-default-data'] = 0;
238 chart['visualizer-series'] = data.series;
239 chart['visualizer-data'] = data.data;
240
241 let series = chart['visualizer-series'];
242 let settings = chart['visualizer-settings'];
243 let map = series;
244 let fieldName = 'series';
245
246 if ( 'pie' === chart['visualizer-chart-type']) {
247 map = chart['visualizer-data'];
248 fieldName = 'slices';
249 }
250
251 map.map( ( i, index ) => {
252 if ( 'pie' !== chart['visualizer-chart-type'] && 0 === index ) {
253 return;
254 }
255
256 const seriesIndex = 'pie' !== chart['visualizer-chart-type'] ? index - 1 : index;
257
258 if ( settings[fieldName][seriesIndex] === undefined ) {
259 settings[fieldName][seriesIndex] = {};
260 settings[fieldName][seriesIndex].temp = 1;
261 }
262 });
263
264 settings[fieldName] = settings[fieldName].filter( ( i, index ) => {
265 const length = 'pie' !== chart['visualizer-chart-type'] ? map.length - 1 : map.length;
266 return index < length;
267 });
268
269 chart['visualizer-settings'] = settings;
270
271 this.setState({
272 chart,
273 isModified: true,
274 isLoading: false
275 });
276
277 return data;
278 }
279
280 this.setState({
281 isLoading: false
282 });
283 },
284 ( err ) => {
285 this.setState({
286 isLoading: false
287 });
288
289 return err;
290 }
291 );
292 }
293
294 async getChartData( id ) {
295 await this.setState({
296 isLoading: 'getChartData'
297 });
298
299 let result = await apiFetch({ path: `wp/v2/visualizer/${id}` });
300
301 let chart = { ...this.state.chart };
302
303 chart['visualizer-source'] = 'Visualizer_Source_Csv';
304 chart['visualizer-default-data'] = 0;
305 chart['visualizer-series'] = result['chart_data']['visualizer-series'];
306 chart['visualizer-data'] = result['chart_data']['visualizer-data'];
307
308 this.setState({
309 isLoading: false,
310 chart
311 });
312 }
313
314 editChartData( chartData, type ) {
315 let chart = { ...this.state.chart };
316 let series = [];
317 let settings = { ...chart['visualizer-settings'] };
318 chartData[0].map( ( i, index ) => {
319 series[index] = {
320 label: i,
321 type: chartData[1][index]
322 };
323 });
324
325 chartData.splice( 0, 2 );
326
327 let map = series;
328 let fieldName = 'series';
329
330 if ( 'pie' === chart['visualizer-chart-type']) {
331 map = chartData;
332 fieldName = 'slices';
333 }
334
335 map.map( ( i, index ) => {
336 if ( 'pie' !== chart['visualizer-chart-type'] && 0 === index ) {
337 return;
338 }
339
340 const seriesIndex = 'pie' !== chart['visualizer-chart-type'] ? index - 1 : index;
341
342 if ( settings[fieldName][seriesIndex] === undefined ) {
343 settings[fieldName][seriesIndex] = {};
344 settings[fieldName][seriesIndex].temp = 1;
345 }
346 });
347
348 settings[fieldName] = settings[fieldName].filter( ( i, index ) => {
349 const length = 'pie' !== chart['visualizer-chart-type'] ? map.length - 1 : map.length;
350 return index < length;
351 });
352
353 chart['visualizer-source'] = type;
354 chart['visualizer-default-data'] = 0;
355 chart['visualizer-data'] = chartData;
356 chart['visualizer-series'] = series;
357 chart['visualizer-settings'] = settings;
358 chart['visualizer-chart-url'] = '';
359
360 this.setState({
361 chart,
362 isModified: true,
363 isScheduled: false
364 });
365 }
366
367 updateChart() {
368 this.setState({ isLoading: 'updateChart' });
369
370 const data = this.state.chart;
371
372 if ( false === this.state.isScheduled ) {
373 data['visualizer-chart-schedule'] = '';
374 }
375
376 let fieldName = 'series';
377
378 if ( 'pie' === data['visualizer-chart-type']) {
379 fieldName = 'slices';
380 }
381
382 Object.keys( data['visualizer-settings'][fieldName])
383 .map( i => {
384 if ( data['visualizer-settings'][fieldName][i] !== undefined ) {
385 if ( data['visualizer-settings'][fieldName][i].temp !== undefined ) {
386 delete data['visualizer-settings'][fieldName][i].temp;
387 }
388 }
389 }
390 );
391
392 apiRequest({ path: `/visualizer/v1/update-chart?id=${ this.props.attributes.id }`, method: 'POST', data: data }).then(
393 ( data ) => {
394
395 this.setState({
396 isLoading: false,
397 isModified: false
398 });
399
400 return data;
401 },
402 ( err ) => {
403 return err;
404 }
405 );
406 }
407
408 render() {
409 if ( 'renderChart' === this.state.route && null !== this.state.chart ) {
410 return (
411 <ChartRender
412 id={ this.props.attributes.id }
413 chart={ this.state.chart }
414 className={ this.props.className }
415 editChart={ this.editChart }
416 />
417 );
418 }
419
420 return (
421 <div className="visualizer-settings">
422
423 <div className="visualizer-settings__title">
424
425 <Dashicon icon="chart-pie" />
426 { __( 'Visualizer' ) }
427
428 </div>
429
430 { 'home' === this.state.route && (
431 <div className="visualizer-settings__content">
432 <div className="visualizer-settings__content-description">
433 { __( 'Make a new chart or display an existing one?' ) }
434 </div>
435
436 { /* You can apply "locked" class to lock any of the following list items. */ }
437
438 <a
439 href={ visualizerLocalize.adminPage }
440 target="_blank"
441 className="visualizer-settings__content-option"
442 >
443
444 <span className="visualizer-settings__content-option-title">
445 { __( 'Create a new chart' ) }
446 </span>
447
448 <div className="visualizer-settings__content-option-icon">
449 <Dashicon icon="arrow-right-alt2" />
450 </div>
451
452 </a>
453
454 <div
455 className="visualizer-settings__content-option"
456 onClick={ () => {
457 this.setState({ route: 'showCharts' });
458 this.props.setAttributes({ route: 'showCharts' });
459 } }
460 >
461
462 <span className="visualizer-settings__content-option-title">
463 { __( 'Display an existing chart' ) }
464 </span>
465
466 <div className="visualizer-settings__content-option-icon">
467 <Dashicon icon="arrow-right-alt2" />
468 </div>
469
470 </div>
471
472 </div>
473 ) }
474
475 { ( ( 'getChart' === this.state.isLoading ) || ( 'chartSelect' === this.state.route && null === this.state.chart ) || ( 'renderChart' === this.state.route && null === this.state.chart ) ) && (
476 <Placeholder>
477 <Spinner/>
478 </Placeholder>
479 ) }
480
481 { ( 'showCharts' === this.state.route && false === this.state.isLoading ) && <Charts getChart={ this.getChart }/> }
482
483 { ( 'chartSelect' === this.state.route && null !== this.state.chart ) &&
484 <ChartSelect
485 id={ this.props.attributes.id }
486 chart={ this.state.chart }
487 editSettings={ this.editSettings }
488 editPermissions={ this.editPermissions }
489 url={ this.state.url }
490 readUploadedFile={ this.readUploadedFile }
491 editURL={ this.editURL }
492 editSchedule={ this.editSchedule }
493 editJSONURL={ this.editJSONURL }
494 editJSONHeaders={ this.editJSONHeaders }
495 editJSONSchedule={ this.editJSONSchedule }
496 editJSONRoot={ this.editJSONRoot }
497 editJSONPaging={ this.editJSONPaging }
498 JSONImportData={ this.JSONImportData }
499 editDatabaseSchedule={ this.editDatabaseSchedule }
500 databaseImportData={ this.databaseImportData }
501 uploadData={ this.uploadData }
502 getChartData={ this.getChartData }
503 editChartData={ this.editChartData }
504 isLoading={ this.state.isLoading }
505 />
506 }
507
508 <div className="visualizer-settings__controls">
509
510 { ( 'showCharts' === this.state.route || 'chartSelect' === this.state.route ) &&
511 <ButtonGroup>
512
513 <Button
514 isDefault
515 isLarge
516 onClick={ () => {
517 let route;
518 if ( 'showCharts' === this.state.route ) {
519 route = 'home';
520 } else if ( 'chartSelect' === this.state.route ) {
521 route = 'showCharts';
522 }
523 this.setState({ route });
524 this.props.setAttributes({ route });
525 } }
526 >
527 { __( 'Back' ) }
528 </Button>
529
530 { 'chartSelect' === this.state.route &&
531 <Fragment>
532
533 { false === this.state.isModified ?
534 <Button
535 isDefault
536 isLarge
537 onClick={ () => {
538 this.setState({ route: 'renderChart' });
539 this.props.setAttributes({ route: 'renderChart' });
540 } }
541 >
542 { __( 'Done' ) }
543 </Button> :
544 <Button
545 isPrimary
546 isLarge
547 isBusy={ 'updateChart' === this.state.isLoading }
548 disabled={ 'updateChart' === this.state.isLoading }
549 onClick={ this.updateChart }
550 >
551 { __( 'Save' ) }
552 </Button>
553 }
554
555 </Fragment>
556 }
557
558 </ButtonGroup>
559 }
560
561 </div>
562 </div>
563 );
564 }
565 }
566
567 export default Editor;
568