Skip to content

Commit 51e19a7

Browse files
feat(substation/transformerwinding): add create wizard (openscd#1154)
* feat(../wizard-library.ts):add_create_wizard * feat(../transformerwinding.test.ts):test
1 parent ea59f70 commit 51e19a7

File tree

6 files changed

+258
-4
lines changed

6 files changed

+258
-4
lines changed

src/wizards/generalEquipment.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
Wizard,
1010
WizardActor,
1111
WizardInputElement,
12-
} from '../foundation';
12+
} from '../foundation.js';
1313

1414
export function editGeneralEquipmentWizard(element: Element): Wizard {
1515
const name = element.getAttribute('name');

src/wizards/transformerWinding.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { get, translate } from 'lit-translate';
33

44
import {
55
cloneElement,
6+
createElement,
67
getChildElementsByTagName,
78
getValue,
89
SimpleAction,
@@ -11,6 +12,56 @@ import {
1112
WizardInputElement,
1213
} from '../foundation.js';
1314

15+
function createTransformerWindingAction(parent: Element): WizardActor {
16+
return (inputs: WizardInputElement[]) => {
17+
const transformerWindingAttrs: Record<string, string | null> = {};
18+
const transformerWindingKeys = ['name', 'desc', 'type', 'virtual'];
19+
transformerWindingKeys.forEach(key => {
20+
transformerWindingAttrs[key] = getValue(
21+
inputs.find(i => i.label === key)!
22+
);
23+
});
24+
25+
const transformerWinding = createElement(
26+
parent.ownerDocument,
27+
'TransformerWinding',
28+
transformerWindingAttrs
29+
);
30+
31+
return [{ new: { parent, element: transformerWinding } }];
32+
};
33+
}
34+
35+
export function createTransformerWindingWizard(parent: Element): Wizard {
36+
const name = '';
37+
const desc = null;
38+
const type = null;
39+
const virtual = null;
40+
const reservedNames = Array.from(
41+
parent.querySelectorAll('TransformerWinding')
42+
).map(TransformerWinding => TransformerWinding.getAttribute('name')!);
43+
44+
return [
45+
{
46+
title: get('wizard.title.add', { tagName: 'TransformerWinding' }),
47+
primary: {
48+
icon: 'save',
49+
label: get('save'),
50+
action: createTransformerWindingAction(parent),
51+
},
52+
content: [
53+
...contentTransformerWindingWizard({
54+
name,
55+
desc,
56+
type,
57+
virtual,
58+
reservedNames,
59+
}),
60+
],
61+
},
62+
];
63+
}
64+
1465
function updateTransformerWindingAction(element: Element): WizardActor {
1566
return (inputs: WizardInputElement[]): SimpleAction[] => {
1667
const transformerWindingAttrs: Record<string, string | null> = {};

src/wizards/wizard-library.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ import {
4444
createGeneralEquipmentWizard,
4545
editGeneralEquipmentWizard,
4646
} from './generalEquipment.js';
47-
import { editTransformerWindingWizard } from './transformerWinding.js';
47+
import {
48+
createTransformerWindingWizard,
49+
editTransformerWindingWizard,
50+
} from './transformerWinding.js';
4851

4952
type SclElementWizard = (
5053
element: Element,
@@ -536,7 +539,7 @@ export const wizards: Record<
536539
},
537540
TransformerWinding: {
538541
edit: editTransformerWindingWizard,
539-
create: emptyWizard,
542+
create: createTransformerWindingWizard,
540543
},
541544
TrgOps: {
542545
edit: editTrgOpsWizard,

test/unit/editors/substation/__snapshots__/powertransformer-editor.test.snap.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,17 @@ snapshots["powertransformer-editor rendered as action pane looks like the latest
113113
LNode
114114
</span>
115115
</mwc-list-item>
116+
<mwc-list-item
117+
aria-disabled="false"
118+
mwc-list-item=""
119+
role="menuitem"
120+
tabindex="-1"
121+
value="TransformerWinding"
122+
>
123+
<span>
124+
TransformerWinding
125+
</span>
126+
</mwc-list-item>
116127
<mwc-list-item
117128
aria-disabled="false"
118129
mwc-list-item=""
@@ -223,6 +234,17 @@ snapshots["powertransformer-editor rendered as action pane with EqFunction child
223234
LNode
224235
</span>
225236
</mwc-list-item>
237+
<mwc-list-item
238+
aria-disabled="false"
239+
mwc-list-item=""
240+
role="menuitem"
241+
tabindex="-1"
242+
value="TransformerWinding"
243+
>
244+
<span>
245+
TransformerWinding
246+
</span>
247+
</mwc-list-item>
226248
<mwc-list-item
227249
aria-disabled="false"
228250
mwc-list-item=""
@@ -329,6 +351,17 @@ snapshots["powertransformer-editor rendered as action pane with LNode children l
329351
LNode
330352
</span>
331353
</mwc-list-item>
354+
<mwc-list-item
355+
aria-disabled="false"
356+
mwc-list-item=""
357+
role="menuitem"
358+
tabindex="-1"
359+
value="TransformerWinding"
360+
>
361+
<span>
362+
TransformerWinding
363+
</span>
364+
</mwc-list-item>
332365
<mwc-list-item
333366
aria-disabled="false"
334367
mwc-list-item=""
@@ -437,6 +470,17 @@ snapshots["powertransformer-editor rendered as action pane with SubEquipment chi
437470
LNode
438471
</span>
439472
</mwc-list-item>
473+
<mwc-list-item
474+
aria-disabled="false"
475+
mwc-list-item=""
476+
role="menuitem"
477+
tabindex="-1"
478+
value="TransformerWinding"
479+
>
480+
<span>
481+
TransformerWinding
482+
</span>
483+
</mwc-list-item>
440484
<mwc-list-item
441485
aria-disabled="false"
442486
mwc-list-item=""

test/unit/wizards/__snapshots__/transformerwinding.test.snap.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,57 @@ snapshots["Wizards for SCL TransformerWinding element define an edit wizard that
5555
`;
5656
/* end snapshot Wizards for SCL TransformerWinding element define an edit wizard that looks like the the latest snapshot */
5757

58+
snapshots["Wizards for SCL TransformerWinding element define an create wizard that looks like the the latest snapshot"] =
59+
`<mwc-dialog
60+
defaultaction="next"
61+
heading="[wizard.title.add]"
62+
open=""
63+
style="--mdc-dialog-min-width:calc(100% + 0px)"
64+
>
65+
<div id="wizard-content">
66+
<wizard-textfield
67+
dialoginitialfocus=""
68+
helper="[scl.name]"
69+
label="name"
70+
required=""
71+
validationmessage="[textfield.required]"
72+
>
73+
</wizard-textfield>
74+
<wizard-textfield
75+
disabled=""
76+
helper="[scl.desc]"
77+
label="desc"
78+
nullable=""
79+
>
80+
</wizard-textfield>
81+
<wizard-textfield
82+
disabled=""
83+
helper="[scl.type]"
84+
label="type"
85+
>
86+
</wizard-textfield>
87+
<wizard-checkbox
88+
helper="[scl.virtual]"
89+
label="virtual"
90+
nullable=""
91+
>
92+
</wizard-checkbox>
93+
</div>
94+
<mwc-button
95+
dialogaction="close"
96+
label="[close]"
97+
slot="secondaryAction"
98+
style="--mdc-theme-primary: var(--mdc-theme-error)"
99+
>
100+
</mwc-button>
101+
<mwc-button
102+
icon="save"
103+
label="[save]"
104+
slot="primaryAction"
105+
trailingicon=""
106+
>
107+
</mwc-button>
108+
</mwc-dialog>
109+
`;
110+
/* end snapshot Wizards for SCL TransformerWinding element define an create wizard that looks like the the latest snapshot */
111+

test/unit/wizards/transformerwinding.test.ts

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@ import { MockWizard } from '../../mock-wizard.js';
66

77
import { WizardTextField } from '../../../src/wizard-textfield.js';
88
import {
9+
Create,
10+
isCreate,
911
isReplace,
1012
Replace,
1113
WizardInputElement,
1214
} from '../../../src/foundation.js';
13-
import { editTransformerWindingWizard } from '../../../src/wizards/transformerWinding';
15+
import {
16+
createTransformerWindingWizard,
17+
editTransformerWindingWizard,
18+
} from '../../../src/wizards/transformerWinding';
1419
import { WizardCheckbox } from '../../../src/wizard-checkbox.js';
1520

1621
describe('Wizards for SCL TransformerWinding element', () => {
@@ -124,4 +129,101 @@ describe('Wizards for SCL TransformerWinding element', () => {
124129
);
125130
});
126131
});
132+
133+
describe('define an create wizard that', () => {
134+
beforeEach(async () => {
135+
const wizard = createTransformerWindingWizard(
136+
doc.querySelector('PowerTransformer')!
137+
);
138+
element.workflow.push(() => wizard);
139+
await element.requestUpdate();
140+
141+
inputs = Array.from(element.wizardUI.inputs);
142+
143+
primaryAction = <HTMLElement>(
144+
element.wizardUI.dialog?.querySelector(
145+
'mwc-button[slot="primaryAction"]'
146+
)
147+
);
148+
149+
await element.wizardUI.requestUpdate(); // make sure wizard is rendered
150+
});
151+
152+
it('looks like the the latest snapshot', async () =>
153+
await expect(element.wizardUI.dialog).dom.to.equalSnapshot());
154+
155+
it('does not accept empty name attribute', async () => {
156+
await primaryAction.click();
157+
158+
expect(actionEvent).to.not.have.been.called;
159+
});
160+
161+
it('allows to create required attributes name', async () => {
162+
inputs[0].value = 'someNonEmptyName';
163+
await element.requestUpdate();
164+
await primaryAction.click();
165+
166+
expect(actionEvent).to.be.calledOnce;
167+
const action = actionEvent.args[0][0].detail.action;
168+
expect(action).to.satisfy(isCreate);
169+
const createAction = <Create>action;
170+
171+
expect(createAction.new.element).to.have.attribute(
172+
'name',
173+
'someNonEmptyName'
174+
);
175+
176+
expect(createAction.new.element).to.not.have.attribute('desc');
177+
});
178+
179+
it('allows to create name and non required attribute virtual', async () => {
180+
inputs[0].value = 'someNonEmptyName';
181+
182+
const virtualCheckbox = <WizardCheckbox>(
183+
element.wizardUI.dialog?.querySelector(
184+
'wizard-checkbox[label="virtual"]'
185+
)
186+
);
187+
188+
virtualCheckbox.nullSwitch!.click();
189+
virtualCheckbox.maybeValue = 'true';
190+
await element.requestUpdate();
191+
await primaryAction.click();
192+
193+
expect(actionEvent).to.be.calledOnce;
194+
const action = actionEvent.args[0][0].detail.action;
195+
expect(action).to.satisfy(isCreate);
196+
const createAction = <Create>action;
197+
expect(createAction.new.element).to.have.attribute(
198+
'name',
199+
'someNonEmptyName'
200+
);
201+
expect(createAction.new.element).to.have.attribute('virtual', 'true');
202+
});
203+
204+
it('allows to create name and non required attribute desc', async () => {
205+
inputs[0].value = 'someNonEmptyName';
206+
const descField = <WizardTextField>(
207+
element.wizardUI.dialog?.querySelector('wizard-textfield[label="desc"]')
208+
);
209+
210+
await new Promise(resolve => setTimeout(resolve, 100)); // await animation
211+
descField.nullSwitch!.click();
212+
await element.updateComplete;
213+
inputs[1].value = 'someNonEmptyDesc';
214+
215+
await element.requestUpdate();
216+
await primaryAction.click();
217+
218+
expect(actionEvent).to.be.calledOnce;
219+
const action = actionEvent.args[0][0].detail.action;
220+
expect(action).to.satisfy(isCreate);
221+
const createAction = <Create>action;
222+
223+
expect(createAction.new.element).to.have.attribute(
224+
'desc',
225+
'someNonEmptyDesc'
226+
);
227+
});
228+
});
127229
});

0 commit comments

Comments
 (0)