Skip to content
19 changes: 19 additions & 0 deletions InfoLogger/public/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,22 @@ a.disabled { pointer-events: none; cursor: default; }
flex-direction: column;
gap: 0.25rem;
}

.status-number {
font-variant-numeric: tabular-nums;
}

/* match the 1.5em text line height so the status bar does not change height when the button appears in a running live mode */
#status-bar-auto-scroll {
padding-block: 0;
line-height: 1.5;
margin-left: 0; /* .btn-sm adds its own margin; spacing comes from the parent's gap */
}

#status-bar-application-options {
justify-content: flex-end;
}

#status-bar-buffer-dot {
margin-right: var(--space-xs);
}
1 change: 1 addition & 0 deletions InfoLogger/public/log/Log.js
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ export default class Log extends Observable {
this.limitReached = null;
this.resetStats();
this.queryResult = RemoteData.notAsked(); // empty all data from last query
this.statusDropdown = false;
this.activeMode = MODE.LIVE.RUNNING;
this.liveStartedAt = new Date();

Expand Down
63 changes: 43 additions & 20 deletions InfoLogger/public/log/statusBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,17 @@ 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 label/button.
* some application messages and some basic options like auto-scroll button.
* @param {Model} model - root model of the application
* @returns {vnode} - the view of the bottom bar
*/
export default (model) => [
h('.flex-row', { id: 'status-bar' }, [
h('', { style: 'width:50%' }, statusLogs(model)),
h('', { style: 'text-align: center; width:30%' }, sqlQuery(model)),
h('.flex-row.items-center.ph2.mv2.gc3', { id: 'status-bar' }, [
h('.flex-grow.flex-wrap.items-center.gc2', [statusLogs(model), applicationMessage(model)]),
model.log.isActiveModeQuery() && h('', { style: 'text-align: center; width:30%' }, sqlQuery(model)),
h(
'.flex-grow.text-right',
{ id: 'status-bar-application-options' },
applicationMessage(model),
'.flex-row.items-center.gc3',
{ id: 'status-bar-application-options', style: 'width:20%' },
applicationOptions(model),
),
]),
Expand Down Expand Up @@ -85,7 +84,7 @@ const applicationMessage = (model) => model.log.list.length > model.log.applicat
? h(
'span.danger',
{ id: 'status-bar-application-message' },
`Application reached more than ${model.log.applicationLimit} logs, please clear if possible `,
`Application reached more than ${model.log.applicationLimit} logs, please clear if possible`,
)
: null;

Expand Down Expand Up @@ -115,13 +114,12 @@ const applicationOptions = (model) => {
h('span.d-inline', autoScrollEnabled ? 'Autoscroll Enabled' : 'Autoscroll Disabled'),
],
),
h('span.mh1'),
],
h('label.d-inline', { title: 'Show details of selected log' }, h('input', {
h('label.flex-row.items-center.g1.m0', { title: 'Show details of selected log' }, h('input', {
type: 'checkbox',
checked: model.inspectorEnabled,
onchange: () => model.toggleInspector(),
}), ' Inspector'),
}), 'Inspector'),
];
};

Expand All @@ -140,7 +138,11 @@ const statusQuery = (model, result) => `in ${(result.time / 1000).toFixed(2)}s`;
* @returns {vnode} - the view of the live status
*/
const statusLive = (model, frameworkInfo) =>
[`(Connected to ${frameworkInfo.mysql.host} for ${model.timezone.formatDuration(model.log.liveStartedAt)})`];
h('span', [
`(Connected to ${frameworkInfo.mysql.host} for `,
h('span.status-number', model.timezone.formatDuration(model.log.liveStartedAt)),
')',
]);

/**
* Status of the log's list (independent of mode): how many global and how many per severity
Expand All @@ -149,13 +151,16 @@ const statusLive = (model, frameworkInfo) =>
*/
const statusStats = (model) => [
h(
'span.ph1',
'span',
{
id: 'status-bar-buffer-size',
},
[
bufferStatus(model),
`${model.log.list.length.toLocaleString('en-US')} / ${model.log.limit.toLocaleString('en-US')} (Buffer size)`,
statNumber(model.log.list.length),
' / ',
statNumber(model.log.limit),
' (Buffer size)',
],
),
model.log.queryResult.match({
Expand All @@ -164,13 +169,31 @@ const statusStats = (model) => [
Success: (result) => statusQuery(model, result),
Failure: () => null, // notification
}),
h('span.ph1.severity-d', `${model.log.stats.debug} debug`),
h('span.ph1.severity-i', `${model.log.stats.info} info`),
h('span.ph1.severity-w', `${model.log.stats.warning} warn`),
h('span.ph1.severity-e', `${model.log.stats.error} error`),
h('span.ph1.severity-f', `${model.log.stats.fatal} fatal`),
statLabel(model.log.stats.debug, 'debug'),
statLabel(model.log.stats.info, 'info'),
statLabel(model.log.stats.warning, 'warn'),
statLabel(model.log.stats.error, 'error'),
statLabel(model.log.stats.fatal, 'fatal'),
];

/**
* Number to display in the status bar in a locale aware format
* Digits use tabular figures so a count changing without gaining a digit does not shift the status bar
* @param {number} value - number to display
* @returns {vnode} - view of the number
*/
const statNumber = (value) =>
h('span.status-number', value.toLocaleString('en-US'));

/**
* Label for a specific severity level in the status bar
* @param {number} value - number of logs for this severity
* @param {string} severity - name of the severity level
* @returns {vnode} - view of the severity label
*/
const statLabel = (value, severity) =>
h(`span.severity-${severity.charAt(0)}`, [statNumber(value), ` ${severity}`]);

const bufferStatus = (model) => {
let dotClass = 'gray-darker'; // grey - unknown status default

Expand All @@ -180,7 +203,7 @@ const bufferStatus = (model) => {
dotClass = 'success'; // green - limit not reached
}

return h(`span.${dotClass}.f7.mh1`, {
return h(`span.${dotClass}.f7`, {
title: model.log.limitReached === null ? 'No query data loaded' :
model.log.limitReached === true ? 'Limit reached - results may be incomplete' : 'Limit OK',
id: 'status-bar-buffer-dot',
Expand Down
2 changes: 1 addition & 1 deletion InfoLogger/public/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default (model) => [
logsTable(model),
inspectorSide(model),
]),
h('footer.f7.ph1', [statusBar(model)]),
h('footer.f7', [statusBar(model)]),
],
),
];
Expand Down
4 changes: 2 additions & 2 deletions InfoLogger/test/public/status-bar-mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ async function getSeverityCounts(page) {
const counts = {};
const severityLabels = ['d', 'i', 'w', 'e', 'f'];
severityLabels.forEach((label) => {
const el = document.querySelector(`span.ph1.severity-${label}`);
const count = Number(el.textContent.trim().split(' ')[0]);
const el = document.querySelector(`span.severity-${label} .status-number`);
const count = Number(el.textContent.replace(/,/g, ''));
counts[label.toUpperCase()] = count;
});
return counts;
Expand Down
Loading