Skip to content

Commit

Permalink
Split logging (#1334)
Browse files Browse the repository at this point in the history
* Chore: Renamed Logging to Historing

* Fixed tests

* Fixed german translation

* Update packages/open-scd/src/Historing.ts

Co-authored-by: Juan Munoz <juan.munoz@alliander.com>

---------

Co-authored-by: Juan Munoz <juan.munoz@alliander.com>
  • Loading branch information
pascalwilbrink and juancho0202 authored Oct 31, 2023
1 parent 74fa468 commit 370f47a
Show file tree
Hide file tree
Showing 24 changed files with 372 additions and 140 deletions.
198 changes: 140 additions & 58 deletions packages/open-scd/src/Logging.ts → packages/open-scd/src/Historing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ import { Snackbar } from '@material/mwc-snackbar';

import './filtered-list.js';
import {
CommitDetail,
CommitEntry,
ifImplemented,
InfoDetail,
InfoEntry,
invert,
IssueDetail,
IssueEvent,
Expand All @@ -40,7 +43,6 @@ const icons = {
info: 'info',
warning: 'warning',
error: 'report',
action: 'history',
};

function getPluginName(src: string): string {
Expand All @@ -66,13 +68,18 @@ function getPluginName(src: string): string {
* Renders the `history` to `logUI` and the latest `'error'` [[`LogEntry`]] to
* `messageUI`.
*/
export type LoggingElement = Mixin<typeof Logging>;
export type HistoringElement = Mixin<typeof Historing>;

export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
class LoggingElement extends Base {
export function Historing<TBase extends LitElementConstructor>(Base: TBase) {
class HistoringElement extends Base {
/** All [[`LogEntry`]]s received so far through [[`LogEvent`]]s. */
@property({ type: Array })
history: LogEntry[] = [];
log: InfoEntry[] = [];

/** All [[`CommitEntry`]]s received so far through [[`LogEvent`]]s */
@property({ type: Array })
history: CommitEntry[] = [];

/** Index of the last [[`EditorAction`]] applied. */
@property({ type: Number })
editCount = -1;
Expand All @@ -82,6 +89,7 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
latestIssue!: IssueDetail;

@query('#log') logUI!: Dialog;
@query('#history') historyUI!: Dialog;
@query('#diagnostic') diagnosticUI!: Dialog;
@query('#error') errorUI!: Snackbar;
@query('#warning') warningUI!: Snackbar;
Expand Down Expand Up @@ -140,16 +148,10 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
return true;
}

private onLog(le: LogEvent): void {
if (le.detail.kind === 'reset') {
this.history = [];
this.editCount = -1;
return;
}

const entry: LogEntry = {
private onHistory(detail: CommitDetail) {
const entry: CommitEntry = {
time: new Date(),
...le.detail,
...detail,
};

if (entry.kind === 'action') {
Expand All @@ -160,22 +162,51 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
}

this.history.push(entry);
this.requestUpdate('history', []);
}

private onReset() {
this.log = [];
this.history = [];
this.editCount = -1;
}

private onInfo(detail: InfoDetail) {
const entry: InfoEntry = {
time: new Date(),
...detail,
};

this.log.push(entry);
if (!this.logUI.open) {
const ui = {
error: this.errorUI,
warning: this.warningUI,
info: this.infoUI,
action: this.infoUI,
}[le.detail.kind];
}[detail.kind];

ui.close();
ui.show();
}
if (le.detail.kind == 'error') {
if (detail.kind == 'error') {
this.errorUI.close(); // hack to reset timeout
this.errorUI.show();
}
this.requestUpdate('history', []);
this.requestUpdate('log', []);
}

private onLog(le: LogEvent): void {
switch (le.detail.kind) {
case 'reset':
this.onReset();
break;
case 'action':
this.onHistory(le.detail);
break;
default:
this.onInfo(le.detail);
break;
}
}

async performUpdate() {
Expand All @@ -197,7 +228,36 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
}

renderLogEntry(
entry: LogEntry,
entry: InfoEntry,
index: number,
log: LogEntry[]
): TemplateResult {
return html` <abbr title="${entry.title}">
<mwc-list-item
class="${entry.kind}"
graphic="icon"
?twoline=${!!entry.message}
?activated=${this.editCount == log.length - index - 1}
>
<span>
<!-- FIXME: replace tt with mwc-chip asap -->
<tt>${entry.time?.toLocaleString()}</tt>
${entry.title}</span
>
<span slot="secondary">${entry.message}</span>
<mwc-icon
slot="graphic"
style="--mdc-theme-text-icon-on-background:var(${ifDefined(
iconColors[entry.kind]
)})"
>${icons[entry.kind]}</mwc-icon
>
</mwc-list-item></abbr
>`;
}

renderHistoryEntry(
entry: CommitEntry,
index: number,
history: LogEntry[]
): TemplateResult {
Expand All @@ -219,18 +279,31 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
style="--mdc-theme-text-icon-on-background:var(${ifDefined(
iconColors[entry.kind]
)})"
>${icons[entry.kind]}</mwc-icon
>history</mwc-icon
>
</mwc-list-item></abbr
>`;
}

private renderLog(): TemplateResult[] | TemplateResult {
if (this.log.length > 0)
return this.log.slice().reverse().map(this.renderLogEntry, this);
else
return html`<mwc-list-item disabled graphic="icon">
<span>${translate('log.placeholder')}</span>
<mwc-icon slot="graphic">info</mwc-icon>
</mwc-list-item>`;
}

private renderHistory(): TemplateResult[] | TemplateResult {
if (this.history.length > 0)
return this.history.slice().reverse().map(this.renderLogEntry, this);
return this.history
.slice()
.reverse()
.map(this.renderHistoryEntry, this);
else
return html`<mwc-list-item disabled graphic="icon">
<span>${translate('log.placeholder')}</span>
<span>${translate('history.placeholder')}</span>
<mwc-icon slot="graphic">info</mwc-icon>
</mwc-list-item>`;
}
Expand Down Expand Up @@ -281,6 +354,42 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
);
}

private renderLogDialog(): TemplateResult {
return html` <mwc-dialog id="log" heading="${translate('log.name')}">
${this.renderFilterButtons()}
<mwc-list id="content" wrapFocus>${this.renderLog()}</mwc-list>
<mwc-button slot="primaryAction" dialogaction="close"
>${translate('close')}</mwc-button
>
</mwc-dialog>`;
}

private renderHistoryDialog(): TemplateResult {
return html` <mwc-dialog
id="history"
heading="${translate('history.name')}"
>
<mwc-list id="content" wrapFocus>${this.renderHistory()}</mwc-list>
<mwc-button
icon="undo"
label="${translate('undo')}"
?disabled=${!this.canUndo}
@click=${this.undo}
slot="secondaryAction"
></mwc-button>
<mwc-button
icon="redo"
label="${translate('redo')}"
?disabled=${!this.canRedo}
@click=${this.redo}
slot="secondaryAction"
></mwc-button>
<mwc-button slot="primaryAction" dialogaction="close"
>${translate('close')}</mwc-button
>
</mwc-dialog>`;
}

render(): TemplateResult {
return html`${ifImplemented(super.render())}
<style>
Expand All @@ -298,13 +407,9 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
#log > mwc-icon-button-toggle:nth-child(4) {
right: 158px;
}
#log > mwc-icon-button-toggle:nth-child(5) {
right: 206px;
}
#content mwc-list-item.info,
#content mwc-list-item.warning,
#content mwc-list-item.error,
#content mwc-list-item.action {
#content mwc-list-item.error {
display: none;
}
#infofilter[on] ~ #content mwc-list-item.info {
Expand All @@ -316,9 +421,6 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
#errorfilter[on] ~ #content mwc-list-item.error {
display: flex;
}
#actionfilter[on] ~ #content mwc-list-item.action {
display: flex;
}
#infofilter[on] {
color: var(--cyan);
Expand All @@ -336,7 +438,8 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
color: var(--blue);
}
#log {
#log,
#history {
--mdc-dialog-min-width: 92vw;
}
Expand All @@ -346,28 +449,7 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
right: 14px;
}
</style>
<mwc-dialog id="log" heading="${translate('log.name')}">
${this.renderFilterButtons()}
<mwc-list id="content" wrapFocus>${this.renderHistory()}</mwc-list>
<mwc-button
icon="undo"
label="${translate('undo')}"
?disabled=${!this.canUndo}
@click=${this.undo}
slot="secondaryAction"
></mwc-button>
<mwc-button
icon="redo"
label="${translate('redo')}"
?disabled=${!this.canRedo}
@click=${this.redo}
slot="secondaryAction"
></mwc-button>
<mwc-button slot="primaryAction" dialogaction="close"
>${translate('close')}</mwc-button
>
</mwc-dialog>
${this.renderLogDialog()} ${this.renderHistoryDialog()}
<mwc-dialog id="diagnostic" heading="${translate('diag.name')}">
<filtered-list id="content" wrapFocus
>${this.renderIssues()}</filtered-list
Expand All @@ -380,18 +462,18 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
<mwc-snackbar
id="info"
timeoutMs="4000"
labelText="${this.history
labelText="${this.log
.slice()
.reverse()
.find(le => le.kind === 'info' || le.kind === 'action')?.title ??
.find(le => le.kind === 'info')?.title ??
get('log.snackbar.placeholder')}"
>
<mwc-icon-button icon="close" slot="dismiss"></mwc-icon-button>
</mwc-snackbar>
<mwc-snackbar
id="warning"
timeoutMs="6000"
labelText="${this.history
labelText="${this.log
.slice()
.reverse()
.find(le => le.kind === 'warning')?.title ??
Expand All @@ -408,7 +490,7 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
<mwc-snackbar
id="error"
timeoutMs="10000"
labelText="${this.history
labelText="${this.log
.slice()
.reverse()
.find(le => le.kind === 'error')?.title ??
Expand Down Expand Up @@ -439,5 +521,5 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
}
}

return LoggingElement;
return HistoringElement;
}
15 changes: 11 additions & 4 deletions packages/open-scd/src/Hosting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { ActionDetail, List } from '@material/mwc-list';
import { ListItem } from '@material/mwc-list/mwc-list-item';

import { Mixin, newPendingStateEvent } from './foundation.js';
import { LoggingElement } from './Logging.js';
import { HistoringElement } from './Historing.js';
import { Plugin, PluggingElement, pluginIcons } from './Plugging.js';
import { SettingElement } from './Setting.js';

Expand All @@ -39,12 +39,12 @@ interface MenuPlugin {
run: () => Promise<void>;
}

/** Mixin that hosts the UI for Plugins, Settings and Logging */
/** Mixin that hosts the UI for Plugins, Settings and Historing */
export type HostingElement = Mixin<typeof Hosting>;

export function Hosting<
TBase extends new (...args: any[]) => PluggingElement &
LoggingElement &
HistoringElement &
SettingElement
>(Base: TBase) {
class HostingElement extends Base {
Expand Down Expand Up @@ -176,12 +176,19 @@ export function Hosting<
},
...validators,
{
icon: 'history',
icon: 'list',
name: 'menu.viewLog',
actionItem: true,
action: (): void => this.logUI.show(),
kind: 'static',
},
{
icon: 'history',
name: 'menu.viewHistory',
actionItem: true,
action: (): void => this.historyUI.show(),
kind: 'static',
},
{
icon: 'rule',
name: 'menu.viewDiag',
Expand Down
Loading

0 comments on commit 370f47a

Please sign in to comment.