PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.3.1
GiveWP – Donation Plugin and Fundraising Platform v4.3.1
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 / Log / Admin / Logs / index.js
give / src / Log / Admin / Logs Last commit date
api.js 4 years ago index.js 4 years ago styles.module.scss 4 years ago
index.js
502 lines
1 import {useState} from 'react';
2 import {
3 Card,
4 Label,
5 Notice,
6 Spinner,
7 Pagination,
8 Select,
9 Table,
10 Button,
11 PeriodSelector,
12 Modal,
13 } from '@givewp/components';
14 import API, {useLogFetcher, getEndpoint} from './api';
15
16 import styles from './styles.module.scss';
17
18 import {__} from '@wordpress/i18n';
19
20 const Logs = () => {
21 const [state, setState] = useState({
22 initialLoad: false,
23 currentPage: 1,
24 currentStatus: '', // log type
25 currentSource: '',
26 currentCategory: '',
27 sortColumn: '',
28 sortDirection: '',
29 startDate: null,
30 endDate: null,
31 pages: 0,
32 statuses: [],
33 sources: [],
34 categories: [],
35 isSorting: false,
36 });
37
38 const [logModal, setLogModal] = useState({
39 visible: false,
40 });
41
42 const [logFlushModal, setLogFlushModal] = useState({
43 visible: false,
44 });
45
46 const parameters = {
47 page: state.currentPage,
48 sort: state.sortColumn,
49 direction: state.sortDirection,
50 type: state.currentStatus,
51 source: state.currentSource,
52 category: state.currentCategory,
53 start: state.startDate ? state.startDate.format('YYYY-MM-DD') : '',
54 end: state.endDate ? state.endDate.format('YYYY-MM-DD') : '',
55 };
56
57 const {data, isLoading, isError} = useLogFetcher(getEndpoint('/get-logs', parameters), {
58 onSuccess: ({response}) => {
59 setState((previousState) => {
60 return {
61 ...previousState,
62 initialLoad: true,
63 pages: response.pages,
64 statuses: response.statuses,
65 categories: response.categories,
66 sources: response.sources,
67 currentPage: state.currentPage > response.pages ? 1 : state.currentPage,
68 isSorting: false,
69 };
70 });
71 },
72 });
73
74 const openLogModal = (log) => {
75 setLogModal({
76 visible: true,
77 id: log.id,
78 type: log.log_type,
79 category: log.category,
80 source: log.source,
81 description: log.description,
82 date: log.date,
83 message: log.message,
84 context: JSON.stringify(log.context, null, ' '),
85 });
86 };
87
88 const closeLogModal = () => {
89 setLogModal({visible: false});
90 };
91
92 const openLogFlushModal = (e) => {
93 e.preventDefault();
94 setLogFlushModal({visible: true});
95 };
96
97 const closeLogFlushModal = () => {
98 setLogFlushModal({visible: false});
99 };
100
101 const flushLogs = () => {
102 setLogFlushModal({
103 visible: true,
104 flushing: true,
105 });
106
107 API.delete('/flush-logs')
108 .then(() => {
109 window.location.reload();
110 })
111 .catch(() => {
112 setLogFlushModal((previousState) => {
113 return {
114 ...previousState,
115 type: 'error',
116 error: true,
117 };
118 });
119 });
120 };
121
122 const setSortDirectionForColumn = (column, direction) => {
123 setState((previousState) => {
124 return {
125 ...previousState,
126 sortColumn: column,
127 sortDirection: direction,
128 isSorting: true,
129 };
130 });
131 };
132
133 const setCurrentPage = (currentPage) => {
134 setState((previousState) => {
135 return {
136 ...previousState,
137 currentPage,
138 };
139 });
140 };
141
142 const setCurrentCategory = (e) => {
143 const category = e.target.value;
144 setState((previousState) => {
145 return {
146 ...previousState,
147 currentCategory: category,
148 };
149 });
150 };
151
152 const setCurrentStatus = (e) => {
153 const status = e.target.value;
154 setState((previousState) => {
155 return {
156 ...previousState,
157 currentStatus: status,
158 };
159 });
160 };
161
162 const setCurrentSource = (e) => {
163 const source = e.target.value;
164 setState((previousState) => {
165 return {
166 ...previousState,
167 currentSource: source,
168 };
169 });
170 };
171
172 const setDates = (startDate, endDate) => {
173 setState((previousState) => {
174 return {
175 ...previousState,
176 startDate,
177 endDate,
178 };
179 });
180 };
181
182 const getCategories = () => {
183 const defaultCategory = {
184 value: '',
185 label: __('All categories', 'give'),
186 };
187
188 const categories = Object.values(state.categories).map((label) => {
189 return {
190 label,
191 value: label,
192 };
193 });
194
195 return [defaultCategory, ...categories];
196 };
197
198 const getStatuses = () => {
199 const defaultStatus = {
200 value: '',
201 label: __('All statuses', 'give'),
202 };
203
204 const statuses = Object.entries(state.statuses).map(([value, label]) => {
205 return {
206 label,
207 value,
208 };
209 });
210
211 return [defaultStatus, ...statuses];
212 };
213
214 const getSources = () => {
215 const defaultSource = {
216 value: '',
217 label: __('All sources', 'give'),
218 };
219
220 const sources = Object.values(state.sources).map((label) => {
221 return {
222 label,
223 value: label,
224 };
225 });
226
227 return [defaultSource, ...sources];
228 };
229
230 const getLogModal = () => {
231 return (
232 <Modal
233 visible={logModal.visible}
234 type={logModal.type}
235 handleClose={closeLogModal}
236 data-givewp-test="log-modal"
237 >
238 <Modal.Title>
239 <Label type={logModal.type} text={getLogTypeText(logModal.type)} />
240
241 <strong style={{marginLeft: 20}}>
242 {__('Log ID', 'give')}: {logModal.id}
243 </strong>
244
245 <Modal.CloseIcon onClick={closeLogModal} data-givewp-test="log-modal-close" />
246 </Modal.Title>
247
248 <Modal.Section title={__('Description', 'give')} content={logModal.message} />
249 <Modal.Section title={__('Category', 'give')} content={logModal.category} />
250 <Modal.Section title={__('Source', 'give')} content={logModal.source} />
251 <Modal.Section title={__('Date & Time', 'give')} content={logModal.date} />
252
253 <Modal.AdditionalContext type={logModal.type} context={logModal.context} />
254 </Modal>
255 );
256 };
257
258 const getLogFlushConfirmationModal = () => {
259 return (
260 <Modal visible={logFlushModal.visible} type={logFlushModal.type} handleClose={closeLogFlushModal}>
261 {logFlushModal.flushing ? (
262 <Modal.Content align="center">
263 {logFlushModal.error ? (
264 <>
265 <h2>{__('Something went wrong!', 'give')}</h2>
266 <div>
267 Try to{' '}
268 <a onClick={() => window.location.reload()} href="#">
269 reload
270 </a>{' '}
271 the browser
272 </div>
273 </>
274 ) : (
275 <>
276 <Spinner />
277 <div style={{marginTop: 20}}>{__('Flushing logs', 'give')}</div>
278 </>
279 )}
280 </Modal.Content>
281 ) : (
282 <>
283 <Modal.Title>{__('Flush all logs', 'give')}</Modal.Title>
284
285 <Modal.Content>{__('Do you want to flush all logs?', 'give')}</Modal.Content>
286
287 <Modal.Content>
288 <button
289 style={{marginRight: 20}}
290 className="button button-primary"
291 onClick={flushLogs}
292 data-givewp-test="flush-logs-confirm-btn"
293 >
294 {__('Confirm', 'give')}
295 </button>
296 <button className="button" onClick={closeLogFlushModal}>
297 {__('Cancel', 'give')}
298 </button>
299 </Modal.Content>
300 </>
301 )}
302 </Modal>
303 );
304 };
305
306 const getLogTypeText = (type) => {
307 if (type in window.GiveLogs.logTypes) {
308 return window.GiveLogs.logTypes[type];
309 }
310 return type;
311 };
312
313 const resetQueryParameters = (e) => {
314 e.preventDefault();
315
316 // Reset table sort state
317 Table.resetSortState();
318
319 setState((previousState) => {
320 return {
321 ...previousState,
322 currentPage: 1,
323 currentStatus: '',
324 currentSource: '',
325 currentCategory: '',
326 sortColumn: '',
327 sortDirection: '',
328 startDate: null,
329 endDate: null,
330 };
331 });
332 };
333
334 const columns = [
335 {
336 key: 'log_type',
337 label: __('Status', 'give'),
338 sort: true,
339 sortCallback: (direction) => setSortDirectionForColumn('log_type', direction),
340 },
341 {
342 key: 'category',
343 label: __('Category', 'give'),
344 sort: true,
345 sortCallback: (direction) => setSortDirectionForColumn('category', direction),
346 },
347 {
348 key: 'source',
349 label: __('Source', 'give'),
350 sort: true,
351 sortCallback: (direction) => setSortDirectionForColumn('source', direction),
352 },
353 {
354 key: 'date',
355 label: __('Date/Time', 'give'),
356 sort: true,
357 sortCallback: (direction) => setSortDirectionForColumn('date', direction),
358 },
359 {
360 key: 'message',
361 label: __('Description', 'give'),
362 },
363 {
364 key: 'details',
365 label: __('Details', 'give'),
366 append: true,
367 styles: {
368 maxWidth: 100,
369 textAlign: 'center',
370 justifyContent: 'center',
371 },
372 },
373 ];
374
375 const columnFilters = {
376 log_type: (type) => <Label type={type} text={getLogTypeText(type)} />,
377 details: (value, log) => {
378 return (
379 <Button
380 data-givewp-test="view-log"
381 onClick={(e) => {
382 e.preventDefault();
383 openLogModal(log);
384 }}
385 icon={true}
386 >
387 <span className="dashicons dashicons-visibility" />
388 </Button>
389 );
390 },
391 };
392
393 // Initial load
394 if (!state.initialLoad && isLoading) {
395 return (
396 <Notice>
397 <Spinner />
398 <h2>{__('Loading log activity', 'give')}</h2>
399 </Notice>
400 );
401 }
402
403 // Is error?
404 if (isError) {
405 return (
406 <Notice>
407 <h2>{__('Something went wrong!', 'give')}</h2>
408 <div>
409 Try to{' '}
410 <a onClick={() => window.location.reload()} href="#">
411 reload
412 </a>{' '}
413 the browser
414 </div>
415 </Notice>
416 );
417 }
418
419 return (
420 <>
421 <div className={styles.headerRow}>
422 <Select
423 options={getStatuses()}
424 onChange={setCurrentStatus}
425 defaultValue={state.currentStatus}
426 className={styles.headerItem}
427 data-givewp-test="logs-status-dropdown"
428 />
429
430 <Select
431 options={getCategories()}
432 onChange={setCurrentCategory}
433 defaultValue={state.currentCategory}
434 className={styles.headerItem}
435 data-givewp-test="logs-category-dropdown"
436 />
437
438 <Select
439 options={getSources()}
440 onChange={setCurrentSource}
441 defaultValue={state.currentSource}
442 className={styles.headerItem}
443 data-givewp-test="logs-source-dropdown"
444 />
445
446 <PeriodSelector
447 period={{
448 startDate: state.startDate,
449 endDate: state.endDate,
450 }}
451 setDates={setDates}
452 />
453
454 <Button onClick={resetQueryParameters}>{__('Reset', 'give')}</Button>
455
456 <div className={styles.pagination}>
457 <Pagination
458 currentPage={state.currentPage}
459 setPage={setCurrentPage}
460 totalPages={state.pages}
461 disabled={isLoading}
462 />
463 </div>
464 </div>
465
466 <Card>
467 <Table
468 columns={columns}
469 data={data}
470 columnFilters={columnFilters}
471 isLoading={isLoading}
472 isSorting={state.isSorting}
473 stripped={false}
474 data-givewp-test="logs-table"
475 />
476 </Card>
477
478 <div className={styles.footerRow}>
479 {data && data.length > 0 && (
480 <button className="button" onClick={openLogFlushModal} data-givewp-test="flush-logs-btn">
481 {__('Flush all logs', 'give')}
482 </button>
483 )}
484
485 <div className={styles.pagination}>
486 <Pagination
487 currentPage={state.currentPage}
488 setPage={setCurrentPage}
489 totalPages={state.pages}
490 disabled={isLoading}
491 />
492 </div>
493 </div>
494
495 {logModal.visible && getLogModal()}
496 {logFlushModal.visible && getLogFlushConfirmationModal()}
497 </>
498 );
499 };
500
501 export default Logs;
502