@omicronenergy/oscd-scl-dialogs 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +4 -2
  3. package/custom-elements.json +292 -3
  4. package/dist/OscdSclDialogs.d.ts +2 -0
  5. package/dist/OscdSclDialogs.js +62 -12
  6. package/dist/OscdSclDialogs.js.map +1 -1
  7. package/dist/wizards/dataset.d.ts +2 -0
  8. package/dist/wizards/dataset.js +86 -0
  9. package/dist/wizards/dataset.js.map +1 -0
  10. package/dist/wizards/dataset.spec.d.ts +1 -0
  11. package/dist/wizards/dataset.spec.js +240 -0
  12. package/dist/wizards/dataset.spec.js.map +1 -0
  13. package/dist/wizards/gsecontrol.d.ts +2 -0
  14. package/dist/wizards/gsecontrol.js +86 -0
  15. package/dist/wizards/gsecontrol.js.map +1 -0
  16. package/dist/wizards/gsecontrol.spec.d.ts +1 -0
  17. package/dist/wizards/gsecontrol.spec.js +216 -0
  18. package/dist/wizards/gsecontrol.spec.js.map +1 -0
  19. package/dist/wizards/lnode.d.ts +1 -0
  20. package/dist/wizards/lnode.js +101 -1
  21. package/dist/wizards/lnode.js.map +1 -1
  22. package/dist/wizards/patterns.d.ts +2 -0
  23. package/dist/wizards/patterns.js +2 -0
  24. package/dist/wizards/patterns.js.map +1 -1
  25. package/dist/wizards/sampledvaluecontrol.d.ts +2 -0
  26. package/dist/wizards/sampledvaluecontrol.js +115 -0
  27. package/dist/wizards/sampledvaluecontrol.js.map +1 -0
  28. package/dist/wizards/sampledvaluecontrol.spec.d.ts +1 -0
  29. package/dist/wizards/sampledvaluecontrol.spec.js +227 -0
  30. package/dist/wizards/sampledvaluecontrol.spec.js.map +1 -0
  31. package/dist/wizards/smvopts.d.ts +2 -0
  32. package/dist/wizards/smvopts.js +43 -0
  33. package/dist/wizards/smvopts.js.map +1 -0
  34. package/dist/wizards/smvopts.spec.d.ts +1 -0
  35. package/dist/wizards/smvopts.spec.js +193 -0
  36. package/dist/wizards/smvopts.spec.js.map +1 -0
  37. package/dist/wizards/wizards.js +16 -4
  38. package/dist/wizards/wizards.js.map +1 -1
  39. package/package.json +1 -1
@@ -0,0 +1,115 @@
1
+ import { html } from 'lit';
2
+ import { getValue, reservedNames, } from '../foundation.js';
3
+ import { maxLength, tSecurityEnable, tSmpMod } from './patterns.js';
4
+ function render(options) {
5
+ const fields = [
6
+ html `<scl-text-field
7
+ label="name"
8
+ .value=${options.name}
9
+ required
10
+ maxLength="${maxLength.cbName}"
11
+ .reservedValues=${options.reservedValues}
12
+ dialogInitialFocus
13
+ ></scl-text-field>`,
14
+ html `<scl-text-field
15
+ label="desc"
16
+ .value=${options.desc}
17
+ nullable
18
+ ></scl-text-field>`,
19
+ html `<scl-text-field
20
+ label="smvID"
21
+ .value=${options.smvID}
22
+ required
23
+ ></scl-text-field>`,
24
+ html `<scl-select
25
+ label="smpMod"
26
+ .selectOptions=${tSmpMod}
27
+ .value=${options.smpMod}
28
+ nullable
29
+ ></scl-select>`,
30
+ html `<scl-text-field
31
+ label="smpRate"
32
+ .value=${options.smpRate}
33
+ required
34
+ type="number"
35
+ min="0"
36
+ ></scl-text-field>`,
37
+ html `<scl-text-field
38
+ label="nofASDU"
39
+ .value=${options.nofASDU}
40
+ required
41
+ type="number"
42
+ min="0"
43
+ ></scl-text-field>`,
44
+ html `<scl-select
45
+ label="securityEnabled"
46
+ .selectOptions=${tSecurityEnable}
47
+ .value=${options.securityEnabled}
48
+ nullable
49
+ ></scl-select>`,
50
+ ];
51
+ if (options.multicast === 'false') {
52
+ fields.push(html `<scl-checkbox
53
+ label="multicast"
54
+ .value=${'false'}
55
+ disabled
56
+ ></scl-checkbox>`);
57
+ }
58
+ return fields;
59
+ }
60
+ function updateAction(element) {
61
+ return (inputs) => {
62
+ const name = getValue(inputs.find(i => i.label === 'name'));
63
+ const desc = getValue(inputs.find(i => i.label === 'desc'));
64
+ const smvID = getValue(inputs.find(i => i.label === 'smvID'));
65
+ const smpMod = getValue(inputs.find(i => i.label === 'smpMod'));
66
+ const smpRate = getValue(inputs.find(i => i.label === 'smpRate'));
67
+ const nofASDU = getValue(inputs.find(i => i.label === 'nofASDU'));
68
+ const securityEnabled = getValue(inputs.find(i => i.label === 'securityEnabled'));
69
+ if (name === element.getAttribute('name') &&
70
+ desc === element.getAttribute('desc') &&
71
+ smvID === element.getAttribute('smvID') &&
72
+ smpMod === element.getAttribute('smpMod') &&
73
+ smpRate === element.getAttribute('smpRate') &&
74
+ nofASDU === element.getAttribute('nofASDU') &&
75
+ securityEnabled === element.getAttribute('securityEnabled')) {
76
+ return [];
77
+ }
78
+ return [
79
+ {
80
+ element,
81
+ attributes: {
82
+ name,
83
+ desc,
84
+ smvID,
85
+ smpMod,
86
+ smpRate,
87
+ nofASDU,
88
+ securityEnabled,
89
+ },
90
+ },
91
+ ];
92
+ };
93
+ }
94
+ export function editSampledValueControlWizard(element) {
95
+ return {
96
+ title: 'Edit SampledValueControl',
97
+ primary: {
98
+ icon: 'edit',
99
+ label: 'save',
100
+ action: updateAction(element),
101
+ },
102
+ content: render({
103
+ name: element.getAttribute('name') ?? '',
104
+ reservedValues: reservedNames(element),
105
+ desc: element.getAttribute('desc'),
106
+ smvID: element.getAttribute('smvID') ?? '',
107
+ smpMod: element.getAttribute('smpMod'),
108
+ smpRate: element.getAttribute('smpRate') ?? '',
109
+ nofASDU: element.getAttribute('nofASDU') ?? '',
110
+ securityEnabled: element.getAttribute('securityEnabled'),
111
+ multicast: element.getAttribute('multicast'),
112
+ }),
113
+ };
114
+ }
115
+ //# sourceMappingURL=sampledvaluecontrol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sampledvaluecontrol.js","sourceRoot":"","sources":["../../wizards/sampledvaluecontrol.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult } from 'lit';\n\nimport { EditV2 } from '@openscd/oscd-api';\n\nimport {\n getValue,\n reservedNames,\n Wizard,\n WizardActor,\n WizardInputElement,\n} from '../foundation.js';\nimport { maxLength, tSecurityEnable, tSmpMod } from './patterns.js';\n\ntype RenderOptions = {\n name: string;\n reservedValues: string[];\n desc: string | null;\n smvID: string;\n smpMod: string | null;\n smpRate: string;\n nofASDU: string;\n securityEnabled: string | null;\n multicast: string | null;\n};\n\nfunction render(options: RenderOptions): TemplateResult[] {\n const fields: TemplateResult[] = [\n html`<scl-text-field\n label=\"name\"\n .value=${options.name}\n required\n maxLength=\"${maxLength.cbName}\"\n .reservedValues=${options.reservedValues}\n dialogInitialFocus\n ></scl-text-field>`,\n html`<scl-text-field\n label=\"desc\"\n .value=${options.desc}\n nullable\n ></scl-text-field>`,\n html`<scl-text-field\n label=\"smvID\"\n .value=${options.smvID}\n required\n ></scl-text-field>`,\n html`<scl-select\n label=\"smpMod\"\n .selectOptions=${tSmpMod}\n .value=${options.smpMod}\n nullable\n ></scl-select>`,\n html`<scl-text-field\n label=\"smpRate\"\n .value=${options.smpRate}\n required\n type=\"number\"\n min=\"0\"\n ></scl-text-field>`,\n html`<scl-text-field\n label=\"nofASDU\"\n .value=${options.nofASDU}\n required\n type=\"number\"\n min=\"0\"\n ></scl-text-field>`,\n html`<scl-select\n label=\"securityEnabled\"\n .selectOptions=${tSecurityEnable}\n .value=${options.securityEnabled}\n nullable\n ></scl-select>`,\n ];\n\n if (options.multicast === 'false') {\n fields.push(\n html`<scl-checkbox\n label=\"multicast\"\n .value=${'false'}\n disabled\n ></scl-checkbox>`,\n );\n }\n\n return fields;\n}\n\nfunction updateAction(element: Element): WizardActor {\n return (inputs: WizardInputElement[]): EditV2[] => {\n const name = getValue(inputs.find(i => i.label === 'name')!)!;\n const desc = getValue(inputs.find(i => i.label === 'desc')!);\n const smvID = getValue(inputs.find(i => i.label === 'smvID')!)!;\n const smpMod = getValue(inputs.find(i => i.label === 'smpMod')!);\n const smpRate = getValue(inputs.find(i => i.label === 'smpRate')!)!;\n const nofASDU = getValue(inputs.find(i => i.label === 'nofASDU')!)!;\n const securityEnabled = getValue(\n inputs.find(i => i.label === 'securityEnabled')!,\n );\n\n if (\n name === element.getAttribute('name') &&\n desc === element.getAttribute('desc') &&\n smvID === element.getAttribute('smvID') &&\n smpMod === element.getAttribute('smpMod') &&\n smpRate === element.getAttribute('smpRate') &&\n nofASDU === element.getAttribute('nofASDU') &&\n securityEnabled === element.getAttribute('securityEnabled')\n ) {\n return [];\n }\n\n return [\n {\n element,\n attributes: {\n name,\n desc,\n smvID,\n smpMod,\n smpRate,\n nofASDU,\n securityEnabled,\n },\n },\n ];\n };\n}\n\nexport function editSampledValueControlWizard(element: Element): Wizard {\n return {\n title: 'Edit SampledValueControl',\n primary: {\n icon: 'edit',\n label: 'save',\n action: updateAction(element),\n },\n content: render({\n name: element.getAttribute('name') ?? '',\n reservedValues: reservedNames(element),\n desc: element.getAttribute('desc'),\n smvID: element.getAttribute('smvID') ?? '',\n smpMod: element.getAttribute('smpMod'),\n smpRate: element.getAttribute('smpRate') ?? '',\n nofASDU: element.getAttribute('nofASDU') ?? '',\n securityEnabled: element.getAttribute('securityEnabled'),\n multicast: element.getAttribute('multicast'),\n }),\n };\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,227 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
2
+ import { expect, fixture } from '@open-wc/testing';
3
+ import { html } from 'lit';
4
+ import { editSampledValueControlWizard } from './sampledvaluecontrol.js';
5
+ import { XMLEditor } from '@openscd/oscd-editor';
6
+ import { SclTextField } from '@openenergytools/scl-text-field';
7
+ import { SclSelect } from '@openenergytools/scl-select';
8
+ import { SclCheckbox } from '@openenergytools/scl-checkbox';
9
+ if (!customElements.get('scl-text-field')) {
10
+ customElements.define('scl-text-field', SclTextField);
11
+ }
12
+ if (!customElements.get('scl-select')) {
13
+ customElements.define('scl-select', SclSelect);
14
+ }
15
+ if (!customElements.get('scl-checkbox')) {
16
+ customElements.define('scl-checkbox', SclCheckbox);
17
+ }
18
+ const xmlParser = new DOMParser();
19
+ function createSclDoc(multicast) {
20
+ const multicastAttr = multicast !== undefined ? `multicast="${multicast}"` : '';
21
+ return xmlParser.parseFromString(`
22
+ <SCL xmlns="http://www.iec.ch/61850/2003/SCL">
23
+ <IED name="IED1">
24
+ <AccessPoint name="AP1">
25
+ <Server>
26
+ <LDevice inst="LD1">
27
+ <LN0 lnClass="LLN0" inst="" lnType="LLN0_Type">
28
+ <SampledValueControl name="SVC1" desc="SV control 1" smvID="SV_ID1" smpMod="SmpPerPeriod" smpRate="80" nofASDU="1" securityEnabled="None" ${multicastAttr} datSet="ds1" confRev="1" />
29
+ <SampledValueControl name="SVC2" smvID="SV_ID2" smpRate="256" nofASDU="2" />
30
+ </LN0>
31
+ </LDevice>
32
+ </Server>
33
+ </AccessPoint>
34
+ </IED>
35
+ </SCL>
36
+ `, 'application/xml');
37
+ }
38
+ async function renderContent(wizard) {
39
+ const content = await fixture(html `<form>${wizard.content}</form>`);
40
+ const nameField = content.querySelector('scl-text-field[label="name"]');
41
+ const descField = content.querySelector('scl-text-field[label="desc"]');
42
+ const smvIDField = content.querySelector('scl-text-field[label="smvID"]');
43
+ const smpModField = content.querySelector('scl-select[label="smpMod"]');
44
+ const smpRateField = content.querySelector('scl-text-field[label="smpRate"]');
45
+ const nofASDUField = content.querySelector('scl-text-field[label="nofASDU"]');
46
+ const securityEnabledField = content.querySelector('scl-select[label="securityEnabled"]');
47
+ const multicastField = content.querySelector('scl-checkbox[label="multicast"]');
48
+ expect(nameField).to.exist;
49
+ expect(descField).to.exist;
50
+ expect(smvIDField).to.exist;
51
+ expect(smpModField).to.exist;
52
+ expect(smpRateField).to.exist;
53
+ expect(nofASDUField).to.exist;
54
+ expect(securityEnabledField).to.exist;
55
+ return {
56
+ content,
57
+ nameField,
58
+ descField,
59
+ smvIDField,
60
+ smpModField,
61
+ smpRateField,
62
+ nofASDUField,
63
+ securityEnabledField,
64
+ multicastField,
65
+ };
66
+ }
67
+ describe('SampledValueControl edit wizard', () => {
68
+ let xmlEditor;
69
+ let renderedContainer;
70
+ beforeEach(() => {
71
+ xmlEditor = new XMLEditor();
72
+ });
73
+ afterEach(() => {
74
+ if (renderedContainer) {
75
+ renderedContainer.remove();
76
+ }
77
+ });
78
+ it('returns a wizard with correct title and 7 fields (multicast true/absent)', () => {
79
+ const scl = createSclDoc();
80
+ const element = scl.querySelector('SampledValueControl[name="SVC1"]');
81
+ const wizard = editSampledValueControlWizard(element);
82
+ expect(wizard.title).to.equal('Edit SampledValueControl');
83
+ expect(wizard.primary).to.exist;
84
+ expect(wizard.primary.icon).to.equal('edit');
85
+ expect(wizard.primary.label).to.equal('save');
86
+ // 7 fields: name, desc, smvID, smpMod, smpRate, nofASDU, securityEnabled
87
+ // No multicast field when multicast is absent (defaults to true)
88
+ expect(wizard.content).to.have.lengthOf(7);
89
+ });
90
+ it('shows 8 fields with disabled multicast checkbox when multicast is false', () => {
91
+ const scl = createSclDoc('false');
92
+ const element = scl.querySelector('SampledValueControl[name="SVC1"]');
93
+ const wizard = editSampledValueControlWizard(element);
94
+ expect(wizard.content).to.have.lengthOf(8);
95
+ });
96
+ it('does not show multicast field when multicast is true', () => {
97
+ const scl = createSclDoc('true');
98
+ const element = scl.querySelector('SampledValueControl[name="SVC1"]');
99
+ const wizard = editSampledValueControlWizard(element);
100
+ // 7 fields — no multicast
101
+ expect(wizard.content).to.have.lengthOf(7);
102
+ });
103
+ it('populates fields with current attribute values', async () => {
104
+ const scl = createSclDoc();
105
+ const element = scl.querySelector('SampledValueControl[name="SVC1"]');
106
+ const wizard = editSampledValueControlWizard(element);
107
+ const fields = await renderContent(wizard);
108
+ renderedContainer = fields.content;
109
+ expect(fields.nameField.value).to.equal('SVC1');
110
+ expect(fields.descField.value).to.equal('SV control 1');
111
+ expect(fields.smvIDField.value).to.equal('SV_ID1');
112
+ expect(fields.smpModField.value).to.equal('SmpPerPeriod');
113
+ expect(fields.smpRateField.value).to.equal('80');
114
+ expect(fields.nofASDUField.value).to.equal('1');
115
+ expect(fields.securityEnabledField.value).to.equal('None');
116
+ expect(fields.multicastField).to.be.null;
117
+ });
118
+ it('returns [] when no changes are made', async () => {
119
+ const scl = createSclDoc();
120
+ const element = scl.querySelector('SampledValueControl[name="SVC1"]');
121
+ const wizard = editSampledValueControlWizard(element);
122
+ const fields = await renderContent(wizard);
123
+ renderedContainer = fields.content;
124
+ const edits = wizard.primary.action([
125
+ fields.nameField,
126
+ fields.descField,
127
+ fields.smvIDField,
128
+ fields.smpModField,
129
+ fields.smpRateField,
130
+ fields.nofASDUField,
131
+ fields.securityEnabledField,
132
+ ], renderedContainer);
133
+ expect(edits).to.have.lengthOf(0);
134
+ });
135
+ it('returns SetAttributes with changed name', async () => {
136
+ const scl = createSclDoc();
137
+ const element = scl.querySelector('SampledValueControl[name="SVC1"]');
138
+ const wizard = editSampledValueControlWizard(element);
139
+ const fields = await renderContent(wizard);
140
+ renderedContainer = fields.content;
141
+ fields.nameField.value = 'SVC_New';
142
+ const edits = wizard.primary.action([
143
+ fields.nameField,
144
+ fields.descField,
145
+ fields.smvIDField,
146
+ fields.smpModField,
147
+ fields.smpRateField,
148
+ fields.nofASDUField,
149
+ fields.securityEnabledField,
150
+ ], renderedContainer);
151
+ expect(edits).to.have.lengthOf(1);
152
+ const edit = edits[0];
153
+ expect(edit.element).to.equal(element);
154
+ expect(edit.attributes.name).to.equal('SVC_New');
155
+ });
156
+ it('applies changed attributes to the document', async () => {
157
+ const scl = createSclDoc();
158
+ const element = scl.querySelector('SampledValueControl[name="SVC1"]');
159
+ const wizard = editSampledValueControlWizard(element);
160
+ const fields = await renderContent(wizard);
161
+ renderedContainer = fields.content;
162
+ fields.nameField.value = 'SVC_New';
163
+ fields.smpRateField.value = '4000';
164
+ fields.nofASDUField.value = '8';
165
+ const edits = wizard.primary.action([
166
+ fields.nameField,
167
+ fields.descField,
168
+ fields.smvIDField,
169
+ fields.smpModField,
170
+ fields.smpRateField,
171
+ fields.nofASDUField,
172
+ fields.securityEnabledField,
173
+ ], renderedContainer);
174
+ xmlEditor.commit(edits);
175
+ expect(element.getAttribute('name')).to.equal('SVC_New');
176
+ expect(element.getAttribute('smpRate')).to.equal('4000');
177
+ expect(element.getAttribute('nofASDU')).to.equal('8');
178
+ });
179
+ it('handles nullable smpMod cleared returns null attribute', async () => {
180
+ const scl = createSclDoc();
181
+ const element = scl.querySelector('SampledValueControl[name="SVC1"]');
182
+ expect(element.getAttribute('smpMod')).to.equal('SmpPerPeriod');
183
+ const wizard = editSampledValueControlWizard(element);
184
+ const fields = await renderContent(wizard);
185
+ renderedContainer = fields.content;
186
+ fields.smpModField.value = null;
187
+ const edits = wizard.primary.action([
188
+ fields.nameField,
189
+ fields.descField,
190
+ fields.smvIDField,
191
+ fields.smpModField,
192
+ fields.smpRateField,
193
+ fields.nofASDUField,
194
+ fields.securityEnabledField,
195
+ ], renderedContainer);
196
+ expect(edits).to.have.lengthOf(1);
197
+ const edit = edits[0];
198
+ expect(edit.attributes.smpMod).to.be.null;
199
+ xmlEditor.commit(edits);
200
+ expect(element.getAttribute('smpMod')).to.be.null;
201
+ });
202
+ it('handles element with minimal attributes (SVC2)', async () => {
203
+ const scl = createSclDoc();
204
+ const element = scl.querySelector('SampledValueControl[name="SVC2"]');
205
+ const wizard = editSampledValueControlWizard(element);
206
+ const fields = await renderContent(wizard);
207
+ renderedContainer = fields.content;
208
+ expect(fields.nameField.value).to.equal('SVC2');
209
+ expect(fields.descField.value).to.be.null;
210
+ expect(fields.smvIDField.value).to.equal('SV_ID2');
211
+ expect(fields.smpModField.value).to.be.null;
212
+ expect(fields.smpRateField.value).to.equal('256');
213
+ expect(fields.nofASDUField.value).to.equal('2');
214
+ expect(fields.securityEnabledField.value).to.be.null;
215
+ });
216
+ it('renders disabled multicast checkbox for unicast SV', async () => {
217
+ const scl = createSclDoc('false');
218
+ const element = scl.querySelector('SampledValueControl[name="SVC1"]');
219
+ const wizard = editSampledValueControlWizard(element);
220
+ const fields = await renderContent(wizard);
221
+ renderedContainer = fields.content;
222
+ expect(fields.multicastField).to.exist;
223
+ expect(fields.multicastField.disabled).to.be.true;
224
+ expect(fields.multicastField.value).to.equal('false');
225
+ });
226
+ });
227
+ //# sourceMappingURL=sampledvaluecontrol.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sampledvaluecontrol.spec.js","sourceRoot":"","sources":["../../wizards/sampledvaluecontrol.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-expressions */\nimport { expect, fixture } from '@open-wc/testing';\nimport { html } from 'lit';\n\nimport { editSampledValueControlWizard } from './sampledvaluecontrol.js';\nimport { EditV2, SetAttributes } from '@openscd/oscd-api';\nimport { XMLEditor } from '@openscd/oscd-editor';\nimport { SclTextField } from '@openenergytools/scl-text-field';\nimport { SclSelect } from '@openenergytools/scl-select';\nimport { SclCheckbox } from '@openenergytools/scl-checkbox';\nimport { Wizard } from '../foundation.js';\n\nif (!customElements.get('scl-text-field')) {\n customElements.define('scl-text-field', SclTextField);\n}\nif (!customElements.get('scl-select')) {\n customElements.define('scl-select', SclSelect);\n}\nif (!customElements.get('scl-checkbox')) {\n customElements.define('scl-checkbox', SclCheckbox);\n}\n\nconst xmlParser = new DOMParser();\nfunction createSclDoc(multicast?: string): XMLDocument {\n const multicastAttr =\n multicast !== undefined ? `multicast=\"${multicast}\"` : '';\n return xmlParser.parseFromString(\n `\n <SCL xmlns=\"http://www.iec.ch/61850/2003/SCL\">\n <IED name=\"IED1\">\n <AccessPoint name=\"AP1\">\n <Server>\n <LDevice inst=\"LD1\">\n <LN0 lnClass=\"LLN0\" inst=\"\" lnType=\"LLN0_Type\">\n <SampledValueControl name=\"SVC1\" desc=\"SV control 1\" smvID=\"SV_ID1\" smpMod=\"SmpPerPeriod\" smpRate=\"80\" nofASDU=\"1\" securityEnabled=\"None\" ${multicastAttr} datSet=\"ds1\" confRev=\"1\" />\n <SampledValueControl name=\"SVC2\" smvID=\"SV_ID2\" smpRate=\"256\" nofASDU=\"2\" />\n </LN0>\n </LDevice>\n </Server>\n </AccessPoint>\n </IED>\n </SCL>\n `,\n 'application/xml',\n );\n}\n\nasync function renderContent(wizard: Wizard) {\n const content = await fixture(html`<form>${wizard.content}</form>`);\n\n const nameField = content.querySelector(\n 'scl-text-field[label=\"name\"]',\n ) as SclTextField;\n const descField = content.querySelector(\n 'scl-text-field[label=\"desc\"]',\n ) as SclTextField;\n const smvIDField = content.querySelector(\n 'scl-text-field[label=\"smvID\"]',\n ) as SclTextField;\n const smpModField = content.querySelector(\n 'scl-select[label=\"smpMod\"]',\n ) as SclSelect;\n const smpRateField = content.querySelector(\n 'scl-text-field[label=\"smpRate\"]',\n ) as SclTextField;\n const nofASDUField = content.querySelector(\n 'scl-text-field[label=\"nofASDU\"]',\n ) as SclTextField;\n const securityEnabledField = content.querySelector(\n 'scl-select[label=\"securityEnabled\"]',\n ) as SclSelect;\n const multicastField = content.querySelector(\n 'scl-checkbox[label=\"multicast\"]',\n ) as SclCheckbox | null;\n\n expect(nameField).to.exist;\n expect(descField).to.exist;\n expect(smvIDField).to.exist;\n expect(smpModField).to.exist;\n expect(smpRateField).to.exist;\n expect(nofASDUField).to.exist;\n expect(securityEnabledField).to.exist;\n\n return {\n content,\n nameField,\n descField,\n smvIDField,\n smpModField,\n smpRateField,\n nofASDUField,\n securityEnabledField,\n multicastField,\n };\n}\n\ndescribe('SampledValueControl edit wizard', () => {\n let xmlEditor: XMLEditor;\n let renderedContainer: Element | undefined;\n\n beforeEach(() => {\n xmlEditor = new XMLEditor();\n });\n\n afterEach(() => {\n if (renderedContainer) {\n renderedContainer.remove();\n }\n });\n\n it('returns a wizard with correct title and 7 fields (multicast true/absent)', () => {\n const scl = createSclDoc();\n const element = scl.querySelector('SampledValueControl[name=\"SVC1\"]')!;\n const wizard = editSampledValueControlWizard(element);\n\n expect(wizard.title).to.equal('Edit SampledValueControl');\n expect(wizard.primary).to.exist;\n expect(wizard.primary!.icon).to.equal('edit');\n expect(wizard.primary!.label).to.equal('save');\n // 7 fields: name, desc, smvID, smpMod, smpRate, nofASDU, securityEnabled\n // No multicast field when multicast is absent (defaults to true)\n expect(wizard.content).to.have.lengthOf(7);\n });\n\n it('shows 8 fields with disabled multicast checkbox when multicast is false', () => {\n const scl = createSclDoc('false');\n const element = scl.querySelector('SampledValueControl[name=\"SVC1\"]')!;\n const wizard = editSampledValueControlWizard(element);\n\n expect(wizard.content).to.have.lengthOf(8);\n });\n\n it('does not show multicast field when multicast is true', () => {\n const scl = createSclDoc('true');\n const element = scl.querySelector('SampledValueControl[name=\"SVC1\"]')!;\n const wizard = editSampledValueControlWizard(element);\n\n // 7 fields — no multicast\n expect(wizard.content).to.have.lengthOf(7);\n });\n\n it('populates fields with current attribute values', async () => {\n const scl = createSclDoc();\n const element = scl.querySelector('SampledValueControl[name=\"SVC1\"]')!;\n const wizard = editSampledValueControlWizard(element);\n const fields = await renderContent(wizard);\n renderedContainer = fields.content;\n\n expect(fields.nameField.value).to.equal('SVC1');\n expect(fields.descField.value).to.equal('SV control 1');\n expect(fields.smvIDField.value).to.equal('SV_ID1');\n expect(fields.smpModField.value).to.equal('SmpPerPeriod');\n expect(fields.smpRateField.value).to.equal('80');\n expect(fields.nofASDUField.value).to.equal('1');\n expect(fields.securityEnabledField.value).to.equal('None');\n expect(fields.multicastField).to.be.null;\n });\n\n it('returns [] when no changes are made', async () => {\n const scl = createSclDoc();\n const element = scl.querySelector('SampledValueControl[name=\"SVC1\"]')!;\n const wizard = editSampledValueControlWizard(element);\n const fields = await renderContent(wizard);\n renderedContainer = fields.content;\n\n const edits = wizard.primary!.action(\n [\n fields.nameField,\n fields.descField,\n fields.smvIDField,\n fields.smpModField,\n fields.smpRateField,\n fields.nofASDUField,\n fields.securityEnabledField,\n ],\n renderedContainer!,\n ) as EditV2[];\n\n expect(edits).to.have.lengthOf(0);\n });\n\n it('returns SetAttributes with changed name', async () => {\n const scl = createSclDoc();\n const element = scl.querySelector('SampledValueControl[name=\"SVC1\"]')!;\n const wizard = editSampledValueControlWizard(element);\n const fields = await renderContent(wizard);\n renderedContainer = fields.content;\n\n fields.nameField.value = 'SVC_New';\n\n const edits = wizard.primary!.action(\n [\n fields.nameField,\n fields.descField,\n fields.smvIDField,\n fields.smpModField,\n fields.smpRateField,\n fields.nofASDUField,\n fields.securityEnabledField,\n ],\n renderedContainer!,\n ) as EditV2[];\n\n expect(edits).to.have.lengthOf(1);\n const edit = edits[0] as SetAttributes;\n expect(edit.element).to.equal(element);\n expect(edit.attributes!.name).to.equal('SVC_New');\n });\n\n it('applies changed attributes to the document', async () => {\n const scl = createSclDoc();\n const element = scl.querySelector('SampledValueControl[name=\"SVC1\"]')!;\n const wizard = editSampledValueControlWizard(element);\n const fields = await renderContent(wizard);\n renderedContainer = fields.content;\n\n fields.nameField.value = 'SVC_New';\n fields.smpRateField.value = '4000';\n fields.nofASDUField.value = '8';\n\n const edits = wizard.primary!.action(\n [\n fields.nameField,\n fields.descField,\n fields.smvIDField,\n fields.smpModField,\n fields.smpRateField,\n fields.nofASDUField,\n fields.securityEnabledField,\n ],\n renderedContainer!,\n ) as EditV2[];\n\n xmlEditor.commit(edits);\n expect(element.getAttribute('name')).to.equal('SVC_New');\n expect(element.getAttribute('smpRate')).to.equal('4000');\n expect(element.getAttribute('nofASDU')).to.equal('8');\n });\n\n it('handles nullable smpMod cleared returns null attribute', async () => {\n const scl = createSclDoc();\n const element = scl.querySelector('SampledValueControl[name=\"SVC1\"]')!;\n expect(element.getAttribute('smpMod')).to.equal('SmpPerPeriod');\n\n const wizard = editSampledValueControlWizard(element);\n const fields = await renderContent(wizard);\n renderedContainer = fields.content;\n\n fields.smpModField.value = null as unknown as string;\n\n const edits = wizard.primary!.action(\n [\n fields.nameField,\n fields.descField,\n fields.smvIDField,\n fields.smpModField,\n fields.smpRateField,\n fields.nofASDUField,\n fields.securityEnabledField,\n ],\n renderedContainer!,\n ) as EditV2[];\n\n expect(edits).to.have.lengthOf(1);\n const edit = edits[0] as SetAttributes;\n expect(edit.attributes!.smpMod).to.be.null;\n\n xmlEditor.commit(edits);\n expect(element.getAttribute('smpMod')).to.be.null;\n });\n\n it('handles element with minimal attributes (SVC2)', async () => {\n const scl = createSclDoc();\n const element = scl.querySelector('SampledValueControl[name=\"SVC2\"]')!;\n const wizard = editSampledValueControlWizard(element);\n const fields = await renderContent(wizard);\n renderedContainer = fields.content;\n\n expect(fields.nameField.value).to.equal('SVC2');\n expect(fields.descField.value).to.be.null;\n expect(fields.smvIDField.value).to.equal('SV_ID2');\n expect(fields.smpModField.value).to.be.null;\n expect(fields.smpRateField.value).to.equal('256');\n expect(fields.nofASDUField.value).to.equal('2');\n expect(fields.securityEnabledField.value).to.be.null;\n });\n\n it('renders disabled multicast checkbox for unicast SV', async () => {\n const scl = createSclDoc('false');\n const element = scl.querySelector('SampledValueControl[name=\"SVC1\"]')!;\n const wizard = editSampledValueControlWizard(element);\n const fields = await renderContent(wizard);\n renderedContainer = fields.content;\n\n expect(fields.multicastField).to.exist;\n expect(fields.multicastField!.disabled).to.be.true;\n expect(fields.multicastField!.value).to.equal('false');\n });\n});\n"]}
@@ -0,0 +1,2 @@
1
+ import { Wizard } from '../foundation.js';
2
+ export declare function editSmvOptsWizard(element: Element): Wizard;
@@ -0,0 +1,43 @@
1
+ import { html } from 'lit';
2
+ import { getValue, } from '../foundation.js';
3
+ const smvOptKeys = [
4
+ 'refreshTime',
5
+ 'sampleRate',
6
+ 'dataSet',
7
+ 'security',
8
+ 'synchSourceId',
9
+ ];
10
+ function render(options) {
11
+ return smvOptKeys.map(key => html `<scl-checkbox
12
+ label="${key}"
13
+ .value=${options[key]}
14
+ nullable
15
+ ></scl-checkbox>`);
16
+ }
17
+ function updateAction(element) {
18
+ return (inputs) => {
19
+ const attributes = {};
20
+ for (const key of smvOptKeys) {
21
+ attributes[key] = getValue(inputs.find(i => i.label === key));
22
+ }
23
+ if (!smvOptKeys.some(key => attributes[key] !== element.getAttribute(key)))
24
+ return [];
25
+ return [{ element, attributes }];
26
+ };
27
+ }
28
+ export function editSmvOptsWizard(element) {
29
+ const options = {};
30
+ for (const key of smvOptKeys) {
31
+ options[key] = element.getAttribute(key);
32
+ }
33
+ return {
34
+ title: 'Edit SmvOpts',
35
+ primary: {
36
+ icon: 'edit',
37
+ label: 'save',
38
+ action: updateAction(element),
39
+ },
40
+ content: render(options),
41
+ };
42
+ }
43
+ //# sourceMappingURL=smvopts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smvopts.js","sourceRoot":"","sources":["../../wizards/smvopts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAC;AAI3C,OAAO,EACL,QAAQ,GAIT,MAAM,kBAAkB,CAAC;AAE1B,MAAM,UAAU,GAAG;IACjB,aAAa;IACb,YAAY;IACZ,SAAS;IACT,UAAU;IACV,eAAe;CACP,CAAC;AAMX,SAAS,MAAM,CAAC,OAAsB;IACpC,OAAO,UAAU,CAAC,GAAG,CACnB,GAAG,CAAC,EAAE,CACJ,IAAI,CAAA;iBACO,GAAG;iBACH,OAAO,CAAC,GAAG,CAAC;;uBAEN,CACpB,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,OAAgB;IACpC,OAAO,CAAC,MAA4B,EAAY,EAAE;QAChD,MAAM,UAAU,GAAkC,EAAE,CAAC;QACrD,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC7B,UAAU,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,GAAG,CAAE,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;YACxE,OAAO,EAAE,CAAC;QAEZ,OAAO,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IACnC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAgB;IAChD,MAAM,OAAO,GAAG,EAAmB,CAAC;IACpC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO;QACL,KAAK,EAAE,cAAc;QACrB,OAAO,EAAE;YACP,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC;SAC9B;QACD,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC;KACzB,CAAC;AACJ,CAAC","sourcesContent":["import { html, TemplateResult } from 'lit';\n\nimport { EditV2 } from '@openscd/oscd-api';\n\nimport {\n getValue,\n Wizard,\n WizardActor,\n WizardInputElement,\n} from '../foundation.js';\n\nconst smvOptKeys = [\n 'refreshTime',\n 'sampleRate',\n 'dataSet',\n 'security',\n 'synchSourceId',\n] as const;\n\ntype SmvOptKey = (typeof smvOptKeys)[number];\n\ntype RenderOptions = Record<SmvOptKey, string | null>;\n\nfunction render(options: RenderOptions): TemplateResult[] {\n return smvOptKeys.map(\n key =>\n html`<scl-checkbox\n label=\"${key}\"\n .value=${options[key]}\n nullable\n ></scl-checkbox>`,\n );\n}\n\nfunction updateAction(element: Element): WizardActor {\n return (inputs: WizardInputElement[]): EditV2[] => {\n const attributes: Record<string, string | null> = {};\n for (const key of smvOptKeys) {\n attributes[key] = getValue(inputs.find(i => i.label === key)!);\n }\n\n if (!smvOptKeys.some(key => attributes[key] !== element.getAttribute(key)))\n return [];\n\n return [{ element, attributes }];\n };\n}\n\nexport function editSmvOptsWizard(element: Element): Wizard {\n const options = {} as RenderOptions;\n for (const key of smvOptKeys) {\n options[key] = element.getAttribute(key);\n }\n\n return {\n title: 'Edit SmvOpts',\n primary: {\n icon: 'edit',\n label: 'save',\n action: updateAction(element),\n },\n content: render(options),\n };\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};