Skip to content

Commit 774add7

Browse files
feat(wizards/function): add create wizards for Function, SubFunction, EqFunction and EqSubFunction element (openscd#731)
* feat(wizards/function): add create wizard * feat(wizard/wizard-library): add create wizard for Function element * feat(wizards/subfunction): add create wizard (openscd#733) * feat(wizards/subfunction): add create wizard * feat(editors/substation/sub-function-editor): add add button * feat(wizards/eqfunction): add create wizard (openscd#737) * feat(wizards/eqsubfunction): add create wizard (openscd#757) * test(editors/substation): update snapshots
1 parent dd9843e commit 774add7

37 files changed

+2833
-26
lines changed

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

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@ import {
44
html,
55
LitElement,
66
property,
7+
query,
78
TemplateResult,
89
} from 'lit-element';
910
import { translate } from 'lit-translate';
1011

1112
import '@material/mwc-fab';
1213
import '@material/mwc-icon';
1314
import '@material/mwc-icon-button';
15+
import '@material/mwc-menu';
16+
import { Menu } from '@material/mwc-menu';
17+
import { IconButton } from '@material/mwc-icon-button';
18+
import { ListItem } from '@material/mwc-list/mwc-list-item';
1419

1520
import '../../action-icon.js';
1621
import '../../action-pane.js';
@@ -21,9 +26,19 @@ import {
2126
getChildElementsByTagName,
2227
newActionEvent,
2328
newWizardEvent,
29+
SCLTag,
30+
tags,
2431
} from '../../foundation.js';
2532
import { BayEditor } from './bay-editor.js';
26-
import { wizards } from '../../wizards/wizard-library.js';
33+
import { emptyWizard, wizards } from '../../wizards/wizard-library.js';
34+
35+
function childTags(element: Element | null | undefined): SCLTag[] {
36+
if (!element) return [];
37+
38+
return tags[<SCLTag>element.tagName].children.filter(
39+
child => wizards[child].create !== emptyWizard
40+
);
41+
}
2742

2843
/** [[`SubstationEditor`]] subeditor for a `ConductingEquipment` element. */
2944
@customElement('conducting-equipment-editor')
@@ -40,6 +55,9 @@ export class ConductingEquipmentEditor extends LitElement {
4055
@property({ type: Boolean })
4156
showfunctions = false;
4257

58+
@query('mwc-menu') addMenu!: Menu;
59+
@query('mwc-icon-button[icon="playlist_add"]') addButton!: IconButton;
60+
4361
private openEditWizard(): void {
4462
const wizard = wizards['ConductingEquipment'].edit(this.element);
4563
if (wizard) this.dispatchEvent(newWizardEvent(wizard));
@@ -50,6 +68,12 @@ export class ConductingEquipmentEditor extends LitElement {
5068
if (wizard) this.dispatchEvent(newWizardEvent(wizard));
5169
}
5270

71+
private openCreateWizard(tagName: string): void {
72+
const wizard = wizards[<SCLTag>tagName].create(this.element!);
73+
74+
if (wizard) this.dispatchEvent(newWizardEvent(wizard));
75+
}
76+
5377
remove(): void {
5478
if (this.element)
5579
this.dispatchEvent(
@@ -63,6 +87,11 @@ export class ConductingEquipmentEditor extends LitElement {
6387
);
6488
}
6589

90+
firstUpdated(): void {
91+
if (this.addMenu && this.addButton)
92+
this.addMenu.anchor = <HTMLElement>this.addButton;
93+
}
94+
6695
private renderLNodes(): TemplateResult {
6796
const lNodes = getChildElementsByTagName(this.element, 'LNode');
6897

@@ -85,6 +114,15 @@ export class ConductingEquipmentEditor extends LitElement {
85114
)}`;
86115
}
87116

117+
private renderAddButtons(): TemplateResult[] {
118+
return childTags(this.element).map(
119+
child =>
120+
html`<mwc-list-item value="${child}"
121+
><span>${child}</span></mwc-list-item
122+
>`
123+
);
124+
}
125+
88126
renderContentPane(): TemplateResult {
89127
return html`<mwc-icon slot="icon" style="width:24px;height:24px"
90128
>${getIcon(this.element)}</mwc-icon
@@ -120,8 +158,26 @@ export class ConductingEquipmentEditor extends LitElement {
120158
mini
121159
icon="delete"
122160
@click="${() => this.remove()}}"
123-
></mwc-icon-button>
124-
</abbr> `;
161+
></mwc-icon-button> </abbr
162+
><abbr
163+
slot="action"
164+
style="position:relative;"
165+
title="${translate('add')}"
166+
>
167+
<mwc-icon-button
168+
icon="playlist_add"
169+
@click=${() => (this.addMenu.open = true)}
170+
></mwc-icon-button
171+
><mwc-menu
172+
corner="BOTTOM_RIGHT"
173+
menuCorner="END"
174+
@selected=${(e: Event) => {
175+
const tagName = (<ListItem>(<Menu>e.target).selected).value;
176+
this.openCreateWizard(tagName);
177+
}}
178+
>${this.renderAddButtons()}</mwc-menu
179+
>
180+
</abbr>`;
125181
}
126182
127183
renderContentIcon(): TemplateResult {

src/editors/substation/eq-function-editor.ts

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,34 @@ import {
66
customElement,
77
state,
88
css,
9+
query,
910
} from 'lit-element';
11+
import { translate } from 'lit-translate';
12+
13+
import '@material/mwc-icon-button';
14+
import '@material/mwc-list/mwc-list-item';
15+
import '@material/mwc-menu';
16+
import { IconButton } from '@material/mwc-icon-button';
17+
import { ListItem } from '@material/mwc-list/mwc-list-item';
18+
import { Menu } from '@material/mwc-menu';
1019

1120
import '../../action-pane.js';
1221
import './eq-sub-function-editor.js';
13-
import { getChildElementsByTagName } from '../../foundation.js';
22+
import {
23+
getChildElementsByTagName,
24+
newWizardEvent,
25+
SCLTag,
26+
tags,
27+
} from '../../foundation.js';
28+
import { emptyWizard, wizards } from '../../wizards/wizard-library.js';
29+
30+
function childTags(element: Element | null | undefined): SCLTag[] {
31+
if (!element) return [];
32+
33+
return tags[<SCLTag>element.tagName].children.filter(
34+
child => wizards[child].create !== emptyWizard
35+
);
36+
}
1437

1538
/** Pane rendering `EqFunction` element with its children */
1639
@customElement('eq-function-editor')
@@ -27,6 +50,19 @@ export class EqFunctionEditor extends LitElement {
2750
return `${name}${desc ? ` - ${desc}` : ''}${type ? ` (${type})` : ''}`;
2851
}
2952

53+
@query('mwc-menu') addMenu!: Menu;
54+
@query('mwc-icon-button[icon="playlist_add"]') addButton!: IconButton;
55+
56+
private openCreateWizard(tagName: string): void {
57+
const wizard = wizards[<SCLTag>tagName].create(this.element!);
58+
59+
if (wizard) this.dispatchEvent(newWizardEvent(wizard));
60+
}
61+
62+
firstUpdated(): void {
63+
this.addMenu.anchor = <HTMLElement>this.addButton;
64+
}
65+
3066
private renderLNodes(): TemplateResult {
3167
const lNodes = getChildElementsByTagName(this.element, 'LNode');
3268

@@ -52,12 +88,39 @@ export class EqFunctionEditor extends LitElement {
5288
)}`;
5389
}
5490

91+
private renderAddButtons(): TemplateResult[] {
92+
return childTags(this.element).map(
93+
child =>
94+
html`<mwc-list-item value="${child}"
95+
><span>${child}</span></mwc-list-item
96+
>`
97+
);
98+
}
99+
55100
render(): TemplateResult {
56101
return html`<action-pane
57102
label="${this.header}"
58103
icon="functions"
59104
secondary
60105
highlighted
106+
><abbr
107+
slot="action"
108+
style="position:relative;"
109+
title="${translate('add')}"
110+
>
111+
<mwc-icon-button
112+
icon="playlist_add"
113+
@click=${() => (this.addMenu.open = true)}
114+
></mwc-icon-button
115+
><mwc-menu
116+
corner="BOTTOM_RIGHT"
117+
menuCorner="END"
118+
@selected=${(e: Event) => {
119+
const tagName = (<ListItem>(<Menu>e.target).selected).value;
120+
this.openCreateWizard(tagName);
121+
}}
122+
>${this.renderAddButtons()}</mwc-menu
123+
></abbr
61124
>${this.renderLNodes()}${this.renderEqSubFunctions()}</action-pane
62125
>`;
63126
}

src/editors/substation/eq-sub-function-editor.ts

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,34 @@ import {
66
customElement,
77
state,
88
css,
9+
query,
910
} from 'lit-element';
1011

12+
import { translate } from 'lit-translate';
13+
14+
import '@material/mwc-icon-button';
15+
import '@material/mwc-list/mwc-list-item';
16+
import '@material/mwc-menu';
17+
import { IconButton } from '@material/mwc-icon-button';
18+
import { ListItem } from '@material/mwc-list/mwc-list-item';
19+
import { Menu } from '@material/mwc-menu';
20+
1121
import '../../action-pane.js';
12-
import { getChildElementsByTagName } from '../../foundation.js';
22+
import {
23+
getChildElementsByTagName,
24+
newWizardEvent,
25+
SCLTag,
26+
tags,
27+
} from '../../foundation.js';
28+
import { emptyWizard, wizards } from '../../wizards/wizard-library.js';
1329

30+
function childTags(element: Element | null | undefined): SCLTag[] {
31+
if (!element) return [];
32+
33+
return tags[<SCLTag>element.tagName].children.filter(
34+
child => wizards[child].create !== emptyWizard
35+
);
36+
}
1437
/** Pane rendering `EqSubFunction` element with its children */
1538
@customElement('eq-sub-function-editor')
1639
export class EqSubFunctionEditor extends LitElement {
@@ -26,6 +49,31 @@ export class EqSubFunctionEditor extends LitElement {
2649
return `${name}${desc ? ` - ${desc}` : ''}${type ? ` (${type})` : ''}`;
2750
}
2851

52+
@query('mwc-menu') addMenu!: Menu;
53+
@query('mwc-icon-button[icon="playlist_add"]') addButton!: IconButton;
54+
55+
private openCreateWizard(tagName: string): void {
56+
const wizard = wizards[<SCLTag>tagName].create(this.element!);
57+
58+
if (wizard) this.dispatchEvent(newWizardEvent(wizard));
59+
}
60+
61+
firstUpdated(): void {
62+
this.addMenu.anchor = <HTMLElement>this.addButton;
63+
}
64+
65+
private renderLNodes(): TemplateResult {
66+
const lNodes = getChildElementsByTagName(this.element, 'LNode');
67+
68+
return lNodes.length
69+
? html`<div class="container lnode">
70+
${lNodes.map(
71+
lNode => html`<l-node-editor .element=${lNode}></l-node-editor>`
72+
)}
73+
</div>`
74+
: html``;
75+
}
76+
2977
private renderEqSubFunctions(): TemplateResult {
3078
const eqSubFunctions = getChildElementsByTagName(
3179
this.element,
@@ -39,20 +87,35 @@ export class EqSubFunctionEditor extends LitElement {
3987
)}`;
4088
}
4189

42-
private renderLNodes(): TemplateResult {
43-
const lNodes = getChildElementsByTagName(this.element, 'LNode');
44-
45-
return lNodes.length
46-
? html`<div class="container lnode">
47-
${lNodes.map(
48-
lNode => html`<l-node-editor .element=${lNode}></l-node-editor>`
49-
)}
50-
</div>`
51-
: html``;
90+
private renderAddButtons(): TemplateResult[] {
91+
return childTags(this.element).map(
92+
child =>
93+
html`<mwc-list-item value="${child}"
94+
><span>${child}</span></mwc-list-item
95+
>`
96+
);
5297
}
5398

5499
render(): TemplateResult {
55100
return html`<action-pane label="${this.header}" icon="functions" secondary
101+
><abbr
102+
slot="action"
103+
style="position:relative;"
104+
title="${translate('add')}"
105+
>
106+
<mwc-icon-button
107+
icon="playlist_add"
108+
@click=${() => (this.addMenu.open = true)}
109+
></mwc-icon-button
110+
><mwc-menu
111+
corner="BOTTOM_RIGHT"
112+
menuCorner="END"
113+
@selected=${(e: Event) => {
114+
const tagName = (<ListItem>(<Menu>e.target).selected).value;
115+
this.openCreateWizard(tagName);
116+
}}
117+
>${this.renderAddButtons()}</mwc-menu
118+
></abbr
56119
>${this.renderLNodes()}${this.renderEqSubFunctions()}</action-pane
57120
>`;
58121
}

0 commit comments

Comments
 (0)