From 3364eab4006610729079556a0662da389a1fd2ca Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Tue, 17 May 2022 12:23:22 +0200 Subject: [PATCH] Added new Communication 104 Editor framework. Signed-off-by: Dennis Labordus --- public/js/plugins.js | 7 ++ src/editors/Communication104.ts | 106 ++++++++++++++++++ .../communication104/foundation/foundation.ts | 32 ++++++ .../communication104/network-container.ts | 13 +++ .../communication104/values-container.ts | 13 +++ src/translations/de.ts | 6 + src/translations/en.ts | 6 + .../__snapshots__/open-scd.test.snap.js | 15 +++ .../editors/Communication104.test.ts | 44 ++++++++ .../{sampledvalues => }/SampledValues.test.ts | 8 +- .../{subscription => }/Subscription.test.ts | 10 +- .../Communication104.test.snap.js | 61 ++++++++++ .../__snapshots__/SampledValues.test.snap.js | 0 .../__snapshots__/Subscription.test.snap.js | 0 test/unit/editors/importieds.test.ts | 1 - .../{editors => menu}/subscriberinfo.test.ts | 0 .../updatesubstation.test.ts | 0 17 files changed, 312 insertions(+), 10 deletions(-) create mode 100644 src/editors/Communication104.ts create mode 100644 src/editors/communication104/foundation/foundation.ts create mode 100644 src/editors/communication104/network-container.ts create mode 100644 src/editors/communication104/values-container.ts create mode 100644 test/integration/editors/Communication104.test.ts rename test/integration/editors/{sampledvalues => }/SampledValues.test.ts (93%) rename test/integration/editors/{subscription => }/Subscription.test.ts (98%) create mode 100644 test/integration/editors/__snapshots__/Communication104.test.snap.js rename test/integration/editors/{sampledvalues => }/__snapshots__/SampledValues.test.snap.js (100%) rename test/integration/editors/{subscription => }/__snapshots__/Subscription.test.snap.js (100%) delete mode 100644 test/unit/editors/importieds.test.ts rename test/unit/{editors => menu}/subscriberinfo.test.ts (100%) rename test/unit/{editors => menu}/updatesubstation.test.ts (100%) diff --git a/public/js/plugins.js b/public/js/plugins.js index a1e4e11c67..9e0836c03e 100644 --- a/public/js/plugins.js +++ b/public/js/plugins.js @@ -41,6 +41,13 @@ export const officialPlugins = [ default: true, kind: 'editor', }, + { + name: '104', + src: '/src/editors/Communication104.js', + icon: 'settings_ethernet', + default: false, + kind: 'editor', + }, { name: 'Templates', src: '/src/editors/Templates.js', diff --git a/src/editors/Communication104.ts b/src/editors/Communication104.ts new file mode 100644 index 0000000000..488800d939 --- /dev/null +++ b/src/editors/Communication104.ts @@ -0,0 +1,106 @@ +import { + css, + html, + LitElement, + property, + query, + TemplateResult +} from "lit-element"; +import {translate} from "lit-translate"; + +import '@material/mwc-fab'; +import '@material/mwc-radio'; +import '@material/mwc-formfield'; + +import {RadioListItem} from "@material/mwc-list/mwc-radio-list-item"; + +import './communication104/network-container.js' +import './communication104/values-container.js' + +import { + newViewEvent, + View, + VIEW_EVENT_NAME, + ViewEvent +} from "./communication104/foundation/foundation.js"; + +/** Defining view outside the class, which makes it persistent. */ +let selectedViewCommunication104Plugin: View = View.VALUES; + +/** An editor [[`plugin`]] for editing the `IED` section. */ +export default class Communication104Plugin extends LitElement { + /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ + @property() + doc!: XMLDocument; + + @query('#byValuesRadio') + byValuesRadio!: RadioListItem; + + @query('#byNetworkRadio') + byNetworkRadio!: RadioListItem; + + @query('div[class="container"]') + listDiv!: Element; + + constructor() { + super(); + + this.addEventListener(VIEW_EVENT_NAME, (evt: ViewEvent) => { + selectedViewCommunication104Plugin = evt.detail.view; + this.requestUpdate(); + }); + } + + firstUpdated(): void { + selectedViewCommunication104Plugin == View.VALUES + ? this.byValuesRadio.setAttribute('checked', '') + : this.byNetworkRadio.setAttribute('checked', '') + } + + render(): TemplateResult { + return html`
+ + this.listDiv.dispatchEvent(newViewEvent(View.VALUES))} + > + + + this.listDiv.dispatchEvent(newViewEvent(View.NETWORK))} + > + +
+ ${selectedViewCommunication104Plugin == View.VALUES + ? html`` + : html`` + } +
+
`; + } + + static styles = css` + :host { + width: 100vw; + } + + .container { + display: flex; + padding: 8px 6px 16px; + height: 86vh; + } + + .row { + flex: 50%; + margin: 0px 6px 0px; + min-width: 300px; + height: 100%; + overflow-y: scroll; + } + `; +} diff --git a/src/editors/communication104/foundation/foundation.ts b/src/editors/communication104/foundation/foundation.ts new file mode 100644 index 0000000000..ef16f000ec --- /dev/null +++ b/src/editors/communication104/foundation/foundation.ts @@ -0,0 +1,32 @@ +/** + * Enumeration stating the current view of the 104 plugin. + */ +export enum View { + VALUES, + NETWORK +} + +export const VIEW_EVENT_NAME = 'view-change-104-plugin'; + +// Objects needed to register and fire the change of a view within the Communication 104 Plugin +export interface ViewDetail { + view: View; +} +export type ViewEvent = CustomEvent; +export function newViewEvent( + view: View, + eventInitDict?: CustomEventInit +): ViewEvent { + return new CustomEvent(VIEW_EVENT_NAME, { + bubbles: true, + composed: true, + ...eventInitDict, + detail: { view, ...eventInitDict?.detail }, + }); +} + +declare global { + interface ElementEventMap { + [VIEW_EVENT_NAME]: ViewEvent; + } +} diff --git a/src/editors/communication104/network-container.ts b/src/editors/communication104/network-container.ts new file mode 100644 index 0000000000..1ec3abfce2 --- /dev/null +++ b/src/editors/communication104/network-container.ts @@ -0,0 +1,13 @@ +import {css, customElement, html, LitElement, TemplateResult} from "lit-element"; + +@customElement('network-104-container') +export class NetworkContainer extends LitElement { + render(): TemplateResult { + return html` +

Network Container

+ `; + } + + static styles = css` + `; +} diff --git a/src/editors/communication104/values-container.ts b/src/editors/communication104/values-container.ts new file mode 100644 index 0000000000..d108807897 --- /dev/null +++ b/src/editors/communication104/values-container.ts @@ -0,0 +1,13 @@ +import {css, customElement, html, LitElement, TemplateResult} from "lit-element"; + +@customElement('values-104-container') +export class ValuesContainer extends LitElement { + render(): TemplateResult { + return html` +

Values Container

+ `; + } + + static styles = css` + `; +} diff --git a/src/translations/de.ts b/src/translations/de.ts index ce8fe8653b..a4c6da15f4 100644 --- a/src/translations/de.ts +++ b/src/translations/de.ts @@ -355,6 +355,12 @@ export const de: Translations = { noSampledValuesSelected: 'Keinen Kontrollblock ausgewählt', }, }, + communication104: { + view: { + valuesView: 'Values', + networkView: 'Network', + } + }, 'enum-val': { wizard: { title: { diff --git a/src/translations/en.ts b/src/translations/en.ts index 02a695c372..e3b107d270 100644 --- a/src/translations/en.ts +++ b/src/translations/en.ts @@ -352,6 +352,12 @@ export const en = { noSampledValuesSelected: 'No control block selected', }, }, + communication104: { + view: { + valuesView: 'Values', + networkView: 'Network', + } + }, 'enum-val': { wizard: { title: { diff --git a/test/integration/__snapshots__/open-scd.test.snap.js b/test/integration/__snapshots__/open-scd.test.snap.js index 53922f1ac2..73ee5789ae 100644 --- a/test/integration/__snapshots__/open-scd.test.snap.js +++ b/test/integration/__snapshots__/open-scd.test.snap.js @@ -652,6 +652,21 @@ snapshots["open-scd looks like its snapshot"] = Communication + + + settings_ethernet + + 104 + { + customElements.define( + 'communication104-plugin', + Wizarding(Editing(Communication104)) + ); + let element: Communication104; + let doc: XMLDocument; + + beforeEach(async () => { + doc = await fetch('/test/testfiles/communication.scd') + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')); + + element = await fixture( + html`` + ); + }); + + describe('in Values view', () => { + it('the plugin looks like the latest snapshot', async () => { + await expect(element).shadowDom.to.equalSnapshot(); + }); + }); + + describe('in Network view', () => { + beforeEach(async () => { + const radioButton = element.shadowRoot?.querySelector('#byNetworkRadio'); + (radioButton).click(); + await element.updateComplete; + }); + + it('the plugin looks like the latest snapshot', async () => { + await expect(element).shadowDom.to.equalSnapshot(); + }); + }); +}); diff --git a/test/integration/editors/sampledvalues/SampledValues.test.ts b/test/integration/editors/SampledValues.test.ts similarity index 93% rename from test/integration/editors/sampledvalues/SampledValues.test.ts rename to test/integration/editors/SampledValues.test.ts index a794d726f7..fc74ad1b0f 100644 --- a/test/integration/editors/sampledvalues/SampledValues.test.ts +++ b/test/integration/editors/SampledValues.test.ts @@ -1,10 +1,10 @@ import { html, fixture, expect } from '@open-wc/testing'; -import '../../../mock-wizard.js'; +import '../../mock-wizard.js'; -import SampledValues from '../../../../src/editors/SampledValues.js'; -import { Editing } from '../../../../src/Editing.js'; -import { Wizarding } from '../../../../src/Wizarding.js'; +import SampledValues from '../../../src/editors/SampledValues.js'; +import { Editing } from '../../../src/Editing.js'; +import { Wizarding } from '../../../src/Wizarding.js'; describe('Sampled Values Plugin', () => { customElements.define('smv-plugin', Wizarding(Editing(SampledValues))); diff --git a/test/integration/editors/subscription/Subscription.test.ts b/test/integration/editors/Subscription.test.ts similarity index 98% rename from test/integration/editors/subscription/Subscription.test.ts rename to test/integration/editors/Subscription.test.ts index b5d01c0387..b2522b45c1 100644 --- a/test/integration/editors/subscription/Subscription.test.ts +++ b/test/integration/editors/Subscription.test.ts @@ -1,10 +1,10 @@ import { html, fixture, expect } from '@open-wc/testing'; -import '../../../mock-wizard.js'; +import '../../mock-wizard.js'; -import Subscription from '../../../../src/editors/Subscription.js'; -import { Editing } from '../../../../src/Editing.js'; -import { Wizarding } from '../../../../src/Wizarding.js'; +import Subscription from '../../../src/editors/Subscription.js'; +import { Editing } from '../../../src/Editing.js'; +import { Wizarding } from '../../../src/Wizarding.js'; describe('Subscription Plugin', () => { customElements.define( @@ -197,7 +197,7 @@ describe('Subscription Plugin', () => { (radioButton).click(); await element.updateComplete; }); - + describe('initially', () => { it('the plugin looks like the latest snapshot', async () => { await expect(element).shadowDom.to.equalSnapshot(); diff --git a/test/integration/editors/__snapshots__/Communication104.test.snap.js b/test/integration/editors/__snapshots__/Communication104.test.snap.js new file mode 100644 index 0000000000..841dd8a705 --- /dev/null +++ b/test/integration/editors/__snapshots__/Communication104.test.snap.js @@ -0,0 +1,61 @@ +/* @web/test-runner snapshot v1 */ +export const snapshots = {}; + +snapshots["Communication 104 Plugin in Values view the plugin looks like the latest snapshot"] = +`
+ + + + + + + + +
+ + +
+
+ + +`; +/* end snapshot Communication 104 Plugin in Values view the plugin looks like the latest snapshot */ + +snapshots["Communication 104 Plugin in Network view the plugin looks like the latest snapshot"] = +`
+ + + + + + + + +
+ + +
+
+ + +`; +/* end snapshot Communication 104 Plugin in Network view the plugin looks like the latest snapshot */ + diff --git a/test/integration/editors/sampledvalues/__snapshots__/SampledValues.test.snap.js b/test/integration/editors/__snapshots__/SampledValues.test.snap.js similarity index 100% rename from test/integration/editors/sampledvalues/__snapshots__/SampledValues.test.snap.js rename to test/integration/editors/__snapshots__/SampledValues.test.snap.js diff --git a/test/integration/editors/subscription/__snapshots__/Subscription.test.snap.js b/test/integration/editors/__snapshots__/Subscription.test.snap.js similarity index 100% rename from test/integration/editors/subscription/__snapshots__/Subscription.test.snap.js rename to test/integration/editors/__snapshots__/Subscription.test.snap.js diff --git a/test/unit/editors/importieds.test.ts b/test/unit/editors/importieds.test.ts deleted file mode 100644 index f0fe4d7aa8..0000000000 --- a/test/unit/editors/importieds.test.ts +++ /dev/null @@ -1 +0,0 @@ -describe('ImportIedsPlugin', () => {}); diff --git a/test/unit/editors/subscriberinfo.test.ts b/test/unit/menu/subscriberinfo.test.ts similarity index 100% rename from test/unit/editors/subscriberinfo.test.ts rename to test/unit/menu/subscriberinfo.test.ts diff --git a/test/unit/editors/updatesubstation.test.ts b/test/unit/menu/updatesubstation.test.ts similarity index 100% rename from test/unit/editors/updatesubstation.test.ts rename to test/unit/menu/updatesubstation.test.ts