From 9623493454654145f7cd29ac9adaf4a8bf7da0fb Mon Sep 17 00:00:00 2001 From: Jakob Vogelsang Date: Thu, 9 Dec 2021 13:42:44 +0100 Subject: [PATCH] refactor(ied-editor): use action-icon --- src/zeroline/ied-editor.ts | 161 +++--------------- .../__snapshots__/ied-editor.test.snap.js | 28 +++ test/unit/zeroline/ied-editor.test.ts | 82 +++++++++ 3 files changed, 135 insertions(+), 136 deletions(-) create mode 100644 test/unit/zeroline/__snapshots__/ied-editor.test.snap.js create mode 100644 test/unit/zeroline/ied-editor.test.ts diff --git a/src/zeroline/ied-editor.ts b/src/zeroline/ied-editor.ts index 02ed1ef2bc..bdff48db51 100644 --- a/src/zeroline/ied-editor.ts +++ b/src/zeroline/ied-editor.ts @@ -1,5 +1,4 @@ import { - css, customElement, html, LitElement, @@ -12,25 +11,27 @@ import '@material/mwc-fab'; import '@material/mwc-icon'; import { Fab } from '@material/mwc-fab'; +import '../action-icon.js'; import { createClientLnWizard } from '../wizards/clientln.js'; import { gooseIcon } from '../icons.js'; import { newWizardEvent } from '../foundation.js'; import { selectGseControlWizard } from '../wizards/gsecontrol.js'; -/** [[`SubstationEditor`]] subeditor for a `ConductingEquipment` element. */ +/** [[`SubstationEditor`]] subeditor for a child-less `IED` element. */ @customElement('ied-editor') export class IedEditor extends LitElement { - @property({ type: Element }) + /** SCL element IED */ + @property({ attribute: false }) element!: Element; - + /** IED name attribute */ @property({ type: String }) get name(): string { - return this.element.getAttribute('name') ?? ''; + return this.element.getAttribute('name') ?? 'UNDEFINED'; } - @query('#connectreport') connectReport!: Fab; + @query('.connectreport') connectReport!: Fab; - openCommunicationMapping(): void { + private openCommunicationMapping(): void { const sendingIeds = Array.from( this.element.closest('SCL')?.querySelectorAll('IED') ?? [] ); @@ -38,139 +39,27 @@ export class IedEditor extends LitElement { if (wizard) this.dispatchEvent(newWizardEvent(wizard)); } - openGseControlSelection(): void { + private openGseControlSelection(): void { const wizard = selectGseControlWizard(this.element); if (wizard) this.dispatchEvent(newWizardEvent(wizard)); } render(): TemplateResult { - return html` -
- - developer_board - - ${gooseIcon} -
-

${this.name}

- `; + return html` + ${gooseIcon} `; } - - static styles = css` - #container { - color: var(--mdc-theme-on-surface); - width: 50px; - height: 50px; - margin: auto; - position: relative; - transition: all 200ms linear; - user-select: none; - } - - #container:focus { - outline: none; - } - - .icon { - color: var(--mdc-theme-on-surface); - --mdc-icon-size: 50px; - transition: transform 150ms linear, box-shadow 200ms linear; - outline-color: var(--mdc-theme-primary); - outline-style: solid; - outline-width: 0px; - } - - #container > .icon { - color: var(--mdc-theme-on-surface); - width: 50px; - height: 50px; - transition: transform 150ms linear, box-shadow 200ms linear; - outline-color: var(--mdc-theme-primary); - outline-style: solid; - outline-width: 0px; - } - - #container:focus > .icon { - box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), - 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2); - } - - #container:hover > .icon { - outline: 2px dashed var(--mdc-theme-primary); - transition: transform 200ms linear, box-shadow 250ms linear; - } - - #container:focus-within > .icon { - outline: 2px solid var(--mdc-theme-primary); - background: var(--mdc-theme-on-primary); - transform: scale(0.8); - transition: transform 200ms linear, box-shadow 250ms linear; - } - - .menu-item { - color: var(--mdc-theme-on-surface); - transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 200ms linear; - position: absolute; - top: 2px; - left: 2px; - pointer-events: none; - z-index: 1; - opacity: 0; - } - - #container:focus-within > .menu-item { - transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 250ms linear; - pointer-events: auto; - opacity: 1; - } - - #container:focus-within > .menu-item.up { - transform: translate(0px, -60px); - } - - #container:focus-within > .menu-item.down { - transform: translate(0px, 60px); - } - - #container:focus-within > .menu-item.right { - transform: translate(60px, 0px); - } - - #container:focus-within > .menu-item.left { - transform: translate(-60px, 0px); - } - - h4 { - color: var(--mdc-theme-on-surface); - font-family: 'Roboto', sans-serif; - font-weight: 300; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - margin: 0px; - opacity: 1; - transition: opacity 200ms linear; - text-align: center; - direction: rtl; - } - - :host(.moving) #container, - :host(.moving) h4 { - opacity: 0.3; - } - `; } diff --git a/test/unit/zeroline/__snapshots__/ied-editor.test.snap.js b/test/unit/zeroline/__snapshots__/ied-editor.test.snap.js new file mode 100644 index 0000000000..16b24bc053 --- /dev/null +++ b/test/unit/zeroline/__snapshots__/ied-editor.test.snap.js @@ -0,0 +1,28 @@ +/* @web/test-runner snapshot v1 */ +export const snapshots = {}; + +snapshots["A component to visualize SCL element IED looks like the latest snapshot"] = +` + + + + + + + +`; +/* end snapshot A component to visualize SCL element IED looks like the latest snapshot */ + diff --git a/test/unit/zeroline/ied-editor.test.ts b/test/unit/zeroline/ied-editor.test.ts new file mode 100644 index 0000000000..34aca2e04b --- /dev/null +++ b/test/unit/zeroline/ied-editor.test.ts @@ -0,0 +1,82 @@ +import { fixture, html, expect } from '@open-wc/testing'; +import { SinonSpy, spy } from 'sinon'; + +import '../../../src/zeroline/ied-editor.js'; +import { IedEditor } from '../../../src/zeroline/ied-editor.js'; + +describe('A component to visualize SCL element IED', () => { + let element: IedEditor; + let validSCL: XMLDocument; + + let wizardEvent: SinonSpy; + + beforeEach(async () => { + validSCL = await fetch('/test/testfiles/valid2007B4.scd') + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')); + + element = ( + await fixture( + html`` + ) + ); + + wizardEvent = spy(); + window.addEventListener('wizard', wizardEvent); + }); + + it('looks like the latest snapshot', async () => { + await expect(element).shadowDom.to.equalSnapshot(); + }); + + it('renders label UNDEFINED in case IED name attribute is missing', async () => { + const condEq = validSCL.querySelector('IED'); + condEq?.removeAttribute('name'); + await element.requestUpdate(); + + expect(element).to.have.property('name', 'UNDEFINED'); + }); + + it('triggers select wizard for GSEControl element on action button click', async () => { + (( + element.shadowRoot?.querySelector('mwc-fab[class="selectgse"]') + )).click(); + + await element.requestUpdate(); + + expect(wizardEvent).to.have.be.calledOnce; + expect(wizardEvent.args[0][0].detail.wizard[0].title).to.contain('select'); + }); + + it('triggers create wizard for ClientLN element on action button click', async () => { + (( + element.shadowRoot?.querySelector('mwc-fab[class="connectreport"]') + )).click(); + + await element.requestUpdate(); + + expect(wizardEvent).to.have.be.calledOnce; + expect(wizardEvent.args[0][0].detail.wizard[0].title).to.contain( + 'connectToIED' + ); + }); + + it('still triggers create wizard for ClientLN element with missing parent', async () => { + const copyElement: Element = element.cloneNode(true); + element.element = copyElement; + await element.requestUpdate(); + + (( + element.shadowRoot?.querySelector('mwc-fab[class="connectreport"]') + )).click(); + + await element.requestUpdate(); + + expect(wizardEvent).to.have.been.calledOnce; + expect(wizardEvent.args[0][0].detail.wizard[0].title).to.contain( + 'connectToIED' + ); + }); +});