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