Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(editors/substation): add read-only l-node-editor #730

Merged
merged 14 commits into from
May 17, 2022
Merged
Show file tree
Hide file tree
Changes from 12 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
19 changes: 9 additions & 10 deletions src/action-icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,6 @@ export class ActionIcon extends LitElement {
--mdc-icon-size: 64px;
}

:host(:focus-within) ::slotted([slot='icon']),
:host(:focus-within) mwc-icon {
outline-style: solid;
outline-width: 4px;
transform: scale(0.8);
transition: all 250ms linear;
box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2);
}

:host([secondary]) ::slotted([slot='icon']),
:host([secondary]) mwc-icon {
outline-color: var(--mdc-theme-secondary);
Expand All @@ -96,6 +86,15 @@ export class ActionIcon extends LitElement {
outline-width: 2px;
}

:host(:focus-within) ::slotted([slot='icon']),
:host(:focus-within) mwc-icon {
outline-style: solid;
outline-width: 4px;
transform: scale(0.8);
transition: all 250ms linear;
box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2);
}
::slotted([slot='icon']:hover),
mwc-icon:hover {
outline-style: dashed;
Expand Down
16 changes: 15 additions & 1 deletion src/editors/substation/bay-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,20 @@ export class BayEditor extends LitElement {
this.addMenu.anchor = <HTMLElement>this.addButton;
}

private renderLNodes(): TemplateResult {
if (!this.showfunctions) return html``;

const lNodes = getChildElementsByTagName(this.element, 'LNode');

return lNodes.length
? html`<div class="container lnode">
${lNodes.map(
lNode => html`<l-node-editor .element=${lNode}></l-node-editor>`
)}
</div>`
: html``;
}

renderFunctions(): TemplateResult {
if (!this.showfunctions) return html``;

Expand Down Expand Up @@ -177,7 +191,7 @@ export class BayEditor extends LitElement {
>${this.renderAddButtons()}</mwc-menu
>
</abbr>
${this.renderIedContainer()} ${this.renderFunctions()}
${this.renderIedContainer()}${this.renderLNodes()}${this.renderFunctions()}
<div
class="${classMap({
content: true,
Expand Down
19 changes: 17 additions & 2 deletions src/editors/substation/conducting-equipment-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import '@material/mwc-icon-button';
import '../../action-icon.js';
import '../../action-pane.js';
import './eq-function-editor.js';
import { startMove, getIcon } from './foundation.js';
import './l-node-editor.js';
import { startMove, getIcon, styles } from './foundation.js';
import {
getChildElementsByTagName,
newActionEvent,
Expand Down Expand Up @@ -62,6 +63,18 @@ export class ConductingEquipmentEditor extends LitElement {
);
}

private renderLNodes(): TemplateResult {
const lNodes = getChildElementsByTagName(this.element, 'LNode');

return lNodes.length
? html`<div class="container lnode">
${lNodes.map(
lNode => html`<l-node-editor .element=${lNode}></l-node-editor>`
)}
</div>`
: html``;
}

renderEqFunctions(): TemplateResult {
if (!this.showfunctions) return html``;

Expand Down Expand Up @@ -143,7 +156,7 @@ export class ConductingEquipmentEditor extends LitElement {
render(): TemplateResult {
if (this.showfunctions)
return html`<action-pane label="${this.name}"
>${this.renderContentPane()}${this.renderEqFunctions()}</action-pane
>${this.renderContentPane()}${this.renderLNodes()}${this.renderEqFunctions()}</action-pane
>`;

return html`<action-icon label="${this.name}"
Expand All @@ -152,6 +165,8 @@ export class ConductingEquipmentEditor extends LitElement {
}

static styles = css`
${styles}

:host(.moving) {
opacity: 0.3;
}
Expand Down
14 changes: 13 additions & 1 deletion src/editors/substation/eq-function-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ export class EqFunctionEditor extends LitElement {
return `${name}${desc ? ` - ${desc}` : ''}${type ? ` (${type})` : ''}`;
}

private renderLNodes(): TemplateResult {
const lNodes = getChildElementsByTagName(this.element, 'LNode');

return lNodes.length
? html`<div class="container lnode">
${lNodes.map(
lNode => html`<l-node-editor .element=${lNode}></l-node-editor>`
)}
</div>`
: html``;
}

private renderEqSubFunctions(): TemplateResult {
const eqSubFunctions = getChildElementsByTagName(
this.element,
Expand All @@ -45,7 +57,7 @@ export class EqFunctionEditor extends LitElement {
icon="functions"
secondary
highlighted
>${this.renderEqSubFunctions()}</action-pane
>${this.renderLNodes()}${this.renderEqSubFunctions()}</action-pane
>`;
}
}
20 changes: 19 additions & 1 deletion src/editors/substation/eq-sub-function-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import {
property,
customElement,
state,
css,
} from 'lit-element';

import '../../action-pane.js';
import { getChildElementsByTagName } from '../../foundation.js';
import { styles } from './foundation.js';

/** Pane rendering `EqSubFunction` element with its children */
@customElement('eq-sub-function-editor')
Expand Down Expand Up @@ -38,9 +40,25 @@ export class EqSubFunctionEditor extends LitElement {
)}`;
}

private renderLNodes(): TemplateResult {
const lNodes = getChildElementsByTagName(this.element, 'LNode');

return lNodes.length
? html`<div class="container lnode">
${lNodes.map(
lNode => html`<l-node-editor .element=${lNode}></l-node-editor>`
)}
</div>`
: html``;
}

render(): TemplateResult {
return html`<action-pane label="${this.header}" icon="functions" secondary
>${this.renderEqSubFunctions()}</action-pane
>${this.renderLNodes()}${this.renderEqSubFunctions()}</action-pane
>`;
}

static styles = css`
${styles}
`;
}
8 changes: 8 additions & 0 deletions src/editors/substation/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,14 @@ export const styles = css`
grid-template-columns: repeat(auto-fit, minmax(64px, auto));
}

.container.lnode {
display: grid;
grid-gap: 12px;
padding: 8px 12px 16px;
box-sizing: border-box;
grid-template-columns: repeat(auto-fit, minmax(64px, auto));
}

powertransformer-editor[showfunctions] {
margin: 4px 8px 16px;
}
Expand Down
14 changes: 13 additions & 1 deletion src/editors/substation/function-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ export class FunctionEditor extends LitElement {
return `${name}${desc ? ` - ${desc}` : ''}${type ? ` (${type})` : ''}`;
}

private renderLNodes(): TemplateResult {
const lNodes = getChildElementsByTagName(this.element, 'LNode');

return lNodes.length
? html`<div class="container lnode">
${lNodes.map(
lNode => html`<l-node-editor .element=${lNode}></l-node-editor>`
)}
</div>`
: html``;
}

private renderSubFunctions(): TemplateResult {
const subfunctions = getChildElementsByTagName(this.element, 'SubFunction');
return html` ${subfunctions.map(
Expand All @@ -42,7 +54,7 @@ export class FunctionEditor extends LitElement {
icon="functions"
secondary
highlighted
>${this.renderSubFunctions()}</action-pane
>${this.renderLNodes()}${this.renderSubFunctions()}</action-pane
>`;
}
}
88 changes: 88 additions & 0 deletions src/editors/substation/l-node-editor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import {
html,
LitElement,
TemplateResult,
property,
customElement,
state,
} from 'lit-element';

import '../../action-icon.js';
import { identity } from '../../foundation.js';
import {
automationLogicalNode,
controlLogicalNode,
functionalLogicalNode,
furtherPowerSystemEquipmentLogicalNode,
generalLogicalNode,
interfacingLogicalNode,
measurementLogicalNode,
nonElectricalLogicalNode,
powerTransformerLogicalNode,
protectionLogicalNode,
protectionRelatedLogicalNode,
qualityLogicalNode,
supervisionLogicalNode,
switchgearLogicalNode,
systemLogicalNode,
transformerLogicalNode,
} from '../../icons/lnode.js';

export function getLNodeIcon(lNode: Element): TemplateResult {
const lnClassGroup = lNode.getAttribute('lnClass')?.charAt(0) ?? '';
return lnClassIcons[lnClassGroup] ?? systemLogicalNode;
}

const lnClassIcons: Partial<Record<string, TemplateResult>> = {
L: systemLogicalNode,
A: automationLogicalNode,
C: controlLogicalNode,
F: functionalLogicalNode,
G: generalLogicalNode,
I: interfacingLogicalNode,
K: nonElectricalLogicalNode,
M: measurementLogicalNode,
P: protectionLogicalNode,
Q: qualityLogicalNode,
R: protectionRelatedLogicalNode,
S: supervisionLogicalNode,
T: transformerLogicalNode,
X: switchgearLogicalNode,
Y: powerTransformerLogicalNode,
Z: furtherPowerSystemEquipmentLogicalNode,
};

/** Pane rendering `LNode` element with its children */
@customElement('l-node-editor')
export class LNodeEditor extends LitElement {
/** The edited `LNode` element */
@property({ attribute: false })
element!: Element;
@state()
private get header(): string {
const prefix = this.element.getAttribute('prefix') ?? '';
const lnClass = this.element.getAttribute('lnClass');
const lnInst = this.element.getAttribute('lnInst');

const header = this.missingIedReference
? `${prefix} ${lnClass} ${lnInst}`
: identity(this.element);

return typeof header === 'string' ? header : '';
}
@state()
private get missingIedReference(): boolean {
return this.element.getAttribute('iedName') === 'None' ?? false;
}

render(): TemplateResult {
return html`<action-icon
label="${this.header}"
?secondary=${this.missingIedReference}
?highlighted=${this.missingIedReference}
><mwc-icon slot="icon"
>${getLNodeIcon(this.element)}</mwc-icon
></action-icon
>`;
}
}
14 changes: 13 additions & 1 deletion src/editors/substation/powertransformer-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ export class PowerTransformerEditor extends LitElement {
);
}

private renderLNodes(): TemplateResult {
const lNodes = getChildElementsByTagName(this.element, 'LNode');

return lNodes.length
? html`<div class="container lnode">
${lNodes.map(
lNode => html`<l-node-editor .element=${lNode}></l-node-editor>`
)}
</div>`
: html``;
}

renderEqFunctions(): TemplateResult {
if (!this.showfunctions) return html``;

Expand Down Expand Up @@ -159,7 +171,7 @@ export class PowerTransformerEditor extends LitElement {
render(): TemplateResult {
if (this.showfunctions)
return html`<action-pane label="${this.name}"
>${this.renderContentPane()}${this.renderEqFunctions()}</action-pane
>${this.renderContentPane()}${this.renderLNodes()}${this.renderEqFunctions()}</action-pane
> `;

return html`<action-icon label="${this.name}"
Expand Down
14 changes: 13 additions & 1 deletion src/editors/substation/sub-function-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ export class SubFunctionEditor extends LitElement {
return `${name}${desc ? ` - ${desc}` : ''}${type ? ` (${type})` : ''}`;
}

private renderLNodes(): TemplateResult {
const lNodes = getChildElementsByTagName(this.element, 'LNode');

return lNodes.length
? html`<div class="container lnode">
${lNodes.map(
lNode => html`<l-node-editor .element=${lNode}></l-node-editor>`
)}
</div>`
: html``;
}

private renderSubFunctions(): TemplateResult {
const subfunctions = getChildElementsByTagName(this.element, 'SubFunction');
return html` ${subfunctions.map(
Expand All @@ -38,7 +50,7 @@ export class SubFunctionEditor extends LitElement {

render(): TemplateResult {
return html`<action-pane label="${this.header}" icon="functions" secondary
>${this.renderSubFunctions()}</action-pane
>${this.renderLNodes()}${this.renderSubFunctions()}</action-pane
>`;
}
}
16 changes: 15 additions & 1 deletion src/editors/substation/substation-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@ export class SubstationEditor extends LitElement {
this.addMenu.anchor = <HTMLElement>this.addButton;
}

private renderLNodes(): TemplateResult {
if (!this.showfunctions) return html``;

const lNodes = getChildElementsByTagName(this.element, 'LNode');

return lNodes.length
? html`<div class="container lnode">
${lNodes.map(
lNode => html`<l-node-editor .element=${lNode}></l-node-editor>`
)}
</div>`
: html``;
}

renderFunctions(): TemplateResult {
if (!this.showfunctions) return html``;

Expand Down Expand Up @@ -207,7 +221,7 @@ export class SubstationEditor extends LitElement {
>${this.renderAddButtons()}</mwc-menu
>
</abbr>
${this.renderIedContainer()}${this.renderFunctions()}
${this.renderIedContainer()}${this.renderLNodes()}${this.renderFunctions()}
${this.renderPowerTransformerContainer()}
${Array.from(this.element.querySelectorAll(selectors.VoltageLevel)).map(
voltageLevel =>
Expand Down
Loading