Skip to content

Commit f6e96b5

Browse files
pascalwilbrinkDennis Labordus
andauthored
feat(editor/substation): read-only editor for SubEquipment element (openscd#1030)
* Added sub-equipment to Sub-Station editor Signed-off-by: Pascal Wilbrink <[email protected]> * Fixed review comments Signed-off-by: Pascal Wilbrink <[email protected]> Signed-off-by: Pascal Wilbrink <[email protected]> * Fixed formatting Signed-off-by: Pascal Wilbrink <[email protected]> Signed-off-by: Pascal Wilbrink <[email protected]> * Added new tests for parents of the SubEquipmentEditor Signed-off-by: Pascal Wilbrink <[email protected]> Signed-off-by: Pascal Wilbrink <[email protected]> * Added new tests for children of the SubEquipmentEditor Signed-off-by: Pascal Wilbrink <[email protected]> Signed-off-by: Pascal Wilbrink <[email protected]> * Fixed formatting Signed-off-by: Pascal Wilbrink <[email protected]> Signed-off-by: Pascal Wilbrink <[email protected]> * reverted test files Signed-off-by: Pascal Wilbrink <[email protected]> Signed-off-by: Pascal Wilbrink <[email protected]> Signed-off-by: Pascal Wilbrink <[email protected]> Co-authored-by: Dennis Labordus <[email protected]>
1 parent 81da900 commit f6e96b5

14 files changed

+761
-13
lines changed

src/editors/substation/conducting-equipment-editor.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import {
3232
import { BayEditor } from './bay-editor.js';
3333
import { emptyWizard, wizards } from '../../wizards/wizard-library.js';
3434

35+
import './sub-equipment-editor.js';
36+
3537
function childTags(element: Element | null | undefined): SCLTag[] {
3638
if (!element) return [];
3739

@@ -54,7 +56,7 @@ export class ConductingEquipmentEditor extends LitElement {
5456
get name(): string {
5557
return this.element.getAttribute('name') ?? '';
5658
}
57-
/** Whether `EqFunction` and `SubEqFunction` are rendered */
59+
/** Whether `EqFunction`, `SubEqFunction` and `SubEquipment` are rendered */
5860
@property({ type: Boolean })
5961
showfunctions = false;
6062

@@ -219,10 +221,32 @@ export class ConductingEquipmentEditor extends LitElement {
219221
></mwc-fab>`;
220222
}
221223
224+
private renderSubEquipments(): TemplateResult {
225+
if (!this.showfunctions) return html``;
226+
227+
const subEquipments = getChildElementsByTagName(
228+
this.element,
229+
'SubEquipment'
230+
);
231+
232+
return subEquipments.length
233+
? html`<div class="container subequipment">
234+
${subEquipments.map(
235+
subEquipment =>
236+
html`<sub-equipment-editor
237+
.doc=${this.doc}
238+
.element=${subEquipment}
239+
></sub-equipment-editor>`
240+
)}
241+
</div>`
242+
: html``;
243+
}
244+
222245
render(): TemplateResult {
223246
if (this.showfunctions)
224247
return html`<action-pane label="${this.name}"
225-
>${this.renderContentPane()}${this.renderLNodes()}${this.renderEqFunctions()}</action-pane
248+
>${this.renderContentPane()}${this.renderLNodes()}${this.renderEqFunctions()}${this.renderSubEquipments()}</action-pane
249+
></action-pane
226250
>`;
227251
228252
return html`<action-icon label="${this.name}"

src/editors/substation/foundation.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,14 @@ export const styles = css`
305305
grid-template-columns: repeat(auto-fit, minmax(64px, auto));
306306
}
307307
308+
.container.subequipment {
309+
display: grid;
310+
grid-gap: 12px;
311+
padding: 8px 12px 16px;
312+
box-sizing: border-box;
313+
grid-template-columns: repeat(auto-fit, minmax(64px, auto));
314+
}
315+
308316
powertransformer-editor[showfunctions] {
309317
margin: 4px 8px 16px;
310318
}

src/editors/substation/powertransformer-editor.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import { SubstationEditor } from './substation-editor.js';
3333
import { BayEditor } from './bay-editor.js';
3434
import { VoltageLevelEditor } from './voltage-level-editor.js';
3535

36+
import './sub-equipment-editor.js';
37+
3638
function childTags(element: Element | null | undefined): SCLTag[] {
3739
if (!element) return [];
3840

@@ -56,7 +58,7 @@ export class PowerTransformerEditor extends LitElement {
5658
get name(): string {
5759
return this.element.getAttribute('name') ?? 'UNDEFINED';
5860
}
59-
/** Whether `EqFunction` and `SubEqFunction` are rendered */
61+
/** Whether `EqFunction`, `SubEqFunction` and `SubEquipment` are rendered */
6062
@property({ type: Boolean })
6163
showfunctions = false;
6264

@@ -197,6 +199,26 @@ export class PowerTransformerEditor extends LitElement {
197199
</abbr>`;
198200
}
199201
202+
private renderSubEquipments(): TemplateResult {
203+
if (!this.showfunctions) return html``;
204+
const subEquipments = getChildElementsByTagName(
205+
this.element,
206+
'SubEquipment'
207+
);
208+
209+
return subEquipments.length
210+
? html`<div class="container subequipment">
211+
${subEquipments.map(
212+
subEquipment =>
213+
html`<sub-equipment-editor
214+
.doc=${this.doc}
215+
.element=${subEquipment}
216+
></sub-equipment-editor>`
217+
)}
218+
</div>`
219+
: html``;
220+
}
221+
200222
renderContentIcon(): TemplateResult {
201223
return html`<mwc-icon slot="icon"
202224
>${powerTransformerTwoWindingIcon}</mwc-icon
@@ -237,7 +259,7 @@ export class PowerTransformerEditor extends LitElement {
237259
render(): TemplateResult {
238260
if (this.showfunctions)
239261
return html`<action-pane label="${this.name}"
240-
>${this.renderContentPane()}${this.renderLNodes()}${this.renderEqFunctions()}</action-pane
262+
>${this.renderContentPane()}${this.renderLNodes()}${this.renderEqFunctions()}${this.renderSubEquipments()}</action-pane
241263
> `;
242264
243265
return html`<action-icon label="${this.name}"
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import {
2+
css,
3+
customElement,
4+
html,
5+
LitElement,
6+
property,
7+
TemplateResult,
8+
} from 'lit-element';
9+
10+
import '@material/mwc-fab';
11+
import '@material/mwc-icon';
12+
import '@material/mwc-icon-button';
13+
import '@material/mwc-menu';
14+
15+
import '../../action-icon.js';
16+
import '../../action-pane.js';
17+
18+
import { styles } from './foundation.js';
19+
import { getChildElementsByTagName } from '../../foundation.js';
20+
21+
/** [[`SubstationEditor`]] subeditor for a child-less `SubEquipment` element. */
22+
@customElement('sub-equipment-editor')
23+
export class SubEquipmentEditor extends LitElement {
24+
/** The document being edited as provided to editor by [[`Zeroline`]]. */
25+
@property({ attribute: false })
26+
doc!: XMLDocument;
27+
/** SCL element SubEquipment */
28+
@property({ attribute: false })
29+
element!: Element;
30+
31+
/** SubEquipment name attribute */
32+
@property({ type: String })
33+
get label(): string {
34+
const name = `${
35+
this.element.hasAttribute('name')
36+
? `${this.element.getAttribute('name')}`
37+
: ''
38+
}`;
39+
40+
const description = `${
41+
this.element.hasAttribute('desc')
42+
? ` - ${this.element.getAttribute('desc')}`
43+
: ''
44+
}`;
45+
46+
const phase = `${
47+
this.element.hasAttribute('phase')
48+
? ` (${this.element.getAttribute('phase')})`
49+
: ''
50+
}`;
51+
52+
return `${name}${description}${phase}`;
53+
}
54+
55+
private renderLNodes(): TemplateResult {
56+
const lNodes = getChildElementsByTagName(this.element, 'LNode');
57+
58+
return lNodes.length
59+
? html`<div class="container lnode">
60+
${lNodes.map(
61+
lNode =>
62+
html`<l-node-editor
63+
.doc=${this.doc}
64+
.element=${lNode}
65+
></l-node-editor>`
66+
)}
67+
</div>`
68+
: html``;
69+
}
70+
71+
private renderEqFunctions(): TemplateResult {
72+
const eqFunctions = getChildElementsByTagName(this.element, 'EqFunction');
73+
return eqFunctions.length
74+
? html` ${eqFunctions.map(
75+
eqFunction =>
76+
html`<eq-function-editor
77+
.doc=${this.doc}
78+
.element=${eqFunction}
79+
></eq-function-editor>`
80+
)}`
81+
: html``;
82+
}
83+
84+
render(): TemplateResult {
85+
return html`<action-pane label="${this.label}">
86+
${this.renderLNodes()} ${this.renderEqFunctions()}
87+
</action-pane> `;
88+
}
89+
90+
static styles = css`
91+
${styles}
92+
93+
:host(.moving) {
94+
opacity: 0.3;
95+
}
96+
97+
abbr {
98+
text-decoration: none;
99+
border-bottom: none;
100+
}
101+
`;
102+
}

src/foundation.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1699,7 +1699,11 @@ export const tags: Record<
16991699
identity: namingIdentity,
17001700
selector: namingSelector,
17011701
parents: ['Process', 'Line', 'SubFunction', 'Function', 'Bay'],
1702-
children: [...tAbstractConductingEquipmentSequence, 'EqFunction'],
1702+
children: [
1703+
...tAbstractConductingEquipmentSequence,
1704+
'EqFunction',
1705+
'SubEquipment',
1706+
],
17031707
},
17041708
ConfDataSet: {
17051709
identity: singletonIdentity,
@@ -2127,6 +2131,7 @@ export const tags: Record<
21272131
'TransformerWinding',
21282132
'SubEquipment',
21292133
'EqFunction',
2134+
'SubEquipment',
21302135
],
21312136
},
21322137
Private: {
@@ -2357,6 +2362,8 @@ export const tags: Record<
23572362
parents: [
23582363
'TapChanger',
23592364
'PowerTransformer',
2365+
'ConductingEquipment',
2366+
'TransformerWinding',
23602367
...tAbstractConductingEquipment,
23612368
],
23622369
children: [...tPowerSystemResourceSequence, 'EqFunction'],
@@ -2435,6 +2442,7 @@ export const tags: Record<
24352442
'TapChanger',
24362443
'NeutralPoint',
24372444
'EqFunction',
2445+
'SubEquipment',
24382446
],
24392447
},
24402448
TrgOps: {

0 commit comments

Comments
 (0)