From 97c7428ff13d5cec6d1aef72c317a389d7e21ded Mon Sep 17 00:00:00 2001 From: Jakob Vogelsang Date: Wed, 19 Jan 2022 09:02:23 +0100 Subject: [PATCH 1/7] refactor(wizards/trgops): remove intPd manipulation as it collides with dynamic reports --- src/wizards/trgops.ts | 24 +------- test/unit/wizards/trgops.test.ts | 94 -------------------------------- 2 files changed, 1 insertion(+), 117 deletions(-) diff --git a/src/wizards/trgops.ts b/src/wizards/trgops.ts index b763c3d117..221c6ec048 100644 --- a/src/wizards/trgops.ts +++ b/src/wizards/trgops.ts @@ -6,7 +6,6 @@ import '@material/mwc-list/mwc-list-item'; import '../wizard-select.js'; import { cloneElement, - EditorAction, getValue, Wizard, WizardAction, @@ -14,22 +13,6 @@ import { WizardInput, } from '../foundation.js'; -function updateIntPdInParentReportAction( - report: Element | null, - isPeriodActive: boolean -): EditorAction | undefined { - if ( - !report || - (isPeriodActive && report.getAttribute('intgPd')) || - (!isPeriodActive && !report.getAttribute('intgPd')) - ) - return; - - const intgPd = isPeriodActive ? '1000' : null; - const newElement = cloneElement(report, { intgPd }); - return { old: { element: report }, new: { element: newElement } }; -} - function updateTrgOpsAction(element: Element): WizardActor { return (inputs: WizardInput[]): WizardAction[] => { const dchg = getValue(inputs.find(i => i.label === 'dchg')!); @@ -56,12 +39,7 @@ function updateTrgOpsAction(element: Element): WizardActor { }); const trgOptAction = { old: { element }, new: { element: newElement } }; - const intPdAction = updateIntPdInParentReportAction( - element.parentElement, - period === 'true' ? true : false - ); - - return intPdAction ? [trgOptAction, intPdAction] : [trgOptAction]; + return [trgOptAction]; }; } diff --git a/test/unit/wizards/trgops.test.ts b/test/unit/wizards/trgops.test.ts index 5fd2a03902..b7a0eee114 100644 --- a/test/unit/wizards/trgops.test.ts +++ b/test/unit/wizards/trgops.test.ts @@ -143,99 +143,5 @@ describe('Wizards for SCL TrgOps element', () => { expect(updateAction.old.element).to.not.have.attribute('period'); expect(updateAction.new.element).to.have.attribute('period', 'true'); }); - - describe('with existing parent report control block', () => { - let reportControlBlock: Element; - - beforeEach(async () => { - reportControlBlock = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - trgOps = reportControlBlock.querySelector('TrgOps')!; - element.workflow.length = 0; - const wizard = editTrgOpsWizard(trgOps); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - await element.requestUpdate(); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('adds missing intgPd in parent report control block with selected period', async () => { - const input = inputs[3]; - input.nullSwitch?.click(); - input.value = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledTwice; - - const action1 = actionEvent.args[0][0].detail.action; - const action2 = actionEvent.args[1][0].detail.action; - - expect(action1).to.satisfy(isUpdate); - expect(action2).to.satisfy(isUpdate); - - const updateAction2 = action2; - - expect(updateAction2.old.element).to.not.have.attribute('intgPd'); - expect(updateAction2.new.element).to.have.attribute('intgPd', '1000'); - }); - - it('removes intgPd in parent report control block with deselected period', async () => { - const input = inputs[3]; - reportControlBlock.setAttribute('intgPd', '1000'); - input.nullSwitch?.click(); - input.value = 'false'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledTwice; - - const action1 = actionEvent.args[0][0].detail.action; - const action2 = actionEvent.args[1][0].detail.action; - - expect(action1).to.satisfy(isUpdate); - expect(action2).to.satisfy(isUpdate); - - const updateAction2 = action2; - expect(updateAction2.old.element).to.have.attribute('intgPd', '1000'); - expect(updateAction2.new.element).to.not.have.attribute('intgPd'); - }); - - it('does not falsely add intgPd in parent report control block', async () => { - const input = inputs[3]; - reportControlBlock.setAttribute('intgPd', '1000'); - input.nullSwitch?.click(); - input.value = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - }); - - it('does not falsely remove intgPd in parent report control block', async () => { - const input = inputs[3]; - input.nullSwitch?.click(); - input.value = 'false'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - }); - }); }); }); From eba4898f56f578c4b1c0cc4d2aca931c12031a2c Mon Sep 17 00:00:00 2001 From: Jakob Vogelsang Date: Wed, 19 Jan 2022 10:34:13 +0100 Subject: [PATCH 2/7] refactor(wizards/dataset): disable name update and move action button to bottom --- src/wizards/dataset.ts | 25 +++++++++---------- .../__snapshots__/dataset.test.snap.js | 11 ++++---- test/unit/wizards/dataset.test.ts | 8 +++--- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/wizards/dataset.ts b/src/wizards/dataset.ts index 7bf27bc6b1..ecb24430a6 100644 --- a/src/wizards/dataset.ts +++ b/src/wizards/dataset.ts @@ -11,7 +11,7 @@ import { cloneElement, getValue, identity, - newWizardEvent, + newSubWizardEvent, selector, Update, Wizard, @@ -19,7 +19,7 @@ import { WizardActor, WizardInput, } from '../foundation.js'; -import { wizards } from './wizard-library.js'; +import { createFCDAsWizard } from './fcda.js'; function updateDataSetAction(element: Element): WizardActor { return (inputs: WizardInput[], wizard: Element): WizardAction[] => { @@ -95,6 +95,7 @@ export function editDataSetWizard(element: Element): Wizard { .maybeValue=${name} helper="${translate('scl.name')}" required + disabled="true" > `, html` `, - html` { - const wizard = wizards['FCDA'].create(element); - if (wizard) { - e.target?.dispatchEvent(newWizardEvent(wizard)); - e.target?.dispatchEvent(newWizardEvent()); - } - }} - >`, html`${Array.from(element.querySelectorAll('FCDA')).map( fcda => @@ -124,6 +114,15 @@ export function editDataSetWizard(element: Element): Wizard { >` )}`, + html``, ], }, ]; diff --git a/test/unit/wizards/__snapshots__/dataset.test.snap.js b/test/unit/wizards/__snapshots__/dataset.test.snap.js index 5b297d70ab..4c987b3e23 100644 --- a/test/unit/wizards/__snapshots__/dataset.test.snap.js +++ b/test/unit/wizards/__snapshots__/dataset.test.snap.js @@ -9,6 +9,7 @@ snapshots["dataset wizards include a dataset edit wizard looks like the latest s >
- - + +
{ element.workflow.push(() => wizard); await element.requestUpdate(); - wizardEvent = sinon.spy(); + wizardEvent = spy(); window.addEventListener('wizard', wizardEvent); - actionEvent = sinon.spy(); + actionEvent = spy(); window.addEventListener('editor-action', actionEvent); }); @@ -50,7 +50,7 @@ describe('dataset wizards', () => { element.wizardUI.dialog?.querySelector('mwc-button[icon="add"]') ); await addButton.click(); - expect(wizardEvent).to.be.calledTwice; + expect(wizardEvent).to.be.calledOnce; }); describe('with stand alone DataSet', () => { From 9748dc4160753272957df76ef331164502bf628e Mon Sep 17 00:00:00 2001 From: Jakob Vogelsang Date: Wed, 19 Jan 2022 10:40:25 +0100 Subject: [PATCH 3/7] refactor(wiazrds/fcda): adapt for dynamic sub-wizards --- src/wizards/fcda.ts | 19 ++++++++++--------- test/unit/wizards/fcda.test.ts | 8 ++------ 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/wizards/fcda.ts b/src/wizards/fcda.ts index c9aace2906..c71ed473f1 100644 --- a/src/wizards/fcda.ts +++ b/src/wizards/fcda.ts @@ -114,9 +114,8 @@ function getReader(server: Element): (path: string[]) => Promise { }; } -export function createFCDAsWizard(parent: Element): Wizard | undefined { +export function createFCDAsWizard(parent: Element): Wizard { const server = parent.closest('Server'); - if (!server) return; return [ { @@ -127,13 +126,15 @@ export function createFCDAsWizard(parent: Element): Wizard | undefined { action: createFCDAsAction(parent), }, content: [ - html` path[path.length - 1]} - >`, + server + ? html` path[path.length - 1]} + >` + : html``, ], }, ]; diff --git a/test/unit/wizards/fcda.test.ts b/test/unit/wizards/fcda.test.ts index e78ec6db03..82995f0481 100644 --- a/test/unit/wizards/fcda.test.ts +++ b/test/unit/wizards/fcda.test.ts @@ -1,5 +1,5 @@ import { expect, fixture, html } from '@open-wc/testing'; -import sinon, { SinonSpy } from 'sinon'; +import { SinonSpy, spy } from 'sinon'; import '../../mock-wizard.js'; import { MockWizard } from '../../mock-wizard.js'; @@ -21,7 +21,7 @@ describe('create wizard for FCDA element', () => { .then(response => response.text()) .then(str => new DOMParser().parseFromString(str, 'application/xml')); - actionEvent = sinon.spy(); + actionEvent = spy(); window.addEventListener('editor-action', actionEvent); }); @@ -43,10 +43,6 @@ describe('create wizard for FCDA element', () => { await expect(element.wizardUI.dialog).to.equalSnapshot(); }); - it('returns undefined wizard for parents without Server', () => - expect(createFCDAsWizard(doc.querySelector('AccessPoint')!)).to.be - .undefined); - it('indicates error in case children cannot be determined', async () => { finder.paths = [['some wrong path']]; await element.requestUpdate(); From 507cf6aac5b27b0c8218d36eeba9b480822201a7 Mon Sep 17 00:00:00 2001 From: Jakob Vogelsang Date: Wed, 19 Jan 2022 10:58:31 +0100 Subject: [PATCH 4/7] feat(translation): add scl terms --- src/translations/de.ts | 2 ++ src/translations/en.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/translations/de.ts b/src/translations/de.ts index 3d4a5c596b..6de352ea8e 100644 --- a/src/translations/de.ts +++ b/src/translations/de.ts @@ -34,6 +34,8 @@ export const de: Translations = { securityEnabled: 'Aktive Sicherungsmaßnahmen', DataSet: 'Datensetz', Communication: 'Kommunikation', + TrgOps: 'Triggerbedingungen', + OptFields: 'Optionale felder', }, settings: { title: 'Einstellungen', diff --git a/src/translations/en.ts b/src/translations/en.ts index 0f2698340d..03b21e020f 100644 --- a/src/translations/en.ts +++ b/src/translations/en.ts @@ -32,6 +32,8 @@ export const en = { securityEnabled: 'Security enabled', DataSet: 'Dataset', Communication: 'Communication', + TrgOps: 'Trigger options', + OptFields: 'Optional fields', }, settings: { title: 'Settings', From 493a0c75c7820af6c3c17e47dc5f23a4369f8e4c Mon Sep 17 00:00:00 2001 From: Jakob Vogelsang Date: Wed, 19 Jan 2022 10:59:52 +0100 Subject: [PATCH 5/7] feat(wiazrds/reportcontrol): add related sub wizards --- src/wizards/reportcontrol.ts | 45 ++++++++++++++++ .../reportcontrol-wizarding-editing.test.ts | 54 +++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/src/wizards/reportcontrol.ts b/src/wizards/reportcontrol.ts index 289c1880b7..73d3fab270 100644 --- a/src/wizards/reportcontrol.ts +++ b/src/wizards/reportcontrol.ts @@ -29,6 +29,9 @@ import { Delete, } from '../foundation.js'; import { maxLength, patterns } from './foundation/limits.js'; +import { editTrgOpsWizard } from './trgops.js'; +import { editOptFieldsWizard } from './optfields.js'; +import { editDataSetWizard } from './dataset.js'; export function removeReportControlAction(element: Element): Delete[] { if (!element.parentElement) return []; @@ -241,6 +244,12 @@ export function editReportControlWizard(element: Element): Wizard { const bufTime = element.getAttribute('bufTime'); const intgPd = element.getAttribute('intgPd'); + const trgOps = element.querySelector('TrgOps'); + const optFields = element.querySelector('OptFields'); + const dataSet = element.parentElement?.querySelector( + `DataSet[name="${element.getAttribute('datSet')}"]` + ); + return [ { title: get('wizard.title.edit', { tagName: element.tagName }), @@ -261,6 +270,42 @@ export function editReportControlWizard(element: Element): Wizard { bufTime, intgPd, }), + dataSet + ? html` { + e.target?.dispatchEvent( + newSubWizardEvent(() => editDataSetWizard(dataSet)) + ); + }} + >` + : html``, + trgOps + ? html` { + e.target?.dispatchEvent( + newSubWizardEvent(() => editTrgOpsWizard(trgOps)) + ); + }} + >` + : html``, + optFields + ? html` { + e.target?.dispatchEvent( + newSubWizardEvent(() => editOptFieldsWizard(optFields)) + ); + }} + >` + : html``, html` { let parentIED: Element; beforeEach(async () => { + element.workflow.length = 0; // remove all wizard from FIFO queue parentIED = doc.querySelector('IED')!; element.workflow.push(() => selectReportControlWizard(parentIED)); await element.requestUpdate(); @@ -162,6 +163,59 @@ describe('Wizards for SCL element ReportControl', () => { expect(report.innerHTML).to.contain('ReportCb'); }); + it('opens edit wizard for DataSet element on edit dataset button click', async () => { + const editDataSetButton =