Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(wizards/smvopts): add edit wizard #547

Merged
merged 6 commits into from
Feb 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/translations/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ export const de: Translations = {
smpMod: 'Abtast-Art',
smpRate: 'Abtastrate',
nofASDU: 'Abtastpunkte pro Datenpacket',
SmvOpts: 'Optionale Informationen',
refreshTime: 'Zeitstempel des Abtastwertes zu Telegram hinzufügen',
sampleRate: 'Abtastrate zu Telegram hinzufügen',
dataSet: 'Datensatznamen zu Telegram hinzufügen',
security: 'Potentiel in Zukunft für z.B. digitale Signature',
synchSourceId: 'Identität der Zeitquelle zu Telegram hinzufügen',
},
settings: {
title: 'Einstellungen',
Expand All @@ -51,7 +57,7 @@ export const de: Translations = {
selectFileButton: 'Datei auswählen',
loadNsdTranslations: 'NSDoc-Dateien hochladen',
invalidFileNoIdFound: 'Ungültiges NSDoc; kein \'id\'-Attribut in der Datei gefunden',
invalidNsdocVersion: '???'
invalidNsdocVersion: 'Die Version {{ id }} NSD ({{ nsdVersion }}) passt nicht zu der geladenen NSDoc ({{ nsdocVersion }})'
},
menu: {
new: 'Neues projekt',
Expand Down
8 changes: 7 additions & 1 deletion src/translations/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@ export const en = {
multicast: 'SMV acc. to IEC 61850 9-2',
smpMod: 'Sample mode',
smpRate: 'Sample rate',
nofASDU: 'Samples per paket',
nofASDU: 'Samples per packet',
SmvOpts: 'Optional Information',
refreshTime: 'Add timestamp to SMV packet',
sampleRate: 'Add sample rate to SMV packet',
dataSet: 'Add DataSet name to SMV packet',
security: 'Potential future use. e.g. digital signature',
synchSourceId: 'Add sync source id to SMV packet',
},
settings: {
title: 'Settings',
Expand Down
12 changes: 12 additions & 0 deletions src/wizards/sampledvaluecontrol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
import { securityEnableEnum, smpModEnum } from './foundation/enums.js';
import { maxLength, patterns } from './foundation/limits.js';
import { editSMvWizard } from './smv.js';
import { editSmvOptsWizard } from './smvopts.js';

function getSMV(element: Element): Element | null {
const cbName = element.getAttribute('name');
Expand Down Expand Up @@ -224,6 +225,7 @@ export function editSampledValueControlWizard(element: Element): Wizard {
const securityEnable = element.getAttribute('securityEnabled');

const sMV = getSMV(element);
const smvOpts = element.querySelector('SmvOpts')!;

return [
{
Expand Down Expand Up @@ -257,6 +259,16 @@ export function editSampledValueControlWizard(element: Element): Wizard {
}}}"
></mwc-button>`
: html``,
html`<mwc-button
id="editsmvopts"
label=${translate('scl.SmvOpts')}
icon="edit"
@click="${(e: MouseEvent) => {
e.target?.dispatchEvent(
newSubWizardEvent(() => editSmvOptsWizard(smvOpts))
);
}}}"
></mwc-button>`,
html`<mwc-button
label="${translate('remove')}"
icon="delete"
Expand Down
86 changes: 86 additions & 0 deletions src/wizards/smvopts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { html, TemplateResult } from 'lit-element';
import { get, translate } from 'lit-translate';

import {
cloneElement,
getValue,
Wizard,
WizardAction,
WizardActor,
WizardInput,
} from '../foundation.js';

interface ContentOptions {
refreshTime: string | null;
sampleRate: string | null;
dataSet: string | null;
security: string | null;
synchSourceId: string | null;
}

function contentSmvOptsWizard(option: ContentOptions): TemplateResult[] {
return Object.entries(option).map(
([key, value]) =>
html`<wizard-checkbox
label="${key}"
.maybeValue=${value}
nullable
helper="${translate(`scl.${key}`)}"
></wizard-checkbox>`
);
}

function updateSmvOptsAction(element: Element): WizardActor {
return (inputs: WizardInput[]): WizardAction[] => {
const attributes: Record<string, string | null> = {};
const attributeKeys = [
'refreshTime',
'sampleRate',
'dataSet',
'security',
'synchSourceId',
];
attributeKeys.forEach(key => {
attributes[key] = getValue(inputs.find(i => i.label === key)!);
});

if (
!attributeKeys.some(key => attributes[key] !== element.getAttribute(key))
)
return [];

const newElement = cloneElement(element, attributes);
return [{ old: { element }, new: { element: newElement } }];
};
}

export function editSmvOptsWizard(element: Element): Wizard {
const [refreshTime, sampleRate, dataSet, security, synchSourceId] = [
'refreshTime',
'sampleRate',
'dataSet',
'security',
'synchSourceId',
].map(smvopt => element.getAttribute(smvopt));

return [
{
title: get('wizard.title.edit', { tagName: element.tagName }),
element,
primary: {
icon: 'save',
label: get('save'),
action: updateSmvOptsAction(element),
},
content: [
...contentSmvOptsWizard({
refreshTime,
sampleRate,
dataSet,
security,
synchSourceId,
}),
],
},
];
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ListItemBase } from '@material/mwc-list/mwc-list-item-base';
import { FilteredList } from '../../../src/filtered-list.js';
import { WizardTextField } from '../../../src/wizard-textfield.js';
import { selectSampledValueControlWizard } from '../../../src/wizards/sampledvaluecontrol.js';
import { WizardCheckbox } from '../../../src/wizard-checkbox.js';

describe('Wizards for SCL element SampledValueControl', () => {
let doc: XMLDocument;
Expand Down Expand Up @@ -239,6 +240,28 @@ describe('Wizards for SCL element SampledValueControl', () => {
);
});

it('opens a edit wizard for SMV on edit SMV button click', async () => {
const editSmvOptsButton = <Button>(
element.wizardUI.dialog!.querySelector(
'mwc-button[id="editsmvopts"]'
)!
);
expect(editSmvOptsButton).to.exist;

await editSmvOptsButton.updateComplete;
editSmvOptsButton.click();
await new Promise(resolve => setTimeout(resolve, 100)); // await animation
JakobVogelsang marked this conversation as resolved.
Show resolved Hide resolved

const macField = <WizardCheckbox>(
element.wizardUI.dialog?.querySelector(
'wizard-checkbox[label="refreshTime"]'
)
);
await macField.updateComplete;

expect(macField).to.exist;
});

it('removes the SampledValueControl element and its referenced elements on remove button click', async () => {
expect(
doc.querySelector(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ snapshots["Wizards for SCL element SampledValueControl define an edit wizard tha
SignatureAndEncryption
</mwc-list-item>
</wizard-select>
<mwc-button
icon="edit"
id="editsmvopts"
label="[scl.SmvOpts]"
>
</mwc-button>
<mwc-button
icon="delete"
label="[remove]"
Expand Down
60 changes: 60 additions & 0 deletions test/unit/wizards/__snapshots__/smvopts.test.snap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* @web/test-runner snapshot v1 */
export const snapshots = {};

snapshots["Wizards for SCL SmvOpts element define an edit wizard that looks like the latest snapshot"] =
`<mwc-dialog
defaultaction="close"
heading="[wizard.title.edit]"
open=""
>
<div id="wizard-content">
<wizard-checkbox
helper="[scl.refreshTime]"
label="refreshTime"
nullable=""
>
</wizard-checkbox>
<wizard-checkbox
helper="[scl.sampleRate]"
label="sampleRate"
nullable=""
>
</wizard-checkbox>
<wizard-checkbox
helper="[scl.dataSet]"
label="dataSet"
nullable=""
>
</wizard-checkbox>
<wizard-checkbox
helper="[scl.security]"
label="security"
nullable=""
>
</wizard-checkbox>
<wizard-checkbox
helper="[scl.synchSourceId]"
label="synchSourceId"
nullable=""
>
</wizard-checkbox>
</div>
<mwc-button
dialogaction="close"
label="[cancel]"
slot="secondaryAction"
style="--mdc-theme-primary: var(--mdc-theme-error)"
>
</mwc-button>
<mwc-button
dialoginitialfocus=""
icon="save"
label="[save]"
slot="primaryAction"
trailingicon=""
>
</mwc-button>
</mwc-dialog>
`;
/* end snapshot Wizards for SCL SmvOpts element define an edit wizard that looks like the latest snapshot */

Loading