Skip to content

Commit 76e7e21

Browse files
refactor(wizards/reportcontrol): use report update action
1 parent 22555b6 commit 76e7e21

File tree

8 files changed

+165
-64
lines changed

8 files changed

+165
-64
lines changed

src/translations/de.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,13 @@ export const de: Translations = {
486486
report: {
487487
wizard: { location: 'Ablageort der Reports wählen' },
488488
},
489+
controlblock: {
490+
action: {
491+
edit: '{{type}} "{{name}}" in IED {{iedName}} bearbeitet',
492+
remove:
493+
'{{type}} "{{name}}" and referenzierte Element von IED {{iedName}} entfernt',
494+
},
495+
},
489496
add: 'Hinzufügen',
490497
new: 'Neu',
491498
remove: 'Entfernen',

src/translations/en.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,13 @@ export const en = {
482482
report: {
483483
wizard: { location: 'Select Report Control Location' },
484484
},
485+
controlblock: {
486+
action: {
487+
edit: 'Edited {{type}} "{{name}}" in IED {{iedName}}',
488+
remove:
489+
'Removed {{type}} "{{name}}" and its referenced elements from IED {{iedName}}',
490+
},
491+
},
485492
add: 'Add',
486493
new: 'New',
487494
remove: 'Remove',

src/wizards/gsecontrol.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import '../wizard-select.js';
1313
import '../wizard-textfield.js';
1414
import {
1515
cloneElement,
16+
ComplexAction,
1617
Delete,
1718
EditorAction,
1819
getValue,
@@ -106,8 +107,10 @@ export function renderGseAttributes(
106107
];
107108
}
108109

109-
export function removeGseControl(element: Element): Delete[] {
110-
const dataSet = element.parentElement!.querySelector(
110+
export function removeGseControl(element: Element): ComplexAction | null {
111+
if (!element.parentElement) return null;
112+
113+
const dataSet = element.parentElement.querySelector(
111114
`DataSet[name="${element.getAttribute('datSet')}"]`
112115
);
113116
const gSE = getGSE(element);
@@ -126,7 +129,7 @@ export function removeGseControl(element: Element): Delete[] {
126129

127130
actions.push({
128131
old: {
129-
parent: element.parentElement!,
132+
parent: element.parentElement,
130133
element,
131134
reference: element.nextSibling,
132135
},
@@ -135,9 +138,9 @@ export function removeGseControl(element: Element): Delete[] {
135138
if (dataSet && singleUse)
136139
actions.push({
137140
old: {
138-
parent: element.parentElement!,
141+
parent: element.parentElement,
139142
element: dataSet,
140-
reference: element.nextSibling,
143+
reference: dataSet.nextSibling,
141144
},
142145
});
143146

@@ -150,7 +153,17 @@ export function removeGseControl(element: Element): Delete[] {
150153
},
151154
});
152155

153-
return actions;
156+
const name = element.getAttribute('name')!;
157+
const iedName = element.closest('IED')?.getAttribute('name') ?? '';
158+
159+
return {
160+
title: get('controlblock.action.remove', {
161+
type: element.tagName,
162+
name,
163+
iedName,
164+
}),
165+
actions,
166+
};
154167
}
155168

156169
export function updateGseControlAction(element: Element): WizardActor {
@@ -215,10 +228,10 @@ export function editGseControlWizard(element: Element): Wizard {
215228
label="${translate('remove')}"
216229
icon="delete"
217230
@click=${(e: MouseEvent) => {
218-
const deleteActions = removeGseControl(element);
219-
deleteActions.forEach(deleteAction =>
220-
e.target?.dispatchEvent(newActionEvent(deleteAction))
221-
);
231+
const complexAction = removeGseControl(element);
232+
if (complexAction)
233+
e.target?.dispatchEvent(newActionEvent(complexAction));
234+
222235
e.target?.dispatchEvent(newWizardEvent());
223236
}}
224237
></mwc-button>`,

src/wizards/reportcontrol.ts

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
WizardInput,
3030
Delete,
3131
getUniqueElementName,
32+
ComplexAction,
3233
} from '../foundation.js';
3334
import { FinderList } from '../finder-list.js';
3435
import { dataAttributePicker, iEDPicker } from './foundation/finder.js';
@@ -327,8 +328,10 @@ function prepareReportControlCreateWizard(anyParent: Element): WizardActor {
327328
};
328329
}
329330

330-
export function removeReportControlAction(element: Element): Delete[] {
331-
if (!element.parentElement) return [];
331+
export function removeReportControlAction(
332+
element: Element
333+
): ComplexAction | null {
334+
if (!element.parentElement) return null;
332335

333336
const dataSet = element.parentElement.querySelector(
334337
`DataSet[name="${element.getAttribute('datSet')}"]`
@@ -358,11 +361,17 @@ export function removeReportControlAction(element: Element): Delete[] {
358361
old: {
359362
parent: element.parentElement!,
360363
element: dataSet,
361-
reference: element.nextSibling,
364+
reference: dataSet.nextSibling,
362365
},
363366
});
364367

365-
return actions;
368+
const name = element.getAttribute('name')!;
369+
const iedName = element.closest('IED')?.getAttribute('name') ?? '';
370+
371+
return {
372+
title: get('controlblock.action.remove', { type: 'Report', name, iedName }),
373+
actions,
374+
};
366375
}
367376

368377
function getRptEnabledAction(
@@ -420,7 +429,7 @@ function updateReportControlAction(element: Element): WizardActor {
420429

421430
const max = getValue(inputs.find(i => i.label === 'max Clients')!);
422431

423-
let rptEnabledAction: EditorAction | null = null;
432+
let rptEnabledAction: SimpleAction | null = null;
424433
if (
425434
max !== (element.querySelector('RptEnabled')?.getAttribute('max') ?? null)
426435
)
@@ -430,10 +439,22 @@ function updateReportControlAction(element: Element): WizardActor {
430439
element
431440
);
432441

433-
const actions: EditorAction[] = [];
442+
const actions: SimpleAction[] = [];
434443
if (reportControlAction) actions.push(reportControlAction);
435444
if (rptEnabledAction) actions.push(rptEnabledAction);
436-
return actions;
445+
446+
const name = attributes['name']!;
447+
const iedName = element.closest('IED')!.getAttribute('name')!;
448+
const complexAction = {
449+
title: get('controlblock.action.edit', {
450+
type: 'Report',
451+
name,
452+
iedName,
453+
}),
454+
actions,
455+
};
456+
457+
return actions.length ? [complexAction] : [];
437458
};
438459
}
439460

@@ -515,10 +536,10 @@ export function editReportControlWizard(element: Element): Wizard {
515536
label="${translate('remove')}"
516537
icon="delete"
517538
@click=${(e: MouseEvent) => {
518-
const deleteActions = removeReportControlAction(element);
519-
deleteActions.forEach(deleteAction =>
520-
e.target?.dispatchEvent(newActionEvent(deleteAction))
521-
);
539+
const complexAction = removeReportControlAction(element);
540+
if (complexAction)
541+
e.target?.dispatchEvent(newActionEvent(complexAction));
542+
522543
e.target?.dispatchEvent(newWizardEvent());
523544
}}
524545
></mwc-button>`,

src/wizards/sampledvaluecontrol.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import '../wizard-select.js';
1212
import '../wizard-textfield.js';
1313
import {
1414
cloneElement,
15+
ComplexAction,
1516
Delete,
1617
EditorAction,
1718
getValue,
@@ -47,8 +48,10 @@ function getSMV(element: Element): Element | null {
4748
);
4849
}
4950

50-
export function removeSampledValueControlAction(element: Element): Delete[] {
51-
if (!element.parentElement) return [];
51+
export function removeSampledValueControlAction(
52+
element: Element
53+
): ComplexAction | null {
54+
if (!element.parentElement) return null;
5255

5356
const dataSet = element.parentElement!.querySelector(
5457
`DataSet[name="${element.getAttribute('datSet')}"]`
@@ -90,7 +93,17 @@ export function removeSampledValueControlAction(element: Element): Delete[] {
9093
},
9194
});
9295

93-
return actions;
96+
const name = element.getAttribute('name')!;
97+
const iedName = element.closest('IED')?.getAttribute('name') ?? '';
98+
99+
return {
100+
title: get('controlblock.action.remove', {
101+
type: element.tagName,
102+
name,
103+
iedName,
104+
}),
105+
actions,
106+
};
94107
}
95108

96109
interface ContentOptions {
@@ -273,10 +286,11 @@ export function editSampledValueControlWizard(element: Element): Wizard {
273286
label="${translate('remove')}"
274287
icon="delete"
275288
@click=${(e: MouseEvent) => {
276-
const deleteActions = removeSampledValueControlAction(element);
277-
deleteActions.forEach(deleteAction =>
278-
e.target?.dispatchEvent(newActionEvent(deleteAction))
279-
);
289+
const complexAction = removeSampledValueControlAction(element);
290+
291+
if (complexAction)
292+
e.target?.dispatchEvent(newActionEvent(complexAction));
293+
280294
e.target?.dispatchEvent(newWizardEvent());
281295
}}
282296
></mwc-button>`,

test/unit/wizards/gsecontrol.test.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { MockWizard } from '../../mock-wizard.js';
66

77
import { WizardTextField } from '../../../src/wizard-textfield.js';
88
import {
9+
Delete,
910
isDelete,
1011
isReplace,
1112
Replace,
@@ -139,39 +140,55 @@ describe('gsecontrol wizards', () => {
139140
'application/xml'
140141
).documentElement;
141142

143+
const missingparent = <Element>(
144+
new DOMParser().parseFromString(
145+
`<GSEControl name="myName" datSet="myDataSet"/>`,
146+
'application/xml'
147+
).documentElement
148+
);
149+
142150
it('removes GSEControl and its refereced DataSet if no other GSEControl are aasinged', () => {
143151
const gseControl = ln01gse.querySelector('GSEControl')!;
144-
const actions = removeGseControl(gseControl);
152+
const actions = <Delete[]>removeGseControl(gseControl)!.actions;
145153
expect(actions.length).to.equal(2);
146154
expect(actions[0]).to.satisfy(isDelete);
147155
expect(actions[0].old.element).to.equal(gseControl);
148156
expect(actions[1]).to.satisfy(isDelete);
149157
expect(actions[1].old.element).to.equal(ln01gse.querySelector('DataSet'));
150158
});
159+
151160
it('removes GSEControl only if other GSEControl is assinged to the same DataSet', () => {
152161
const gseControl = ln02gse.querySelector('GSEControl')!;
153-
const actions = removeGseControl(gseControl);
162+
const actions = <Delete[]>removeGseControl(gseControl)!.actions;
154163
expect(actions.length).to.equal(1);
155164
expect(actions[0]).to.satisfy(isDelete);
156165
expect(actions[0].old.element).to.equal(gseControl);
157166
});
167+
158168
it('removes GSEControl only if other ReportControlBlock is assinged to the same DataSet', () => {
159169
const gseControl = ln02rp.querySelector('GSEControl')!;
160-
const actions = removeGseControl(gseControl);
170+
const actions = <Delete[]>removeGseControl(gseControl)!.actions;
161171
expect(actions.length).to.equal(1);
162172
expect(actions[0]).to.satisfy(isDelete);
163173
expect(actions[0].old.element).to.equal(gseControl);
164174
});
175+
165176
it('removes GSEControl only if other SMV is assinged to the same DataSet', () => {
166177
const gseControl = ln02smv.querySelector('GSEControl')!;
167-
const actions = removeGseControl(gseControl);
178+
const actions = <Delete[]>removeGseControl(gseControl)!.actions;
168179
expect(actions.length).to.equal(1);
169180
expect(actions[0]).to.satisfy(isDelete);
170181
expect(actions[0].old.element).to.equal(gseControl);
171182
});
183+
184+
it('does not remove with missing parent element', () => {
185+
const action = removeGseControl(missingparent);
186+
expect(action).to.be.null;
187+
});
188+
172189
it('removes GSE element if present in the Communication section', () => {
173190
const gseControl = doc.querySelector('IED[name="IED1"] GSEControl')!;
174-
const actions = removeGseControl(gseControl);
191+
const actions = <Delete[]>removeGseControl(gseControl)!.actions;
175192
expect(actions.length).to.equal(3);
176193
expect(actions[0]).to.satisfy(isDelete);
177194
expect(actions[0].old.element).to.equal(gseControl);

0 commit comments

Comments
 (0)