PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.10.4
GiveWP – Donation Plugin and Fundraising Platform v2.10.4
4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / src / MigrationLog / Admin / Migrations / index.js
give / src / MigrationLog / Admin / Migrations Last commit date
api.js 5 years ago index.js 5 years ago styles.module.scss 5 years ago
index.js
361 lines
1 import { useState } from 'react';
2 import classNames from 'classnames';
3 import { Card, Label, Notice, Spinner, Pagination, Table, Button, Modal } from '@givewp/components';
4 import API, { useMigrationFetcher, getEndpoint } from './api';
5
6 import styles from './styles.module.scss';
7
8 const { __ } = wp.i18n;
9
10 const Migrations = () => {
11 const [ state, setState ] = useState( {
12 initialLoad: false,
13 currentPage: 1,
14 sortColumn: 'run_order',
15 sortDirection: 'asc',
16 pages: 0,
17 showOptions: false,
18 isSorting: false,
19 } );
20
21 const [ migrationModal, setMigrationModal ] = useState( {
22 visible: false,
23 } );
24
25 const [ migrationRunModal, setMigrationRunModal ] = useState( {
26 visible: false,
27 } );
28
29 const parameters = {
30 page: state.currentPage,
31 sort: state.sortColumn,
32 direction: state.sortDirection,
33 };
34
35 const { data, isLoading, isError, mutate } = useMigrationFetcher( getEndpoint( '/get-migrations', parameters ), {
36 onSuccess: ( { response } ) => {
37 setState( ( previousState ) => {
38 return {
39 ...previousState,
40 initialLoad: true,
41 pages: response.pages,
42 currentPage: state.currentPage > response.pages ? 1 : state.currentPage,
43 showOptions: response.showOptions,
44 isSorting: false,
45 };
46 } );
47 },
48 } );
49
50 const runMigration = () => {
51 setMigrationRunModal( ( previousState ) => {
52 return {
53 ...previousState,
54 visible: true,
55 running: true,
56 };
57 } );
58
59 API.post( '/run-migration', { id: migrationRunModal.id } )
60 .then( ( response ) => {
61 if ( response.data.status ) {
62 closeMigrationRunModal();
63 } else {
64 setMigrationRunModal( ( previousState ) => {
65 return {
66 ...previousState,
67 type: 'error',
68 error: true,
69 errorMessage: response.data.message,
70 };
71 } );
72 }
73 // Invalidate the cache
74 mutate( getEndpoint( '/get-migrations', parameters ) );
75 } )
76 .catch( () => {
77 setMigrationRunModal( ( previousState ) => {
78 return {
79 ...previousState,
80 type: 'error',
81 error: true,
82 };
83 } );
84 } );
85 };
86
87 const openMigrationModal = ( migration ) => {
88 setMigrationModal( {
89 visible: true,
90 id: migration.id,
91 status: migration.status,
92 error: migration.error,
93 last_run: migration.last_run,
94 } );
95 };
96
97 const closeMigrationModal = () => {
98 setMigrationModal( { visible: false } );
99 };
100
101 const openMigrationRunModal = ( migrationId ) => {
102 setMigrationRunModal( {
103 id: migrationId,
104 visible: true,
105 type: 'warning',
106 } );
107 };
108
109 const closeMigrationRunModal = () => {
110 setMigrationRunModal( { visible: false } );
111 };
112
113 const setSortDirectionForColumn = ( column, direction ) => {
114 setState( ( previousState ) => {
115 return {
116 ...previousState,
117 sortColumn: column,
118 sortDirection: direction,
119 isSorting: true,
120 };
121 } );
122 };
123
124 const setCurrentPage = ( currentPage ) => {
125 setState( ( previousState ) => {
126 return {
127 ...previousState,
128 currentPage,
129 };
130 } );
131 };
132
133 const getMigrationModal = () => {
134 return (
135 <Modal visible={ migrationModal.visible } type="error" handleClose={ closeMigrationModal }>
136 <Modal.Title>
137 <strong>
138 { __( 'Migration Failed', 'give' ) }
139 </strong>
140
141 <Modal.CloseIcon onClick={ closeMigrationModal } />
142 </Modal.Title>
143
144 <Modal.Section title={ __( 'Migration ID', 'give' ) } content={ migrationModal.id } />
145 <Modal.Section title={ __( 'Last run', 'give' ) } content={ migrationModal.last_run ?? 'n/a' } />
146
147 <Modal.AdditionalContext type={ migrationModal.status } context={ migrationModal.error } />
148 </Modal>
149 );
150 };
151
152 const getMigrationRunModal = () => {
153 return (
154 <Modal visible={ migrationRunModal.visible } type={ migrationRunModal.type } handleClose={ closeMigrationRunModal }>
155 { migrationRunModal.running ? (
156 <Modal.Content align="center">
157 { migrationRunModal.error ? (
158 <>
159 <Modal.CloseIcon onClick={ closeMigrationRunModal } />
160 <h2>{ __( 'Database update failed!', 'give' ) }</h2>
161 { migrationRunModal.errorMessage && (
162 <Modal.Content align="center">
163 { migrationRunModal.errorMessage }
164 </Modal.Content>
165 ) }
166 <Modal.Content align="center">
167 { __( 'Check migration details for more information', 'give' ) }
168 </Modal.Content>
169 </>
170 ) : (
171 <>
172 <Spinner />
173 <div style={ { marginTop: 20 } }>
174 { __( 'Running Update', 'give' ) }
175 </div>
176 </>
177 ) }
178 </Modal.Content>
179 ) : (
180 <>
181 <Modal.Title>
182 <span className={ classNames( styles.titleIcon, styles.warning ) }>
183 <span className="dashicons dashicons-warning" />
184 </span>
185 { __( 'Create a Backup Before Running Database Update', 'give' ) }
186 </Modal.Title>
187
188 <Modal.Content>
189 <strong style={ { marginRight: 5 } }>{ __( 'Notice', 'give' ) }:</strong>
190 { __( 'We strongly recommend you create a complete backup of your WordPress files and database prior to performing an update. We are not responsible for any misuse, deletions, white screens, fatal errors, or any other issue resulting from the use of this plugin.', 'give' ) }
191 </Modal.Content>
192
193 <Modal.Content>
194 <button style={ { marginRight: 20 } } className="button button-primary" onClick={ runMigration }>
195 { __( 'Confirm', 'give' ) }
196 </button>
197 <button className="button" onClick={ closeMigrationRunModal }>
198 { __( 'Cancel', 'give' ) }
199 </button>
200 </Modal.Content>
201 </>
202 ) }
203 </Modal>
204 );
205 };
206
207 const columns = [
208 {
209 key: 'status',
210 label: __( 'Status', 'give' ),
211 sort: true,
212 sortCallback: ( direction ) => setSortDirectionForColumn( 'status', direction ),
213 styles: {
214 maxWidth: 150,
215 },
216 },
217 {
218 key: 'title',
219 label: __( 'Migration Title', 'give' ),
220 sort: true,
221 sortCallback: ( direction ) => setSortDirectionForColumn( 'title', direction ),
222 styles: {
223 overflowWrap: 'break-word',
224 wordWrap: 'break-word',
225 wordBreak: 'break-all',
226 },
227 },
228 {
229 key: 'last_run',
230 label: __( 'Last run', 'give' ),
231 sort: true,
232 sortCallback: ( direction ) => setSortDirectionForColumn( 'last_run', direction ),
233 styles: {
234 maxWidth: 200,
235 },
236 },
237 {
238 key: 'source',
239 label: __( 'Source', 'give' ),
240 sort: true,
241 sortCallback: ( direction ) => setSortDirectionForColumn( 'source', direction ),
242 styles: {
243 maxWidth: 200,
244 },
245 },
246 {
247 key: 'run_order',
248 label: __( 'Run Order', 'give' ),
249 sort: true,
250 sortCallback: ( direction ) => setSortDirectionForColumn( 'run_order', direction ),
251 styles: {
252 maxWidth: 150,
253 },
254 },
255 {
256 key: 'actions',
257 label: __( 'Actions', 'give' ),
258 append: true,
259 styles: {
260 maxWidth: 100,
261 },
262 },
263 {
264 key: 'details',
265 label: __( 'Details', 'give' ),
266 append: true,
267 styles: {
268 maxWidth: 100,
269 textAlign: 'center',
270 justifyContent: 'center',
271 },
272 },
273 ];
274
275 const columnFilters = {
276 status: ( type ) => <Label type={ type } />,
277 actions: ( type, migration ) => {
278 if ( ! state.showOptions && migration.status !== 'failed' ) {
279 return null;
280 }
281
282 return (
283 <button
284 className="button"
285 onClick={ () => openMigrationRunModal( migration.id ) }>
286 { __( 'Re-run Update', 'give' ) }
287 </button>
288 );
289 },
290 details: ( value, migration ) => {
291 if ( ! migration.error.length ) {
292 return null;
293 }
294
295 return (
296 <Button
297 onClick={ ( e ) => {
298 e.preventDefault();
299 openMigrationModal( migration );
300 } }
301 icon={ true }>
302 <span className="dashicons dashicons-visibility" />
303 </Button>
304 );
305 },
306 };
307
308 // Initial load
309 if ( ! state.initialLoad && isLoading ) {
310 return (
311 <Notice>
312 <Spinner />
313 <h2>{ __( 'Loading updates activity', 'give' ) }</h2>
314 </Notice>
315 );
316 }
317
318 // Is error?
319 if ( isError ) {
320 return (
321 <Notice>
322 <h2>{ __( 'Something went wrong!', 'give' ) }</h2>
323 <div>
324 Try to <a onClick={ () => window.location.reload() } href="#">reload</a> the browser
325 </div>
326 </Notice>
327 );
328 }
329
330 return (
331 <>
332 <Card>
333 <Table
334 columns={ columns }
335 data={ data }
336 columnFilters={ columnFilters }
337 isLoading={ isLoading }
338 isSorting={ state.isSorting }
339 stripped={ false }
340 />
341 </Card>
342
343 <div className={ styles.footerRow }>
344 <div className={ styles.pagination }>
345 <Pagination
346 currentPage={ state.currentPage }
347 setPage={ setCurrentPage }
348 totalPages={ state.pages }
349 disabled={ isLoading }
350 />
351 </div>
352 </div>
353
354 { migrationModal.visible && getMigrationModal() }
355 { migrationRunModal.visible && getMigrationRunModal() }
356 </>
357 );
358 };
359
360 export default Migrations;
361