PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.9.0
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.9.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 / Components / Import / JSONImport.js

JSONImport.js in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.9.0, at classes/Visualizer/Gutenberg/src/Components/Import/JSONImport.js

602 lines 18.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * WordPress dependencies
3 */
4 const { __ } = wp.i18n;
5
6 const {
7 apiFetch,
8 apiRequest
9 } = wp;
10
11 const { Component } = wp.element;
12
13 const {
14 Button,
15 ExternalLink,
16 IconButton,
17 Modal,
18 PanelBody,
19 SelectControl,
20 TextControl
21 } = wp.components;
22
23 class JSONImport extends Component {
24 constructor() {
25 super( ...arguments );
26
27 this.openModal = this.openModal.bind( this );
28 this.initTable = this.initTable.bind( this );
29 this.onToggle = this.onToggle.bind( this );
30 this.toggleHeaders = this.toggleHeaders.bind( this );
31 this.getJSONRoot = this.getJSONRoot.bind( this );
32 this.getJSONData = this.getJSONData.bind( this );
33 this.getTableData = this.getTableData.bind( this );
34
35 this.state = {
36 isOpen: false,
37 isLoading: false,
38 isFirstStepOpen: true,
39 isSecondStepOpen: false,
40 isThirdStepOpen: false,
41 isFourthStepOpen: false,
42 isHeaderPanelOpen: false,
43 endpointRoots: [],
44 endpointPaging: [],
45 table: null,
46 requestHeaders: {
47 method: 'GET',
48 username: '',
49 password: '',
50 auth: ''
51 }
52 };
53 }
54
55 async openModal() {
56 await this.setState({ isOpen: true });
57
58 const table = document.querySelector( '#visualizer-json-query-table' );
59
60 if ( this.state.isFourthStepOpen && null !== this.state.table ) {
61 table.innerHTML = this.state.table;
62 this.initTable();
63 }
64 }
65
66 initTable() {
67 jQuery( '#visualizer-json-query-table table' ).DataTable({
68 paging: false,
69 searching: false,
70 ordering: false,
71 select: false,
72 scrollX: '600px',
73 scrollY: '400px',
74 info: false,
75 colReorder: {
76 fixedColumnsLeft: 1
77 },
78 dom: 'Bt',
79 buttons: [
80 {
81 extend: 'colvis',
82 columns: ':gt(0)',
83 collectionLayout: 'four-column'
84 }
85 ]
86 });
87 }
88
89 async onToggle( value ) {
90 if ( null === this.state.table && ( this.state.endpointRoots && 0 < this.state.endpointRoots.length ) && ( 'isFirstStepOpen' === value || 'isSecondStepOpen' === value ) ) {
91 this.setState({
92 isFirstStepOpen: ( 'isFirstStepOpen' === value ? true : false ),
93 isSecondStepOpen: ( 'isSecondStepOpen' === value ? true : false ),
94 isThirdStepOpen: false,
95 isFourthStepOpen: false
96 });
97 }
98
99 if ( null !== this.state.table ) {
100 await this.setState({
101 isFirstStepOpen: ( 'isFirstStepOpen' === value ? true : false ),
102 isSecondStepOpen: ( 'isSecondStepOpen' === value ? true : false ),
103 isThirdStepOpen: ( 'isThirdStepOpen' === value ? true : false ),
104 isFourthStepOpen: ( 'isFourthStepOpen' === value ? true : false )
105 });
106
107 if ( 'isFourthStepOpen' === value ) {
108 const table = document.querySelector( '#visualizer-json-query-table' );
109
110 if ( this.state.isFourthStepOpen ) {
111 table.innerHTML = this.state.table;
112 this.initTable();
113 }
114 }
115 }
116 }
117
118 toggleHeaders() {
119 this.setState({ isHeaderPanelOpen: ! this.state.isHeaderPanelOpen });
120 }
121
122 async getJSONRoot() {
123 this.setState({
124 isLoading: true,
125 endpointRoots: [],
126 endpointPaging: [],
127 table: null
128 });
129
130 let response = await apiRequest({
131 path: `/visualizer/v1/get-json-root?url=${ this.props.chart['visualizer-json-url'] }`,
132 data: {
133 method: this.props.chart['visualizer-json-headers'] ? this.props.chart['visualizer-json-headers'].method : this.state.requestHeaders.method,
134 username: this.props.chart['visualizer-json-headers'] ?
135 (
136 'object' === typeof this.props.chart['visualizer-json-headers'].auth ?
137 this.props.chart['visualizer-json-headers'].auth.username :
138 this.state.requestHeaders.username
139 ) :
140 this.state.requestHeaders.username,
141 password: this.props.chart['visualizer-json-headers'] ?
142 (
143 'object' === typeof this.props.chart['visualizer-json-headers'].auth ?
144 this.props.chart['visualizer-json-headers'].auth.password :
145 this.state.requestHeaders.password
146 ) :
147 this.state.requestHeaders.password,
148 auth: this.props.chart['visualizer-json-headers'] ?
149 (
150 'object' !== typeof this.props.chart['visualizer-json-headers'].auth ?
151 this.props.chart['visualizer-json-headers'].auth :
152 this.state.requestHeaders.auth
153 ) :
154 this.state.requestHeaders.auth
155 },
156 method: 'GET'
157 });
158
159 if ( response.success ) {
160 const roots = Object.keys( response.data.roots ).map( i => {
161 return {
162 label: response.data.roots[i].replace( />/g, '' ),
163 value: response.data.roots[i]
164 };
165 });
166
167 this.setState({
168 isLoading: false,
169 isFirstStepOpen: false,
170 isSecondStepOpen: true,
171 endpointRoots: roots
172 });
173 } else {
174 this.setState({ isLoading: false });
175 alert( response.data.msg );
176 }
177 }
178
179 async getJSONData() {
180 this.setState({ isLoading: true });
181
182 let response = await apiRequest({
183 path: `/visualizer/v1/get-json-data?url=${ this.props.chart['visualizer-json-url'] }&chart=${ this.props.id }`,
184 data: {
185 root: this.props.chart['visualizer-json-root'] || this.state.endpointRoots[0].value,
186 method: this.props.chart['visualizer-json-headers'] ? this.props.chart['visualizer-json-headers'].method : this.state.requestHeaders.method,
187 username: this.props.chart['visualizer-json-headers'] ?
188 (
189 'object' === typeof this.props.chart['visualizer-json-headers'].auth ?
190 this.props.chart['visualizer-json-headers'].auth.username :
191 this.state.requestHeaders.username
192 ) :
193 this.state.requestHeaders.username,
194 password: this.props.chart['visualizer-json-headers'] ?
195 (
196 'object' === typeof this.props.chart['visualizer-json-headers'].auth ?
197 this.props.chart['visualizer-json-headers'].auth.password :
198 this.state.requestHeaders.password
199 ) :
200 this.state.requestHeaders.password,
201 auth: this.props.chart['visualizer-json-headers'] ?
202 (
203 'object' !== typeof this.props.chart['visualizer-json-headers'].auth ?
204 this.props.chart['visualizer-json-headers'].auth :
205 this.state.requestHeaders.auth
206 ) :
207 this.state.requestHeaders.auth
208 },
209 method: 'GET'
210 });
211
212 if ( response.success ) {
213 const paging = [
214 {
215 label: __( 'Don\'t use pagination' ),
216 value: 0
217 }
218 ];
219
220 if ( response.data.paging && 'root>next' === response.data.paging[0]) {
221 paging.push(
222 {
223 label: __( 'Get first 5 pages using root ➤ next' ),
224 value: 'root>next'
225 }
226 );
227 }
228
229 this.setState({
230 isLoading: false,
231 isSecondStepOpen: false,
232 isFourthStepOpen: true,
233 endpointPaging: paging,
234 table: response.data.table
235 });
236
237 const table = document.querySelector( '#visualizer-json-query-table' );
238 table.innerHTML = response.data.table;
239
240 this.initTable();
241 } else {
242 this.setState({ isLoading: false });
243 alert( response.data.msg );
244 }
245 }
246
247 async getTableData() {
248 this.setState({ isLoading: true });
249
250 const columns = document.querySelectorAll( '#visualizer-json-query-table input' );
251 const select = document.querySelectorAll( '#visualizer-json-query-table select' );
252 const header = [];
253 const type = {};
254
255 columns.forEach( column => header.push( column.value ) );
256 select.forEach( el => type[el.name] = el.value );
257
258 let response = await apiRequest({
259 path: '/visualizer/v1/set-json-data',
260 data: {
261 url: this.props.chart['visualizer-json-url'],
262 method: this.props.chart['visualizer-json-headers'] ? this.props.chart['visualizer-json-headers'].method : this.state.requestHeaders.method,
263 username: this.props.chart['visualizer-json-headers'] ?
264 (
265 'object' === typeof this.props.chart['visualizer-json-headers'].auth ?
266 this.props.chart['visualizer-json-headers'].auth.username :
267 this.state.requestHeaders.username
268 ) :
269 this.state.requestHeaders.username,
270 password: this.props.chart['visualizer-json-headers'] ?
271 (
272 'object' === typeof this.props.chart['visualizer-json-headers'].auth ?
273 this.props.chart['visualizer-json-headers'].auth.password :
274 this.state.requestHeaders.password
275 ) :
276 this.state.requestHeaders.password,
277 auth: this.props.chart['visualizer-json-headers'] ?
278 (
279 'object' !== typeof this.props.chart['visualizer-json-headers'].auth ?
280 this.props.chart['visualizer-json-headers'].auth :
281 this.state.requestHeaders.auth
282 ) :
283 this.state.requestHeaders.auth,
284 root: this.props.chart['visualizer-json-root'] || this.state.endpointRoots[0].value,
285 paging: this.props.chart['visualizer-json-paging'] || 0,
286 header,
287 ...type
288 },
289 method: 'GET'
290 });
291
292 if ( response.success ) {
293 this.props.JSONImportData( response.data.name, JSON.parse( response.data.series ), JSON.parse( response.data.data ) );
294
295 this.setState({
296 isOpen: false,
297 isLoading: false
298 });
299 } else {
300 alert( response.data.msg );
301
302 this.setState({ isLoading: false });
303 }
304 }
305
306 render() {
307 return (
308 <PanelBody
309 title={ __( 'Import from JSON' ) }
310 className="visualizer-inner-sections"
311 initialOpen={ false }
312 >
313 <p>{ __( 'You can choose here to import or synchronize your chart data with a remote JSON source.' ) }</p>
314
315 <p>
316 <ExternalLink href="https://docs.themeisle.com/article/1052-how-to-generate-charts-from-json-data-rest-endpoints">
317 { __( 'For more info check this tutorial.' ) }
318 </ExternalLink>
319 </p>
320
321 <SelectControl
322 label={ __( 'How often do you want to check the url?' ) }
323 value={ this.props.chart['visualizer-json-schedule'] ? this.props.chart['visualizer-json-schedule'] : 1 }
324 options={ [
325 { label: __( 'One-time' ), value: '-1' },
326 { label: __( 'Live' ), value: '0' },
327 { label: __( 'Each hour' ), value: '1' },
328 { label: __( 'Each 12 hours' ), value: '12' },
329 { label: __( 'Each day' ), value: '24' },
330 { label: __( 'Each 3 days' ), value: '72' }
331 ] }
332 onChange={ this.props.editSchedule }
333 />
334
335 <Button
336 isPrimary
337 isLarge
338 onClick={ this.openModal }
339 >
340 { __( 'Modify Parameters' ) }
341 </Button>
342
343 { this.state.isOpen && (
344 <Modal
345 title={ __( 'Import from JSON' ) }
346 className="visualizer-json-query-modal"
347 shouldCloseOnClickOutside={ false }
348 onRequestClose={ () => {
349 this.setState({
350 isOpen: false,
351 isTableRendered: false
352 });
353 } }
354 >
355 <PanelBody
356 title={ __( 'Step 1: Specify the JSON endpoint/URL' ) }
357 opened={ this.state.isFirstStepOpen }
358 onToggle={ () => this.onToggle( 'isFirstStepOpen' ) }
359 >
360 <p>{ __( 'If you want to add authentication, add headers to the endpoint or change the request in any way, please refer to our document here:' ) }</p>
361
362 <p>
363 <ExternalLink href="https://docs.themeisle.com/article/1043-visualizer-how-to-extend-rest-endpoints-with-json-response">
364 { __( 'How to extend REST endpoints with JSON response' ) }
365 </ExternalLink>
366 </p>
367
368 <TextControl
369 placeholder={ __( 'Please enter the URL of your JSON file' ) }
370 value={ this.props.chart['visualizer-json-url'] ? this.props.chart['visualizer-json-url'] : '' }
371 onChange={ this.props.editJSONURL }
372 />
373
374 <IconButton
375 icon="arrow-right-alt2"
376 label={ __( 'Add Headers' ) }
377 onClick={ this.toggleHeaders }
378 >
379 { __( 'Add Headers' ) }
380 </IconButton>
381
382 { this.state.isHeaderPanelOpen && (
383 <div className="visualizer-json-query-modal-headers-panel">
384 <SelectControl
385 label={ __( 'Request Type' ) }
386 value={ this.props.chart['visualizer-json-headers'] ? this.props.chart['visualizer-json-headers'].method : this.state.requestHeaders.method }
387 options={ [
388 {
389 value: 'GET',
390 label: __( 'GET' )
391 },
392 {
393 value: 'POST',
394 label: __( 'POST' )
395 }
396 ] }
397 onChange={ e => {
398 let headers = { ...this.state.requestHeaders };
399 let headersState = this.state.requestHeaders;
400 headers.method = e;
401 headersState = {
402 ...headersState,
403 method: e
404 };
405 this.setState({ requestHeaders: headersState });
406 this.props.editJSONHeaders( headers );
407 } }
408 />
409
410 <p>{ __( 'Credentials' ) }</p>
411
412 <TextControl
413 label={ __( 'Username' ) }
414 placeholder={ __( 'Username/Access Key' ) }
415 value={
416 this.props.chart['visualizer-json-headers'] ?
417 (
418 'object' === typeof this.props.chart['visualizer-json-headers'].auth ?
419 this.props.chart['visualizer-json-headers'].auth.username :
420 this.state.requestHeaders.username
421 ) :
422 this.state.requestHeaders.username
423 }
424 onChange={ e => {
425 let headers = { ...this.state.requestHeaders };
426 let headersState = this.state.requestHeaders;
427 headers.auth = {
428 username: e,
429 password: this.props.chart['visualizer-json-headers'] ?
430 (
431 'object' === typeof this.props.chart['visualizer-json-headers'].auth ?
432 this.props.chart['visualizer-json-headers'].auth.password :
433 this.state.requestHeaders.password
434 ) :
435 this.state.requestHeaders.password
436 };
437 headersState = {
438 ...headersState,
439 username: e,
440 password: headers.password
441 };
442 this.setState({ requestHeaders: headersState });
443 this.props.editJSONHeaders( headers );
444 } }
445 />
446
447 <span className="visualizer-json-query-modal-field-separator" >{ __( '&' ) }</span>
448
449 <TextControl
450 label={ __( 'Password' ) }
451 placeholder={ __( 'Password/Secret Key' ) }
452 type="password"
453 value={
454 this.props.chart['visualizer-json-headers'] ?
455 (
456 'object' === typeof this.props.chart['visualizer-json-headers'].auth ?
457 this.props.chart['visualizer-json-headers'].auth.password :
458 this.state.requestHeaders.password
459 ) :
460 this.state.requestHeaders.password
461 }
462 onChange={ e => {
463 let headers = { ...this.state.requestHeaders };
464 let headersState = this.state.requestHeaders;
465 headers.auth = {
466 username: this.props.chart['visualizer-json-headers'] ?
467 (
468 'object' === typeof this.props.chart['visualizer-json-headers'].auth ?
469 this.props.chart['visualizer-json-headers'].auth.username :
470 this.state.requestHeaders.username
471 ) :
472 this.state.requestHeaders.username,
473 password: e
474 };
475 headersState = {
476 ...headersState,
477 username: headers.username,
478 password: e
479 };
480 this.setState({ requestHeaders: headersState });
481 this.props.editJSONHeaders( headers );
482 } }
483 />
484
485 <p>{ __( 'OR' ) }</p>
486
487 <TextControl
488 label={ __( 'Authorization' ) }
489 placeholder={ __( 'e.g. SharedKey <AccountName>:<Signature>' ) }
490 value={
491 this.props.chart['visualizer-json-headers'] ?
492 (
493 'object' !== typeof this.props.chart['visualizer-json-headers'].auth ?
494 this.props.chart['visualizer-json-headers'].auth :
495 this.state.requestHeaders.auth
496 ) :
497 this.state.requestHeaders.auth
498 }
499 onChange={ e => {
500 let headers = { ...this.state.requestHeaders };
501 let headersState = this.state.requestHeaders;
502 headers.auth = e;
503 headersState = {
504 ...headersState,
505 auth: e
506 };
507 this.setState({ requestHeaders: headersState });
508 this.props.editJSONHeaders( headers );
509 } }
510 />
511 </div>
512 ) }
513
514 <Button
515 isPrimary
516 isLarge
517 isBusy={ this.state.isLoading }
518 disabled={ this.state.isLoading }
519 onClick={ this.getJSONRoot }
520 >
521 { __( 'Fetch Endpoint' ) }
522 </Button>
523 </PanelBody>
524
525 <PanelBody
526 title={ __( 'Step 2: Choose the JSON root' ) }
527 initialOpen={ false }
528 opened={ this.state.isSecondStepOpen }
529 onToggle={ () => this.onToggle( 'isSecondStepOpen' ) }
530 >
531
532 <p>{ __( 'If you see Invalid Data, you may have selected the wrong root to fetch data from. Please select an alternative.' ) }</p>
533
534 <SelectControl
535 value={ this.props.chart['visualizer-json-root'] }
536 options={ this.state.endpointRoots }
537 onChange={ this.props.editJSONRoot }
538 />
539
540 <Button
541 isPrimary
542 isLarge
543 isBusy={ this.state.isLoading }
544 disabled={ this.state.isLoading }
545 onClick={ this.getJSONData }
546 >
547 { __( 'Parse Endpoint' ) }
548 </Button>
549 </PanelBody>
550
551 <PanelBody
552 title={ __( 'Step 3: Specify miscellaneous parameters' ) }
553 initialOpen={ false }
554 opened={ this.state.isThirdStepOpen }
555 onToggle={ () => this.onToggle( 'isThirdStepOpen' ) }
556 >
557 { ( 'community' !== visualizerLocalize.isPro ) ? (
558 <SelectControl
559 value={ this.props.chart['visualizer-json-paging'] || 0 }
560 options={ this.state.endpointPaging }
561 onChange={ this.props.editJSONPaging }
562 />
563 ) : (
564 <p>{ __( 'Enable this feature in PRO version!' ) }</p>
565 ) }
566 </PanelBody>
567
568 <PanelBody
569 title={ __( 'Step 4: Select the data to display in the chart' ) }
570 initialOpen={ false }
571 opened={ this.state.isFourthStepOpen }
572 onToggle={ () => this.onToggle( 'isFourthStepOpen' ) }
573 >
574 <ul>
575 <li>{ __( 'Select whether to include the data in the chart. Each column selected will form one series.' ) }</li>
576 <li>{ __( 'If a column is selected to be included, specify its data type.' ) }</li>
577 <li>{ __( 'You can use drag/drop to reorder the columns but this column position is not saved. So when you reload the table, you may have to reorder again.' ) }</li>
578 <li>{ __( 'You can select any number of columns but the chart type selected will determine how many will display in the chart.' ) }</li>
579 </ul>
580
581 <div id="visualizer-json-query-table"></div>
582
583 <Button
584 isPrimary
585 isLarge
586 isBusy={ this.state.isLoading }
587 disabled={ this.state.isLoading }
588 onClick={ this.getTableData }
589 >
590 { __( 'Save & Show Chart' ) }
591 </Button>
592 </PanelBody>
593 </Modal>
594 )}
595
596 </PanelBody>
597 );
598 }
599 }
600
601 export default JSONImport;
602