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

481 lines 11.3 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 id={ this.props.attributes.id }
334 chart={ this.state.chart }
335 className={ this.props.className }
336 editChart={ this.editChart }
337 />
338 );
339 }
340
341 return (
342 <div className="visualizer-settings">
343
344 <div className="visualizer-settings__title">
345
346 <Dashicon icon="chart-pie" />
347 { __( 'Visualizer' ) }
348
349 </div>
350
351 { 'home' === this.state.route && (
352 <div className="visualizer-settings__content">
353 <div className="visualizer-settings__content-description">
354 { __( 'Make a new chart or display an existing one?' ) }
355 </div>
356
357 { /* You can apply "locked" class to lock any of the following list items. */ }
358
359 <a
360 href={ visualizerLocalize.adminPage }
361 target="_blank"
362 className="visualizer-settings__content-option"
363 >
364
365 <span className="visualizer-settings__content-option-title">
366 { __( 'Create a new chart' ) }
367 </span>
368
369 <div className="visualizer-settings__content-option-icon">
370 <Dashicon icon="arrow-right-alt2" />
371 </div>
372
373 </a>
374
375 <div
376 className="visualizer-settings__content-option"
377 onClick={ () => {
378 this.setState({ route: 'showCharts' });
379 this.props.setAttributes({ route: 'showCharts' });
380 } }
381 >
382
383 <span className="visualizer-settings__content-option-title">
384 { __( 'Display an existing chart' ) }
385 </span>
386
387 <div className="visualizer-settings__content-option-icon">
388 <Dashicon icon="arrow-right-alt2" />
389 </div>
390
391 </div>
392
393 </div>
394 ) }
395
396 { ( ( 'getChart' === this.state.isLoading ) || ( 'chartSelect' === this.state.route && null === this.state.chart ) || ( 'renderChart' === this.state.route && null === this.state.chart ) ) && (
397 <Placeholder>
398 <Spinner/>
399 </Placeholder>
400 ) }
401
402 { ( 'showCharts' === this.state.route && false === this.state.isLoading ) && <Charts getChart={ this.getChart }/> }
403
404 { ( 'chartSelect' === this.state.route && null !== this.state.chart ) &&
405 <ChartSelect
406 id={ this.props.attributes.id }
407 chart={ this.state.chart }
408 editSettings={ this.editSettings }
409 editPermissions={ this.editPermissions }
410 url={ this.state.url }
411 readUploadedFile={ this.readUploadedFile }
412 editURL={ this.editURL }
413 editSchedule={ this.editSchedule }
414 uploadData={ this.uploadData }
415 getChartData={ this.getChartData }
416 editChartData={ this.editChartData }
417 isLoading={ this.state.isLoading }
418 />
419 }
420
421 <div className="visualizer-settings__controls">
422
423 { ( 'showCharts' === this.state.route || 'chartSelect' === this.state.route ) &&
424 <ButtonGroup>
425
426 <Button
427 isDefault
428 isLarge
429 onClick={ () => {
430 let route;
431 if ( 'showCharts' === this.state.route ) {
432 route = 'home';
433 } else if ( 'chartSelect' === this.state.route ) {
434 route = 'showCharts';
435 }
436 this.setState({ route });
437 this.props.setAttributes({ route });
438 } }
439 >
440 { __( 'Back' ) }
441 </Button>
442
443 { 'chartSelect' === this.state.route &&
444 <Fragment>
445
446 { false === this.state.isModified ?
447 <Button
448 isDefault
449 isLarge
450 onClick={ () => {
451 this.setState({ route: 'renderChart' });
452 this.props.setAttributes({ route: 'renderChart' });
453 } }
454 >
455 { __( 'Done' ) }
456 </Button> :
457 <Button
458 isPrimary
459 isLarge
460 isBusy={ 'updateChart' === this.state.isLoading }
461 disabled={ 'updateChart' === this.state.isLoading }
462 onClick={ this.updateChart }
463 >
464 { __( 'Save' ) }
465 </Button>
466 }
467
468 </Fragment>
469 }
470
471 </ButtonGroup>
472 }
473
474 </div>
475 </div>
476 );
477 }
478 }
479
480 export default Editor;
481