Skip to content

Commit 81487c1

Browse files
feat(editors/communication): add GSE and SMV editor type elements (openscd#1021)
1 parent 984652a commit 81487c1

17 files changed

+1031
-511
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import {
2+
LitElement,
3+
TemplateResult,
4+
html,
5+
customElement,
6+
property,
7+
state,
8+
} from 'lit-element';
9+
10+
import '@material/mwc-icon';
11+
12+
import '../../action-icon.js';
13+
import { sizableGooseIcon } from '../../icons/icons.js';
14+
15+
@customElement('gse-editor')
16+
export class GseEditor extends LitElement {
17+
@property({ attribute: false })
18+
doc!: XMLDocument;
19+
20+
@property({ attribute: false })
21+
element!: Element;
22+
23+
@state()
24+
get label(): string {
25+
return (
26+
this.element.getAttribute('ldInst') +
27+
'/' +
28+
this.element.getAttribute('cbName')
29+
);
30+
}
31+
32+
render(): TemplateResult {
33+
return html`<action-icon label="${this.label}"
34+
><mwc-icon slot="icon">${sizableGooseIcon}</mwc-icon></action-icon
35+
>`;
36+
}
37+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import {
2+
LitElement,
3+
TemplateResult,
4+
html,
5+
customElement,
6+
property,
7+
state,
8+
} from 'lit-element';
9+
10+
import '@material/mwc-icon';
11+
12+
import '../../action-icon.js';
13+
import { sizableSmvIcon } from '../../icons/icons.js';
14+
15+
@customElement('smv-editor')
16+
export class SmvEditor extends LitElement {
17+
@property({ attribute: false })
18+
doc!: XMLDocument;
19+
20+
@property({ attribute: false })
21+
element!: Element;
22+
23+
@state()
24+
get label(): string {
25+
return (
26+
this.element.getAttribute('ldInst') +
27+
'/' +
28+
this.element.getAttribute('cbName')
29+
);
30+
}
31+
32+
render(): TemplateResult {
33+
return html`<action-icon label="${this.label}"
34+
><mwc-icon slot="icon">${sizableSmvIcon}</mwc-icon>
35+
</action-icon>`;
36+
}
37+
}

src/editors/communication/subnetwork-editor.ts

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { translate } from 'lit-translate';
1111
import '@material/mwc-icon-button';
1212

1313
import './connectedap-editor.js';
14+
import './gse-editor.js';
15+
import './smv-editor.js';
1416
import {
1517
newWizardEvent,
1618
newActionEvent,
@@ -75,26 +77,60 @@ export class SubNetworkEditor extends LitElement {
7577
);
7678
}
7779

80+
private renderSmvEditors(iedName: string): TemplateResult[] {
81+
return Array.from(
82+
this.element
83+
.closest('Communication')
84+
?.querySelectorAll(`ConnectedAP[iedName="${iedName}"] > SMV`) ?? []
85+
).map(
86+
smv => html`<smv-editor
87+
class="${smv.closest('SubNetwork') !== this.element ? 'disabled' : ''}"
88+
.doc=${this.doc}
89+
.element=${smv}
90+
></smv-editor>`
91+
);
92+
}
93+
94+
private renderGseEditors(iedName: string): TemplateResult[] {
95+
return Array.from(
96+
this.element
97+
.closest('Communication')
98+
?.querySelectorAll(`ConnectedAP[iedName="${iedName}"] > GSE`) ?? []
99+
).map(
100+
gse => html`<gse-editor
101+
class="${gse.closest('SubNetwork') !== this.element ? 'disabled' : ''}"
102+
.doc=${this.doc}
103+
.element=${gse}
104+
></gse-editor>`
105+
);
106+
}
107+
108+
private renderConnectedApEditors(iedName: string): TemplateResult[] {
109+
return Array.from(
110+
this.element.parentElement?.querySelectorAll(
111+
`:scope > SubNetwork > ConnectedAP[iedName="${iedName}"]`
112+
) ?? []
113+
).map(
114+
connectedAP =>
115+
html`<connectedap-editor
116+
class="${connectedAP.parentElement !== this.element
117+
? 'disabled'
118+
: ''}"
119+
.element=${connectedAP}
120+
></connectedap-editor>`
121+
);
122+
}
123+
78124
private renderIEDs(): TemplateResult[] {
79125
return Array.from(this.element.querySelectorAll(':scope > ConnectedAP'))
80126
.map(connAP => connAP.getAttribute('iedName')!)
81127
.filter((v, i, a) => a.indexOf(v) === i)
82128
.sort(compareNames)
83129
.map(
84130
iedName => html` <action-pane id="iedSection" label="${iedName}">
85-
${Array.from(
86-
this.element.parentElement?.querySelectorAll(
87-
`:scope > SubNetwork > ConnectedAP[iedName="${iedName}"]`
88-
) ?? []
89-
).map(
90-
connectedAP =>
91-
html`<connectedap-editor
92-
class="${connectedAP.parentElement !== this.element
93-
? 'disabled'
94-
: ''}"
95-
.element=${connectedAP}
96-
></connectedap-editor>`
97-
)}
131+
${this.renderConnectedApEditors(iedName)}${this.renderGseEditors(
132+
iedName
133+
)}${this.renderSmvEditors(iedName)}
98134
</action-pane>`
99135
);
100136
}
@@ -149,6 +185,14 @@ export class SubNetworkEditor extends LitElement {
149185
display: none;
150186
}
151187
188+
#iedSection:not(:focus):not(:focus-within) gse-editor {
189+
display: none;
190+
}
191+
192+
#iedSection:not(:focus):not(:focus-within) smv-editor {
193+
display: none;
194+
}
195+
152196
#iedSection .disabled {
153197
pointer-events: none;
154198
opacity: 0.5;

src/icons/icons.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,3 +676,12 @@ export const openSCDIcon = html` <svg
676676
fill="#2aa198"
677677
/>
678678
</svg>`;
679+
680+
export const sizableSmvIcon = svg`
681+
<svg viewBox="0 0 24 24">
682+
<path fill="currentColor" d="M11,7H15V9H11V11H13A2,2 0 0,1 15,13V15A2,2 0 0,1 13,17H9V15H13V13H11A2,2 0 0,1 9,11V9A2,2 0 0,1 11,7M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" />
683+
</svg>`;
684+
685+
export const sizableGooseIcon = svg`<svg viewBox="0 0 24 24">
686+
<path fill="currentColor" d="M11,7H15V9H11V15H13V11H15V15A2,2 0 0,1 13,17H11A2,2 0 0,1 9,15V9A2,2 0 0,1 11,7M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" />
687+
</svg>`;

0 commit comments

Comments
 (0)