Skip to content

Commit 0c84a09

Browse files
committed
Fix: Pagination values no longer reset when navigating away from logs overview
1 parent 292959c commit 0c84a09

5 files changed

Lines changed: 111 additions & 62 deletions

File tree

lib/public/components/Filters/index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { iconChevronBottom, iconChevronRight } from '/js/src/icons.js';
2222
*/
2323
const filters = (model, columns) =>
2424
h('.w-100.shadow-level1.p2', [
25-
h('.f3', 'Filters'),
25+
h('.f3', { style: 'margin-bottom: var(--space-xs);' }, 'Filters'),
2626
Object.entries(columns).reduce((accumulator, [key, column]) => {
2727
if (column.filter) {
2828
accumulator.push([
@@ -39,6 +39,11 @@ const filters = (model, columns) =>
3939
}
4040
return accumulator;
4141
}, []),
42+
h('button.btn.btn-danger', {
43+
style: 'margin-top: var(--space-s);',
44+
disabled: !model.logs.isAnyFilterActive(),
45+
onclick: () => model.logs.resetFilters(),
46+
}, 'Reset all filters'),
4247
]);
4348

4449
export default filters;

lib/public/views/Logs/Create/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const createScreen = (model) => {
5151
return h('div#create-log', [
5252
data.isFailure() && data.payload.map(errorAlert),
5353
h('', {
54-
onremove: () => model.logs.flushModel(),
54+
onremove: () => model.logs.clearAllEditors(),
5555
}, [
5656
h('h2.mv2', 'Create Log'),
5757
h('h3.black.line-break: auto', 'Title of the log'),

lib/public/views/Logs/Details/index.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,7 @@ const logDetailScreen = (model) => {
5151
};
5252

5353
return h('', [
54-
h('h2.mv2', {
55-
onremove: () => {
56-
model.logs.clearLogs(),
57-
model.logs.flushModel();
58-
},
59-
}, 'Log Tree'),
54+
h('h2.mv2', 'Log Tree'),
6055
h('.w-100.flex-column', {
6156
oncreate: () => scrollTo(`#post${id}`, 150),
6257
}, tree(data.payload[0])),

lib/public/views/Logs/Logs.js

Lines changed: 54 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,21 @@ export default class Overview extends Observable {
3232
this.resetFilters(false);
3333

3434
this.createdLog = RemoteData.NotAsked();
35-
this.title = '';
36-
this.text = '';
37-
38-
this.isPreviewActive = false;
39-
this.editors = [];
40-
41-
this.collapsableColumns = [];
42-
this.collapsedColumns = [];
35+
this.clearAllEditors();
4336
}
4437

4538
/**
4639
* Retrieve every relevant log from the API
47-
* @param {Number} offset Pagination offset to include when making the API call
4840
* @returns {undefined} Injects the data object with the response data
4941
*/
50-
async fetchAllLogs(offset = 0) {
42+
async fetchAllLogs() {
5143
if (!this.model.tags.getTags().isSuccess()) {
5244
this.logs = RemoteData.loading();
5345
this.notify();
5446
}
5547

5648
const params = {
57-
'page[offset]': offset,
49+
'page[offset]': (this.selectedPage - 1) * this.logsPerPage,
5850
'page[limit]': this.logsPerPage,
5951
...this.titleFilterText && {
6052
'filter[title]': this.titleFilterText,
@@ -252,6 +244,51 @@ export default class Overview extends Observable {
252244
return this.createdLog;
253245
}
254246

247+
/**
248+
* Returns all filters and pagination settings to their default values
249+
* @param {Boolean} fetch Whether to refetch all logs after filters have been reset
250+
* @return {undefined}
251+
*/
252+
resetFilters(fetch = true) {
253+
this.expandedFilters = [];
254+
255+
this.titleFilterText = '';
256+
this.titleFilterDebounce = null;
257+
258+
this.authorFilterText = '';
259+
this.authorFilterDebounce = null;
260+
261+
this.createdFilterFrom = '';
262+
this.createdFilterTo = '';
263+
264+
this.tagFilterOperation = 'AND';
265+
this.tagFilterValues = [];
266+
this.moreTags = false;
267+
268+
this.amountDropdownVisible = false;
269+
this.logsPerPage = 10;
270+
this.selectedPage = 1;
271+
this.totalPages = 1;
272+
273+
if (fetch) {
274+
this.fetchAllLogs();
275+
}
276+
}
277+
278+
/**
279+
* Checks if any filter value has been modified from their default (empty)
280+
* @returns {Boolean} If any filter is active
281+
*/
282+
isAnyFilterActive() {
283+
return (
284+
this.titleFilterText !== ''
285+
|| this.authorFilterText !== ''
286+
|| this.createdFilterFrom !== ''
287+
|| this.createdFilterTo !== ''
288+
|| this.tagFilterValues.length !== 0
289+
);
290+
}
291+
255292
/**
256293
* Toggle the expansion state (visibility) of a filter menu
257294
* @param {String} targetKey The key of the filter whose visibility should be toggled
@@ -397,30 +434,6 @@ export default class Overview extends Observable {
397434
this.notify();
398435
}
399436

400-
/**
401-
* Returns all filters to their default (empty) values
402-
* @param {Boolean} fetch Whether to refetch all logs after filters have been reset
403-
* @return {undefined}
404-
*/
405-
resetFilters(fetch = true) {
406-
this.titleFilterText = '';
407-
this.titleFilterDebounce = null;
408-
409-
this.authorFilterText = '';
410-
this.authorFilterDebounce = null;
411-
412-
this.createdFilterFrom = null;
413-
this.createdFilterTo = null;
414-
415-
this.tagFilterOperation = 'AND';
416-
this.tagFilterValues = [];
417-
this.moreTags = false;
418-
419-
if (fetch) {
420-
this.fetchAllLogs();
421-
}
422-
}
423-
424437
/**
425438
* Toggles the visibility of the menu within the log amounts dropdown
426439
* @return {Boolean} The new state of the amounts dropdown
@@ -439,11 +452,10 @@ export default class Overview extends Observable {
439452
if (this.logsPerPage !== amount) {
440453
this.logsPerPage = amount;
441454
this.selectedPage = 1;
442-
this.fetchAllLogs((this.selectedPage - 1) * amount);
455+
this.fetchAllLogs();
443456
}
444457

445458
this.amountDropdownVisible = false;
446-
this.notify();
447459
}
448460

449461
/**
@@ -454,8 +466,7 @@ export default class Overview extends Observable {
454466
setSelectedPage(page) {
455467
if (this.selectedPage !== page) {
456468
this.selectedPage = page;
457-
this.fetchAllLogs((this.selectedPage - 1) * this.logsPerPage);
458-
this.notify();
469+
this.fetchAllLogs();
459470
}
460471
}
461472

@@ -465,13 +476,8 @@ export default class Overview extends Observable {
465476
*/
466477
clearLogs() {
467478
this.logs = RemoteData.NotAsked();
479+
this.collapsableColumns = [];
468480
this.collapsedColumns = [];
469-
this.expandedFilters = [];
470-
471-
this.amountDropdownVisible = false;
472-
this.logsPerPage = 10;
473-
this.selectedPage = 1;
474-
this.totalPages = 1;
475481
}
476482

477483
/**
@@ -484,19 +490,16 @@ export default class Overview extends Observable {
484490
}
485491

486492
/**
487-
* Clear the model variables to prevent memory leaks
493+
* Clear all editors in the model
488494
* @returns {undefined}
489495
*/
490-
flushModel() {
491-
this.rootLogId = -1;
492-
this.parentLogId = -1;
496+
clearAllEditors() {
493497
this.isPreviewActive = false;
498+
this.parentLogId = -1;
494499
this.text = '';
495500
this.title = '';
496501
this.editor = null;
497502
this.editors = [];
498-
this.collapsedColumns = [];
499-
this.isCollapsed = false;
500503

501504
// Remove trailing CodeMirror div(s)
502505
removeElement('.CodeMirror');

test/public/logs/overview.test.js

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ module.exports = () => {
222222
await page.waitFor(100);
223223
});
224224

225-
it('can filter by logs dynamically with special operators', async () => {
225+
it('can filter by tags', async () => {
226226
// Open the tag filters
227227
await page.click('#tagsFilterToggle');
228228
await page.waitFor(100);
@@ -278,6 +278,10 @@ module.exports = () => {
278278
const TAGS_LIMIT = 5;
279279
const buttonId = '#toggleMoreTags';
280280

281+
// Open the tag filters again
282+
await page.click('#tagsFilterToggle');
283+
await page.waitFor(100);
284+
281285
// Expect the page to have a button allowing for showing more tags
282286
const toggleFiltersButton = await page.$(buttonId);
283287
let buttonText = await page.evaluate((element) => element.innerText, toggleFiltersButton);
@@ -411,6 +415,12 @@ module.exports = () => {
411415
await page.waitFor(100);
412416
const pageOneButton = await page.$('#page1');
413417
expect(Boolean(pageOneButton)).to.be.false;
418+
419+
// Revert changes for next test
420+
await page.evaluate(() => {
421+
// eslint-disable-next-line no-undef
422+
model.logs.setLogsPerPage(10);
423+
});
414424
});
415425

416426
it('can create a log from the overview page', async () => {
@@ -447,7 +457,7 @@ module.exports = () => {
447457
// Return the page to home
448458
const buttonHame = await page.$('#home');
449459
await buttonHame.evaluate((button) => button.click());
450-
await page.waitFor(150);
460+
await page.waitFor(250);
451461

452462
// Ensure you are at the overview page again
453463
const doesTableExist = await page.$$('tr') ? true : false;
@@ -509,9 +519,45 @@ module.exports = () => {
509519
// We expect the entry page to have the same id as the id from the log overview
510520
const row = await page.$(`tr#${firstRowId}`);
511521
await row.evaluate((row) => row.click());
512-
await page.waitFor(200);
522+
await page.waitFor(500);
513523

514524
const redirectedUrl = await page.url();
515525
expect(redirectedUrl).to.equal(`${url}/?page=entry&id=${parsedFirstRowId}`);
516526
});
527+
528+
it('does not reset pagination filters when navigating away', async () => {
529+
// Go back to the home page
530+
await page.click('#home');
531+
await page.waitFor(100);
532+
533+
// Override the amount of logs visible per page manually
534+
await page.evaluate(() => {
535+
// eslint-disable-next-line no-undef
536+
model.logs.setLogsPerPage(1);
537+
});
538+
await page.waitFor(100);
539+
540+
// Go to the second page of "logs"
541+
const secondPageButton = await page.$('#page2');
542+
await secondPageButton.evaluate((button) => button.click());
543+
await page.waitFor(100);
544+
545+
// Navigate to a log detail page
546+
table = await page.$$('tr');
547+
firstRowId = await getFirstRow(table, page);
548+
const row = await page.$(`tr#${firstRowId}`);
549+
await row.evaluate((row) => row.click());
550+
await page.waitFor(500);
551+
552+
// Go back to the home page again
553+
await page.goBack();
554+
await page.waitFor(100);
555+
556+
// Expect the pagination to still be on page two
557+
const firstPageButton = await page.$('#page1');
558+
const firstPageButtonClass = await page.evaluate((element) => element.className, firstPageButton);
559+
const secondPageButtonClass = await page.evaluate((element) => element.className, secondPageButton);
560+
expect(firstPageButtonClass).to.not.include('selected');
561+
expect(secondPageButtonClass).to.include('selected');
562+
});
517563
};

0 commit comments

Comments
 (0)