From 865f7ab33f7361b8f481be2c47f77b0fe1f05e81 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 28 Apr 2022 07:38:41 +0200 Subject: [PATCH] feat(iededitor): Added implementation to change enum values in IED Editor. --- src/editors/ied/foundation/foundation.ts | 77 ++++++++++--- src/wizards/dai.ts | 3 +- .../testfiles/valid2007B4ForDAIValidation.scd | 8 +- .../__snapshots__/foundation.test.snap.js | 55 +++++++++ .../editors/ied/foundation/foundation.test.ts | 107 +++++++++++------- 5 files changed, 191 insertions(+), 59 deletions(-) diff --git a/src/editors/ied/foundation/foundation.ts b/src/editors/ied/foundation/foundation.ts index 2d45b8c71e..557f4d33d9 100644 --- a/src/editors/ied/foundation/foundation.ts +++ b/src/editors/ied/foundation/foundation.ts @@ -1,14 +1,19 @@ import { html, TemplateResult } from "lit-html"; import { translate } from "lit-translate"; +import '@material/mwc-list/mwc-list-item'; + import '../../../../src/wizard-textfield.js'; import '../../../../src/wizard-select.js'; export interface CustomField { - render(value: string): TemplateResult; + render( + element: Element, + instanceElement?: Element + ): TemplateResult; } -const daiValidationTypes = ['BOOLEAN', 'INT8', 'INT16', 'INT24', 'INT32', 'INT64', +const daiValidationTypes = ['BOOLEAN', 'Enum', 'INT8', 'INT16', 'INT24', 'INT32', 'INT64', 'INT128', 'INT8U', 'INT16U', 'INT24U', 'INT32U', 'FLOAT32', 'FLOAT64', 'VisString32', 'VisString64', 'VisString65', 'VisString129', 'VisString255'] as const; export type DaiValidationTypes = typeof daiValidationTypes[number]; @@ -16,6 +21,7 @@ export type DaiValidationTypes = typeof daiValidationTypes[number]; export function getCustomField(): Record { return { BOOLEAN: booleanField(), + Enum: enumField(), INT8: integerField('INT8', -(2**8), 2**8-1), INT16: integerField('INT16', -(2**16), 2**16-1), INT24: integerField('INT24', -(2**24), 2**24-1), @@ -37,10 +43,10 @@ export function getCustomField(): Record { function booleanField(): CustomField { return { - render: (value: string) => { + render: (element: Element, instanceElement?: Element) => { return html` true @@ -50,48 +56,85 @@ export function getCustomField(): Record { } } + function enumField(): CustomField { + return { + render: (element: Element, instanceElement?: Element) => { + return html` + ${getEnumValues(element).map( + enumValue => { + return html`${enumValue}`; + })} + `; + } + } + } + function integerField(type: string, min: number, max: number): CustomField { return { - render: (value: string) => { + render: (element: Element, instanceElement?: Element) => { return html``; + max=${max}> + `; } } } function floatField(type: string, min: number, max: number): CustomField { return { - render: (value: string) => { + render: (element: Element, instanceElement?: Element) => { return html``; + step="0.1"> + `; } } } function stringField(type: string, maxNrOfCharacters: number): CustomField { return { - render: (value: string) => { + render: (element: Element, instanceElement?: Element) => { return html``; + type="text"> + `; } } } -} \ No newline at end of file + + function getValue(instanceElement?: Element): string { + return instanceElement!.querySelector('Val')?.textContent?.trim() ?? ''; + } + + function getEnumValues(element: Element): string[] { + const daType = element.getAttribute('type'); + const values: string[] = []; + + // No retrieve all the EnumVal Element to process these as values for the Select Element. + // Sort them on the attribute 'ord' and filter the ones that don't have a value. + Array.from(element.ownerDocument.querySelectorAll(`EnumType[id="${daType}"] > EnumVal`)) + .filter(enumValElement => enumValElement.textContent && enumValElement.textContent !== "") + .sort((eve1, eve2) => parseInt(eve1.getAttribute('ord') ?? "0") - parseInt(eve2.getAttribute('ord') ?? "0")) + .forEach(enumValElement => { + values.push(enumValElement.textContent ?? ''); + }); + + return values; + } +} diff --git a/src/wizards/dai.ts b/src/wizards/dai.ts index b8fe9671ab..1b122bdb53 100644 --- a/src/wizards/dai.ts +++ b/src/wizards/dai.ts @@ -36,10 +36,9 @@ export function renderDAIWizard( instanceElement?: Element ): TemplateResult[] { const bType = element.getAttribute('bType')!; - const value = instanceElement!.querySelector('Val')?.textContent?.trim() ?? ''; return [ - html`${getCustomField()[bType].render(value)}`, + html`${getCustomField()[bType].render(element, instanceElement)}`, ]; } diff --git a/test/testfiles/valid2007B4ForDAIValidation.scd b/test/testfiles/valid2007B4ForDAIValidation.scd index 9b80208d4f..1dfe96b847 100644 --- a/test/testfiles/valid2007B4ForDAIValidation.scd +++ b/test/testfiles/valid2007B4ForDAIValidation.scd @@ -141,6 +141,9 @@ true + + blocked + 5 @@ -206,7 +209,7 @@ - + status-only @@ -569,6 +572,7 @@ + @@ -742,4 +746,4 @@ process - \ No newline at end of file + diff --git a/test/unit/editors/ied/foundation/__snapshots__/foundation.test.snap.js b/test/unit/editors/ied/foundation/__snapshots__/foundation.test.snap.js index f388f550db..98a3beef24 100644 --- a/test/unit/editors/ied/foundation/__snapshots__/foundation.test.snap.js +++ b/test/unit/editors/ied/foundation/__snapshots__/foundation.test.snap.js @@ -56,6 +56,61 @@ snapshots["foundation getCustomField renders a BOOLEAN field correctly"] = `; /* end snapshot foundation getCustomField renders a BOOLEAN field correctly */ +snapshots["foundation getCustomField renders a ENUM field correctly"] = +`
+
+
+ + + + + + +
+
+
+
+
+`; +/* end snapshot foundation getCustomField renders a ENUM field correctly */ + snapshots["foundation getCustomField renders a INT8 field correctly"] = `
diff --git a/test/unit/editors/ied/foundation/foundation.test.ts b/test/unit/editors/ied/foundation/foundation.test.ts index 0611c3388d..1aa1f3414a 100644 --- a/test/unit/editors/ied/foundation/foundation.test.ts +++ b/test/unit/editors/ied/foundation/foundation.test.ts @@ -12,149 +12,180 @@ describe('foundation', async () => { }); describe('getCustomField', () => { - function getValue(daiName: string) { - return validSCL.querySelector(`DAI[name="${daiName}"] > Val`)?.textContent?.trim() + function getDAElement(doType: string, doName: string): Element { + return validSCL.querySelector(`DOType[id="${doType}"] > DA[name="${doName}"]`)!; + } + + function getDAIElement(daiName: string): Element | null { + return validSCL.querySelector(`DAI[name="${daiName}"]`); } it('renders a BOOLEAN field correctly', async () => { - const value = getValue("booleantest"); - const element = await fixture(html`${getCustomField()['BOOLEAN']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "booleantest"); + const daiElement = getDAIElement("booleantest"); + const element = await fixture(html`${getCustomField()['BOOLEAN']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('true'); }); + it('renders a ENUM field correctly', async () => { + const daElement = getDAElement("Dummy.LLN0.Beh", "enumtest"); + const daiElement = getDAIElement("enumtest"); + const element = await fixture(html`${getCustomField()['Enum']?.render(daElement, daiElement!)}`); + + await expect(element).shadowDom.to.equalSnapshot(); + expect(element.shadowRoot?.querySelector('input')?.value).to.eql('blocked'); + }); + it('renders a INT8 field correctly', async () => { - const value = getValue("int8test"); - const element = await fixture(html`${getCustomField()['INT8']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "int8test"); + const daiElement = getDAIElement("int8test"); + const element = await fixture(html`${getCustomField()['INT8']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('5'); }); it('renders a INT16 field correctly', async () => { - const value = getValue("int16test"); - const element = await fixture(html`${getCustomField()['INT16']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "int16test"); + const daiElement = getDAIElement("int16test"); + const element = await fixture(html`${getCustomField()['INT16']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('500'); }); it('renders a INT24 field correctly', async () => { - const value = getValue("int24test"); - const element = await fixture(html`${getCustomField()['INT24']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "int24test"); + const daiElement = getDAIElement("int24test"); + const element = await fixture(html`${getCustomField()['INT24']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('8321'); }); it('renders a INT32 field correctly', async () => { - const value = getValue("int32test"); - const element = await fixture(html`${getCustomField()['INT32']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "int32test"); + const daiElement = getDAIElement("int32test"); + const element = await fixture(html`${getCustomField()['INT32']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('83218'); }); it('renders a INT64 field correctly', async () => { - const value = getValue("int64test"); - const element = await fixture(html`${getCustomField()['INT64']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "int64test"); + const daiElement = getDAIElement("int64test"); + const element = await fixture(html`${getCustomField()['INT64']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('-543923'); }); it('renders a INT128 field correctly', async () => { - const value = getValue("int128test"); - const element = await fixture(html`${getCustomField()['INT128']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "int128test"); + const daiElement = getDAIElement("int128test"); + const element = await fixture(html`${getCustomField()['INT128']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('-8'); }); it('renders a INT8U field correctly', async () => { - const value = getValue("int8utest"); - const element = await fixture(html`${getCustomField()['INT8U']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "int8utest"); + const daiElement = getDAIElement("int8utest"); + const element = await fixture(html`${getCustomField()['INT8U']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('99'); }); it('renders a INT16U field correctly', async () => { - const value = getValue("int16utest"); - const element = await fixture(html`${getCustomField()['INT16U']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "int16utest"); + const daiElement = getDAIElement("int16utest"); + const element = await fixture(html`${getCustomField()['INT16U']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('20000'); }); it('renders a INT24U field correctly', async () => { - const value = getValue("int24utest"); - const element = await fixture(html`${getCustomField()['INT24U']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "int24utest"); + const daiElement = getDAIElement("int24utest"); + const element = await fixture(html`${getCustomField()['INT24U']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('654321'); }); it('renders a INT32U field correctly', async () => { - const value = getValue("int32utest"); - const element = await fixture(html`${getCustomField()['INT32U']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "int32utest"); + const daiElement = getDAIElement("int32utest"); + const element = await fixture(html`${getCustomField()['INT32U']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('2'); }); it('renders a FLOAT32 field correctly', async () => { - const value = getValue("float32test"); - const element = await fixture(html`${getCustomField()['INT32U']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "float32test"); + const daiElement = getDAIElement("float32test"); + const element = await fixture(html`${getCustomField()['INT32U']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('659.3'); }); it('renders a FLOAT64 field correctly', async () => { - const value = getValue("float64test"); - const element = await fixture(html`${getCustomField()['FLOAT64']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "float64test"); + const daiElement = getDAIElement("float64test"); + const element = await fixture(html`${getCustomField()['FLOAT64']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('1111659.8'); }); it('renders a VisString32 field correctly', async () => { - const value = getValue("visstring32test"); - const element = await fixture(html`${getCustomField()['VisString32']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "visstring32test"); + const daiElement = getDAIElement("visstring32test"); + const element = await fixture(html`${getCustomField()['VisString32']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('pull-ups'); }); it('renders a VisString64 field correctly', async () => { - const value = getValue("visstring64test"); - const element = await fixture(html`${getCustomField()['VisString64']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "visstring64test"); + const daiElement = getDAIElement("visstring64test"); + const element = await fixture(html`${getCustomField()['VisString64']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('lat pulldown'); }); it('renders a VisString65 field correctly', async () => { - const value = getValue("visstring65test"); - const element = await fixture(html`${getCustomField()['VisString65']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "visstring65test"); + const daiElement = getDAIElement("visstring65test"); + const element = await fixture(html`${getCustomField()['VisString65']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('bench press'); }); it('renders a VisString129 field correctly', async () => { - const value = getValue("visstring129test"); - const element = await fixture(html`${getCustomField()['VisString129']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "visstring129test"); + const daiElement = getDAIElement("visstring129test"); + const element = await fixture(html`${getCustomField()['VisString129']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('front squat'); }); it('renders a VisString255 field correctly', async () => { - const value = getValue("visstring255test"); - const element = await fixture(html`${getCustomField()['VisString255']?.render(value!)}`); + const daElement = getDAElement("Dummy.LLN0.Beh", "visstring255test"); + const daiElement = getDAIElement("visstring255test"); + const element = await fixture(html`${getCustomField()['VisString255']?.render(daElement, daiElement!)}`); await expect(element).shadowDom.to.equalSnapshot(); expect(element.shadowRoot?.querySelector('input')?.value).to.eql('deadlift');