Skip to content

Commit 8ee23fc

Browse files
JakobVogelsangca-d
andauthored
feat(editors/subtation): allow instantiation of LNode from LNodeType's (openscd#766)
* refactor(foundation): change menu action API * feat(wizards/lnode): add create wizards * feat(wizards/wizard-library): add LNode create wizard to library * test(editors/substation): test LNode instatiotion with function type editors * refactor(wizards/lnode): combine reference type and instace type wizard * fix(wizard-libraray): import statement * refactor(wizards/lnode): triggered by review * refactor(wizards/lnode): better uniqueLnInst function * refactor(wizards/lnode): better search for uniqeu lnInst * test(wizards/lnode): better test unique lnInst selection * fix(wizard-dialog): stabilize jump to initial page This fixes the issue we had when opening the LNode instance reference create wizard from the overflow menu of the LNodeType reference create wizard. Co-authored-by: Christian Dinkel <[email protected]>
1 parent a520eef commit 8ee23fc

File tree

60 files changed

+1642
-155
lines changed

Some content is hidden

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

60 files changed

+1642
-155
lines changed

src/translations/de.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,11 @@ export const de: Translations = {
324324
none: 'Keine Verbindung vorhanden',
325325
publisherGoose: {
326326
title: 'GOOSE-Publizierer',
327-
subscriberTitle: 'Verbunden mit {{ selected }}'
327+
subscriberTitle: 'Verbunden mit {{ selected }}',
328328
},
329329
subscriberGoose: {
330330
title: 'IED-Publizierer',
331-
publisherTitle: 'GOOSE(s) verbunden mit {{selected}}'
331+
publisherTitle: 'GOOSE(s) verbunden mit {{selected}}',
332332
},
333333
subscriber: {
334334
subscribed: 'Verbunden',
@@ -338,9 +338,9 @@ export const de: Translations = {
338338
noIedSelected: 'Keine IED ausgewählt',
339339
},
340340
view: {
341-
publisherView: "Zeigt verbundene IED(s) der ausgewählten GOOSE",
342-
subscriberView: "Zeigt verbundene GOOSE(s) des ausgewählten IED"
343-
}
341+
publisherView: 'Zeigt verbundene IED(s) der ausgewählten GOOSE',
342+
subscriberView: 'Zeigt verbundene GOOSE(s) des ausgewählten IED',
343+
},
344344
},
345345
sampledvalues: {
346346
none: 'Keine Verbindung vorhanden',
@@ -460,8 +460,17 @@ export const de: Translations = {
460460
selectIEDs: 'Auswahl IEDs',
461461
selectLDs: 'Auswahl logische Geräte',
462462
selectLNs: 'Auswahl logische Knoten',
463+
selectLNodeTypes: 'Auswahl logische Knoten Type',
463464
},
464465
placeholder: 'Bitte laden Sie eine SCL-Datei, die IED-Elemente enthält.',
466+
uniquewarning: 'Logische Knoten Klasse existiert bereits',
467+
reference: 'Referenz auf bestehenden logischen Knoten erstellen',
468+
instance: 'Referenz auf logischen Knoten Typ erstellen',
469+
},
470+
log: {
471+
title: 'LNode vom Type {{lnClass}} kann nicht hinzugefügt werden',
472+
nonuniquelninst: 'Keine eindeutige Instanz (lnInst)',
473+
uniqueln0: 'Nur eine Instanz von {{lnClass}} zulässig',
465474
},
466475
tooltip: 'Referenz zu logischen Knoten erstellen',
467476
},

src/translations/en.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -321,11 +321,11 @@ export const en = {
321321
none: 'None',
322322
publisherGoose: {
323323
title: 'GOOSE Publisher',
324-
subscriberTitle: 'Subscriber of {{ selected }}'
324+
subscriberTitle: 'Subscriber of {{ selected }}',
325325
},
326326
subscriberGoose: {
327327
title: 'GOOSE Subscriber',
328-
publisherTitle: 'GOOSE(s) subscribed by {{selected}}'
328+
publisherTitle: 'GOOSE(s) subscribed by {{selected}}',
329329
},
330330
subscriber: {
331331
subscribed: 'Subscribed',
@@ -335,9 +335,9 @@ export const en = {
335335
noIedSelected: 'No IED selected',
336336
},
337337
view: {
338-
publisherView: "Show subscriber IED(s) per selected GOOSE",
339-
subscriberView: "Show subscribed GOOSE publisher for selected IED"
340-
}
338+
publisherView: 'Show subscriber IED(s) per selected GOOSE',
339+
subscriberView: 'Show subscribed GOOSE publisher for selected IED',
340+
},
341341
},
342342
sampledvalues: {
343343
none: 'none',
@@ -457,8 +457,17 @@ export const en = {
457457
selectIEDs: 'Select IEDs',
458458
selectLDs: 'Select logical devices',
459459
selectLNs: 'Select logical nodes',
460+
selectLNodeTypes: 'Select logical node types',
460461
},
461462
placeholder: 'Please load an SCL file that contains IED elements.',
463+
uniquewarning: 'Logical node class already exists',
464+
reference: 'Add reference to existing logical node',
465+
instance: 'Add reference to logical node type',
466+
},
467+
log: {
468+
title: 'Cannot add LNode of class {{lnClass}}',
469+
nonuniquelninst: 'Cannot find unique lnInst',
470+
uniqueln0: 'Only one instance of {{lnClass}} allowed',
462471
},
463472
tooltip: 'Create logical nodes reference',
464473
},

src/wizard-dialog.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,15 @@ export class WizardDialog extends LitElement {
174174
}
175175

176176
prev(): void {
177-
if (this.pageIndex > 0) this.pageIndex--;
177+
if (this.pageIndex <= 0) return;
178+
this.pageIndex--;
179+
this.dialog?.show();
178180
}
181+
179182
async next(): Promise<void> {
180183
if (dialogValid(this.dialog)) {
181184
if (this.wizard.length > this.pageIndex + 1) this.pageIndex++;
185+
this.dialog?.show();
182186
} else {
183187
this.dialog?.show();
184188
await this.dialog?.updateComplete;
@@ -295,8 +299,7 @@ export class WizardDialog extends LitElement {
295299
: 0;
296300

297301
return html`<mwc-dialog
298-
defaultAction="close"
299-
?open=${index === this.pageIndex}
302+
defaultAction="next"
300303
heading=${page.title}
301304
@closed=${this.onClosed}
302305
style="--mdc-dialog-min-width:calc(100% + ${extraWidth}px)"

src/wizards/ied.ts

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,17 @@ import {
2121
} from '../foundation.js';
2222
import { patterns } from './foundation/limits.js';
2323

24-
import { updateNamingAttributeWithReferencesAction } from "./foundation/actions.js";
25-
import { deleteReferences } from "./foundation/references.js";
26-
import { emptyInputsDeleteActions } from "../foundation/ied.js";
24+
import { updateNamingAttributeWithReferencesAction } from './foundation/actions.js';
25+
import { deleteReferences } from './foundation/references.js';
26+
import { emptyInputsDeleteActions } from '../foundation/ied.js';
2727

28-
const iedNamePattern = "[A-Za-z][0-9A-Za-z_]{0,2}|" +
29-
"[A-Za-z][0-9A-Za-z_]{4,63}|" +
30-
"[A-MO-Za-z][0-9A-Za-z_]{3}|" +
31-
"N[0-9A-Za-np-z_][0-9A-Za-z_]{2}|" +
32-
"No[0-9A-Za-mo-z_][0-9A-Za-z_]|" +
33-
"Non[0-9A-Za-df-z_]";
28+
const iedNamePattern =
29+
'[A-Za-z][0-9A-Za-z_]{0,2}|' +
30+
'[A-Za-z][0-9A-Za-z_]{4,63}|' +
31+
'[A-MO-Za-z][0-9A-Za-z_]{3}|' +
32+
'N[0-9A-Za-np-z_][0-9A-Za-z_]{2}|' +
33+
'No[0-9A-Za-mo-z_][0-9A-Za-z_]|' +
34+
'Non[0-9A-Za-df-z_]';
3435

3536
export function renderIEDWizard(
3637
name: string | null,
@@ -59,26 +60,26 @@ export function renderIEDWizard(
5960
}
6061

6162
function renderIEDReferencesWizard(references: Delete[]): TemplateResult[] {
62-
return [html `
63-
<section>
64-
<h1>${translate('ied.wizard.title.references')}</h1>
65-
<mwc-list>
66-
${references.map(reference => {
67-
const oldElement = <Element>reference.old.element
68-
return html `
69-
<mwc-list-item noninteractive twoline>
70-
<span>${oldElement.tagName}</span>
71-
<span slot="secondary">${identity(<Element>reference.old.element)}</span>
72-
</mwc-list-item>`;
73-
})}
74-
</mwc-list>
75-
</section>`];
63+
return [
64+
html` <section>
65+
<h1>${translate('ied.wizard.title.references')}</h1>
66+
<mwc-list>
67+
${references.map(reference => {
68+
const oldElement = <Element>reference.old.element;
69+
return html` <mwc-list-item noninteractive twoline>
70+
<span>${oldElement.tagName}</span>
71+
<span slot="secondary"
72+
>${identity(<Element>reference.old.element)}</span
73+
>
74+
</mwc-list-item>`;
75+
})}
76+
</mwc-list>
77+
</section>`,
78+
];
7679
}
7780

7881
export function reservedNamesIED(currentElement: Element): string[] {
79-
return Array.from(
80-
currentElement.parentNode!.querySelectorAll('IED')
81-
)
82+
return Array.from(currentElement.parentNode!.querySelectorAll('IED'))
8283
.filter(isPublic)
8384
.map(ied => ied.getAttribute('name') ?? '')
8485
.filter(name => name !== currentElement.getAttribute('name'));
@@ -92,21 +93,24 @@ export function removeIEDAndReferences(element: Element): WizardActor {
9293
// Get Delete Actions for other elements that also need to be removed
9394
const referencesDeleteActions = deleteReferences(element);
9495
// Use the ExtRef Elements to check if after removing the ExtRef there are empty Inputs that can also be removed.
95-
const extRefsDeleteActions = referencesDeleteActions
96-
.filter(deleteAction => (<Element>deleteAction.old.element).tagName === 'ExtRef')
97-
const inputsDeleteActions = emptyInputsDeleteActions(extRefsDeleteActions)
96+
const extRefsDeleteActions = referencesDeleteActions.filter(
97+
deleteAction => (<Element>deleteAction.old.element).tagName === 'ExtRef'
98+
);
99+
const inputsDeleteActions = emptyInputsDeleteActions(extRefsDeleteActions);
98100

99101
// Create Complex Action to remove IED and all references.
100102
const name = element.getAttribute('name') ?? 'Unknown';
101103
const complexAction: ComplexAction = {
102104
actions: [],
103-
title: get('ied.action.deleteied', {name}),
105+
title: get('ied.action.deleteied', { name }),
104106
};
105-
complexAction.actions.push({ old: { parent: element.parentElement!, element } });
107+
complexAction.actions.push({
108+
old: { parent: element.parentElement!, element },
109+
});
106110
complexAction.actions.push(...referencesDeleteActions);
107111
complexAction.actions.push(...inputsDeleteActions);
108112
return [complexAction];
109-
}
113+
};
110114
}
111115

112116
export function removeIEDWizard(element: Element): Wizard | null {
@@ -157,7 +161,10 @@ export function editIEDWizard(element: Element): Wizard {
157161
primary: {
158162
icon: 'edit',
159163
label: get('save'),
160-
action: updateNamingAttributeWithReferencesAction(element, 'ied.action.updateied'),
164+
action: updateNamingAttributeWithReferencesAction(
165+
element,
166+
'ied.action.updateied'
167+
),
161168
},
162169
content: renderIEDWizard(
163170
element.getAttribute('name'),

0 commit comments

Comments
 (0)