PluginProbe
TablePress – Tables in WordPress made easy / 3.2.1
TablePress – Tables in WordPress made easy v3.2.1
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.2.1, at admin/js/export/screen.jsx

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