diff --git a/src/components/cc-logs-addon-runtime/cc-logs-addon-runtime.smart.js b/src/components/cc-logs-addon-runtime/cc-logs-addon-runtime.smart.js index 52ee9020a..d0546cf8a 100644 --- a/src/components/cc-logs-addon-runtime/cc-logs-addon-runtime.smart.js +++ b/src/components/cc-logs-addon-runtime/cc-logs-addon-runtime.smart.js @@ -47,6 +47,10 @@ defineSmartComponent({ controller.setNewDateRange(range); }); + onEvent('cc-logs-clear', () => { + controller.clearVisibleLogs(); + }); + onEvent('cc-logs-loading-pause', () => { controller.pause(); }); @@ -159,6 +163,11 @@ class SmartController extends LogsStream { this._component.appendLogs(logs); } + clearVisibleLogs() { + this.resetVisible(); + this._component.clear(); + } + init() { this.openLogsStream(this._dateRange); } diff --git a/src/components/cc-logs-app-access/cc-logs-app-access.smart.js b/src/components/cc-logs-app-access/cc-logs-app-access.smart.js index d1b9a6e54..68ed4e69a 100644 --- a/src/components/cc-logs-app-access/cc-logs-app-access.smart.js +++ b/src/components/cc-logs-app-access/cc-logs-app-access.smart.js @@ -47,6 +47,10 @@ defineSmartComponent({ controller.setNewDateRange(range); }); + onEvent('cc-logs-clear', () => { + controller.clearVisibleLogs(); + }); + onEvent('cc-logs-loading-pause', () => { controller.pause(); }); @@ -149,6 +153,11 @@ class SmartController extends LogsStream { this._component.appendLogs(logs); } + clearVisibleLogs() { + this.resetVisible(); + this._component.clear(); + } + /** * @param {DateRange} dateRange */ diff --git a/src/components/cc-logs-app-runtime/cc-logs-app-runtime.smart.js b/src/components/cc-logs-app-runtime/cc-logs-app-runtime.smart.js index 23761b090..df54880d6 100644 --- a/src/components/cc-logs-app-runtime/cc-logs-app-runtime.smart.js +++ b/src/components/cc-logs-app-runtime/cc-logs-app-runtime.smart.js @@ -62,6 +62,10 @@ defineSmartComponent({ controller.setNewInstanceSelection(instances); }); + onEvent('cc-logs-clear', () => { + controller.clearVisibleLogs(); + }); + onEvent('cc-logs-loading-pause', () => { controller.pause(); }); @@ -218,6 +222,11 @@ class SmartController extends LogsStream { this._updateState({ type: 'loadingInstances' }); } + clearVisibleLogs() { + this.resetVisible(); + this._component.clear(); + } + /** * @param {DateRange} dateRange * @param {Array} selection diff --git a/src/components/cc-logs-control/cc-logs-control.events.js b/src/components/cc-logs-control/cc-logs-control.events.js index 36719c023..0e20aae8c 100644 --- a/src/components/cc-logs-control/cc-logs-control.events.js +++ b/src/components/cc-logs-control/cc-logs-control.events.js @@ -18,3 +18,15 @@ export class CcLogsOptionsChangeEvent extends CcEvent { super(CcLogsOptionsChangeEvent.TYPE, detail); } } + +/** + * Dispatched when clearing of the logs is requested. + * @extends {CcEvent} + */ +export class CcLogsClearEvent extends CcEvent { + static TYPE = 'cc-logs-clear'; + + constructor() { + super(CcLogsClearEvent.TYPE); + } +} diff --git a/src/components/cc-logs-control/cc-logs-control.js b/src/components/cc-logs-control/cc-logs-control.js index 954579a07..d741a6706 100644 --- a/src/components/cc-logs-control/cc-logs-control.js +++ b/src/components/cc-logs-control/cc-logs-control.js @@ -1,6 +1,7 @@ import { css, html, LitElement } from 'lit'; import { createRef, ref } from 'lit/directives/ref.js'; import { + iconRemixEraserLine as clearIcon, iconRemixCalendarScheduleLine as dateIcon, iconRemixPaletteLine as displayIcon, iconRemixPantoneLine as metadataIcon, @@ -22,7 +23,7 @@ import { DATE_DISPLAYS, TIMEZONES } from '../cc-logs/date-displayer.js'; import '../cc-popover/cc-popover.js'; import '../cc-select/cc-select.js'; import '../cc-toggle/cc-toggle.js'; -import { CcLogsOptionsChangeEvent } from './cc-logs-control.events.js'; +import { CcLogsClearEvent, CcLogsOptionsChangeEvent } from './cc-logs-control.events.js'; /** * @type {{[key in LogsControlPalette]: string}} @@ -248,6 +249,10 @@ export class CcLogsControl extends LitElement { this._logsRef.value?.scrollToBottom(); } + _onClearButtonClick() { + this.dispatchEvent(new CcLogsClearEvent()); + } + /** * @param {CcSelectEvent} event */ @@ -328,6 +333,13 @@ export class CcLogsControl extends LitElement { @cc-click=${this._onScrollToBottomButtonClick} > + + = this._overflowWatermark) { + if (!this._overflowWasNotified && this.isOverflowing()) { this._overflowWasNotified = true; return true; } @@ -85,7 +91,7 @@ export class LogsProgress { } isOverflowing() { - return this._value >= this._overflowWatermark; + return this._visibleValue >= this._overflowWatermark; } getLastLogDate() { diff --git a/src/lib/logs/logs-stream.js b/src/lib/logs/logs-stream.js index ae2d9d8a7..c3a938f8f 100644 --- a/src/lib/logs/logs-stream.js +++ b/src/lib/logs/logs-stream.js @@ -180,6 +180,10 @@ export class LogsStream { }); } + resetVisible() { + this.#progress.resetVisible(); + } + /** * @return {Date|null} The date of the last received log. Or `null` if no logs have been received. */ diff --git a/src/translations/translations.en.js b/src/translations/translations.en.js index 3d8dfff17..ea72c6239 100644 --- a/src/translations/translations.en.js +++ b/src/translations/translations.en.js @@ -1276,6 +1276,7 @@ export const translations = { 'cc-logs-app-runtime.options.display-instance': `Display instance name`, //#endregion //#region cc-logs-control + 'cc-logs-control.clear': `Clear logs`, 'cc-logs-control.date-display': `Date format`, 'cc-logs-control.date-display.datetime-iso': `Date and hour ISO`, 'cc-logs-control.date-display.datetime-short': `Date and hour`, diff --git a/src/translations/translations.fr.js b/src/translations/translations.fr.js index c126ee1e2..58b3ff63f 100644 --- a/src/translations/translations.fr.js +++ b/src/translations/translations.fr.js @@ -1287,6 +1287,7 @@ export const translations = { 'cc-logs-app-runtime.options.display-instance': `Afficher le nom de l'instance`, //#endregion //#region cc-logs-control + 'cc-logs-control.clear': `Effacer les logs`, 'cc-logs-control.date-display': `Format de date`, 'cc-logs-control.date-display.datetime-iso': `Date et heure ISO`, 'cc-logs-control.date-display.datetime-short': `Date et heure`, diff --git a/test/logs/logs-progress.test.js b/test/logs/logs-progress.test.js index 1991ec9ad..4077a316c 100644 --- a/test/logs/logs-progress.test.js +++ b/test/logs/logs-progress.test.js @@ -43,6 +43,17 @@ describe('logs-progress', () => { expect(logsProgress.isOverflowing()).to.eq(false); }); + it('should return false when progress lower than the overflowWatermark after reset visible', () => { + const logsProgress = new LogsProgress(10); + logsProgress.start({ since: new Date().toISOString() }); + logsProgress.progress(generateLogs(15)); + logsProgress.resetVisible(); + + logsProgress.progress(generateLogs(9)); + + expect(logsProgress.isOverflowing()).to.eq(false); + }); + it('should return true when progress equals the overflowWatermark', () => { const logsProgress = new LogsProgress(10); logsProgress.start({ since: new Date().toISOString() }); @@ -103,6 +114,17 @@ describe('logs-progress', () => { expect(watermarkReached).to.eq(false); }); + it('should return false when watermark not reached after reset visible', () => { + const logsProgress = new LogsProgress(10); + logsProgress.start({ since: new Date().toISOString() }); + logsProgress.progress(generateLogs(9)); + logsProgress.resetVisible(); + + const watermarkReached = logsProgress.progress(generateLogs(5)); + + expect(watermarkReached).to.eq(false); + }); + it('should return true when watermark is reached', () => { const logsProgress = new LogsProgress(10); logsProgress.start({ since: new Date().toISOString() }); diff --git a/test/logs/logs-stream.test.js b/test/logs/logs-stream.test.js index 31ac3f555..1e1436b24 100644 --- a/test/logs/logs-stream.test.js +++ b/test/logs/logs-stream.test.js @@ -327,22 +327,6 @@ describe('logs-stream', () => { overflowing: false, }); }); - - it('should set completed state', async () => { - const logsStream = new FakeLogsStream(); - logsStream.openLogsStream({ since: new Date().toISOString(), until: new Date().toISOString() }); - await fakeLogsReceived(logsStream); - logsStream.resetSpies(); - - await logsStream.sseFakeApi.end(); - - expect(logsStream.spies.updateStreamState.callCount).to.eql(1); - expect(logsStream.spies.updateStreamState.firstCall.args[0]).to.eql({ - type: 'completed', - progress: { value: 1, percent: 100 }, - overflowing: false, - }); - }); }); describe('pause() method', () => {