PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.2.0
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.2.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.2.0, at classes/Visualizer/Gutenberg/src/Editor.js

474 lines 11.1 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.uploadData = this.uploadData.bind( this );
47 this.getChartData = this.getChartData.bind( this );
48 this.editChartData = this.editChartData.bind( this );
49 this.updateChart = this.updateChart.bind( this );
50
51 this.state = {
52
53 /**
54 * Block Route Status
55 *
56 * home - Initial screen.
57 * showCharts - Display list of charts to pick.
58 * chartSelect - Chart selected.
59 * renderChart - Chart render.
60 */
61 route: ( this.props.attributes.route ? this.props.attributes.route : 'home' ),
62 chart: null,
63 isModified: false,
64 isLoading: false,
65 isScheduled: false
66 };
67 }
68
69 async componentDidMount() {
70
71 // Fetch review again if block loaded after saving.
72 if ( this.props.attributes.id ) {
73 let result = await apiFetch({ path: `wp/v2/visualizer/${this.props.attributes.id}` });
74
75 this.setState({
76 chart: result['chart_data']
77 });
78 }
79 }
80
81 async getChart( id ) {
82 await this.setState({
83 isLoading: 'getChart'
84 });
85
86 let result = await apiFetch({ path: `wp/v2/visualizer/${id}` });
87
88 this.setState({
89 route: 'chartSelect',
90 chart: result['chart_data'],
91 isLoading: false
92 });
93
94 this.props.setAttributes({
95 id,
96 route: 'chartSelect'
97 });
98 }
99
100 editChart() {
101 this.setState({ route: 'chartSelect' });
102 this.props.setAttributes({ route: 'chartSelect' });
103 }
104
105 editSettings( settings ) {
106 let chart = { ...this.state.chart };
107 chart['visualizer-settings'] = settings;
108 this.setState({
109 chart,
110 isModified: true
111 });
112 }
113
114 editPermissions( permissions ) {
115 let chart = { ...this.state.chart };
116 chart['visualizer-permissions'] = permissions;
117 this.setState({
118 chart,
119 isModified: true
120 });
121 }
122
123 readUploadedFile( e ) {
124 const fileTobeRead = e.current.files[0];
125 const fileReader = new FileReader();
126 fileReader.onload = () => {
127 const data = CSVToArray( fileReader.result );
128 this.editChartData( data, 'Visualizer_Source_Csv' );
129 };
130 fileReader.readAsText( fileTobeRead );
131 }
132
133 editURL( url ) {
134 let chart = { ...this.state.chart };
135 chart['visualizer-chart-url'] = url;
136 this.setState({ chart });
137 }
138
139 editSchedule( schedule ) {
140 let chart = { ...this.state.chart };
141 chart['visualizer-chart-schedule'] = schedule;
142 this.setState({ chart });
143 }
144
145 uploadData( scheduled = false ) {
146 this.setState({
147 isLoading: 'uploadData',
148 isScheduled: scheduled
149 });
150
151 apiRequest({ path: `/visualizer/v1/upload-data?url=${this.state.chart['visualizer-chart-url']}`, method: 'POST' }).then(
152 ( data ) => {
153 if ( 2 <= Object.keys( data ).length ) {
154 let chart = { ...this.state.chart };
155
156 chart['visualizer-source'] = 'Visualizer_Source_Csv_Remote';
157 chart['visualizer-default-data'] = 0;
158 chart['visualizer-series'] = data.series;
159 chart['visualizer-data'] = data.data;
160
161 let series = chart['visualizer-series'];
162 let settings = chart['visualizer-settings'];
163 let map = series;
164 let fieldName = 'series';
165
166 if ( 'pie' === chart['visualizer-chart-type']) {
167 map = chart['visualizer-data'];
168 fieldName = 'slices';
169 }
170
171 map.map( ( i, index ) => {
172 if ( 'pie' !== chart['visualizer-chart-type'] && 0 === index ) {
173 return;
174 }
175
176 const seriesIndex = 'pie' !== chart['visualizer-chart-type'] ? index - 1 : index;
177
178 if ( settings[fieldName][seriesIndex] === undefined ) {
179 settings[fieldName][seriesIndex] = {};
180 settings[fieldName][seriesIndex].temp = 1;
181 }
182 });
183
184 settings[fieldName] = settings[fieldName].filter( ( i, index ) => {
185 const length = 'pie' !== chart['visualizer-chart-type'] ? map.length - 1 : map.length;
186 return index < length;
187 });
188
189 chart['visualizer-settings'] = settings;
190
191 this.setState({
192 chart,
193 isModified: true,
194 isLoading: false
195 });
196
197 return data;
198 }
199
200 this.setState({
201 isLoading: false
202 });
203 },
204 ( err ) => {
205 this.setState({
206 isLoading: false
207 });
208
209 return err;
210 }
211 );
212 }
213
214 async getChartData( id ) {
215 await this.setState({
216 isLoading: 'getChartData'
217 });
218
219 let result = await apiFetch({ path: `wp/v2/visualizer/${id}` });
220
221 let chart = { ...this.state.chart };
222
223 chart['visualizer-source'] = 'Visualizer_Source_Csv';
224 chart['visualizer-default-data'] = 0;
225 chart['visualizer-series'] = result['chart_data']['visualizer-series'];
226 chart['visualizer-data'] = result['chart_data']['visualizer-data'];
227
228 this.setState({
229 isLoading: false,
230 chart
231 });
232 }
233
234 editChartData( chartData, type ) {
235 let chart = { ...this.state.chart };
236 let series = [];
237 let settings = { ...chart['visualizer-settings'] };
238
239 chartData[0].map( ( i, index ) => {
240 series[index] = {
241 label: i,
242 type: chartData[1][index]
243 };
244 });
245
246 chartData.splice( 0, 2 );
247
248 let map = series;
249 let fieldName = 'series';
250
251 if ( 'pie' === chart['visualizer-chart-type']) {
252 map = chartData;
253 fieldName = 'slices';
254 }
255
256 map.map( ( i, index ) => {
257 if ( 'pie' !== chart['visualizer-chart-type'] && 0 === index ) {
258 return;
259 }
260
261 const seriesIndex = 'pie' !== chart['visualizer-chart-type'] ? index - 1 : index;
262
263 if ( settings[fieldName][seriesIndex] === undefined ) {
264 settings[fieldName][seriesIndex] = {};
265 settings[fieldName][seriesIndex].temp = 1;
266 }
267 });
268
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 });
273
274 chart['visualizer-source'] = type;
275 chart['visualizer-default-data'] = 0;
276 chart['visualizer-data'] = chartData;
277 chart['visualizer-series'] = series;
278 chart['visualizer-settings'] = settings;
279 chart['visualizer-chart-url'] = '';
280
281 this.setState({
282 chart,
283 isModified: true,
284 isScheduled: false
285 });
286 }
287
288 updateChart() {
289 this.setState({ isLoading: 'updateChart' });
290
291 const data = this.state.chart;
292
293 if ( false === this.state.isScheduled ) {
294 data['visualizer-chart-schedule'] = '';
295 }
296
297 let fieldName = 'series';
298
299 if ( 'pie' === data['visualizer-chart-type']) {
300 fieldName = 'slices';
301 }
302
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 );
312
313 apiRequest({ path: `/visualizer/v1/update-chart?id=${this.props.attributes.id}`, method: 'POST', data: data }).then(
314 ( data ) => {
315
316 this.setState({
317 isLoading: false,
318 isModified: false
319 });
320
321 return data;
322 },
323 ( err ) => {
324 return err;
325 }
326 );
327 }
328
329 render() {
330 if ( 'renderChart' === this.state.route && null !== this.state.chart ) {
331 return (
332 <ChartRender
333 chart={ this.state.chart }
334 className={ this.props.className }
335 editChart={ this.editChart }
336 />
337 );
338 }
339
340 return (
341 <div className="visualizer-settings">
342
343 <div className="visualizer-settings__title">
344
345 <Dashicon icon="chart-pie" />
346 { __( 'Visualizer' ) }
347
348 </div>
349
350 { 'home' === this.state.route && (
351 <div className="visualizer-settings__content">
352
353 <div className="visualizer-settings__content-description">
354 { __( 'Make a new chart or display an existing one?' ) }
355 </div>
356
357 <div className="visualizer-settings__content-option locked">
358
359 <span className="visualizer-settings__content-option-title">
360 { __( 'Create a new chart (coming soon)' ) }
361 </span>
362
363 <div className="visualizer-settings__content-option-icon">
364 <Dashicon icon="lock" />
365 </div>
366
367 </div>
368
369 <div
370 className="visualizer-settings__content-option"
371 onClick={ () => {
372 this.setState({ route: 'showCharts' });
373 this.props.setAttributes({ route: 'showCharts' });
374 } }
375 >
376
377 <span className="visualizer-settings__content-option-title">
378 { __( 'Display an existing chart' ) }
379 </span>
380
381 <div className="visualizer-settings__content-option-icon">
382 <Dashicon icon="arrow-right-alt2" />
383 </div>
384
385 </div>
386
387 </div>
388 ) }
389
390 { ( ( 'getChart' === this.state.isLoading ) || ( 'chartSelect' === this.state.route && null === this.state.chart ) || ( 'renderChart' === this.state.route && null === this.state.chart ) ) && (
391 <Placeholder>
392 <Spinner/>
393 </Placeholder>
394 ) }
395
396 { ( 'showCharts' === this.state.route && false === this.state.isLoading ) && <Charts getChart={ this.getChart }/> }
397
398 { ( 'chartSelect' === this.state.route && null !== this.state.chart ) &&
399 <ChartSelect
400 chart={ this.state.chart }
401 editSettings={ this.editSettings }
402 editPermissions={ this.editPermissions }
403 url={ this.state.url }
404 readUploadedFile={ this.readUploadedFile }
405 editURL={ this.editURL }
406 editSchedule={ this.editSchedule }
407 uploadData={ this.uploadData }
408 getChartData={ this.getChartData }
409 editChartData={ this.editChartData }
410 isLoading={ this.state.isLoading }
411 />
412 }
413
414 <div className="visualizer-settings__controls">
415
416 { ( 'showCharts' === this.state.route || 'chartSelect' === this.state.route ) &&
417 <ButtonGroup>
418
419 <Button
420 isDefault
421 isLarge
422 onClick={ () => {
423 let route;
424 if ( 'showCharts' === this.state.route ) {
425 route = 'home';
426 } else if ( 'chartSelect' === this.state.route ) {
427 route = 'showCharts';
428 }
429 this.setState({ route });
430 this.props.setAttributes({ route });
431 } }
432 >
433 { __( 'Back' ) }
434 </Button>
435
436 { 'chartSelect' === this.state.route &&
437 <Fragment>
438
439 { false === this.state.isModified ?
440 <Button
441 isDefault
442 isLarge
443 onClick={ () => {
444 this.setState({ route: 'renderChart' });
445 this.props.setAttributes({ route: 'renderChart' });
446 } }
447 >
448 { __( 'Done' ) }
449 </Button> :
450 <Button
451 isPrimary
452 isLarge
453 isBusy={ 'updateChart' === this.state.isLoading }
454 disabled={ 'updateChart' === this.state.isLoading }
455 onClick={ this.updateChart }
456 >
457 { __( 'Save' ) }
458 </Button>
459 }
460
461 </Fragment>
462 }
463
464 </ButtonGroup>
465 }
466
467 </div>
468 </div>
469 );
470 }
471 }
472
473 export default Editor;
474