Skip to content

Commit

Permalink
feat(wizards/services): add read-only wizard on access point and ied (o…
Browse files Browse the repository at this point in the history
…penscd#1109)

* Services wizard (WIP)

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

* Refactoring of services to prevent merge (big) conflicts

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

* Fixed snapshot test
Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

* Only add the Services icon if there actually is a Services element within the IED.

The
Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

* Wizardpages are optional in the Services Wizard.
Don't show the wizard pages if no content is available

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

* Map the nullable WizardPage to an actual WizardPage (nulls are already filtered out)
Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

* Added report and GSE configuration pages

* Different querySelector

* Fixed snapshot test

* Added wizard page for Networking related configurations

* Added wizard page for SMV related configurations

* Added wizard page for other Client/Server related configurations

* Read out values for log settingsGroup

* Fixed possible null on wizard select
Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

* Added Tests

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

* Fixed typo (uppercase file fetching in test)

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

* Fixed typo (uppercase file fetching in test)

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

* Fixed review comments

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

* Added Tests for AccessPoint.
Changed the check if a wizard page should be shown to a more `complex` function. Added tests for that function

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

* Added array to isEmptyObject function to provide additional nullable properties

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

* Removed Sitipe stuff

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>

---------

Signed-off-by: Pascal Wilbrink <pascal.wilbrink@alliander.com>
Co-authored-by: Stef3st <steffen.van.den.driest@alliander.com>
Co-authored-by: Jakob Vogelsang <jakob-vogelsang@posteo.de>
  • Loading branch information
3 people authored Feb 23, 2023
1 parent d9680fa commit 81088f0
Show file tree
Hide file tree
Showing 19 changed files with 5,733 additions and 46 deletions.
32 changes: 27 additions & 5 deletions src/WizardDivider.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
import {css, customElement, html, LitElement, TemplateResult} from "lit-element";
import {
css,
customElement,
html,
LitElement,
property,
TemplateResult,
} from 'lit-element';

@customElement('wizard-divider')
export class WizardDividerElement extends LitElement {
@property({
type: String,
})
header?: string;

render(): TemplateResult {
return html `
<div role="separator"></div>
`
return html` ${this.renderHeader()} ${this.renderSeparator()}`;
}

private renderHeader(): TemplateResult {
if (!this.header) {
return html``;
}

return html`<h4 class="header">${this.header}</h4>`;
}

private renderSeparator(): TemplateResult {
return html`<div role="separator"></div>`;
}

static styles = css`
Expand All @@ -18,5 +40,5 @@ export class WizardDividerElement extends LitElement {
border-image: initial;
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
}
`
`;
}
46 changes: 37 additions & 9 deletions src/editors/ied/access-point-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@ import {
TemplateResult,
} from 'lit-element';
import { nothing } from 'lit-html';
import { translate } from 'lit-translate';
import { wizards } from '../../wizards/wizard-library.js';

import { getDescriptionAttribute, getNameAttribute } from '../../foundation.js';
import {
getDescriptionAttribute,
getNameAttribute,
newWizardEvent,
} from '../../foundation.js';
import { accessPointIcon } from '../../icons/ied-icons.js';
import { editServicesWizard } from '../../wizards/services.js';

import '../../action-pane.js';
import './server-container.js';
Expand All @@ -23,13 +30,6 @@ export class AccessPointContainer extends Container {
@property()
selectedLNClasses: string[] = [];

private header(): TemplateResult {
const name = getNameAttribute(this.element);
const desc = getDescriptionAttribute(this.element);

return html`${name}${desc ? html` &mdash; ${desc}` : nothing}`;
}

protected updated(_changedProperties: PropertyValues): void {
super.updated(_changedProperties);

Expand All @@ -39,6 +39,26 @@ export class AccessPointContainer extends Container {
}
}

private renderServicesIcon(): TemplateResult {
const services: Element | null = this.element.querySelector('Services');

if (!services) {
return html``;
}

return html` <abbr slot="action" title="${translate('settings')}">
<mwc-icon-button
icon="settings"
@click=${() => this.openSettingsWizard(services)}
></mwc-icon-button>
</abbr>`;
}

private openSettingsWizard(services: Element): void {
const wizard = editServicesWizard(services);
if (wizard) this.dispatchEvent(newWizardEvent(wizard));
}

@state()
private get lnElements(): Element[] {
return Array.from(this.element.querySelectorAll(':scope > LN')).filter(
Expand All @@ -49,11 +69,19 @@ export class AccessPointContainer extends Container {
);
}

private header(): TemplateResult {
const name = getNameAttribute(this.element);
const desc = getDescriptionAttribute(this.element);

return html`${name}${desc ? html` &mdash; ${desc}` : nothing}`;
}

render(): TemplateResult {
const lnElements = this.lnElements;

return html`<action-pane .label="${this.header()}">
<mwc-icon slot="icon">${accessPointIcon}</mwc-icon>
${this.renderServicesIcon()}
${Array.from(this.element.querySelectorAll(':scope > Server')).map(
server =>
html`<server-container
Expand All @@ -71,7 +99,7 @@ export class AccessPointContainer extends Container {
.element=${ln}
.nsdoc=${this.nsdoc}
.ancestors=${[...this.ancestors, this.element]}
></ln-container> `
></ln-container>`
)}
</div>
</action-pane>`;
Expand Down
22 changes: 22 additions & 0 deletions src/editors/ied/ied-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
newWizardEvent,
} from '../../foundation.js';
import { removeIEDWizard } from '../../wizards/ied.js';
import { editServicesWizard } from '../../wizards/services.js';

/** [[`IED`]] plugin subeditor for editing `IED` element. */
@customElement('ied-container')
Expand All @@ -32,6 +33,26 @@ export class IedContainer extends Container {
if (wizard) this.dispatchEvent(newWizardEvent(wizard));
}

private renderServicesIcon(): TemplateResult {
const services: Element | null = this.element.querySelector('Services');

if (!services) {
return html``;
}

return html` <abbr slot="action" title="${translate('settings')}">
<mwc-icon-button
icon="settings"
@click=${() => this.openSettingsWizard(services)}
></mwc-icon-button>
</abbr>`;
}

private openSettingsWizard(services: Element): void {
const wizard = editServicesWizard(services);
if (wizard) this.dispatchEvent(newWizardEvent(wizard));
}

private removeIED(): void {
const wizard = removeIEDWizard(this.element);
if (wizard) {
Expand Down Expand Up @@ -68,6 +89,7 @@ export class IedContainer extends Container {
@click=${() => this.openEditWizard()}
></mwc-icon-button>
</abbr>
${this.renderServicesIcon()}
${Array.from(this.element.querySelectorAll(':scope > AccessPoint')).map(
ap => html`<access-point-container
.doc=${this.doc}
Expand Down
6 changes: 5 additions & 1 deletion src/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,11 @@ export const wizardInputSelector =
export type WizardInputElement =
| WizardTextField
| TextField
| (AceEditor & { checkValidity: () => boolean; label: string })
| (AceEditor & {
checkValidity: () => boolean;
label: string;
requestUpdate(name?: PropertyKey, oldValue?: unknown): Promise<unknown>;
})
// TODO(c-dinkel): extend component
| Select
| WizardSelect;
Expand Down
Loading

1 comment on commit 81088f0

@vercel
Copy link

@vercel vercel bot commented on 81088f0 Feb 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.