From c10f405b8c73af2b8f4b22c78b801a6a70bfcd07 Mon Sep 17 00:00:00 2001 From: Rob Tjalma Date: Tue, 30 Nov 2021 23:16:12 +0100 Subject: [PATCH] Added terminal and Connectivity Node information (#402) * Added terminal/connectivity node information * Removed console.log * Some refactoring * Small refactoring * fix(translations/de): add missing German translations Thank you very much for adding these nice wizards to translate! :+1: Co-authored-by: Rob Tjalma Co-authored-by: Christian Dinkel --- src/editors/SingleLineDiagram.ts | 30 +++++++-- src/editors/singlelinediagram/sld-drawing.ts | 26 ++++---- src/icons.ts | 2 +- src/translations/de.ts | 23 +++++++ src/translations/en.ts | 23 +++++++ src/wizards/connectivitynode.ts | 55 +++++++++++++++++ src/wizards/terminal.ts | 65 ++++++++++++++++++++ src/wizards/wizard-library.ts | 6 +- 8 files changed, 209 insertions(+), 21 deletions(-) create mode 100644 src/wizards/connectivitynode.ts create mode 100644 src/wizards/terminal.ts diff --git a/src/editors/SingleLineDiagram.ts b/src/editors/SingleLineDiagram.ts index 515c99afa6..9d6b1173c8 100644 --- a/src/editors/SingleLineDiagram.ts +++ b/src/editors/SingleLineDiagram.ts @@ -7,7 +7,7 @@ import { TemplateResult, } from 'lit-element'; -import { identity } from '../foundation.js'; +import { identity, newWizardEvent, SCLTag } from '../foundation.js'; import panzoom from 'panzoom'; @@ -33,6 +33,7 @@ import { getPathNameAttribute, getNameAttribute, } from './singlelinediagram/foundation.js'; +import { wizards } from '../wizards/wizard-library.js'; /** * Main class plugin for Single Line Diagram editor. @@ -148,7 +149,8 @@ export default class SingleLineDiagramPlugin extends LitElement { const cNodePosition = getAbsolutePositionConnectivityNode(cNode); const cNodeElement = createConnectivityNodeElement( cNode, - cNodePosition + cNodePosition, + () => this.openEditWizard(cNode) ); this.addElementToGroup(cNodeElement, identity(cNode.parentElement)); @@ -233,7 +235,8 @@ export default class SingleLineDiagramPlugin extends LitElement { const terminal = createTerminalElement( cEquipmentAbsolutePosition, sideToDrawTerminalOn, - terminalElement! + terminalElement!, + () => this.openEditWizard(terminalElement!) ); this.svg @@ -301,11 +304,12 @@ export default class SingleLineDiagramPlugin extends LitElement { const terminal = createTerminalElement( cEquipmentAbsolutePosition, sideToDrawTerminalOn, - terminalElement! + terminalElement!, + () => this.openEditWizard(terminalElement!) ); this.svg - .querySelectorAll(` g[id="${identity(cEquipment)}"]`) + .querySelectorAll(`g[id="${identity(cEquipment)}"]`) .forEach(eq => eq.appendChild(terminal)); }); }); @@ -321,7 +325,7 @@ export default class SingleLineDiagramPlugin extends LitElement { this.drawPowerTransformers(); this.drawConnectivityNodes(); this.drawBusBars(); - + this.drawConnectivityNodeConnections(); this.drawBusBarConnections(); } @@ -337,6 +341,15 @@ export default class SingleLineDiagramPlugin extends LitElement { .forEach(group => group.appendChild(elementToAdd)); } + /** + * Open an Edit wizard for an element. + * @param element - The element to show the wizard for. + */ + openEditWizard(element: Element): void { + const wizard = wizards[(element.tagName)].edit(element); + if (wizard) this.dispatchEvent(newWizardEvent(wizard)); + } + firstUpdated(): void { panzoom(this.panzoomContainer); this.drawSubstationElements(); @@ -360,5 +373,10 @@ export default class SingleLineDiagramPlugin extends LitElement { .sldContainer { overflow: hidden; } + + g[type='ConnectivityNode']:hover, g[type='Terminal']:hover { + outline: 2px dashed var(--mdc-theme-primary); + transition: transform 200ms linear, box-shadow 250ms linear; + } `; } diff --git a/src/editors/singlelinediagram/sld-drawing.ts b/src/editors/singlelinediagram/sld-drawing.ts index bd8bafef3d..d9cbce09f6 100644 --- a/src/editors/singlelinediagram/sld-drawing.ts +++ b/src/editors/singlelinediagram/sld-drawing.ts @@ -173,12 +173,14 @@ export function createTextElement( * @param elementPosition - The position of the element belonging to the terminal/ * @param sideToDraw - The side of the element the terminal must be drawn on. * @param terminalElement - The terminal element to extract information from. + * @param clickAction - The action to execute when the terminal is being clicked. * @returns The terminal SVG element. */ export function createTerminalElement( elementPosition: Point, sideToDraw: Side, - terminalElement: Element + terminalElement: Element, + clickAction: () => void ): SVGElement { const groupElement = createGroupElement(terminalElement); @@ -187,7 +189,6 @@ export function createTerminalElement( ? identity(terminalElement) : 'unidentifiable'; - const terminalName = getNameAttribute(terminalElement)!; const pointToDrawTerminalOn = getAbsolutePositionTerminal( elementPosition, sideToDraw @@ -200,15 +201,9 @@ export function createTerminalElement( icon.setAttribute('cy', `${pointToDrawTerminalOn.y}`); icon.setAttribute('r', '2'); - // Also add a text element. - const textElementPosition = - sideToDraw == 'bottom' || sideToDraw == 'top' - ? { x: pointToDrawTerminalOn.x! + 5, y: pointToDrawTerminalOn.y! + 5 } - : { x: pointToDrawTerminalOn.x! - 5, y: pointToDrawTerminalOn.y! - 5 }; - const text = createTextElement(terminalName, textElementPosition, 'xx-small'); - groupElement.appendChild(icon); - groupElement.appendChild(text); + + groupElement.addEventListener('click', clickAction); return groupElement; } @@ -322,11 +317,13 @@ export function createPowerTransformerElement( * Create a Connectivity Node element. * @param cNodeElement - The name of the busbar * @param position - The SCL position of the Connectivity Node. + * @param clickAction - The action to execute when the terminal is being clicked. * @returns The Connectivity Node SVG element. */ export function createConnectivityNodeElement( cNodeElement: Element, - position: Point + position: Point, + clickAction: () => void ): SVGElement { const groupElement = createGroupElement(cNodeElement); @@ -339,6 +336,8 @@ export function createConnectivityNodeElement( groupElement.appendChild(icon); }); + groupElement.addEventListener('click', clickAction); + return groupElement; } @@ -409,7 +408,10 @@ export function drawRouteBetweenElements( line.setAttribute('stroke', 'currentColor'); line.setAttribute('stroke-width', '1.5'); - svgToDrawOn.appendChild(line); + // Inserting elements like this works kind of like z-index (not supported in SVG yet), + // these elements are placed behind all other elements. + // By doing it like this, all other elements are hoverable for example. + svgToDrawOn.insertAdjacentElement('afterbegin', line); return sides; } diff --git a/src/icons.ts b/src/icons.ts index 39be94b51b..b6eecfee3d 100644 --- a/src/icons.ts +++ b/src/icons.ts @@ -565,7 +565,7 @@ export const connectivityNodeIcon = html` `, + html``, + ]; +} + +export function editConnectivityNodeWizard(element: Element): Wizard { + const reservedNames = Array.from( + element.parentNode!.querySelectorAll('ConnectivityNode') + ) + .filter(isPublic) + .map(cNode => cNode.getAttribute('name') ?? '') + .filter(name => name !== element.getAttribute('name')); + + return [ + { + title: get('connectivitynode.wizard.title.edit'), + element, + content: render( + element.getAttribute('name'), + element.getAttribute('pathName'), + reservedNames + ), + }, + ]; +} diff --git a/src/wizards/terminal.ts b/src/wizards/terminal.ts new file mode 100644 index 0000000000..d6bf82473e --- /dev/null +++ b/src/wizards/terminal.ts @@ -0,0 +1,65 @@ +import { html, TemplateResult } from 'lit-element'; +import { get, translate } from 'lit-translate'; + +import { + isPublic, + Wizard, +} from '../foundation.js'; + +function render( + name: string | null, + connectivityNode: string | null, + cNodeName: string | null, + reservedNames: string[] +): TemplateResult[] { + return [ + html``, + html``, + html``, + ]; +} + +export function editTerminalWizard(element: Element): Wizard { + const reservedNames = Array.from( + element.parentNode!.querySelectorAll('ConnectivityNode') + ) + .filter(isPublic) + .map(cNode => cNode.getAttribute('name') ?? '') + .filter(name => name !== element.getAttribute('name')); + + return [ + { + title: get('terminal.wizard.title.edit'), + element, + content: render( + element.getAttribute('name'), + element.getAttribute('connectivityNode'), + element.getAttribute('cNodeName'), + reservedNames + ), + }, + ]; +} diff --git a/src/wizards/wizard-library.ts b/src/wizards/wizard-library.ts index ec98dbaefa..cb53b1d7e9 100644 --- a/src/wizards/wizard-library.ts +++ b/src/wizards/wizard-library.ts @@ -5,9 +5,11 @@ import { createConductingEquipmentWizard, editConductingEquipmentWizard, } from './conductingequipment.js'; +import { editConnectivityNodeWizard } from './connectivitynode.js'; import { createFCDAsWizard } from './fcda.js'; import { lNodeWizard } from './lnode.js'; import { createSubstationWizard, substationEditWizard } from './substation.js'; +import { editTerminalWizard } from './terminal.js'; import { voltageLevelCreateWizard, voltageLevelEditWizard, @@ -111,7 +113,7 @@ export const wizards: Record< create: emptyWizard, }, ConnectivityNode: { - edit: emptyWizard, + edit: editConnectivityNodeWizard, create: emptyWizard, }, DA: { @@ -483,7 +485,7 @@ export const wizards: Record< create: emptyWizard, }, Terminal: { - edit: emptyWizard, + edit: editTerminalWizard, create: emptyWizard, }, Text: {