PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.20.0
GiveWP – Donation Plugin and Fundraising Platform v2.20.0
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 4 years ago index.js 4 years ago styles.module.scss 4 years ago
index.js
365 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 import {__} from '@wordpress/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>{__('Migration Failed', 'give')}</strong>
138
139 <Modal.CloseIcon onClick={closeMigrationModal}/>
140 </Modal.Title>
141
142 <Modal.Section title={__('Migration ID', 'give')} content={migrationModal.id}/>
143 <Modal.Section title={__('Last run', 'give')} content={migrationModal.last_run ?? __('n/a', 'give')}/>
144
145 <Modal.AdditionalContext type={migrationModal.status} context={migrationModal.error}/>
146 </Modal>
147 );
148 };
149
150 const getMigrationRunModal = () => {
151 return (
152 <Modal
153 visible={migrationRunModal.visible}
154 type={migrationRunModal.type}
155 handleClose={closeMigrationRunModal}
156 >
157 {migrationRunModal.running ? (
158 <Modal.Content align="center">
159 {migrationRunModal.error ? (
160 <>
161 <Modal.CloseIcon onClick={closeMigrationRunModal}/>
162 <h2>{__('Database update failed!', 'give')}</h2>
163 {migrationRunModal.errorMessage && (
164 <Modal.Content align="center">{migrationRunModal.errorMessage}</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}}>{__('Running Update', 'give')}</div>
174 </>
175 )}
176 </Modal.Content>
177 ) : (
178 <>
179 <Modal.Title>
180 <span className={classNames(styles.titleIcon, styles.warning)}>
181 <span className="dashicons dashicons-warning"/>
182 </span>
183 {__('Create a Backup Before Running Database Update', 'give')}
184 </Modal.Title>
185
186 <Modal.Content>
187 <strong style={{marginRight: 5}}>{__('Notice', 'give')}:</strong>
188 {__(
189 '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.',
190 'give'
191 )}
192 </Modal.Content>
193
194 <Modal.Content>
195 <button style={{marginRight: 20}} className="button button-primary" onClick={runMigration}>
196 {__('Confirm', 'give')}
197 </button>
198 <button className="button" onClick={closeMigrationRunModal}>
199 {__('Cancel', 'give')}
200 </button>
201 </Modal.Content>
202 </>
203 )}
204 </Modal>
205 );
206 };
207
208 const columns = [
209 {
210 key: 'status',
211 label: __('Status', 'give'),
212 sort: true,
213 sortCallback: (direction) => setSortDirectionForColumn('status', direction),
214 styles: {
215 maxWidth: 150,
216 },
217 },
218 {
219 key: 'title',
220 label: __('Migration Title', 'give'),
221 sort: true,
222 sortCallback: (direction) => setSortDirectionForColumn('title', direction),
223 styles: {
224 overflowWrap: 'break-word',
225 wordWrap: 'break-word',
226 wordBreak: 'break-all',
227 },
228 },
229 {
230 key: 'last_run',
231 label: __('Last run', 'give'),
232 sort: true,
233 sortCallback: (direction) => setSortDirectionForColumn('last_run', direction),
234 styles: {
235 maxWidth: 200,
236 },
237 },
238 {
239 key: 'source',
240 label: __('Source', 'give'),
241 sort: true,
242 sortCallback: (direction) => setSortDirectionForColumn('source', direction),
243 styles: {
244 maxWidth: 200,
245 },
246 },
247 {
248 key: 'run_order',
249 label: __('Run Order', 'give'),
250 sort: true,
251 sortCallback: (direction) => setSortDirectionForColumn('run_order', direction),
252 styles: {
253 maxWidth: 150,
254 },
255 },
256 {
257 key: 'actions',
258 label: __('Actions', 'give'),
259 append: true,
260 styles: {
261 maxWidth: 100,
262 },
263 },
264 {
265 key: 'details',
266 label: __('Details', 'give'),
267 append: true,
268 styles: {
269 maxWidth: 100,
270 textAlign: 'center',
271 justifyContent: 'center',
272 },
273 },
274 ];
275
276 const columnFilters = {
277 status: (type) => <Label type={type}/>,
278 actions: (type, migration) => {
279 if (!state.showOptions && migration.status !== 'failed') {
280 return null;
281 }
282
283 return (
284 <button className="button" onClick={() => openMigrationRunModal(migration.id)}>
285 {__('Re-run Update', 'give')}
286 </button>
287 );
288 },
289 details: (value, migration) => {
290 if (!migration.error.length) {
291 return null;
292 }
293
294 return (
295 <Button
296 onClick={(e) => {
297 e.preventDefault();
298 openMigrationModal(migration);
299 }}
300 icon={true}
301 >
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{' '}
325 <a onClick={() => window.location.reload()} href="#">
326 reload
327 </a>{' '}
328 the browser
329 </div>
330 </Notice>
331 );
332 }
333
334 return (
335 <>
336 <Card>
337 <Table
338 columns={columns}
339 data={data}
340 columnFilters={columnFilters}
341 isLoading={isLoading}
342 isSorting={state.isSorting}
343 stripped={false}
344 />
345 </Card>
346
347 <div className={styles.footerRow}>
348 <div className={styles.pagination}>
349 <Pagination
350 currentPage={state.currentPage}
351 setPage={setCurrentPage}
352 totalPages={state.pages}
353 disabled={isLoading}
354 />
355 </div>
356 </div>
357
358 {migrationModal.visible && getMigrationModal()}
359 {migrationRunModal.visible && getMigrationRunModal()}
360 </>
361 );
362 };
363
364 export default Migrations;
365