Skip to content

Commit 5d07886

Browse files
feat(public/templates): add logical node classes (#320)
* feat(public/templates): add more LNodeTypes and its children * fix(public/templates): missing references * fix(public/templates): found by the validators :) * fix(templates): fix reference issues on create DataTypeTemplates * feat(lnodetype-wizard): allow multiple lnClass from templates * test(templates): update snapshots * test(templates): update tests on templates update * feat(public/templates): add LLN0 and LPHD
1 parent 9bb51ec commit 5d07886

File tree

9 files changed

+1890
-415
lines changed

9 files changed

+1890
-415
lines changed

__snapshots__/DAType wizards.md

Lines changed: 260 additions & 52 deletions
Large diffs are not rendered by default.

__snapshots__/DOType wizards.md

Lines changed: 366 additions & 46 deletions
Large diffs are not rendered by default.

__snapshots__/LNodeType wizards.md

Lines changed: 466 additions & 7 deletions
Large diffs are not rendered by default.

public/xml/templates.scd

Lines changed: 703 additions & 199 deletions
Large diffs are not rendered by default.

src/editors/Templates.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { LitElement, html, TemplateResult, property, css } from 'lit-element';
22
import { translate } from 'lit-translate';
33

44
import {
5+
createElement,
56
getReference,
67
identity,
78
newActionEvent,
@@ -125,7 +126,7 @@ export default class TemplatesPlugin extends LitElement {
125126
newActionEvent({
126127
new: {
127128
parent: this.doc.documentElement,
128-
element: this.doc.createElement('DataTypeTemplates'),
129+
element: createElement(this.doc, 'DataTypeTemplates', {}),
129130
reference: getReference(
130131
this.doc.documentElement,
131132
'DataTypeTemplates'

src/editors/templates/lnodetype-wizard.ts

Lines changed: 44 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
Create,
77
createElement,
88
EditorAction,
9+
getChildElementsByTagName,
910
getReference,
1011
getValue,
1112
identity,
@@ -378,29 +379,25 @@ function startLNodeTypeCreate(
378379

379380
const desc = getValue(inputs.find(i => i.label === 'desc')!);
380381

381-
const lnClass = (<Select>inputs.find(i => i.label === 'lnClass'))?.selected
382+
const value = (<Select>inputs.find(i => i.label === 'lnClass'))?.selected
382383
?.value;
383-
const templateLNodeType = templates.querySelector(
384-
`LNodeType[lnClass="${lnClass}"]`
385-
);
386-
387-
const autoimport =
388-
wizard.shadowRoot?.querySelector<Switch>('#autoimport')?.checked;
384+
const templateLNodeType = value
385+
? templates.querySelector(selector('LNodeType', value))
386+
: null;
389387

390-
const newLNodeType =
391-
templateLNodeType && autoimport
392-
? <Element>templateLNodeType!.cloneNode(true)
393-
: createElement(parent.ownerDocument, 'LNodeType', {
394-
lnClass: lnClass ?? '',
395-
});
388+
const newLNodeType = templateLNodeType
389+
? <Element>templateLNodeType!.cloneNode(true)
390+
: createElement(parent.ownerDocument, 'LNodeType', {
391+
lnClass: value ?? '',
392+
});
396393

397394
newLNodeType.setAttribute('id', id);
398395
if (desc) newLNodeType.setAttribute('desc', desc);
399396

400-
if (autoimport && templateLNodeType)
397+
if (templateLNodeType)
401398
return addPredefinedLNodeType(parent, newLNodeType, templateLNodeType);
402399

403-
const allDo = getAllDataObjects(nsd74, lnClass!);
400+
const allDo = getAllDataObjects(nsd74, value!);
404401
wizard.dispatchEvent(
405402
newWizardEvent(createLNodeTypeHelperWizard(parent, newLNodeType, allDo))
406403
);
@@ -411,54 +408,25 @@ function startLNodeTypeCreate(
411408
}
412409

413410
function onLnClassChange(e: Event, templates: XMLDocument): void {
414-
const lnClass = (<Select>e.target).selected?.value;
415-
const autoimport = (<Select>e.target).parentElement!.querySelector<Switch>(
416-
'#autoimport'
417-
)!;
411+
const identity = (<Select>e.target).selected?.value;
412+
const lnodetype = identity
413+
? templates.querySelector(selector('LNodeType', identity))
414+
: null;
418415

419416
const primaryAction =
420417
(<Element>e.target)
421418
?.closest('mwc-dialog')
422419
?.querySelector('mwc-button[slot="primaryAction"]') ?? null;
423420

424-
autoimport.parentElement!.removeAttribute('style');
425-
426-
if (templates.querySelector(`LNodeType[lnClass="${lnClass}"]`)) {
427-
autoimport.checked = true;
428-
autoimport.disabled = false;
429-
autoimport.parentElement!.setAttribute(
430-
'label',
431-
get('lnodetype.autoimport')
432-
);
421+
if (lnodetype) {
433422
primaryAction?.setAttribute('label', get('save'));
434423
primaryAction?.setAttribute('icon', 'save');
435424
} else {
436-
autoimport.checked = false;
437-
autoimport.disabled = true;
438-
autoimport.parentElement!.setAttribute(
439-
'label',
440-
get('lnodetype.missinglnclass')
441-
);
442425
primaryAction?.setAttribute('label', get('next') + '...');
443426
primaryAction?.setAttribute('icon', '');
444427
}
445428
}
446429

447-
function toggleAutoimport(e: Event): void {
448-
const autoimport = <Switch>e.target;
449-
const primaryAction =
450-
(<Element>e.target)
451-
?.closest('mwc-dialog')
452-
?.querySelector('mwc-button[slot="primaryAction"]') ?? null;
453-
454-
autoimport.checked
455-
? primaryAction?.setAttribute('label', get('save'))
456-
: primaryAction?.setAttribute('label', get('next') + '...');
457-
autoimport.checked
458-
? primaryAction?.setAttribute('icon', 'save')
459-
: primaryAction?.setAttribute('icon', '');
460-
}
461-
462430
export function createLNodeTypeWizard(
463431
parent: Element,
464432
templates: Document,
@@ -484,6 +452,33 @@ export function createLNodeTypeWizard(
484452
dialogInitialFocus
485453
@selected=${(e: Event) => onLnClassChange(e, templates)}
486454
>
455+
<mwc-list-item noninteractive
456+
>Pre-defined lnClasses from templates</mwc-list-item
457+
>
458+
<li divider role="separator"></li>
459+
${Array.from(templates.querySelectorAll('LNodeType')).map(
460+
lnodetpye => {
461+
const lnClass = lnodetpye.getAttribute('lnClass') ?? '';
462+
const desc = lnodetpye.getAttribute('desc') ?? '';
463+
464+
return html`<mwc-list-item
465+
twoline
466+
style="min-width:200px"
467+
graphic="icon"
468+
hasMeta
469+
value="${identity(lnodetpye)}"
470+
><span>${lnClass}</span>
471+
<span slot="secondary">${desc}</span>
472+
<span slot="meta"
473+
>${getChildElementsByTagName(lnodetpye, 'DO').length}</span
474+
>
475+
</mwc-list-item>`;
476+
}
477+
)}
478+
<mwc-list-item noninteractive
479+
>Empty lnClasses from IEC 61850-7-4</mwc-list-item
480+
>
481+
<li divider role="separator"></li>
487482
${Array.from(nsd74.querySelectorAll('LNClasses > LNClass')).map(
488483
lnClass => {
489484
const className = lnClass.getAttribute('name') ?? '';
@@ -500,13 +495,6 @@ export function createLNodeTypeWizard(
500495
}
501496
)}
502497
</mwc-select>`,
503-
html`<mwc-formfield style="display:none"
504-
><mwc-switch
505-
id="autoimport"
506-
@change=${(e: Event) => toggleAutoimport(e)}
507-
></mwc-switch
508-
><mwc-formfield></mwc-formfield
509-
></mwc-formfield>`,
510498
html`<wizard-textfield
511499
label="id"
512500
helper="${translate('scl.id')}"

test/integration/editors/templates/datype-wizarding.test.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ describe('DAType wizards', () => {
8282
expect(element?.nextElementSibling?.tagName).to.equal('DAType');
8383
expect(element?.previousElementSibling?.tagName).to.equal('DOType');
8484
});
85-
it('recursevly add missing! subsequent EnumType elements', async () => {
85+
it('recursively add missing! subsequent EnumType elements', async () => {
8686
expect(doc.querySelector('DAType[id="myOriginator"]')).to.not.exist;
8787
selector.value = 'OpenSCD_Originator';
8888
idField.maybeValue = 'myOriginator';
@@ -96,18 +96,19 @@ describe('DAType wizards', () => {
9696
doc.querySelectorAll('EnumType[id="OriginatorCategoryKind"]').length
9797
).to.equal(1);
9898
});
99-
it('recursevly add missing! subsequent DAType elements', async () => {
100-
expect(doc.querySelector('DAType[id="OpenSCD_AnalogueValueFloat32"]')).to
99+
it('recursively add missing! subsequent DAType elements', async () => {
100+
expect(doc.querySelector('DAType[id="OpenSCD_AnalogueValue_FLOAT32"]')).to
101101
.not.exist;
102102
selector.value = 'OpenSCD_RangeConfig';
103103
idField.maybeValue = 'myOriginator';
104104
await parent.requestUpdate();
105105
primayAction.click();
106106
await parent.updateComplete;
107-
expect(doc.querySelector('DAType[id="OpenSCD_AnalogueValueFloat32"]')).to
107+
expect(doc.querySelector('DAType[id="OpenSCD_AnalogueValue_FLOAT32"]')).to
108108
.exist;
109109
expect(
110-
doc.querySelectorAll('DAType[id="OpenSCD_AnalogueValueFloat32"]').length
110+
doc.querySelectorAll('DAType[id="OpenSCD_AnalogueValue_FLOAT32"]')
111+
.length
111112
).to.equal(1);
112113
});
113114
});

test/integration/editors/templates/dotype-wizarding.test.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ describe('DOType wizards', () => {
8181
expect(element?.nextElementSibling?.tagName).to.equal('DOType');
8282
expect(element?.previousElementSibling?.tagName).to.equal('LNodeType');
8383
});
84-
it('recursevly add missing! subsequent EnumType elements', async () => {
84+
it('recursively add missing! subsequent EnumType elements', async () => {
8585
expect(doc.querySelector('DOType[id="myENSHealth"]')).to.not.exist;
8686
expect(doc.querySelector('EnumType[id="HealthKind"]')).to.not.exist;
87-
selector.value = 'OpenSCD_ENSHealth';
87+
selector.value = 'OpenSCD_ENS_Health';
8888
idField.maybeValue = 'myENSHealth';
8989
await parent.requestUpdate();
9090
primayAction.click();
@@ -95,19 +95,18 @@ describe('DOType wizards', () => {
9595
1
9696
);
9797
});
98-
it('recursevly add missing! subsequent DAType elements', async () => {
99-
expect(doc.querySelector('DAType[id="OpenSCD_AnalogueValueFloat32"]')).to
98+
it('recursively add missing! subsequent DAType elements', async () => {
99+
expect(doc.querySelector('DAType[id="OpenSCD_AnalogueValue_INT32"]')).to
100100
.not.exist;
101-
selector.value = 'OpenSCD_MVinst';
101+
selector.value = 'OpenSCD_MV_int';
102102
idField.maybeValue = 'myMV';
103103
await parent.requestUpdate();
104104
primayAction.click();
105105
await parent.updateComplete;
106-
await new Promise(resolve => setTimeout(resolve, 1000)); // await animation
107-
expect(doc.querySelector('DAType[id="OpenSCD_AnalogueValueFloat32"]')).to
106+
expect(doc.querySelector('DAType[id="OpenSCD_AnalogueValue_INT32"]')).to
108107
.exist;
109108
expect(
110-
doc.querySelectorAll('DAType[id="OpenSCD_AnalogueValueFloat32"]').length
109+
doc.querySelectorAll('DAType[id="OpenSCD_AnalogueValue_INT32"]').length
111110
).to.equal(1);
112111
});
113112
});

0 commit comments

Comments
 (0)