Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions InfoLogger/public/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,10 @@ a.disabled { pointer-events: none; cursor: default; }
flex-direction: column;
gap: 0.25rem;
}

#status-bar-auto-scroll {
display: inline-block;
padding: .25em .7em;
line-height: 1;
margin: 0;
}
7 changes: 3 additions & 4 deletions InfoLogger/public/log/Log.js
Original file line number Diff line number Diff line change
Expand Up @@ -575,11 +575,10 @@ export default class Log extends Observable {
}

/**
* Enable or disable auto-scroll for live mode, a checkbox is used to control it
* Enable auto-scroll for live mode and scroll to the bottom of the table
*/
toggleAutoScroll() {
this.autoScrollLive = !this.autoScrollLive;
this.dom.table.focus();
enableAutoScrollLiveAndNotify() {
this.autoScrollLive = true;
this.notify();
}

Expand Down
26 changes: 19 additions & 7 deletions InfoLogger/public/log/statusBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
* or submit itself to any jurisdiction.
*/

import { h } from '/js/src/index.js';
import {
h,
iconWarning,
} from '/js/src/index.js';

/**
* Bottom bar, showing status of the log's list and its details,
* some application messages and some basic options like auto-scroll checkbox.
* some application messages and some basic options like auto-scroll label/button.
* @param {Model} model - root model of the application
* @returns {vnode} - the view of the bottom bar
*/
Expand Down Expand Up @@ -97,11 +100,20 @@ const applicationMessage = (model) => model.log.list.length > model.log.applicat
*/
const applicationOptions = (model) => [
model.log.isLiveModeRunning() && [
h('label.d-inline', { title: 'Scroll down in live mode on new log incoming' }, h('input', {
type: 'checkbox',
checked: model.log.autoScrollLive,
onchange: () => model.log.toggleAutoScroll(),
}), ' Autoscroll'),
model.log.autoScrollLive
? h('span.success', { id: 'status-bar-auto-scroll', title: 'Autoscroll is enabled' }, 'Autoscroll Enabled')
: h(
'button.btn.btn-sm.btn-warning',
{
id: 'status-bar-auto-scroll',
title: 'Click here to re-enable autoscroll',
onclick: () => model.log.enableAutoScrollLiveAndNotify(),
},
[
iconWarning(),
h('span.d-inline', 'Autoscroll Disabled'),
],
),
h('span.mh1'),
],
h('label.d-inline', { title: 'Show details of selected log' }, h('input', {
Expand Down
3 changes: 3 additions & 0 deletions InfoLogger/public/log/tableLogsContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ const autoscrollManager = (model, vnode) => {
return;
}

// forget the last scrolled log so re-enabling autoscroll jumps to bottom straight away on a redraw
delete vnode.dom.dataset.lastLogId;

// Autoscroll to selected item
if (model.log.item) {
// Scroll only if we did not previously, save last try in DOM dataset
Expand Down
29 changes: 20 additions & 9 deletions InfoLogger/test/public/status-bar-mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ async function getSeverityCounts(page) {
}

describe('Status Bar test-suite', async () => {
const AUTOSCROLL_SELECTOR = '#status-bar-application-options label[title*="Scroll down"] input';
const AUTOSCROLL_SELECTOR = '#status-bar-auto-scroll';
const INSPECTOR_SELECTOR = '#status-bar-application-options label[title*="Show details"] input';
const SQL_QUERY = 'SELECT * FROM `messages` WHERE `timestamp`>=? AND `severity` IN (?) '
+ 'ORDER BY `TIMESTAMP` LIMIT 100000';
Expand Down Expand Up @@ -357,16 +357,27 @@ describe('Status Bar test-suite', async () => {
await page.waitForSelector(AUTOSCROLL_SELECTOR, { timeout: 2000 });
});

it('should toggle autoscroll when its checkbox is clicked', async () => {
await page.waitForSelector(AUTOSCROLL_SELECTOR, { timeout: 2000 });
const checkedBefore = await page.$eval(AUTOSCROLL_SELECTOR, (el) => el.checked);
await page.click(AUTOSCROLL_SELECTOR);
it('should show correct label when autoscroll is enabled', async () => {
await waitForTextInElement(page, AUTOSCROLL_SELECTOR, 'Autoscroll Enabled');
});

const checkedAfter = await page.$eval(AUTOSCROLL_SELECTOR, (el) => el.checked);
const autoScrollModelValue = await page.evaluate(() => model.log.autoScrollLive);
it('should show correct button when autoscroll is disabled', async () => {
await page.evaluate(() => {
model.log.autoScrollLive = false;
});
await waitForTextInElement(page, AUTOSCROLL_SELECTOR, 'Autoscroll Disabled');
});

it('should re-enable autoscroll when disabled autoscroll button is clicked', async () => {
await page.evaluate(() => {
model.log.autoScrollLive = false;
});
await waitForTextInElement(page, AUTOSCROLL_SELECTOR, 'Autoscroll Disabled');

await page.click(AUTOSCROLL_SELECTOR);

assert.strictEqual(checkedAfter, !checkedBefore);
assert.strictEqual(autoScrollModelValue, checkedAfter);
await waitForTextInElement(page, AUTOSCROLL_SELECTOR, 'Autoscroll Enabled');
assert.strictEqual(await page.evaluate(() => model.log.autoScrollLive), true);
});
});
});
Expand Down
Loading