Skip to content

Commit 2b759ce

Browse files
committed
feat: provide descriptions against FCDOs and FCDAs in dataset view and picker (closes #6)
1 parent 2fc2b81 commit 2b759ce

File tree

61 files changed

+1177
-124
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1177
-124
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
## testing
1313
/coverage/
14+
screenshots/**/failed/
1415

1516
## temp folders
1617
/.tmp/

demo/index.html

-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@
8080
}
8181
};
8282
</script>
83-
8483
<script type="module">
8584
import '@openenergytools/open-scd-core/open-scd.js';
8685

editors/dataset/data-set-editor.test.ts

+42-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import { sendKeys, sendMouse, setViewport } from '@web/test-runner-commands';
55

66
import { visualDiff } from '@web/test-runner-visual-regression';
77

8-
import { dataSetDoc, otherDataSetDoc } from './data-set-editor.testfiles.js';
8+
import {
9+
dataSetDoc,
10+
otherDataSetDoc,
11+
dataSetDocWithDescs,
12+
} from './data-set-editor.testfiles.js';
913

1014
import { DataSetEditor } from './data-set-editor.js';
1115

@@ -64,7 +68,7 @@ describe('DataSet editor component', () => {
6468
await setViewport({ width: 1900, height: 1200 });
6569

6670
await editor.updateComplete;
67-
await timeout(200);
71+
await timeout(300);
6872
await visualDiff(
6973
editor,
7074
`dataset/data-set-editor/#2 Unselected DataSet 1900x1200`
@@ -155,4 +159,40 @@ describe('DataSet editor component', () => {
155159
});
156160
});
157161
});
162+
163+
describe('with SCL document containing DataSet descriptions', () => {
164+
let editor: DataSetEditor;
165+
beforeEach(async () => {
166+
const doc = new DOMParser().parseFromString(
167+
dataSetDocWithDescs,
168+
'application/xml'
169+
);
170+
// eslint-disable-next-line prefer-const
171+
editor = await fixture(
172+
html`<data-set-editor .doc="${doc}"></data-set-editor>`
173+
);
174+
175+
document.body.prepend(editor);
176+
});
177+
178+
afterEach(async () => {
179+
editor.remove();
180+
});
181+
182+
it('looks like the latest snapshot', async () => {
183+
await setViewport({ width: 1200, height: 1600 });
184+
editor.selectDataSetButton.click();
185+
await editor.updateComplete;
186+
await timeout(300);
187+
188+
await sendMouse({ type: 'click', position: [40, 225] });
189+
await timeout(300);
190+
await editor.updateComplete;
191+
192+
await visualDiff(
193+
editor,
194+
`dataset/data-set-editor/#9 Document shows descriptions in DataSet 1200x1600`
195+
);
196+
});
197+
});
158198
});

editors/dataset/data-set-editor.testfiles.ts

+91
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,94 @@ export const otherDataSetDoc = `
258258
</DataTypeTemplates>
259259
</SCL>
260260
`;
261+
262+
export const dataSetDocWithDescs = `
263+
<SCL xmlns="http://www.iec.ch/61850/2003/SCL" version="2007" revision="B" release="4">
264+
<Header id="ReportControl with description" version="1" revision="1" toolID="OpenSCD, tada!" nameStructure="IEDName">
265+
</Header>
266+
<IED name="IED">
267+
<Services>
268+
<ConfDataSet max="10" maxAttributes="10" />
269+
</Services>
270+
<AccessPoint name="AP1">
271+
<Server>
272+
<Authentication></Authentication>
273+
<LDevice inst="ldInst1" desc="First logical device">
274+
<LN0 lnClass="LLN0" inst="" lnType="LLN0">
275+
<DataSet name="datSet">
276+
<FCDA ldInst="ldInst1" prefix="" lnClass="LLN0" doName="Beh" daName="stVal" fc="ST" />
277+
<FCDA ldInst="ldInst1" prefix="" lnClass="LLN0" doName="Beh" daName="q" fc="ST" />
278+
<FCDA ldInst="ldInst1" prefix="" lnClass="LLN0" doName="Mod" daName="t" fc="ST" />
279+
<FCDA ldInst="ldInst1" prefix="" lnClass="LLN0" doName="Mod" daName="stVal" fc="ST" />
280+
<FCDA ldInst="ldInst1" prefix="" lnClass="LLN0" doName="Mod" daName="q" fc="ST" />
281+
<FCDA ldInst="ldInst1" prefix="" lnClass="LLN0" doName="Mod" daName="t" fc="ST" />
282+
<FCDA ldInst="ldInst1" prefix="prefix" lnClass="MMXU" lnInst="1" doName="PhV.phsA" daName="cVal.mag.f" fc="MX" />
283+
<FCDA ldInst="ldInst1" prefix="prefix" lnClass="MMXU" lnInst="1" doName="PhV.phsA" daName="q" fc="MX" />
284+
<FCDA ldInst="ldInst1" prefix="prefix" lnClass="MMXU" lnInst="1" doName="PhV.phsA" daName="t" fc="MX" />
285+
<FCDA ldInst="ldInst1" prefix="prefix" lnClass="MMXU" lnInst="1" doName="PhV.phsB" fc="MX" />
286+
</DataSet>
287+
<DOI name="Beh" desc="Behaviour"></DOI>
288+
<DOI name="Mod">
289+
<DAI name="d">
290+
<Val>Mode</Val>
291+
</DAI>
292+
293+
</DOI>
294+
</LN0>
295+
<LN prefix="prefix" lnClass="MMXU" inst="1" lnType="MMXU" desc="Line">
296+
<DOI name="PhV" desc="Phase voltages">
297+
<SDI name="phsA">
298+
<SDI name="cVal" desc="complex value">
299+
<SDI name="mag" desc="magnitude">
300+
<DAI name="f" desc="fundamental" />
301+
</SDI>
302+
</SDI>
303+
<DAI name="d">
304+
<Val>Red Phase</Val>
305+
</DAI>
306+
</SDI>
307+
<SDI name="phsB" desc="Phase B"></SDI>
308+
</DOI>
309+
</LN>
310+
</LDevice>
311+
</Server>
312+
</AccessPoint>
313+
</IED>
314+
<DataTypeTemplates>
315+
<LNodeType lnClass="LLN0" id="LLN0">
316+
<DO name="Beh" type="ENS"/>
317+
</LNodeType>
318+
<LNodeType lnClass="MMXU" id="MMXU">
319+
<DO name="PhV" type="WYE"/>
320+
</LNodeType>
321+
<DOType cdc="ENS" id="ENS">
322+
<DA name="stVal" bType="Enum" fc="ST" />
323+
<DA name="q" bType="Quality" fc="ST" />
324+
<DA name="t" bType="Timestamp" fc="ST" />
325+
<DA name="dc" bType="VisString255" fc="DC" />
326+
</DOType>
327+
<DOType cdc="WYE" id="WYE">
328+
<SDO name="phsA" type="CMV" />
329+
<SDO name="phsB" type="CMV" />
330+
<SDO name="phsC" type="CMV" />
331+
<SDO name="phRes" type="CustomWYE" />
332+
</DOType>
333+
<DOType cdc="WYE" id="CustomWYE">
334+
<SDO name="phsA" type="CMV" />
335+
</DOType>
336+
<DOType cdc="CMV" id="CMV">
337+
<DA name="cVal" bType="Struct" type="Vector" fc="MX"/>
338+
<DA name="q" bType="Quality" fc="MX" />
339+
<DA name="t" bType="Timestamp" fc="MX" />
340+
<DA name="d" bType="VisString255" fc="DC" />
341+
</DOType>
342+
<DAType id="Vector">
343+
<BDA name="mag" bType="Struct" type="AnalogueValue" />
344+
<BDA name="ang" bType="Struct" type="AnalogueValue" />
345+
</DAType>
346+
<DAType id="AnalogueValue">
347+
<BDA name="f" bType="FLOAT32" />
348+
</DAType>
349+
</DataTypeTemplates>
350+
</SCL>
351+
`;

editors/dataset/data-set-element-editor.spec.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe('DataSet element editor', () => {
4646
editor.onInputChange();
4747
await timeout(50);
4848

49-
await editor.saveButton.click();
49+
editor.saveButton.click();
5050

5151
expect(editEvent).to.have.be.calledOnce;
5252

@@ -61,7 +61,7 @@ describe('DataSet element editor', () => {
6161
editor.onInputChange();
6262
await timeout(50);
6363

64-
await editor.saveButton.click();
64+
editor.saveButton.click();
6565

6666
expect(editEvent).to.have.be.calledOnce;
6767
expect(editEvent.args[0][0].detail.edit[0].attributes.desc).to.equal(
@@ -81,7 +81,7 @@ describe('DataSet element editor', () => {
8181
await setViewport({ width: 800, height: 1200 });
8282
await sendMouse({ type: 'click', position: [740, 650] }); // open menu
8383
await timeout(500); // await menu to be opened
84-
await sendMouse({ type: 'click', position: [740, 700] }); // click on move up
84+
await sendMouse({ type: 'click', position: [740, 736] }); // click on move up
8585

8686
const toBeMovedFCDA = dataSet.querySelectorAll(':scope > FCDA')[1];
8787
const reference = toBeMovedFCDA.previousElementSibling;
@@ -100,7 +100,7 @@ describe('DataSet element editor', () => {
100100
await setViewport({ width: 800, height: 1200 });
101101
await sendMouse({ type: 'click', position: [740, 650] }); // open menu
102102
await timeout(500); // await menu to be opened
103-
await sendMouse({ type: 'click', position: [740, 750] }); // click on move down
103+
await sendMouse({ type: 'click', position: [740, 792] }); // click on move down
104104

105105
const toBeMovedFCDA = dataSet.querySelectorAll(':scope > FCDA')[1];
106106
const reference = toBeMovedFCDA.nextElementSibling?.nextElementSibling;

editors/dataset/data-set-element-editor.test.ts

+90-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import { sendMouse, setViewport } from '@web/test-runner-commands';
55

66
import { visualDiff } from '@web/test-runner-visual-regression';
77

8-
import { dataSetDoc } from './data-set-editor.testfiles.js';
8+
import {
9+
dataSetDoc,
10+
dataSetDocWithDescs,
11+
} from './data-set-editor.testfiles.js';
912

1013
import { DataSetElementEditor } from './data-set-element-editor.js';
1114

@@ -35,7 +38,7 @@ describe('DataSet element editor component', () => {
3538

3639
it('looks like the latest snapshot', async () => {
3740
await editor.updateComplete;
38-
await timeout(200);
41+
await timeout(300);
3942
await visualDiff(
4043
editor,
4144
`dataset/data-set-element-editor/#1 Missing DataSet`
@@ -318,6 +321,49 @@ describe('DataSet element editor component', () => {
318321
});
319322
});
320323

324+
describe('Allows to add DataAttributes with descriptions through TreeGrid', () => {
325+
let editor: DataSetElementEditor;
326+
beforeEach(async () => {
327+
await setViewport({ width: 1900, height: 1200 });
328+
329+
const dataSet = new DOMParser()
330+
.parseFromString(dataSetDocWithDescs, 'application/xml')
331+
.querySelector('LDevice[inst="ldInst1"] DataSet')!;
332+
333+
editor = await fixture(
334+
html`<data-set-element-editor
335+
.element="${dataSet}"
336+
></data-set-element-editor>`
337+
);
338+
document.body.prepend(editor);
339+
});
340+
341+
afterEach(async () => {
342+
editor.remove();
343+
});
344+
345+
it('looks like the latest snapshot', async () => {
346+
editor.daPicker.paths = [
347+
[
348+
'LDevice: IED>>ldInst1',
349+
'LN: IED>>ldInst1>prefix MMXU 1',
350+
'DO: #MMXU>PhV',
351+
'SDO: #WYE>phsA',
352+
'DA: #CMV>cVal',
353+
'BDA: #Vector>mag',
354+
'BDA: #AnalogueValue>f',
355+
],
356+
];
357+
editor.daPickerButton.click();
358+
await editor.updateComplete;
359+
await timeout(200);
360+
await visualDiff(
361+
editor,
362+
`dataset/data-set-element-editor/#10 DataAttribute picker with descriptions`
363+
);
364+
});
365+
});
366+
321367
describe('Allows to add DataObjects through TreeGrid', () => {
322368
let editor: DataSetElementEditor;
323369
beforeEach(async () => {
@@ -359,6 +405,47 @@ describe('DataSet element editor component', () => {
359405
});
360406
});
361407

408+
describe('Allows to add DataObjects with descriptions through TreeGrid', () => {
409+
let editor: DataSetElementEditor;
410+
beforeEach(async () => {
411+
await setViewport({ width: 1900, height: 1200 });
412+
413+
const dataSet = new DOMParser()
414+
.parseFromString(dataSetDocWithDescs, 'application/xml')
415+
.querySelector('LDevice[inst="ldInst1"] DataSet')!;
416+
417+
editor = await fixture(
418+
html`<data-set-element-editor
419+
.element="${dataSet}"
420+
></data-set-element-editor>`
421+
);
422+
document.body.prepend(editor);
423+
});
424+
425+
afterEach(async () => {
426+
editor.remove();
427+
});
428+
429+
it('looks like the latest snapshot', async () => {
430+
editor.doPicker.paths = [
431+
[
432+
'LDevice: IED>>ldInst1',
433+
'LN: IED>>ldInst1>prefix MMXU 1',
434+
'DO: #MMXU>PhV',
435+
'SDO: #WYE>phsA',
436+
'FC: MX',
437+
],
438+
];
439+
editor.doPickerButton.click();
440+
await editor.updateComplete;
441+
await timeout(200);
442+
await visualDiff(
443+
editor,
444+
`dataset/data-set-element-editor/#11 DataObject picker with descriptions`
445+
);
446+
});
447+
});
448+
362449
describe('Allows to re-order FCDA child elements', () => {
363450
let editor: DataSetElementEditor;
364451
beforeEach(async () => {
@@ -417,7 +504,7 @@ describe('DataSet element editor component', () => {
417504
editor.inputs![0].value = 'someNewDataSetName';
418505
editor.inputs![1].nullSwitch?.click();
419506

420-
await editor.requestUpdate();
507+
await editor.updateComplete;
421508
await timeout(500);
422509
await visualDiff(
423510
editor,

editors/dataset/data-set-element-editor.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
updateDataSet,
2525
} from '@openenergytools/scl-lib';
2626

27-
import { addFCDAs, addFCDOs } from './foundation.js';
27+
import { addFCDAs, addFCDOs, getFcdaInstDesc } from './foundation.js';
2828
import { dataAttributeTree } from './dataAttributePicker.js';
2929
import { dataObjectTree } from './dataObjectPicker.js';
3030

@@ -275,16 +275,23 @@ export class DataSetElementEditor extends ScopedElementsMixin(LitElement) {
275275
},
276276
});
277277

278+
const description = Object.values(getFcdaInstDesc(fcda))
279+
.flat(Infinity as 1)
280+
.join(' > ');
281+
278282
return {
279-
headline: `${doName}${daName ? `.${daName} [${fc}]` : ` [${fc}]`}`,
280-
supportingText: `${ldInst}/${prefix}${lnClass}${lnInst}`,
283+
headline: `${ldInst}/${prefix}${lnClass}${lnInst}.${doName}${
284+
daName ? `.${daName} [${fc}]` : ` [${fc}]`
285+
}`,
286+
supportingText: description,
281287
actions,
282288
};
283289
});
284290

285291
return html`<action-list
286292
class="list fcda"
287293
.items=${items}
294+
height="84"
288295
filterable
289296
searchhelper="Filter Data"
290297
></action-list>`;
@@ -382,7 +389,7 @@ export class DataSetElementEditor extends ScopedElementsMixin(LitElement) {
382389
id="${identity(this.element)}"
383390
label="desc"
384391
.value=${this.desc}
385-
supportingText="DateSet Description"
392+
supportingText="DataSet Description"
386393
nullable
387394
@input=${() => this.onInputChange()}
388395
>

0 commit comments

Comments
 (0)