Skip to content

Commit 6ce2105

Browse files
989 add process (openscd#1219)
* feat(line-editor.ts):unit_test_added * feat(line-editor):add_edit_wizard * feat(line-editor-wizard-editing.test):part-of-test * feat(line-editor_wizard_editing)_continue * feat(line.test,etc):editing_and_testing * feat(line.ts):createLineWizard_added * feat(zeroline-pane):create_Line_added * feat(line.test.ts):create_tests_added * feat(line-editor.ts):remove_line_and_test * feat(line-editor):add_add_button_and_test * feat(process-editor.ts):editor_added * fix(Process.scd):GeneralEquipment_added * fix(Process.scd):GeneralEquipment_added * feat(process-editor):edit_wizard_added * feat(process-editor-wizard-editing.test):added * feat(process-editor-snap):snapshot_updated * feat(process-editor-wizard-editing):added * feat(process.test.ts):test_added * feat(process.ts):create_wizard_added * feat(process.test):test_added * feat(process-editor):delete_added * feat(process-editor):add_added * fix(process.ts):fixed_tagname * fix: fixed snapshot test * fix: substation warning, styling, guess correction --------- Co-authored-by: Steffen van den Driest <[email protected]> Co-authored-by: Stef3st <[email protected]>
1 parent efc3aa1 commit 6ce2105

File tree

6 files changed

+498
-5
lines changed

6 files changed

+498
-5
lines changed

src/editors/Substation.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ export default class SubstationPlugin extends LitElement {
2121

2222
render(): TemplateResult {
2323
return html` <zeroline-pane .doc=${this.doc}></zeroline-pane>
24-
${!this.doc?.querySelector(':root > Substation')
24+
${!this.doc?.querySelector(
25+
':root > Substation, :root > Line, :root > Process'
26+
)
2527
? html`<h1>
2628
<mwc-fab
2729
extended

src/editors/substation/process-editor.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ import {
66
TemplateResult,
77
property,
88
state,
9+
query,
910
} from 'lit-element';
1011

1112
import { translate } from 'lit-translate';
1213

1314
import '@material/mwc-icon';
1415
import '@material/mwc-icon-button';
1516
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';
1620

1721
import './conducting-equipment-editor.js';
1822
import './function-editor.js';
@@ -28,9 +32,19 @@ import {
2832
getChildElementsByTagName,
2933
newActionEvent,
3034
newWizardEvent,
35+
SCLTag,
36+
tags,
3137
} from '../../foundation.js';
3238

33-
import { wizards } from '../../wizards/wizard-library.js';
39+
import { emptyWizard, wizards } from '../../wizards/wizard-library.js';
40+
41+
function childTags(element: Element | null | undefined): SCLTag[] {
42+
if (!element) return [];
43+
44+
return tags[<SCLTag>element.tagName].children.filter(
45+
child => wizards[child].create !== emptyWizard
46+
);
47+
}
3448

3549
@customElement('process-editor')
3650
export class ProcessEditor extends LitElement {
@@ -52,11 +66,20 @@ export class ProcessEditor extends LitElement {
5266
return `${name} ${desc ? `—${desc}` : ''}`;
5367
}
5468

69+
@query('mwc-menu') addMenu!: Menu;
70+
@query('mwc-icon-button[icon="playlist_add"]') addButton!: IconButton;
71+
5572
private openEditWizard(): void {
5673
const wizard = wizards['Process'].edit(this.element);
5774
if (wizard) this.dispatchEvent(newWizardEvent(wizard));
5875
}
5976

77+
private openCreateWizard(tagName: string): void {
78+
const wizard = wizards[<SCLTag>tagName].create(this.element!);
79+
80+
if (wizard) this.dispatchEvent(newWizardEvent(wizard));
81+
}
82+
6083
private renderConductingEquipments(): TemplateResult {
6184
const ConductingEquipments = getChildElementsByTagName(
6285
this.element,
@@ -154,6 +177,20 @@ export class ProcessEditor extends LitElement {
154177
: html``;
155178
}
156179

180+
private renderAddButtons(): TemplateResult[] {
181+
return childTags(this.element).map(
182+
child =>
183+
html`<mwc-list-item value="${child}"
184+
><span>${child}</span></mwc-list-item
185+
>`
186+
);
187+
}
188+
189+
updated(): void {
190+
if (this.addMenu && this.addButton)
191+
this.addMenu.anchor = <HTMLElement>this.addButton;
192+
}
193+
157194
remove(): void {
158195
if (this.element.parentElement)
159196
this.dispatchEvent(
@@ -180,6 +217,25 @@ export class ProcessEditor extends LitElement {
180217
@click=${() => this.remove()}
181218
></mwc-icon-button>
182219
</abbr>
220+
<abbr
221+
slot="action"
222+
style="position:relative;"
223+
title="${translate('add')}"
224+
>
225+
<mwc-icon-button
226+
icon="playlist_add"
227+
@click=${() => (this.addMenu.open = true)}
228+
></mwc-icon-button
229+
><mwc-menu
230+
corner="BOTTOM_RIGHT"
231+
menuCorner="END"
232+
@action=${(e: Event) => {
233+
const tagName = (<ListItem>(<Menu>e.target).selected).value;
234+
this.openCreateWizard(tagName);
235+
}}
236+
>${this.renderAddButtons()}</mwc-menu
237+
></abbr
238+
>
183239
${this.renderConductingEquipments()}${this.renderGeneralEquipments()}${this.renderFunctions()}${this.renderLNodes()}
184240
${this.renderLines()} ${this.renderSubstations()}${this.renderProcesses()}
185241
</action-pane>`;

src/editors/substation/zeroline-pane.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,13 @@ export class ZerolinePane extends LitElement {
148148
></substation-editor>`
149149
)}
150150
</section>`
151-
: html`<h1>
151+
: !this.doc?.querySelector(':root > Line, :root > Process')
152+
? html`<h1>
152153
<span style="color: var(--base1)"
153154
>${translate('substation.missing')}</span
154155
>
155-
</h1>`;
156+
</h1>`
157+
: html``;
156158
}
157159

158160
renderLines(): TemplateResult {
@@ -305,6 +307,8 @@ export class ZerolinePane extends LitElement {
305307
306308
section {
307309
padding: 8px 12px 16px;
310+
display: grid;
311+
gap: 12px;
308312
}
309313
310314
abbr {

src/wizards/substation.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ export function createAction(parent: Element): WizardActor {
6363
}
6464

6565
export function createSubstationWizard(parent: Element): Wizard {
66-
const guessable = parent.querySelector('Substation') === null;
66+
const guessable =
67+
parent.ownerDocument.querySelector('Substation') === null &&
68+
parent.tagName === 'SCL';
6769

6870
return [
6971
{

test/integration/editors/substation/process-editor-wizard-editing.test.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,48 @@ import { expect, fixture, html } from '@open-wc/testing';
22

33
import '../../../mock-wizard-editor.js';
44
import { MockWizardEditor } from '../../../mock-wizard-editor.js';
5+
import { ListItemBase } from '@material/mwc-list/mwc-list-item-base';
56

67
import '../../../../src/editors/substation/process-editor.js';
78
import { ProcessEditor } from '../../../../src/editors/substation/process-editor.js';
89
import { WizardTextField } from '../../../../src/wizard-textfield.js';
10+
import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js';
11+
12+
const openAndCancelMenu: (
13+
parent: MockWizardEditor,
14+
element: ProcessEditor
15+
) => Promise<void> = (
16+
parent: MockWizardEditor,
17+
element: ProcessEditor
18+
): Promise<void> =>
19+
new Promise(async resolve => {
20+
expect(parent.wizardUI.dialog).to.be.undefined;
21+
22+
element?.shadowRoot
23+
?.querySelector<MenuBase>("mwc-icon-button[icon='playlist_add']")!
24+
.click();
25+
const lnodMenuItem: ListItemBase =
26+
element?.shadowRoot?.querySelector<ListItemBase>(
27+
`mwc-list-item[value='LNode']`
28+
)!;
29+
lnodMenuItem.click();
30+
await new Promise(resolve => setTimeout(resolve, 100)); // await animation
31+
32+
expect(parent.wizardUI.dialog).to.exist;
33+
34+
const secondaryAction: HTMLElement = <HTMLElement>(
35+
parent.wizardUI.dialog?.querySelector(
36+
'mwc-button[slot="secondaryAction"][dialogaction="close"]'
37+
)
38+
);
39+
40+
secondaryAction.click();
41+
await new Promise(resolve => setTimeout(resolve, 100)); // await animation
42+
43+
expect(parent.wizardUI.dialog).to.be.undefined;
44+
45+
return resolve();
46+
});
947

1048
describe('process-editor wizarding editing integration', () => {
1149
let doc: XMLDocument;
@@ -146,5 +184,36 @@ describe('process-editor wizarding editing integration', () => {
146184
.exist;
147185
});
148186
});
187+
describe('Open add wizard', () => {
188+
let doc: XMLDocument;
189+
let parent: MockWizardEditor;
190+
let element: ProcessEditor | null;
191+
192+
beforeEach(async () => {
193+
doc = await fetch('/test/testfiles/editors/substation/Process.scd')
194+
.then(response => response.text())
195+
.then(str => new DOMParser().parseFromString(str, 'application/xml'));
196+
parent = <MockWizardEditor>(
197+
await fixture(
198+
html`<mock-wizard-editor
199+
><process-editor
200+
.element=${doc.querySelector(
201+
'Process[name="ProcessGenConduct"]'
202+
)}
203+
></process-editor
204+
></mock-wizard-editor>`
205+
)
206+
);
207+
208+
element = parent.querySelector('process-editor');
209+
210+
await parent.updateComplete;
211+
});
212+
213+
it('Should open the same wizard for the second time', async () => {
214+
await openAndCancelMenu(parent, element!);
215+
await openAndCancelMenu(parent, element!);
216+
});
217+
});
149218
});
150219
});

0 commit comments

Comments
 (0)