PluginProbe
TablePress – Tables in WordPress made easy / 3.0
TablePress – Tables in WordPress made easy v3.0
3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 2.4.4 All 44 releases
tablepress / admin / js / export / screen.jsx

screen.jsx in TablePress – Tables in WordPress made easy 3.0, at admin/js/export/screen.jsx

267 lines 9.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * JavaScript code for the "Export Screen" component.
3 *
4 * @package TablePress
5 * @subpackage Export Screen
6 * @author Tobias Bäthge
7 * @since 2.2.0
8 */
9
10 /* globals tp */
11
12 /**
13 * WordPress dependencies.
14 */
15 import { useEffect, useRef, useState } from 'react';
16 import {
17 Button,
18 CheckboxControl,
19 __experimentalHStack as HStack, // eslint-disable-line @wordpress/no-unsafe-wp-apis
20 Icon,
21 SelectControl,
22 __experimentalVStack as VStack, // eslint-disable-line @wordpress/no-unsafe-wp-apis
23 } from '@wordpress/components';
24 import { info } from '@wordpress/icons';
25 import { __, _x, sprintf } from '@wordpress/i18n';
26
27 // Number of tables.
28 const tablesCount = Object.keys( tp.export.tables ).length;
29
30 // Show at least one empty row in the select, and between 3 and 12 total rows.
31 let exportTablesSelectSize = tablesCount + 1;
32 const maxExportTablesSelectSize = 12;
33 exportTablesSelectSize = Math.max( exportTablesSelectSize, 3 );
34 exportTablesSelectSize = Math.min( exportTablesSelectSize, maxExportTablesSelectSize );
35 const exportTablesSelectMultiple = tp.export.zipSupportAvailable;
36
37 const tablesSelectOptions = Object.entries( tp.export.tables ).map( ( [ tableId, tableName ] ) => {
38 if ( '' === tableName.trim() ) {
39 tableName = __( '(no name)', 'tablepress' );
40 }
41 const optionText = sprintf( __( 'ID %1$s: %2$s', 'tablepress' ), tableId, tableName );
42 return { value: tableId, label: optionText };
43 } );
44 if ( ! exportTablesSelectMultiple ) {
45 tablesSelectOptions.unshift( { value: '', label: __( '— Select —', 'tablepress' ), disabled: true } );
46 }
47
48 const exportFormatsSelectOptions = Object.entries( tp.export.exportFormats ).map( ( [ exportFormat, exportFormatName ] ) => ( { value: exportFormat, label: exportFormatName } ) );
49 const csvDelimitersSelectOptions = Object.entries( tp.export.csvDelimiters ).map( ( [ csvDelimiter, csvDelimiterName ] ) => ( { value: csvDelimiter, label: csvDelimiterName } ) );
50
51 /**
52 * Returns the "Export Screen" component's JSX markup.
53 *
54 * @return {Object} Export Screen component.
55 */
56 const Screen = () => {
57 const tablesExportListSelect = useRef( null );
58 const [ screenData, setScreenData ] = useState( {
59 selectedTables: tp.export.selectedTables,
60 exportFormat: tp.export.exportFormat,
61 csvDelimiter: tp.export.csvDelimiter,
62 createZipFile: false,
63 reverseList: false,
64 } );
65
66 // If more than one table is selected, force the ZIP file checkbox to checked.
67 const zipFileRequired = screenData.selectedTables.length > 1;
68
69 /**
70 * Handles screen data state changes.
71 *
72 * @param {Object} updatedScreenData Data in the screen data state that should be updated.
73 */
74 const updateScreenData = ( updatedScreenData ) => {
75 setScreenData( ( currentScreenData ) => ( {
76 ...currentScreenData,
77 ...updatedScreenData,
78 } ) );
79 };
80
81 /*
82 * Set the size of the export tables dropdown to the number of tables, if ZIP file support is available.
83 * `SelectControl` does not support the HTML `size` attribute, so that this has to be done manually with an effect.
84 */
85 useEffect( () => {
86 tablesExportListSelect.current.size = exportTablesSelectMultiple ? exportTablesSelectSize : 1;
87 }, [] );
88
89 return (
90 <table className="tablepress-postbox-table fixed">
91 <tbody>
92 <tr>
93 <th className="column-1 top-align" scope="row">
94 <VStack
95 spacing="20px"
96 >
97 <label htmlFor="tables-export-list">
98 { __( 'Tables to Export', 'tablepress' ) }:
99 </label>
100 { exportTablesSelectMultiple &&
101 <VStack>
102 <CheckboxControl
103 // Show a "Select all" checkbox to select all entries in the export tables dropdown.
104 __nextHasNoMarginBottom
105 label={ __( 'Select all', 'tablepress' ) }
106 checked={ screenData.selectedTables.length === tablesCount }
107 onChange={ () => {
108 const selectedTables = ( screenData.selectedTables.length === tablesCount ) ? [] : Object.keys( tp.export.tables );
109 updateScreenData( { selectedTables } );
110 } }
111 />
112 { tablesCount > maxExportTablesSelectSize &&
113 <CheckboxControl
114 // Show a "Reverse List" checkbox if more tables are shown than what the height of the export tables dropdown holds.
115 __nextHasNoMarginBottom
116 label={ __( 'Reverse list', 'tablepress' ) }
117 checked={ screenData.reverseList }
118 onChange={ ( reverseList ) => {
119 updateScreenData( { reverseList } );
120 tablesSelectOptions.reverse();
121 } }
122 />
123 }
124 </VStack>
125 }
126 </VStack>
127 </th>
128 <td className="column-2">
129 <SelectControl
130 __nextHasNoMarginBottom
131 ref={ tablesExportListSelect }
132 id="tables-export-list"
133 // size={ exportTablesSelectMultiple ? exportTablesSelectSize : 1 } // Not supported by `SelectControl`, so done with an effect above.
134 multiple={ exportTablesSelectMultiple }
135 value={ exportTablesSelectMultiple ? screenData.selectedTables : ( screenData.selectedTables[0] ?? '' ) }
136 onChange={ ( selectedTables ) => {
137 if ( 'string' === typeof selectedTables ) {
138 selectedTables = [ selectedTables ];
139 }
140 updateScreenData( { selectedTables } );
141 } }
142 options={ tablesSelectOptions }
143 />
144 { exportTablesSelectMultiple &&
145 <HStack
146 alignment="left"
147 >
148 <Icon icon={ info } />
149 <span>
150 { sprintf(
151 __( 'You can select multiple tables by holding down the “%1$s” key or the “%2$s” key for ranges.', 'tablepress' ),
152 window?.navigator?.platform?.includes( 'Mac' ) ? _x( '', 'keyboard shortcut modifier key on a Mac keyboard', 'tablepress' ) : _x( 'Ctrl', 'keyboard key', 'tablepress' ),
153 _x( 'Shift', 'keyboard key', 'tablepress' ) )
154 }
155 </span>
156 </HStack>
157 }
158 </td>
159 </tr>
160 <tr>
161 <th className="column-1" scope="row">
162 <label htmlFor="tables-export-format">
163 { __( 'Export Format', 'tablepress' ) }:
164 </label>
165 </th>
166 <td className="column-2">
167 <HStack>
168 <SelectControl
169 __nextHasNoMarginBottom
170 id="tables-export-format"
171 name="export[format]"
172 value={ screenData.exportFormat }
173 label={ __( 'Export Format', 'tablepress' ) }
174 hideLabelFromVision={ true }
175 onChange={ ( exportFormat ) => updateScreenData( { exportFormat } ) }
176 options={ exportFormatsSelectOptions }
177 />
178 </HStack>
179 </td>
180 </tr>
181 <tr>
182 <th className="column-1" scope="row">
183 <label htmlFor="tables-export-csv-delimiter">
184 { __( 'CSV Delimiter', 'tablepress' ) }:
185 </label>
186 </th>
187 <td className="column-2">
188 <HStack
189 alignment="left"
190 >
191 <SelectControl
192 __nextHasNoMarginBottom
193 id="tables-export-csv-delimiter"
194 name="export[csv_delimiter]"
195 value={ screenData.csvDelimiter }
196 label={ __( 'CSV Delimiter', 'tablepress' ) }
197 hideLabelFromVision={ true }
198 onChange={ ( csvDelimiter ) => updateScreenData( { csvDelimiter } ) }
199 options={ csvDelimitersSelectOptions }
200 disabled={ 'csv' !== screenData.exportFormat }
201 />
202 { 'csv' !== screenData.exportFormat &&
203 <span>
204 { __( '(Only needed for CSV export.)', 'tablepress' ) }
205 </span>
206 }
207 </HStack>
208 </td>
209 </tr>
210 <tr className="bottom-border">
211 <th className="column-1" scope="row">
212 { __( 'ZIP file', 'tablepress' ) }:
213 </th>
214 <td className="column-2">
215 { tp.export.zipSupportAvailable &&
216 <HStack
217 alignment="left"
218 >
219 <CheckboxControl
220 __nextHasNoMarginBottom
221 label={ __( 'Create a ZIP archive.', 'tablepress' ) }
222 checked={ screenData.createZipFile || zipFileRequired }
223 disabled={ zipFileRequired }
224 onChange={ ( createZipFile ) => updateScreenData( { createZipFile } ) }
225 />
226 { zipFileRequired &&
227 <span>
228 { __( '(Mandatory if more than one table is selected.)', 'tablepress' ) }
229 </span>
230 }
231 </HStack>
232 }
233 { ! tp.export.zipSupportAvailable &&
234 __( 'Note: Support for ZIP file creation seems not to be available on this server.', 'tablepress' )
235 }
236 </td>
237 </tr>
238 <tr className="top-border">
239 <td className="column-1"></td>
240 <td className="column-2">
241 <input
242 // Send the list of tables to be exported as a string and not an array, to reduce potential issues with large arrays.
243 type="hidden"
244 name="export[tables_list]"
245 value={ screenData.selectedTables.join() }
246 />
247 <input
248 // Send the ZIP file attribute as a hidden field, as disabled checkboxes are not sent in HTTP POST requests.
249 type="hidden"
250 name="export[zip_file]"
251 value={ screenData.createZipFile || zipFileRequired }
252 />
253 <Button
254 variant="primary"
255 type="submit"
256 disabled={ 0 === screenData.selectedTables.length }
257 text={ __( 'Download Export File', 'tablepress' ) }
258 />
259 </td>
260 </tr>
261 </tbody>
262 </table>
263 );
264 };
265
266 export default Screen;
267