From 1d2bf4edb2513331306f43db955afc4222bad3af Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 27 May 2021 08:04:23 +0200 Subject: [PATCH 001/246] Automate adding issues to project boards. Signed-off-by: Dennis Labordus --- .github/workflows/automate_projects.yml | 33 +++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/automate_projects.yml diff --git a/.github/workflows/automate_projects.yml b/.github/workflows/automate_projects.yml new file mode 100644 index 0000000000..8b08620ecb --- /dev/null +++ b/.github/workflows/automate_projects.yml @@ -0,0 +1,33 @@ +# SPDX-FileCopyrightText: 2021 Alliander N.V. +# +# SPDX-License-Identifier: Apache-2.0 + +name: Add issues and pull request to project boards + +on: [ issues, pull_request ] + +jobs: + github-actions-automate-projects: + runs-on: ubuntu-latest + steps: + - name: add-new-issues-to-repository-based-project-column + uses: takanabe/github-actions-automate-projects@v0.0.2 + if: github.event_name == 'issues' && github.event.action == 'opened' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_PROJECT_URL: https://github.com/com-pas/compas-open-scd/projects/1 + GITHUB_PROJECT_COLUMN_NAME: To do + - name: add-new-pull-rquest-to-repository-based-project-column + uses: takanabe/github-actions-automate-projects@v0.0.2 + if: github.event_name == 'pull_request' && github.event.action == 'opened' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_PROJECT_URL: https://github.com/com-pas/compas-open-scd/projects/1 + GITHUB_PROJECT_COLUMN_NAME: To do + - name: add-new-issues-to-organization-based-project-column + uses: takanabe/github-actions-automate-projects@v0.0.2 + if: github.event_name == 'issues' && github.event.action == 'opened' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_PROJECT_URL: https://github.com/orgs/com-pas/projects/1 + GITHUB_PROJECT_COLUMN_NAME: To do From 46938283537389de110dbdc025641c0bc10d57c4 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 27 May 2021 08:19:41 +0200 Subject: [PATCH 002/246] Automate adding issues to project boards. Signed-off-by: Dennis Labordus --- .github/workflows/automate_projects.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/automate_projects.yml b/.github/workflows/automate_projects.yml index 8b08620ecb..9536fc1df1 100644 --- a/.github/workflows/automate_projects.yml +++ b/.github/workflows/automate_projects.yml @@ -17,7 +17,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_PROJECT_URL: https://github.com/com-pas/compas-open-scd/projects/1 GITHUB_PROJECT_COLUMN_NAME: To do - - name: add-new-pull-rquest-to-repository-based-project-column + - name: add-new-pull-request-to-repository-based-project-column uses: takanabe/github-actions-automate-projects@v0.0.2 if: github.event_name == 'pull_request' && github.event.action == 'opened' env: @@ -31,3 +31,10 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_PROJECT_URL: https://github.com/orgs/com-pas/projects/1 GITHUB_PROJECT_COLUMN_NAME: To do + - name: add-new-pull-request-to-organization-based-project-column + uses: takanabe/github-actions-automate-projects@v0.0.2 + if: github.event_name == 'pull_request' && github.event.action == 'opened' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_PROJECT_URL: https://github.com/orgs/com-pas/projects/2 + GITHUB_PROJECT_COLUMN_NAME: To do From 8e7756e80819539b093b7eb0de5068136b3671fd Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 27 May 2021 16:17:16 +0200 Subject: [PATCH 003/246] Change the secret used for organisation. Signed-off-by: Dennis Labordus --- .github/workflows/automate_projects.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/automate_projects.yml b/.github/workflows/automate_projects.yml index 9536fc1df1..1f1c9a5dec 100644 --- a/.github/workflows/automate_projects.yml +++ b/.github/workflows/automate_projects.yml @@ -1,6 +1,6 @@ # SPDX-FileCopyrightText: 2021 Alliander N.V. # -# SPDX-License-Identifier: Apache-2.0 +# SPDX-License-Identifier: CC-BY-4.0 name: Add issues and pull request to project boards @@ -28,13 +28,13 @@ jobs: uses: takanabe/github-actions-automate-projects@v0.0.2 if: github.event_name == 'issues' && github.event.action == 'opened' env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.ORG_GITHUB_ACTION_SECRET }} GITHUB_PROJECT_URL: https://github.com/orgs/com-pas/projects/1 GITHUB_PROJECT_COLUMN_NAME: To do - name: add-new-pull-request-to-organization-based-project-column uses: takanabe/github-actions-automate-projects@v0.0.2 if: github.event_name == 'pull_request' && github.event.action == 'opened' env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.ORG_GITHUB_ACTION_SECRET }} GITHUB_PROJECT_URL: https://github.com/orgs/com-pas/projects/2 GITHUB_PROJECT_COLUMN_NAME: To do From 148355706c85ccabcfc7f29b50f3024768dd063d Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Mon, 31 May 2021 15:25:39 +0200 Subject: [PATCH 004/246] Used correct github action image. Signed-off-by: Dennis Labordus --- .github/workflows/automate_projects.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/automate_projects.yml b/.github/workflows/automate_projects.yml index 1f1c9a5dec..1046058890 100644 --- a/.github/workflows/automate_projects.yml +++ b/.github/workflows/automate_projects.yml @@ -11,28 +11,28 @@ jobs: runs-on: ubuntu-latest steps: - name: add-new-issues-to-repository-based-project-column - uses: takanabe/github-actions-automate-projects@v0.0.2 + uses: docker://takanabe/github-actions-automate-projects:v0.0.1 if: github.event_name == 'issues' && github.event.action == 'opened' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_PROJECT_URL: https://github.com/com-pas/compas-open-scd/projects/1 GITHUB_PROJECT_COLUMN_NAME: To do - name: add-new-pull-request-to-repository-based-project-column - uses: takanabe/github-actions-automate-projects@v0.0.2 + uses: docker://takanabe/github-actions-automate-projects:v0.0.1 if: github.event_name == 'pull_request' && github.event.action == 'opened' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_PROJECT_URL: https://github.com/com-pas/compas-open-scd/projects/1 GITHUB_PROJECT_COLUMN_NAME: To do - name: add-new-issues-to-organization-based-project-column - uses: takanabe/github-actions-automate-projects@v0.0.2 + uses: docker://takanabe/github-actions-automate-projects:v0.0.1 if: github.event_name == 'issues' && github.event.action == 'opened' env: GITHUB_TOKEN: ${{ secrets.ORG_GITHUB_ACTION_SECRET }} GITHUB_PROJECT_URL: https://github.com/orgs/com-pas/projects/1 GITHUB_PROJECT_COLUMN_NAME: To do - name: add-new-pull-request-to-organization-based-project-column - uses: takanabe/github-actions-automate-projects@v0.0.2 + uses: docker://takanabe/github-actions-automate-projects:v0.0.1 if: github.event_name == 'pull_request' && github.event.action == 'opened' env: GITHUB_TOKEN: ${{ secrets.ORG_GITHUB_ACTION_SECRET }} From 2b8bfe216adf07c26485894ec8bd15c6e59c2ed8 Mon Sep 17 00:00:00 2001 From: Christian Dinkel Date: Wed, 2 Jun 2021 12:10:27 +0200 Subject: [PATCH 005/246] refactor(triggered): add open file plugin --- public/js/plugins.js | 17 ++++++++---- src/Editing.ts | 17 ++++++++++++ src/Logging.ts | 2 ++ src/Plugging.ts | 1 + src/foundation.ts | 54 +++++++++++++++++++++------------------ src/open-scd.ts | 44 ++++++++++--------------------- src/triggered/OpenFile.ts | 41 +++++++++++++++++++++++++++++ 7 files changed, 116 insertions(+), 60 deletions(-) create mode 100644 src/triggered/OpenFile.ts diff --git a/public/js/plugins.js b/public/js/plugins.js index 8cb7d61705..ca9e85c860 100644 --- a/public/js/plugins.js +++ b/public/js/plugins.js @@ -1,4 +1,11 @@ export const officialPlugins = [ + { + name: 'Open file', + src: '/src/triggered/OpenFile.js', + icon: 'coronavirus', + default: true, + kind: 'triggered' + }, { name: 'Substation', src: '/src/editors/Substation.js', @@ -21,11 +28,11 @@ export const officialPlugins = [ kind: 'editor', }, { - "name": "Import IEDs", - "src": "/src/triggered/ImportIEDs.js", - "icon": "snippet_folder", - "default": true, - "kind": "triggered" + name: "Import IEDs", + src: "/src/triggered/ImportIEDs.js", + icon: "snippet_folder", + default: true, + kind: "triggered" }, { name: 'Subscriber Update', diff --git a/src/Editing.ts b/src/Editing.ts index 6185b926f1..fd09ec1d57 100644 --- a/src/Editing.ts +++ b/src/Editing.ts @@ -15,6 +15,7 @@ import { Mixin, Move, newLogEvent, + OpenDocEvent, SimpleAction, Update, } from './foundation.js'; @@ -51,6 +52,8 @@ export function Editing(Base: TBase) { doc: XMLDocument | null = null; /** The name of the current [[`doc`]] */ @property({ type: String }) docName = ''; + /** The UUID of the current [[`doc`]] */ + @property({ type: String }) docId = ''; private checkCreateValidity(create: Create): boolean { if (create.checkValidity !== undefined) return create.checkValidity(); @@ -255,10 +258,24 @@ export function Editing(Base: TBase) { if (element instanceof LitElement) element.requestUpdate(); } + private onOpenDoc(event: OpenDocEvent) { + this.doc = event.detail.doc; + this.docName = event.detail.docName; + this.docId = event.detail.docId ?? ''; + + this.dispatchEvent( + newLogEvent({ + kind: 'info', + title: get('openSCD.loaded', { name: this.docName }), + }) + ); + } + constructor(...args: any[]) { super(...args); this.addEventListener('editor-action', this.onAction); + this.addEventListener('open-doc', this.onOpenDoc); } } diff --git a/src/Logging.ts b/src/Logging.ts index c1e521e6dd..f54c5f090a 100644 --- a/src/Logging.ts +++ b/src/Logging.ts @@ -145,9 +145,11 @@ export function Logging(Base: TBase) { this.undo = this.undo.bind(this); this.redo = this.redo.bind(this); + this.reset = this.reset.bind(this); this.onLog = this.onLog.bind(this); this.addEventListener('log', this.onLog); + this.addEventListener('open-doc', this.reset); } renderLogEntry( diff --git a/src/Plugging.ts b/src/Plugging.ts index 0ddfdac9ce..6ddc13fc91 100644 --- a/src/Plugging.ts +++ b/src/Plugging.ts @@ -150,6 +150,7 @@ export function Plugging EditingElement>( return html`<${loadedPlugins.get(plugin.src)} .doc=${this.doc} .docName=${this.docName} + .docId=${this.docId} >`; }, }; diff --git a/src/foundation.ts b/src/foundation.ts index 0b1aacad79..76c76e903b 100644 --- a/src/foundation.ts +++ b/src/foundation.ts @@ -261,6 +261,26 @@ export function newPendingStateEvent( }); } +/** Represents a document to be opened. */ +export interface OpenDocDetail { + doc: XMLDocument; + docName: string; + docId?: string; +} +export type OpenDocEvent = CustomEvent; +export function newOpenDocEvent( + doc: XMLDocument, + docName: string, + eventInitDict?: CustomEventInit> +): OpenDocEvent { + return new CustomEvent('open-doc', { + bubbles: true, + composed: true, + ...eventInitDict, + detail: { doc, docName, ...eventInitDict?.detail }, + }); +} + /** @returns a reference to `element` with segments delimited by '/'. */ // TODO(c-dinkel): replace with identity (FIXME) export function referencePath(element: Element): string { @@ -441,9 +461,8 @@ function iEDNameIdentity(e: Element): string { function iEDNameSelector(tagName: SCLTag, identity: string): string { const [parentIdentity, childIdentity] = pathParts(identity); - const [iedName, apRef, ldInst, prefix, lnClass, lnInst] = childIdentity.split( - /[ /]/ - ); + const [iedName, apRef, ldInst, prefix, lnClass, lnInst] = + childIdentity.split(/[ /]/); const [ parentSelectors, @@ -637,15 +656,8 @@ function extRefSelector(tagName: SCLTag, identity: string): string { intAddr; if (!childIdentity.includes(':') && !childIdentity.includes('@')) { - [ - iedName, - ldInst, - prefix, - lnClass, - lnInst, - doName, - daName, - ] = childIdentity.split(/[ /]/); + [iedName, ldInst, prefix, lnClass, lnInst, doName, daName] = + childIdentity.split(/[ /]/); } else if (childIdentity.includes(':') && !childIdentity.includes('@')) { [ serviceType, @@ -663,16 +675,8 @@ function extRefSelector(tagName: SCLTag, identity: string): string { daName, ] = childIdentity.split(/[ /:]/); } else if (!childIdentity.includes(':') && childIdentity.includes('@')) { - [ - iedName, - ldInst, - prefix, - lnClass, - lnInst, - doName, - daName, - intAddr, - ] = childIdentity.split(/[ /@]/); + [iedName, ldInst, prefix, lnClass, lnInst, doName, daName, intAddr] = + childIdentity.split(/[ /@]/); } else { [ serviceType, @@ -816,9 +820,8 @@ function clientLNSelector(tagName: SCLTag, identity: string): string { selector(parentTag, parentIdentity).split(',') ); - const [iedName, apRef, ldInst, prefix, lnClass, lnInst] = childIdentity.split( - /[ /]/ - ); + const [iedName, apRef, ldInst, prefix, lnClass, lnInst] = + childIdentity.split(/[ /]/); const [ iedNameSelectors, @@ -2450,6 +2453,7 @@ declare global { interface ElementEventMap { ['pending-state']: PendingStateEvent; ['editor-action']: EditorActionEvent; + ['open-doc']: OpenDocEvent; ['wizard']: WizardEvent; ['log']: LogEvent; } diff --git a/src/open-scd.ts b/src/open-scd.ts index adc0ac2656..899d138246 100644 --- a/src/open-scd.ts +++ b/src/open-scd.ts @@ -44,6 +44,7 @@ import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; import { EditorAction, newLogEvent, + newOpenDocEvent, newPendingStateEvent, newWizardEvent, Wizard, @@ -101,44 +102,27 @@ export class OpenSCD extends Setting( /** Loads and parses an `XMLDocument` after [[`src`]] has changed. */ private async loadDoc(src: string): Promise { - this.reset(); - - this.dispatchEvent( - newLogEvent({ - kind: 'info', - title: get('openSCD.loading', { name: this.docName }), - }) - ); - const response = await fetch(src); const text = await response.text(); - this.doc = new DOMParser().parseFromString(text, 'application/xml'); - - if (src.startsWith('blob:')) URL.revokeObjectURL(src); - - const validated = this.validate(this.doc, { fileName: this.docName }); + if (!text) return; - if (this.doc) this.dispatchEvent(newPendingStateEvent(validated)); + const doc = new DOMParser().parseFromString(text, 'application/xml'); + const docName = src; + this.dispatchEvent(newOpenDocEvent(doc, docName)); - await validated; - - this.dispatchEvent( - newLogEvent({ - kind: 'info', - title: get('openSCD.loaded', { name: this.docName }), - }) - ); - return; + if (src.startsWith('blob:')) URL.revokeObjectURL(src); } - /** Loads the file `event.target.files[0]` into [[`src`]] as a `blob:...`. */ - private loadFile(event: Event): void { + private async loadFile(event: Event): Promise { const file = (event.target)?.files?.item(0) ?? false; - if (file) { - this.docName = file.name; - this.setAttribute('src', URL.createObjectURL(file)); - } + if (!file) return; + + const text = await file.text(); + const docName = file.name; + const doc = new DOMParser().parseFromString(text, 'application/xml'); + + this.dispatchEvent(newOpenDocEvent(doc, docName)); } private saveAs(): void { diff --git a/src/triggered/OpenFile.ts b/src/triggered/OpenFile.ts new file mode 100644 index 0000000000..68f0ca55c7 --- /dev/null +++ b/src/triggered/OpenFile.ts @@ -0,0 +1,41 @@ +import { css, html, LitElement, query, TemplateResult } from 'lit-element'; + +import { newOpenDocEvent } from '../foundation.js'; + +export default class OpenFilePlugin extends LitElement { + @query('#open-plugin-input') pluginFileUI!: HTMLInputElement; + + async openDoc(event: Event): Promise { + const file = + (event.target)?.files?.item(0) ?? false; + if (!file) return; + + const text = await file.text(); + const docName = file.name; + const doc = new DOMParser().parseFromString(text, 'application/xml'); + + document + .querySelector('open-scd')! + .dispatchEvent(newOpenDocEvent(doc, docName)); + this.pluginFileUI.onchange = null; + } + + async trigger(): Promise { + this.pluginFileUI.click(); + } + + render(): TemplateResult { + return html` + ((event.target).value = '')} @change=${ + this.openDoc + } id="open-plugin-input" accept=".sed,.scd,.ssd,.iid,.cid,.icd" type="file">`; + } + + static styles = css` + input { + width: 0; + height: 0; + opacity: 0; + } + `; +} From 0dec98563882486ae225325d4babd612460a0027 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Wed, 2 Jun 2021 14:56:52 +0200 Subject: [PATCH 006/246] First version of integrating CoMPAS in OpenSCD. Signed-off-by: Dennis Labordus --- public/js/plugins.js | 7 +++ src/editors/compas/compas-scl-list.ts | 71 ++++++++++++++++++++++ src/editors/compas/compas-scltype-list.ts | 74 +++++++++++++++++++++++ src/translations/de.ts | 9 +++ src/translations/en.ts | 9 +++ src/triggered/OpenCompas.ts | 26 ++++++++ 6 files changed, 196 insertions(+) create mode 100644 src/editors/compas/compas-scl-list.ts create mode 100644 src/editors/compas/compas-scltype-list.ts create mode 100644 src/triggered/OpenCompas.ts diff --git a/public/js/plugins.js b/public/js/plugins.js index ca9e85c860..a068322f2a 100644 --- a/public/js/plugins.js +++ b/public/js/plugins.js @@ -27,6 +27,13 @@ export const officialPlugins = [ default: true, kind: 'editor', }, + { + name: "Open from CoMPAS", + src: "/src/triggered/OpenCompas.js", + icon: "snippet_folder", + default: true, + kind: "triggered" + }, { name: "Import IEDs", src: "/src/triggered/ImportIEDs.js", diff --git a/src/editors/compas/compas-scl-list.ts b/src/editors/compas/compas-scl-list.ts new file mode 100644 index 0000000000..29ae7f12f5 --- /dev/null +++ b/src/editors/compas/compas-scl-list.ts @@ -0,0 +1,71 @@ +import {customElement, html, LitElement, property, TemplateResult} from "lit-element"; +import {newLogEvent, newOpenDocEvent, newPendingStateEvent, newWizardEvent} from "../../foundation.js"; +import {SingleSelectedEvent} from "@material/mwc-list/mwc-list-foundation"; +import {string} from "fast-check"; +import {Validating} from "../../Validating.js"; +import {get} from "lit-translate"; + +@customElement('compas-scl-list') +export class CompasSclListEditor extends Validating(LitElement) { + @property({type: String}) + code: string | undefined; + + @property({type: Document}) + scls: Document | undefined; + + connectedCallback() { + super.connectedCallback(); + this.fetchData(); + } + + fetchData() { + fetch('http://localhost:8080/scl/v1/' + this.code + '/list') + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')) + .then(scls => { this.scls = scls;}) + } + + openScl(id?: string) { + this.dispatchEvent(newPendingStateEvent(this.loadDoc(id))); + } + + private async loadDoc(id?: string): Promise { + const sclUrl = 'http://localhost:8080/scl/v1/' + this.code + '/' + id + '/scl'; + const doc = await fetch(sclUrl) + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')) + const docName = id + "." + this.code?.toLowerCase(); + + document + .querySelector('open-scd')! + .dispatchEvent(newOpenDocEvent(doc, docName, {detail: {docId: id}})); + } + + render(): TemplateResult { + if (!this.scls) { + return html `Loading...` + } + const scls = Array.from(this.scls.querySelectorAll('Item') ?? []); + if (scls?.length <= 0) { + return html ` + + ${get("compas.open.noScls")} + + ` + } + return html` + + ${scls.map( item => { + const id = item.getElementsByTagName("Id").item(0); + const version = item.getElementsByTagName("Version").item(0); + return html` { + this.openScl(id!.textContent ?? ''); + evt.target!.dispatchEvent(newWizardEvent()); + }}> + ${id} (${version}) + ` + })} + ` + } +} diff --git a/src/editors/compas/compas-scltype-list.ts b/src/editors/compas/compas-scltype-list.ts new file mode 100644 index 0000000000..0ff1ffca94 --- /dev/null +++ b/src/editors/compas/compas-scltype-list.ts @@ -0,0 +1,74 @@ +import {customElement, html, LitElement, property, TemplateResult} from "lit-element"; +import {get} from "lit-translate"; +import {SingleSelectedEvent} from "@material/mwc-list/mwc-list-foundation"; +import {newWizardEvent, Wizard} from '../../foundation.js'; +import {openlListCompasWizard} from "../../triggered/OpenCompas.js"; +import './compas-scl-list.ts'; + +@customElement('compas-scltype-list') +export class CompasSclTypeListEditor extends LitElement { + @property({type: Document}) + sclTypes: Document | undefined; + + connectedCallback() { + super.connectedCallback(); + this.fetchData(); + } + + fetchData() { + fetch('http://localhost:8080/common/v1/type/list') + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')) + .then(sclTypes => { this.sclTypes = sclTypes;}) + } + + listScls(code: string): void { + this.dispatchEvent(newWizardEvent(listSclsWizard(code))); + } + + render(): TemplateResult { + if (!this.sclTypes) { + return html `Loading...` + } + const types = Array.from(this.sclTypes.querySelectorAll('Type') ?? []); + if (types?.length <= 0) { + return html ` + + ${get("compas.open.noSclTypes")} + + ` + } + return html` + + ${types.map( type => { + const code = type.getElementsByTagName("Code").item(0); + const description = type.getElementsByTagName("Description").item(0); + return html` { + evt.target!.dispatchEvent(newWizardEvent()); + this.listScls(code!.textContent ?? ''); + }} + tabindex="0" + > + ${description} (${code}) + `; + })} + ` + } +} + +function listSclsWizard(code: string): Wizard { + return [ + { + title: get('compas.open.listScls', {code: code}), + secondary: { + icon: '', + label: get('cancel'), + action: openlListCompasWizard(), + }, + content: [ + html``, + ], + }, + ]; +} diff --git a/src/translations/de.ts b/src/translations/de.ts index e3832bf78b..ef6b15e58f 100644 --- a/src/translations/de.ts +++ b/src/translations/de.ts @@ -255,4 +255,13 @@ export const de: Translations = { duplicate: 'Klonen', connect: 'Verbinden', disconnect: 'Trennen', + + compas: { + open: { + listSclTypes: '???', + noSclTypes: '???', + listScls: '??? ({{ code }})', + noScls: "???", + } + }, }; diff --git a/src/translations/en.ts b/src/translations/en.ts index eeb30e6ff9..0ec0e72ad9 100644 --- a/src/translations/en.ts +++ b/src/translations/en.ts @@ -252,4 +252,13 @@ export const en = { duplicate: 'Clone', connect: 'Connect', disconnect: 'Disconnect', + + compas: { + open: { + listSclTypes: 'Type of SCL', + noSclTypes: 'No types found', + listScls: 'List of SCL ({{ code }})', + noScls: 'No SCLs found', + } + }, }; diff --git a/src/triggered/OpenCompas.ts b/src/triggered/OpenCompas.ts new file mode 100644 index 0000000000..3d79f72d6a --- /dev/null +++ b/src/triggered/OpenCompas.ts @@ -0,0 +1,26 @@ +import {html, LitElement} from 'lit-element'; +import {get} from "lit-translate"; +import {newWizardEvent, Wizard, WizardActor} from '../foundation.js'; +import '../editors/compas/compas-scltype-list.ts'; + +export default class OpenCompasPlugin extends LitElement { + async trigger(): Promise { + this.dispatchEvent(newWizardEvent(listCompasWizard())); + } +} + +export function openlListCompasWizard(): WizardActor { + return () => [() => listCompasWizard()]; +} + +function listCompasWizard(): Wizard { + return [ + { + title: get('compas.open.listSclTypes'), + content: [ + html``, + ], + }, + ]; +} + From f213bc7aafe8c4a48bf564ee1923a49598002b73 Mon Sep 17 00:00:00 2001 From: Christian Dinkel Date: Thu, 3 Jun 2021 11:18:37 +0200 Subject: [PATCH 007/246] refactor(plugging): rename items -> triggered --- src/Plugging.ts | 2 +- src/open-scd.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Plugging.ts b/src/Plugging.ts index 6ddc13fc91..d3247a142f 100644 --- a/src/Plugging.ts +++ b/src/Plugging.ts @@ -81,7 +81,7 @@ export function Plugging EditingElement>( .filter(plugin => plugin.installed && plugin.kind === 'editor') .map(plugin => this.addContent(plugin)); } - get items(): InstalledPlugin[] { + get triggered(): InstalledPlugin[] { return this.plugins .filter(plugin => plugin.installed && plugin.kind === 'triggered') .map(plugin => this.addContent(plugin)); diff --git a/src/open-scd.ts b/src/open-scd.ts index 899d138246..a3bc86d6ac 100644 --- a/src/open-scd.ts +++ b/src/open-scd.ts @@ -43,7 +43,6 @@ import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; import { EditorAction, - newLogEvent, newOpenDocEvent, newPendingStateEvent, newWizardEvent, @@ -244,7 +243,7 @@ export class OpenSCD extends Setting( get menu(): (MenuItem | 'divider')[] { const items: (MenuItem | 'divider')[] = []; - this.items.forEach(plugin => + this.triggered.forEach(plugin => items.push({ icon: plugin.icon || pluginIcons['triggered'], name: plugin.name, From fc32031d3df0ed7a5ac3867024b962d76e9bcb57 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 3 Jun 2021 14:00:26 +0200 Subject: [PATCH 008/246] Update of integrating CoMPAS in OpenSCD. Signed-off-by: Dennis Labordus --- .../CompasSclList.ts} | 25 ++++++++----------- .../CompasScltypeList.ts} | 11 ++++---- src/compas/CompasService.ts | 20 +++++++++++++++ src/triggered/OpenCompas.ts | 2 +- 4 files changed, 36 insertions(+), 22 deletions(-) rename src/{editors/compas/compas-scl-list.ts => compas/CompasSclList.ts} (69%) rename src/{editors/compas/compas-scltype-list.ts => compas/CompasScltypeList.ts} (86%) create mode 100644 src/compas/CompasService.ts diff --git a/src/editors/compas/compas-scl-list.ts b/src/compas/CompasSclList.ts similarity index 69% rename from src/editors/compas/compas-scl-list.ts rename to src/compas/CompasSclList.ts index 29ae7f12f5..161b18d003 100644 --- a/src/editors/compas/compas-scl-list.ts +++ b/src/compas/CompasSclList.ts @@ -1,17 +1,17 @@ import {customElement, html, LitElement, property, TemplateResult} from "lit-element"; -import {newLogEvent, newOpenDocEvent, newPendingStateEvent, newWizardEvent} from "../../foundation.js"; -import {SingleSelectedEvent} from "@material/mwc-list/mwc-list-foundation"; -import {string} from "fast-check"; -import {Validating} from "../../Validating.js"; import {get} from "lit-translate"; +import {newOpenDocEvent, newPendingStateEvent, newWizardEvent} from "../foundation.js"; +import {SingleSelectedEvent} from "@material/mwc-list/mwc-list-foundation"; +import {Validating} from "../Validating.js"; +import {getSclDocument, listScls} from "./CompasService.js"; @customElement('compas-scl-list') export class CompasSclListEditor extends Validating(LitElement) { @property({type: String}) - code: string | undefined; + code = ''; @property({type: Document}) - scls: Document | undefined; + scls: Document | null = null; connectedCallback() { super.connectedCallback(); @@ -19,21 +19,16 @@ export class CompasSclListEditor extends Validating(LitElement) { } fetchData() { - fetch('http://localhost:8080/scl/v1/' + this.code + '/list') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')) + listScls(this.code) .then(scls => { this.scls = scls;}) } openScl(id?: string) { - this.dispatchEvent(newPendingStateEvent(this.loadDoc(id))); + this.dispatchEvent(newPendingStateEvent(this.getSclDocument(id))); } - private async loadDoc(id?: string): Promise { - const sclUrl = 'http://localhost:8080/scl/v1/' + this.code + '/' + id + '/scl'; - const doc = await fetch(sclUrl) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')) + private async getSclDocument(id?: string): Promise { + const doc = await getSclDocument(this.code, id ?? ''); const docName = id + "." + this.code?.toLowerCase(); document diff --git a/src/editors/compas/compas-scltype-list.ts b/src/compas/CompasScltypeList.ts similarity index 86% rename from src/editors/compas/compas-scltype-list.ts rename to src/compas/CompasScltypeList.ts index 0ff1ffca94..fcace2e540 100644 --- a/src/editors/compas/compas-scltype-list.ts +++ b/src/compas/CompasScltypeList.ts @@ -1,9 +1,10 @@ import {customElement, html, LitElement, property, TemplateResult} from "lit-element"; import {get} from "lit-translate"; import {SingleSelectedEvent} from "@material/mwc-list/mwc-list-foundation"; -import {newWizardEvent, Wizard} from '../../foundation.js'; -import {openlListCompasWizard} from "../../triggered/OpenCompas.js"; -import './compas-scl-list.ts'; +import {newWizardEvent, Wizard} from '../foundation.js'; +import {openlListCompasWizard} from "../triggered/OpenCompas.js"; +import {listSclTypes} from "./CompasService.js"; +import './CompasSclList.ts'; @customElement('compas-scltype-list') export class CompasSclTypeListEditor extends LitElement { @@ -16,9 +17,7 @@ export class CompasSclTypeListEditor extends LitElement { } fetchData() { - fetch('http://localhost:8080/common/v1/type/list') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')) + listSclTypes() .then(sclTypes => { this.sclTypes = sclTypes;}) } diff --git a/src/compas/CompasService.ts b/src/compas/CompasService.ts new file mode 100644 index 0000000000..b39597ec25 --- /dev/null +++ b/src/compas/CompasService.ts @@ -0,0 +1,20 @@ +const baseUrl = '/compas-scl-data-service'; //http://localhost:9090 + +export function listSclTypes(): Promise { + return fetch(baseUrl + '/common/v1/type/list') + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')) +} + +export function listScls(code: string): Promise { + return fetch(baseUrl + '/scl/v1/' + code + '/list') + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')) +} + +export function getSclDocument(code: string, id: string): Promise { + const sclUrl = baseUrl + '/scl/v1/' + code + '/' + id + '/scl'; + return fetch(sclUrl) + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')) +} diff --git a/src/triggered/OpenCompas.ts b/src/triggered/OpenCompas.ts index 3d79f72d6a..fb605d4ec5 100644 --- a/src/triggered/OpenCompas.ts +++ b/src/triggered/OpenCompas.ts @@ -1,7 +1,7 @@ import {html, LitElement} from 'lit-element'; import {get} from "lit-translate"; import {newWizardEvent, Wizard, WizardActor} from '../foundation.js'; -import '../editors/compas/compas-scltype-list.ts'; +import '../compas/CompasScltypeList.ts'; export default class OpenCompasPlugin extends LitElement { async trigger(): Promise { From 26ef864e8901d7f3ecc106a45a5aa493556bbc6b Mon Sep 17 00:00:00 2001 From: Christian Dinkel Date: Mon, 7 Jun 2021 11:07:42 +0200 Subject: [PATCH 009/246] fix(plugins): update open file plugin icon --- public/js/plugins.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/js/plugins.js b/public/js/plugins.js index ca9e85c860..09047c1482 100644 --- a/public/js/plugins.js +++ b/public/js/plugins.js @@ -2,7 +2,7 @@ export const officialPlugins = [ { name: 'Open file', src: '/src/triggered/OpenFile.js', - icon: 'coronavirus', + icon: 'folder_open', default: true, kind: 'triggered' }, From e1eaf0335ad4764539eb9964621d46e586354c7e Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Mon, 7 Jun 2021 16:24:18 +0200 Subject: [PATCH 010/246] Small changes. Signed-off-by: Dennis Labordus --- public/js/plugins.js | 4 ++-- src/compas/CompasSclList.ts | 2 +- src/compas/CompasScltypeList.ts | 2 +- src/compas/CompasService.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/public/js/plugins.js b/public/js/plugins.js index a068322f2a..ed3e0aa3e9 100644 --- a/public/js/plugins.js +++ b/public/js/plugins.js @@ -2,7 +2,7 @@ export const officialPlugins = [ { name: 'Open file', src: '/src/triggered/OpenFile.js', - icon: 'coronavirus', + icon: 'folder_open', default: true, kind: 'triggered' }, @@ -30,7 +30,7 @@ export const officialPlugins = [ { name: "Open from CoMPAS", src: "/src/triggered/OpenCompas.js", - icon: "snippet_folder", + icon: "folder_open", default: true, kind: "triggered" }, diff --git a/src/compas/CompasSclList.ts b/src/compas/CompasSclList.ts index 161b18d003..54f2c84ed9 100644 --- a/src/compas/CompasSclList.ts +++ b/src/compas/CompasSclList.ts @@ -6,7 +6,7 @@ import {Validating} from "../Validating.js"; import {getSclDocument, listScls} from "./CompasService.js"; @customElement('compas-scl-list') -export class CompasSclListEditor extends Validating(LitElement) { +export class CompasSclList extends Validating(LitElement) { @property({type: String}) code = ''; diff --git a/src/compas/CompasScltypeList.ts b/src/compas/CompasScltypeList.ts index fcace2e540..c87589df18 100644 --- a/src/compas/CompasScltypeList.ts +++ b/src/compas/CompasScltypeList.ts @@ -7,7 +7,7 @@ import {listSclTypes} from "./CompasService.js"; import './CompasSclList.ts'; @customElement('compas-scltype-list') -export class CompasSclTypeListEditor extends LitElement { +export class CompasSclTypeList extends LitElement { @property({type: Document}) sclTypes: Document | undefined; diff --git a/src/compas/CompasService.ts b/src/compas/CompasService.ts index b39597ec25..7f177d76c5 100644 --- a/src/compas/CompasService.ts +++ b/src/compas/CompasService.ts @@ -1,4 +1,4 @@ -const baseUrl = '/compas-scl-data-service'; //http://localhost:9090 +const baseUrl = 'http://localhost:9090/compas-scl-data-service'; export function listSclTypes(): Promise { return fetch(baseUrl + '/common/v1/type/list') From c58a73908b42579c5a9f51a8067f275a9e8db9a2 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Tue, 8 Jun 2021 15:27:13 +0200 Subject: [PATCH 011/246] First version of saving to Compas and some refactoring of opening from compas Signed-off-by: Dennis Labordus --- public/js/plugins.js | 7 + src/Editing.ts | 3 + src/Plugging.ts | 1 + src/compas/CompasChangeSet.ts | 19 +++ src/compas/CompasSaveTo.ts | 127 +++++++++++++++++ src/compas/{CompasSclList.ts => CompasScl.ts} | 32 +++-- src/compas/CompasScltype.ts | 128 ++++++++++++++++++ src/compas/CompasScltypeList.ts | 73 ---------- src/compas/CompasService.ts | 45 +++++- src/foundation.ts | 1 + src/translations/de.ts | 5 +- src/translations/en.ts | 5 +- src/triggered/OpenCompas.ts | 24 +--- src/triggered/SaveToCompas.ts | 15 ++ 14 files changed, 378 insertions(+), 107 deletions(-) create mode 100644 src/compas/CompasChangeSet.ts create mode 100644 src/compas/CompasSaveTo.ts rename src/compas/{CompasSclList.ts => CompasScl.ts} (72%) create mode 100644 src/compas/CompasScltype.ts delete mode 100644 src/compas/CompasScltypeList.ts create mode 100644 src/triggered/SaveToCompas.ts diff --git a/public/js/plugins.js b/public/js/plugins.js index ed3e0aa3e9..cc1d842e17 100644 --- a/public/js/plugins.js +++ b/public/js/plugins.js @@ -34,6 +34,13 @@ export const officialPlugins = [ default: true, kind: "triggered" }, + { + name: "Save to CoMPAS", + src: "/src/triggered/SaveToCompas.js", + icon: "folder_open", + default: true, + kind: "triggered" + }, { name: "Import IEDs", src: "/src/triggered/ImportIEDs.js", diff --git a/src/Editing.ts b/src/Editing.ts index fd09ec1d57..87467a4770 100644 --- a/src/Editing.ts +++ b/src/Editing.ts @@ -54,6 +54,8 @@ export function Editing(Base: TBase) { @property({ type: String }) docName = ''; /** The UUID of the current [[`doc`]] */ @property({ type: String }) docId = ''; + /** The type of the current [[`doc`]] */ + @property({ type: String }) docType = ''; private checkCreateValidity(create: Create): boolean { if (create.checkValidity !== undefined) return create.checkValidity(); @@ -262,6 +264,7 @@ export function Editing(Base: TBase) { this.doc = event.detail.doc; this.docName = event.detail.docName; this.docId = event.detail.docId ?? ''; + this.docType = (event.detail.docType ?? '').toLowerCase(); this.dispatchEvent( newLogEvent({ diff --git a/src/Plugging.ts b/src/Plugging.ts index 6ddc13fc91..7141389a4f 100644 --- a/src/Plugging.ts +++ b/src/Plugging.ts @@ -151,6 +151,7 @@ export function Plugging EditingElement>( .doc=${this.doc} .docName=${this.docName} .docId=${this.docId} + .docType=${this.docType} >`; }, }; diff --git a/src/compas/CompasChangeSet.ts b/src/compas/CompasChangeSet.ts new file mode 100644 index 0000000000..edfa0ce1ae --- /dev/null +++ b/src/compas/CompasChangeSet.ts @@ -0,0 +1,19 @@ +import {customElement, html, LitElement, TemplateResult} from "lit-element"; +import {ListItemBase} from "@material/mwc-list/mwc-list-item-base"; + +@customElement('compas-changeset-radiogroup') +export class CompasChangeSetRadiogroup extends LitElement { + render(): TemplateResult { + return html` + + Major change + Minor change + Patch change + + ` + } + + getSelectedValue() : string { + return (this.shadowRoot!.querySelector('mwc-list')!.selected).value; + } +} diff --git a/src/compas/CompasSaveTo.ts b/src/compas/CompasSaveTo.ts new file mode 100644 index 0000000000..f9319e221e --- /dev/null +++ b/src/compas/CompasSaveTo.ts @@ -0,0 +1,127 @@ +import {customElement, html, LitElement, property, TemplateResult} from "lit-element"; +import {newWizardEvent, Wizard, WizardInput} from "../foundation.js"; +import {get, translate} from "lit-translate"; + +import {TextFieldBase} from "@material/mwc-textfield/mwc-textfield-base"; +import {OpenSCD} from "../open-scd.js"; +import {CompasChangeSetRadiogroup} from "./CompasChangeSet.js"; +import {CompasScltypeRadiogroup} from "./CompasScltype.js"; +import {addSclDocument, updateSclDocument} from "./CompasService.js"; + +import '../compas/CompasChangeSet.js'; +import '../compas/CompasScltype.js'; + +@customElement('compas-save-to') +export class CompasSaveTo extends LitElement { + @property({type: String}) + docName!: string; + @property({type: String}) + docId!: string; + @property({type: String}) + docType!: string; + + @property({type: String}) + errorMessage!: string; + + render(): TemplateResult { + return this.renderWizardPage(); + } + + renderWizardPage(): TemplateResult { + if (!this.docId || !this.docType) { + return html` +
${this.errorMessage}
+ + + + + `; + } + return html ` + + `; + } + + getNameValue() : string { + return (this.shadowRoot!.querySelector('mwc-textfield')).value; + } + + getSclType() : string { + return (this.shadowRoot! + .querySelector("compas-scltype-radiogroup")) + .getSelectedValue() + + } + + getChangeSetValue(): string { + return (this.shadowRoot! + .querySelector("compas-changeset-radiogroup")) + .getSelectedValue() + } +} + +function saveToCompass(doc: XMLDocument, docId: string, docType: string) { + return function (inputs: WizardInput[], wizard: Element) { + if (doc) { + const openScd = document.querySelector('open-scd'); + const compasSaveTo = wizard.shadowRoot!.querySelector('compas-save-to') + if (!docId || !docType) { + let name = compasSaveTo.getNameValue(); + if (name!.lastIndexOf(".") == name!.length - 4) { + name = name.substring(0, name.lastIndexOf(".")); + } + const newDocType = compasSaveTo.getSclType(); + + openScd!.docType = newDocType; + openScd!.docName = name + "." + newDocType.toLowerCase() + + addSclDocument(newDocType, name, doc) + .then(document => { + const id = Array.from(document.querySelectorAll('Id') ?? [])[0]; + openScd!.docId = id.textContent ?? ""; + openScd!.docName = (id.textContent ?? "") + "." + newDocType.toLowerCase() + compasSaveTo.errorMessage = ""; + + // Close the Save Dialog. + openScd!.dispatchEvent(newWizardEvent()); + }) + .catch(reason => { + compasSaveTo.errorMessage = "Error adding SCL to CoMPAS!"; + }); + } else { + const changeSet = compasSaveTo.getChangeSetValue(); + updateSclDocument(docType.toUpperCase(), docId, changeSet, doc) + .then(() => { + compasSaveTo.errorMessage = ""; + + // Close the Save Dialog. + openScd!.dispatchEvent(newWizardEvent()); + }) + .catch(reason => { + compasSaveTo.errorMessage = "Error updating SCL in CoMPAS!"; + }); + } + } + + return []; + }; +} + +export function saveToCompasWizard(doc: XMLDocument, docName: string, docId: string, docType: string): Wizard { + return [ + { + title: get('compas.saveTo.title'), + primary: { + icon: 'save', + label: get('save'), + action: saveToCompass(doc, docId, docType), + }, + content: [ + html ` + + ` ], + }, + ]; +} + diff --git a/src/compas/CompasSclList.ts b/src/compas/CompasScl.ts similarity index 72% rename from src/compas/CompasSclList.ts rename to src/compas/CompasScl.ts index 54f2c84ed9..bdfc8957e1 100644 --- a/src/compas/CompasSclList.ts +++ b/src/compas/CompasScl.ts @@ -1,14 +1,14 @@ import {customElement, html, LitElement, property, TemplateResult} from "lit-element"; import {get} from "lit-translate"; -import {newOpenDocEvent, newPendingStateEvent, newWizardEvent} from "../foundation.js"; +import {newOpenDocEvent, newPendingStateEvent, newWizardEvent, Wizard} from "../foundation.js"; import {SingleSelectedEvent} from "@material/mwc-list/mwc-list-foundation"; -import {Validating} from "../Validating.js"; import {getSclDocument, listScls} from "./CompasService.js"; +import {compasSclTypeListWizardActor} from "./CompasScltype.js"; @customElement('compas-scl-list') -export class CompasSclList extends Validating(LitElement) { +export class CompasScl extends LitElement { @property({type: String}) - code = ''; + type = ''; @property({type: Document}) scls: Document | null = null; @@ -19,7 +19,7 @@ export class CompasSclList extends Validating(LitElement) { } fetchData() { - listScls(this.code) + listScls(this.type) .then(scls => { this.scls = scls;}) } @@ -28,12 +28,12 @@ export class CompasSclList extends Validating(LitElement) { } private async getSclDocument(id?: string): Promise { - const doc = await getSclDocument(this.code, id ?? ''); - const docName = id + "." + this.code?.toLowerCase(); + const doc = await getSclDocument(this.type, id ?? ''); + const docName = id + "." + this.type?.toLowerCase(); document .querySelector('open-scd')! - .dispatchEvent(newOpenDocEvent(doc, docName, {detail: {docId: id}})); + .dispatchEvent(newOpenDocEvent(doc, docName, {detail: {docId: id, docType: this.type}})); } render(): TemplateResult { @@ -64,3 +64,19 @@ export class CompasSclList extends Validating(LitElement) { ` } } + +export function listSclsWizard(type: string): Wizard { + return [ + { + title: get('compas.open.listScls', {type: type}), + secondary: { + icon: '', + label: get('cancel'), + action: compasSclTypeListWizardActor(), + }, + content: [ + html``, + ], + }, + ]; +} diff --git a/src/compas/CompasScltype.ts b/src/compas/CompasScltype.ts new file mode 100644 index 0000000000..beb19aa3db --- /dev/null +++ b/src/compas/CompasScltype.ts @@ -0,0 +1,128 @@ +import {customElement, html, LitElement, property, TemplateResult} from "lit-element"; +import {get} from "lit-translate"; +import {SingleSelectedEvent} from "@material/mwc-list/mwc-list-foundation"; +import {newWizardEvent, Wizard, WizardActor} from '../foundation.js'; +import {listSclTypes} from "./CompasService.js"; +import {listSclsWizard} from "./CompasScl.js"; +import {ListItemBase} from "@material/mwc-list/mwc-list-item-base"; + +@customElement('compas-scltype-list') +export class CompasScltypeList extends LitElement { + @property({type: Document}) + sclTypes!: Element[]; + + connectedCallback() { + super.connectedCallback(); + this.fetchData(); + } + + fetchData() { + listSclTypesAndOrder() + .then(types => this.sclTypes = types) + } + + listScls(type: string): void { + this.dispatchEvent(newWizardEvent(listSclsWizard(type))); + } + + render(): TemplateResult { + if (!this.sclTypes) { + return html `Loading...` + } + + if (this.sclTypes.length <= 0) { + return html ` + + ${get("compas.open.noSclTypes")} + + ` + } + return html` + + ${this.sclTypes.map( type => { + const code = type.getElementsByTagName("Code").item(0); + const description = type.getElementsByTagName("Description").item(0); + return html` { + evt.target!.dispatchEvent(newWizardEvent()); + this.listScls(code!.textContent ?? ''); + }} + tabindex="0" + > + ${description} (${code}) + `; + })} + ` + } +} + +@customElement('compas-scltype-radiogroup') +export class CompasScltypeRadiogroup extends LitElement { + @property({type: Document}) + sclTypes!:Element[]; + + connectedCallback() { + super.connectedCallback(); + this.fetchData(); + } + + fetchData() { + listSclTypesAndOrder() + .then(types => this.sclTypes = types) + } + + getSelectedValue() : string { + return (this.shadowRoot!.querySelector('mwc-list')!.selected).value; + } + + render(): TemplateResult { + if (!this.sclTypes) { + return html `Loading...` + } + + if (this.sclTypes.length <= 0) { + return html ` + + ${get("compas.open.noSclTypes")} + + ` + } + return html` + + ${this.sclTypes.map( type => { + const code = type.getElementsByTagName("Code").item(0); + const description = type.getElementsByTagName("Description").item(0); + return html` + ${description} (${code}) + `; + })} + ` + } +} + +function listSclTypesAndOrder(): Promise { + return listSclTypes() + .then(sclTypesDocument => { + return Array.from(sclTypesDocument.querySelectorAll('Type') ?? []) + .sort((type1, type2) => { + const description1 = type1.getElementsByTagName("Description")!.item(0)!.textContent ?? ""; + const description2 = type2.getElementsByTagName("Description")!.item(0)!.textContent ?? ""; + return description1.localeCompare(description2) + }); + }) +} + +export function compasSclTypeListWizardActor(): WizardActor { + return () => [() => compasSclTypeListWizard()]; +} + +export function compasSclTypeListWizard(): Wizard { + return [ + { + title: get('compas.open.listSclTypes'), + content: [ + html``, + ], + }, + ]; +} diff --git a/src/compas/CompasScltypeList.ts b/src/compas/CompasScltypeList.ts deleted file mode 100644 index c87589df18..0000000000 --- a/src/compas/CompasScltypeList.ts +++ /dev/null @@ -1,73 +0,0 @@ -import {customElement, html, LitElement, property, TemplateResult} from "lit-element"; -import {get} from "lit-translate"; -import {SingleSelectedEvent} from "@material/mwc-list/mwc-list-foundation"; -import {newWizardEvent, Wizard} from '../foundation.js'; -import {openlListCompasWizard} from "../triggered/OpenCompas.js"; -import {listSclTypes} from "./CompasService.js"; -import './CompasSclList.ts'; - -@customElement('compas-scltype-list') -export class CompasSclTypeList extends LitElement { - @property({type: Document}) - sclTypes: Document | undefined; - - connectedCallback() { - super.connectedCallback(); - this.fetchData(); - } - - fetchData() { - listSclTypes() - .then(sclTypes => { this.sclTypes = sclTypes;}) - } - - listScls(code: string): void { - this.dispatchEvent(newWizardEvent(listSclsWizard(code))); - } - - render(): TemplateResult { - if (!this.sclTypes) { - return html `Loading...` - } - const types = Array.from(this.sclTypes.querySelectorAll('Type') ?? []); - if (types?.length <= 0) { - return html ` - - ${get("compas.open.noSclTypes")} - - ` - } - return html` - - ${types.map( type => { - const code = type.getElementsByTagName("Code").item(0); - const description = type.getElementsByTagName("Description").item(0); - return html` { - evt.target!.dispatchEvent(newWizardEvent()); - this.listScls(code!.textContent ?? ''); - }} - tabindex="0" - > - ${description} (${code}) - `; - })} - ` - } -} - -function listSclsWizard(code: string): Wizard { - return [ - { - title: get('compas.open.listScls', {code: code}), - secondary: { - icon: '', - label: get('cancel'), - action: openlListCompasWizard(), - }, - content: [ - html``, - ], - }, - ]; -} diff --git a/src/compas/CompasService.ts b/src/compas/CompasService.ts index 7f177d76c5..bbb353a31e 100644 --- a/src/compas/CompasService.ts +++ b/src/compas/CompasService.ts @@ -6,15 +6,52 @@ export function listSclTypes(): Promise { .then(str => new DOMParser().parseFromString(str, 'application/xml')) } -export function listScls(code: string): Promise { - return fetch(baseUrl + '/scl/v1/' + code + '/list') +export function listScls(type: string): Promise { + return fetch(baseUrl + '/scl/v1/' + type + '/list') .then(response => response.text()) .then(str => new DOMParser().parseFromString(str, 'application/xml')) } -export function getSclDocument(code: string, id: string): Promise { - const sclUrl = baseUrl + '/scl/v1/' + code + '/' + id + '/scl'; +export function getSclDocument(type: string, id: string): Promise { + const sclUrl = baseUrl + '/scl/v1/' + type + '/' + id + '/scl'; return fetch(sclUrl) .then(response => response.text()) .then(str => new DOMParser().parseFromString(str, 'application/xml')) } + +export function addSclDocument(type: string, sclName: string, doc: Document): Promise { + const sclUrl = baseUrl + '/scl/v1/' + type; + return fetch(sclUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/xml' + }, + redirect: 'follow', + referrerPolicy: 'no-referrer', + body: ` + + ${sclName} + ${new XMLSerializer().serializeToString(doc.documentElement)} + ` + }) + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')) +} + +export function updateSclDocument(type: string, id: string, changeSet: string, doc: Document): Promise { + const sclUrl = baseUrl + '/scl/v1/' + type + '/' + id; + return fetch(sclUrl, { + method: 'PUT', + headers: { + 'Content-Type': 'application/xml' + }, + redirect: 'follow', + referrerPolicy: 'no-referrer', + body: ` + + ${changeSet} + ${new XMLSerializer().serializeToString(doc.documentElement)} + ` + }) +} + diff --git a/src/foundation.ts b/src/foundation.ts index 76c76e903b..6973226a64 100644 --- a/src/foundation.ts +++ b/src/foundation.ts @@ -266,6 +266,7 @@ export interface OpenDocDetail { doc: XMLDocument; docName: string; docId?: string; + docType?: string; } export type OpenDocEvent = CustomEvent; export function newOpenDocEvent( diff --git a/src/translations/de.ts b/src/translations/de.ts index ef6b15e58f..469ed62ca5 100644 --- a/src/translations/de.ts +++ b/src/translations/de.ts @@ -260,8 +260,11 @@ export const de: Translations = { open: { listSclTypes: '???', noSclTypes: '???', - listScls: '??? ({{ code }})', + listScls: '??? ({{ type }})', noScls: "???", + }, + saveTo: { + title: "???" } }, }; diff --git a/src/translations/en.ts b/src/translations/en.ts index 0ec0e72ad9..82c44121af 100644 --- a/src/translations/en.ts +++ b/src/translations/en.ts @@ -257,8 +257,11 @@ export const en = { open: { listSclTypes: 'Type of SCL', noSclTypes: 'No types found', - listScls: 'List of SCL ({{ code }})', + listScls: 'List of SCL ({{ type }})', noScls: 'No SCLs found', + }, + saveTo: { + title: "Save to Compas" } }, }; diff --git a/src/triggered/OpenCompas.ts b/src/triggered/OpenCompas.ts index fb605d4ec5..b571efcb6e 100644 --- a/src/triggered/OpenCompas.ts +++ b/src/triggered/OpenCompas.ts @@ -1,26 +1,10 @@ -import {html, LitElement} from 'lit-element'; -import {get} from "lit-translate"; -import {newWizardEvent, Wizard, WizardActor} from '../foundation.js'; -import '../compas/CompasScltypeList.ts'; +import {LitElement} from 'lit-element'; +import {newWizardEvent} from '../foundation.js'; +import {compasSclTypeListWizard} from "../compas/CompasScltype.js"; export default class OpenCompasPlugin extends LitElement { async trigger(): Promise { - this.dispatchEvent(newWizardEvent(listCompasWizard())); + this.dispatchEvent(newWizardEvent(compasSclTypeListWizard())); } } -export function openlListCompasWizard(): WizardActor { - return () => [() => listCompasWizard()]; -} - -function listCompasWizard(): Wizard { - return [ - { - title: get('compas.open.listSclTypes'), - content: [ - html``, - ], - }, - ]; -} - diff --git a/src/triggered/SaveToCompas.ts b/src/triggered/SaveToCompas.ts new file mode 100644 index 0000000000..bc3461b4a0 --- /dev/null +++ b/src/triggered/SaveToCompas.ts @@ -0,0 +1,15 @@ +import {LitElement, property} from 'lit-element'; +import {newWizardEvent} from '../foundation.js'; +import {saveToCompasWizard} from "../compas/CompasSaveTo.js"; + +export default class SaveCompasPlugin extends LitElement { + doc!: XMLDocument; + docName!: string; + docId!: string; + docType!: string; + + async trigger(): Promise { + this.dispatchEvent(newWizardEvent(saveToCompasWizard(this.doc, this.docName, this.docId, this.docType))); + } +} + From 115b0734b5edb1ff9aba36060c5eefa0781f4322 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Wed, 9 Jun 2021 09:36:45 +0200 Subject: [PATCH 012/246] Some refactoring. Signed-off-by: Dennis Labordus --- src/compas/CompasChangeSet.ts | 23 +++++-- src/compas/CompasSaveTo.ts | 121 ++++++++++++++++++---------------- src/compas/CompasScl.ts | 11 ++-- src/compas/CompasScltype.ts | 10 +-- src/compas/CompasService.ts | 26 +++++--- src/triggered/SaveToCompas.ts | 2 +- 6 files changed, 111 insertions(+), 82 deletions(-) diff --git a/src/compas/CompasChangeSet.ts b/src/compas/CompasChangeSet.ts index edfa0ce1ae..e983c9054b 100644 --- a/src/compas/CompasChangeSet.ts +++ b/src/compas/CompasChangeSet.ts @@ -1,19 +1,32 @@ import {customElement, html, LitElement, TemplateResult} from "lit-element"; import {ListItemBase} from "@material/mwc-list/mwc-list-item-base"; +export enum ChangeSet { + MAJOR = "MAJOR", + MINOR = "MINOR", + PATCH = "PATCH", +} +type ChangeSetDetail = { + description: string +} +const changeSetDetails = new Map([ + [ChangeSet.MAJOR, {description: "Major change"}], + [ChangeSet.MINOR, {description: "Minor change"}], + [ChangeSet.PATCH, {description: "Patch change"}] +]) + @customElement('compas-changeset-radiogroup') export class CompasChangeSetRadiogroup extends LitElement { render(): TemplateResult { return html` - Major change - Minor change - Patch change + ${Object.values(ChangeSet) + .map((key) => html `${changeSetDetails.get(key)!.description}`)} ` } - getSelectedValue() : string { - return (this.shadowRoot!.querySelector('mwc-list')!.selected).value; + getSelectedValue() : ChangeSet { + return (this.shadowRoot!.querySelector('mwc-list')!.selected).value; } } diff --git a/src/compas/CompasSaveTo.ts b/src/compas/CompasSaveTo.ts index f9319e221e..ab939a3bd6 100644 --- a/src/compas/CompasSaveTo.ts +++ b/src/compas/CompasSaveTo.ts @@ -23,6 +23,20 @@ export class CompasSaveTo extends LitElement { @property({type: String}) errorMessage!: string; + getNameValue() : string { + return (this.shadowRoot!.querySelector('mwc-textfield[id="name"]')).value; + } + + getSclTypeRadioGroup() : CompasScltypeRadiogroup { + return (this.shadowRoot! + .querySelector("compas-scltype-radiogroup")) + } + + getChangeSetRadiogroup(): CompasChangeSetRadiogroup { + return (this.shadowRoot! + .querySelector("compas-changeset-radiogroup")) + } + render(): TemplateResult { return this.renderWizardPage(); } @@ -30,9 +44,9 @@ export class CompasSaveTo extends LitElement { renderWizardPage(): TemplateResult { if (!this.docId || !this.docType) { return html` -
${this.errorMessage}
+
${this.errorMessage}
+ value="${this.docName}" required> @@ -42,84 +56,81 @@ export class CompasSaveTo extends LitElement { `; } +} - getNameValue() : string { - return (this.shadowRoot!.querySelector('mwc-textfield')).value; - } - - getSclType() : string { - return (this.shadowRoot! - .querySelector("compas-scltype-radiogroup")) - .getSelectedValue() - +function addSclToCompass(wizard: Element, doc: XMLDocument) { + const openScd = document.querySelector('open-scd'); + const compasSaveTo = wizard.shadowRoot!.querySelector('compas-save-to') + let name = compasSaveTo.getNameValue(); + if (name!.lastIndexOf(".") == name!.length - 4) { + name = name.substring(0, name.lastIndexOf(".")); } + const newDocType = compasSaveTo.getSclTypeRadioGroup().getSelectedValue(); + + openScd!.docType = newDocType; + openScd!.docName = name + "." + newDocType.toLowerCase() + + addSclDocument(newDocType, {sclName: name, doc: doc}) + .then(document => { + const id = Array.from(document.querySelectorAll('Id') ?? [])[0]; + openScd!.docId = id.textContent ?? ""; + openScd!.docName = (id.textContent ?? "") + "." + newDocType.toLowerCase() + compasSaveTo.errorMessage = ""; + + // Close the Save Dialog. + openScd!.dispatchEvent(newWizardEvent()); + }) + .catch(() => { + compasSaveTo.errorMessage = "Error adding SCL to CoMPAS!"; + }); +} - getChangeSetValue(): string { - return (this.shadowRoot! - .querySelector("compas-changeset-radiogroup")) - .getSelectedValue() - } +function updateSclInCompas(wizard: Element, docType: string, docId: string, doc: XMLDocument) { + const openScd = document.querySelector('open-scd'); + const compasSaveTo = wizard.shadowRoot!.querySelector('compas-save-to') + const changeSet = compasSaveTo.getChangeSetRadiogroup().getSelectedValue(); + updateSclDocument(docType.toUpperCase(), docId, {changeSet: changeSet, doc: doc}) + .then(() => { + compasSaveTo.errorMessage = ""; + + // Close the Save Dialog. + openScd!.dispatchEvent(newWizardEvent()); + }) + .catch(() => { + compasSaveTo.errorMessage = "Error updating SCL in CoMPAS!"; + }); } function saveToCompass(doc: XMLDocument, docId: string, docType: string) { return function (inputs: WizardInput[], wizard: Element) { if (doc) { - const openScd = document.querySelector('open-scd'); - const compasSaveTo = wizard.shadowRoot!.querySelector('compas-save-to') if (!docId || !docType) { - let name = compasSaveTo.getNameValue(); - if (name!.lastIndexOf(".") == name!.length - 4) { - name = name.substring(0, name.lastIndexOf(".")); - } - const newDocType = compasSaveTo.getSclType(); - - openScd!.docType = newDocType; - openScd!.docName = name + "." + newDocType.toLowerCase() - - addSclDocument(newDocType, name, doc) - .then(document => { - const id = Array.from(document.querySelectorAll('Id') ?? [])[0]; - openScd!.docId = id.textContent ?? ""; - openScd!.docName = (id.textContent ?? "") + "." + newDocType.toLowerCase() - compasSaveTo.errorMessage = ""; - - // Close the Save Dialog. - openScd!.dispatchEvent(newWizardEvent()); - }) - .catch(reason => { - compasSaveTo.errorMessage = "Error adding SCL to CoMPAS!"; - }); + addSclToCompass(wizard, doc); } else { - const changeSet = compasSaveTo.getChangeSetValue(); - updateSclDocument(docType.toUpperCase(), docId, changeSet, doc) - .then(() => { - compasSaveTo.errorMessage = ""; - - // Close the Save Dialog. - openScd!.dispatchEvent(newWizardEvent()); - }) - .catch(reason => { - compasSaveTo.errorMessage = "Error updating SCL in CoMPAS!"; - }); + updateSclInCompas(wizard, docType, docId, doc); } } - return []; }; } -export function saveToCompasWizard(doc: XMLDocument, docName: string, docId: string, docType: string): Wizard { +export interface SaveToCompasWizardOptions { + docName: string, + docId: string, + docType: string +} +export function saveToCompasWizard(doc: XMLDocument, saveToOptions: SaveToCompasWizardOptions): Wizard { return [ { title: get('compas.saveTo.title'), primary: { icon: 'save', label: get('save'), - action: saveToCompass(doc, docId, docType), + action: saveToCompass(doc, saveToOptions.docId, saveToOptions.docType), }, content: [ html ` - + ` ], }, ]; diff --git a/src/compas/CompasScl.ts b/src/compas/CompasScl.ts index bdfc8957e1..e8b3c8ba16 100644 --- a/src/compas/CompasScl.ts +++ b/src/compas/CompasScl.ts @@ -10,8 +10,8 @@ export class CompasScl extends LitElement { @property({type: String}) type = ''; - @property({type: Document}) - scls: Document | null = null; + @property() + scls!: Element[]; connectedCallback() { super.connectedCallback(); @@ -20,7 +20,7 @@ export class CompasScl extends LitElement { fetchData() { listScls(this.type) - .then(scls => { this.scls = scls;}) + .then(scls => { this.scls = Array.from(scls.querySelectorAll('Item') ?? [])}) } openScl(id?: string) { @@ -40,8 +40,7 @@ export class CompasScl extends LitElement { if (!this.scls) { return html `Loading...` } - const scls = Array.from(this.scls.querySelectorAll('Item') ?? []); - if (scls?.length <= 0) { + if (this.scls?.length <= 0) { return html ` ${get("compas.open.noScls")} @@ -50,7 +49,7 @@ export class CompasScl extends LitElement { } return html` - ${scls.map( item => { + ${this.scls.map( item => { const id = item.getElementsByTagName("Id").item(0); const version = item.getElementsByTagName("Version").item(0); return html` ${this.sclTypes.map( type => { - const code = type.getElementsByTagName("Code").item(0); - const description = type.getElementsByTagName("Description").item(0); - return html` + const code = type.getElementsByTagName("Code").item(0); + const description = type.getElementsByTagName("Description").item(0); + return html` ${description} (${code}) `; - })} + })} ` } } diff --git a/src/compas/CompasService.ts b/src/compas/CompasService.ts index bbb353a31e..3e469a5d12 100644 --- a/src/compas/CompasService.ts +++ b/src/compas/CompasService.ts @@ -1,3 +1,5 @@ +import {ChangeSet} from "./CompasChangeSet.js"; + const baseUrl = 'http://localhost:9090/compas-scl-data-service'; export function listSclTypes(): Promise { @@ -19,38 +21,42 @@ export function getSclDocument(type: string, id: string): Promise { .then(str => new DOMParser().parseFromString(str, 'application/xml')) } -export function addSclDocument(type: string, sclName: string, doc: Document): Promise { +export interface CreateRequestBody { + sclName: string, + doc: Document +} +export function addSclDocument(type: string, body: CreateRequestBody): Promise { const sclUrl = baseUrl + '/scl/v1/' + type; return fetch(sclUrl, { method: 'POST', headers: { 'Content-Type': 'application/xml' }, - redirect: 'follow', - referrerPolicy: 'no-referrer', body: ` - ${sclName} - ${new XMLSerializer().serializeToString(doc.documentElement)} + ${body.sclName} + ${new XMLSerializer().serializeToString(body.doc.documentElement)} ` }) .then(response => response.text()) .then(str => new DOMParser().parseFromString(str, 'application/xml')) } -export function updateSclDocument(type: string, id: string, changeSet: string, doc: Document): Promise { +export interface UpdateRequestBody { + changeSet: ChangeSet, + doc: Document +} +export function updateSclDocument(type: string, id: string, body: UpdateRequestBody): Promise { const sclUrl = baseUrl + '/scl/v1/' + type + '/' + id; return fetch(sclUrl, { method: 'PUT', headers: { 'Content-Type': 'application/xml' }, - redirect: 'follow', - referrerPolicy: 'no-referrer', body: ` - ${changeSet} - ${new XMLSerializer().serializeToString(doc.documentElement)} + ${body.changeSet} + ${new XMLSerializer().serializeToString(body.doc.documentElement)} ` }) } diff --git a/src/triggered/SaveToCompas.ts b/src/triggered/SaveToCompas.ts index bc3461b4a0..41ad05f799 100644 --- a/src/triggered/SaveToCompas.ts +++ b/src/triggered/SaveToCompas.ts @@ -9,7 +9,7 @@ export default class SaveCompasPlugin extends LitElement { docType!: string; async trigger(): Promise { - this.dispatchEvent(newWizardEvent(saveToCompasWizard(this.doc, this.docName, this.docId, this.docType))); + this.dispatchEvent(newWizardEvent(saveToCompasWizard(this.doc, {docName: this.docName, docId: this.docId, docType: this.docType}))); } } From 106b8e0440d5935ed76a722290961d424de15cef Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Wed, 9 Jun 2021 09:41:09 +0200 Subject: [PATCH 013/246] Some refactoring. Signed-off-by: Dennis Labordus --- src/Editing.ts | 2 +- src/compas/CompasScl.ts | 2 +- src/compas/CompasService.ts | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Editing.ts b/src/Editing.ts index 87467a4770..eeb8df2c39 100644 --- a/src/Editing.ts +++ b/src/Editing.ts @@ -264,7 +264,7 @@ export function Editing(Base: TBase) { this.doc = event.detail.doc; this.docName = event.detail.docName; this.docId = event.detail.docId ?? ''; - this.docType = (event.detail.docType ?? '').toLowerCase(); + this.docType = event.detail.docType ?? ''; this.dispatchEvent( newLogEvent({ diff --git a/src/compas/CompasScl.ts b/src/compas/CompasScl.ts index e8b3c8ba16..1b1c893f9b 100644 --- a/src/compas/CompasScl.ts +++ b/src/compas/CompasScl.ts @@ -33,7 +33,7 @@ export class CompasScl extends LitElement { document .querySelector('open-scd')! - .dispatchEvent(newOpenDocEvent(doc, docName, {detail: {docId: id, docType: this.type}})); + .dispatchEvent(newOpenDocEvent(doc, docName, {detail: {docId: id, docType: this.type?.toLowerCase()}})); } render(): TemplateResult { diff --git a/src/compas/CompasService.ts b/src/compas/CompasService.ts index 3e469a5d12..e2aa5688e3 100644 --- a/src/compas/CompasService.ts +++ b/src/compas/CompasService.ts @@ -9,13 +9,13 @@ export function listSclTypes(): Promise { } export function listScls(type: string): Promise { - return fetch(baseUrl + '/scl/v1/' + type + '/list') + return fetch(baseUrl + '/scl/v1/' + type?.toUpperCase() + '/list') .then(response => response.text()) .then(str => new DOMParser().parseFromString(str, 'application/xml')) } export function getSclDocument(type: string, id: string): Promise { - const sclUrl = baseUrl + '/scl/v1/' + type + '/' + id + '/scl'; + const sclUrl = baseUrl + '/scl/v1/' + type?.toUpperCase() + '/' + id + '/scl'; return fetch(sclUrl) .then(response => response.text()) .then(str => new DOMParser().parseFromString(str, 'application/xml')) @@ -26,7 +26,7 @@ export interface CreateRequestBody { doc: Document } export function addSclDocument(type: string, body: CreateRequestBody): Promise { - const sclUrl = baseUrl + '/scl/v1/' + type; + const sclUrl = baseUrl + '/scl/v1/' + type?.toUpperCase(); return fetch(sclUrl, { method: 'POST', headers: { @@ -47,7 +47,7 @@ export interface UpdateRequestBody { doc: Document } export function updateSclDocument(type: string, id: string, body: UpdateRequestBody): Promise { - const sclUrl = baseUrl + '/scl/v1/' + type + '/' + id; + const sclUrl = baseUrl + '/scl/v1/' + type?.toUpperCase() + '/' + id; return fetch(sclUrl, { method: 'PUT', headers: { From 7b8d8bb34640d84258fe671539941cffa3dc2345 Mon Sep 17 00:00:00 2001 From: Christian Dinkel Date: Wed, 9 Jun 2021 14:11:10 +0200 Subject: [PATCH 014/246] refactor(openproject): replace Open Project with plugin Added the triggered plugin kinds 'loader' and 'saver' and a 'loader' type plugin for opening projects. --- __snapshots__/open-scd.md | 37 ++-- public/js/plugins.js | 14 +- src/Plugging.ts | 14 +- src/Validating.ts | 15 +- .../OpenFile.ts => loaders/OpenProject.ts} | 4 +- src/open-scd.ts | 178 ++++++++++-------- test/integration/open-scd.test.ts | 2 +- 7 files changed, 166 insertions(+), 98 deletions(-) rename src/{triggered/OpenFile.ts => loaders/OpenProject.ts} (91%) diff --git a/__snapshots__/open-scd.md b/__snapshots__/open-scd.md index ff3cc6214a..d8ba846b06 100644 --- a/__snapshots__/open-scd.md +++ b/__snapshots__/open-scd.md @@ -13,12 +13,6 @@ Menu -
  • -
  • Open project + + +
  • +
  • - + + + folder_open + + Open project + + folder_open + + = { editor: 'tab', triggered: 'play_circle', + loader: 'folder_open', + saver: 'save', }; async function storeDefaultPlugins(): Promise { @@ -81,6 +83,16 @@ export function Plugging EditingElement>( .filter(plugin => plugin.installed && plugin.kind === 'editor') .map(plugin => this.addContent(plugin)); } + get loaders(): InstalledPlugin[] { + return this.plugins + .filter(plugin => plugin.installed && plugin.kind === 'loader') + .map(plugin => this.addContent(plugin)); + } + get savers(): InstalledPlugin[] { + return this.plugins + .filter(plugin => plugin.installed && plugin.kind === 'saver') + .map(plugin => this.addContent(plugin)); + } get triggered(): InstalledPlugin[] { return this.plugins .filter(plugin => plugin.installed && plugin.kind === 'triggered') diff --git a/src/Validating.ts b/src/Validating.ts index 6241ac65c4..fddf8cef80 100644 --- a/src/Validating.ts +++ b/src/Validating.ts @@ -1,7 +1,12 @@ import { property } from 'lit-element'; import { get } from 'lit-translate'; -import { LitElementConstructor, Mixin, newLogEvent } from './foundation.js'; +import { + LitElementConstructor, + Mixin, + newLogEvent, + OpenDocEvent, +} from './foundation.js'; import { getSchema, isLoadSchemaResult, @@ -127,6 +132,14 @@ export function Validating(Base: TBase) { worker.postMessage({ content: xsd, name: xsdName }); }); } + + constructor(...args: any[]) { + super(...args); + + this.addEventListener('open-doc', (event: OpenDocEvent) => + this.validate(event.detail.doc, { fileName: event.detail.docName }) + ); + } } return ValidatingElement; diff --git a/src/triggered/OpenFile.ts b/src/loaders/OpenProject.ts similarity index 91% rename from src/triggered/OpenFile.ts rename to src/loaders/OpenProject.ts index 68f0ca55c7..d86670db28 100644 --- a/src/triggered/OpenFile.ts +++ b/src/loaders/OpenProject.ts @@ -2,7 +2,7 @@ import { css, html, LitElement, query, TemplateResult } from 'lit-element'; import { newOpenDocEvent } from '../foundation.js'; -export default class OpenFilePlugin extends LitElement { +export default class OpenProjectPlugin extends LitElement { @query('#open-plugin-input') pluginFileUI!: HTMLInputElement; async openDoc(event: Event): Promise { @@ -20,7 +20,7 @@ export default class OpenFilePlugin extends LitElement { this.pluginFileUI.onchange = null; } - async trigger(): Promise { + async load(): Promise { this.pluginFileUI.click(); } diff --git a/src/open-scd.ts b/src/open-scd.ts index a3bc86d6ac..6273e4285f 100644 --- a/src/open-scd.ts +++ b/src/open-scd.ts @@ -75,6 +75,14 @@ interface Triggered { trigger: () => Promise; } +interface Loader { + load: () => Promise; +} + +interface Saver { + save: () => Promise; +} + /** The `` custom element is the main entry point of the * Open Substation Configuration Designer. */ @customElement('open-scd') @@ -96,7 +104,6 @@ export class OpenSCD extends Setting( } @query('#menu') menuUI!: Drawer; - @query('#file-input') fileUI!: HTMLInputElement; @query('#saveas') saveUI!: Dialog; /** Loads and parses an `XMLDocument` after [[`src`]] has changed. */ @@ -112,18 +119,6 @@ export class OpenSCD extends Setting( if (src.startsWith('blob:')) URL.revokeObjectURL(src); } - private async loadFile(event: Event): Promise { - const file = - (event.target)?.files?.item(0) ?? false; - if (!file) return; - - const text = await file.text(); - const docName = file.name; - const doc = new DOMParser().parseFromString(text, 'application/xml'); - - this.dispatchEvent(newOpenDocEvent(doc, docName)); - } - private saveAs(): void { this.docName = this.saveUI.querySelector('mwc-textfield')?.value || this.docName; @@ -176,7 +171,6 @@ export class OpenSCD extends Setting( if (ctrlAnd('z')) this.undo(); if (ctrlAnd('l')) this.logUI.open ? this.logUI.close() : this.logUI.show(); if (ctrlAnd('m')) this.menuUI.open = !this.menuUI.open; - if (ctrlAnd('o')) this.fileUI.click(); if (ctrlAnd('s')) this.save(); if (ctrlAnd('S')) this.saveUI.show(); if (ctrlAnd('P')) this.pluginUI.show(); @@ -241,10 +235,12 @@ export class OpenSCD extends Setting( } get menu(): (MenuItem | 'divider')[] { - const items: (MenuItem | 'divider')[] = []; + const triggered: (MenuItem | 'divider')[] = []; + const loaders: (MenuItem | 'divider')[] = []; + const savers: (MenuItem | 'divider')[] = []; this.triggered.forEach(plugin => - items.push({ + triggered.push({ icon: plugin.icon || pluginIcons['triggered'], name: plugin.name, action: ae => { @@ -263,15 +259,52 @@ export class OpenSCD extends Setting( }) ); - if (items.length > 0) items.push('divider'); + this.loaders.forEach(plugin => + loaders.push({ + icon: plugin.icon || pluginIcons['loader'], + name: plugin.name, + action: ae => { + this.dispatchEvent( + newPendingStateEvent( + (( + (( + (ae.target).items[ae.detail.index].lastElementChild + )) + )).load() + ) + ); + }, + disabled: (): boolean => false, + content: plugin.content, + }) + ); + + this.savers.forEach(plugin => + loaders.push({ + icon: plugin.icon || pluginIcons['saver'], + name: plugin.name, + action: ae => { + this.dispatchEvent( + newPendingStateEvent( + (( + (( + (ae.target).items[ae.detail.index].lastElementChild + )) + )).save() + ) + ); + }, + disabled: (): boolean => this.doc === null, + content: plugin.content, + }) + ); + + if (triggered.length > 0) triggered.push('divider'); return [ + ...loaders, + ...savers, 'divider', - { - icon: 'folder_open', - name: 'menu.open', - action: (): void => this.fileUI.click(), - }, { icon: 'create_new_folder', name: 'menu.new', @@ -324,7 +357,7 @@ export class OpenSCD extends Setting( action: (): void => this.logUI.show(), }, 'divider', - ...items, + ...triggered, { icon: 'settings', name: 'settings.name', @@ -389,16 +422,17 @@ export class OpenSCD extends Setting( return html` ${translate('menu.name')} - ${ - this.docName ? html`${this.docName}` : '' - } + ${this.docName + ? html`${this.docName}` + : ''} ) => (( this.menu.filter(item => item !== 'divider')[ae.detail.index] ))?.action?.(ae)} - > ${this.menu.map(this.renderMenuItem)} + > + ${this.menu.map(this.renderMenuItem)} @@ -410,70 +444,64 @@ export class OpenSCD extends Setting( >
    ${this.docName}
    ${this.menu.map(this.renderActionItem)} - ${ - this.doc - ? html` - (this.activeTab = e.detail.index)} - > - ${this.editors.map(this.renderEditorTab)} - ` - : `` - } + ${this.doc + ? html` + (this.activeTab = e.detail.index)} + > + ${this.editors.map(this.renderEditorTab)} + ` + : ``}
    - + this.saveAs()} icon="save" - slot="primaryAction"> + slot="primaryAction" + > ${translate('save')} + slot="secondaryAction" + > ${translate('cancel')} - - ${ - this.doc - ? until( - this.editors[this.activeTab] && - this.editors[this.activeTab].content(), - html`` - ) - : html`
    - this.openNewProjectWizard()} - > -
    ${translate('menu.new')}
    -
    - this.fileUI.click()} - > -
    ${translate('menu.open')}
    -
    -
    ` - } - - ((event.target).value = '')} @change="${ - this.loadFile - }"> - ${super.render()} - ${getTheme(this.settings.theme)} + + ${this.doc + ? until( + this.editors[this.activeTab] && + this.editors[this.activeTab].content(), + html`` + ) + : html`
    + this.openNewProjectWizard()} + > +
    ${translate('menu.new')}
    +
    + + this.menuUI.querySelector('mwc-list-item')!.click()} + > +
    ${translate('menu.open')}
    +
    +
    `} + ${super.render()} ${getTheme(this.settings.theme)} `; } diff --git a/test/integration/open-scd.test.ts b/test/integration/open-scd.test.ts index 18c35d2679..e8bc569cf7 100644 --- a/test/integration/open-scd.test.ts +++ b/test/integration/open-scd.test.ts @@ -195,7 +195,7 @@ describe('open-scd', () => { await element.validated; expect(element).property('history').to.have.length(4); expect(element.doc?.querySelector('Bay[name="COUPLING_BAY"]')).to.exist; - }); + }).timeout(10000); it('generates no error messages for valid SCL file', async () => { const validBlobURL = URL.createObjectURL( From 38f0f85a804fc121164cf881a2dae61b9a752de5 Mon Sep 17 00:00:00 2001 From: Christian Dinkel Date: Wed, 9 Jun 2021 16:17:40 +0200 Subject: [PATCH 015/246] fix(open-scd): move menu divider above loaders --- src/open-scd.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/open-scd.ts b/src/open-scd.ts index 6273e4285f..aaae20fa0f 100644 --- a/src/open-scd.ts +++ b/src/open-scd.ts @@ -302,9 +302,9 @@ export class OpenSCD extends Setting( if (triggered.length > 0) triggered.push('divider'); return [ + 'divider', ...loaders, ...savers, - 'divider', { icon: 'create_new_folder', name: 'menu.new', From 83223ecceb73f651a6d6c36b1e4a95b35b82dc15 Mon Sep 17 00:00:00 2001 From: Christian Dinkel Date: Thu, 10 Jun 2021 08:40:37 +0200 Subject: [PATCH 016/246] test(open-scd): update menu snapshot --- __snapshots__/open-scd.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/__snapshots__/open-scd.md b/__snapshots__/open-scd.md index d8ba846b06..c89d4ac585 100644 --- a/__snapshots__/open-scd.md +++ b/__snapshots__/open-scd.md @@ -13,6 +13,12 @@ Menu +
  • +
  • -
  • -
  • Date: Thu, 10 Jun 2021 08:52:17 +0200 Subject: [PATCH 017/246] Some testing added. Signed-off-by: Dennis Labordus --- __snapshots__/compas-changeset-radiogroup.md | 40 +++++++ __snapshots__/compas-scl-list.md | 17 +++ __snapshots__/compas-scltype-list.md | 17 +++ __snapshots__/compas-scltype-radiogroup.md | 17 +++ __snapshots__/open-scd.md | 105 ++++++++++++++++++ package-lock.json | 76 +++++++++++++ src/compas/CompasSaveTo.ts | 4 +- src/compas/CompasScl.ts | 9 +- ...{CompasScltype.ts => CompasScltypeList.ts} | 66 +---------- src/compas/CompasScltypeRadiogroup.ts | 48 ++++++++ src/compas/CompasService.ts | 12 ++ src/triggered/OpenCompas.ts | 2 +- test/unit/compas/CompasChangeSet.test.ts | 30 +++++ test/unit/compas/CompasScl.test.ts | 21 ++++ test/unit/compas/CompasScltypeList.test.ts | 21 ++++ .../compas/CompasScltypeRadiogroup.test.ts | 21 ++++ 16 files changed, 432 insertions(+), 74 deletions(-) create mode 100644 __snapshots__/compas-changeset-radiogroup.md create mode 100644 __snapshots__/compas-scl-list.md create mode 100644 __snapshots__/compas-scltype-list.md create mode 100644 __snapshots__/compas-scltype-radiogroup.md rename src/compas/{CompasScltype.ts => CompasScltypeList.ts} (51%) create mode 100644 src/compas/CompasScltypeRadiogroup.ts create mode 100644 test/unit/compas/CompasChangeSet.test.ts create mode 100644 test/unit/compas/CompasScl.test.ts create mode 100644 test/unit/compas/CompasScltypeList.test.ts create mode 100644 test/unit/compas/CompasScltypeRadiogroup.test.ts diff --git a/__snapshots__/compas-changeset-radiogroup.md b/__snapshots__/compas-changeset-radiogroup.md new file mode 100644 index 0000000000..07eba0a639 --- /dev/null +++ b/__snapshots__/compas-changeset-radiogroup.md @@ -0,0 +1,40 @@ +# `compas-changeset-radiogroup` + +#### `looks like the latest snapshot` + +```html + + + Major change + + + Minor change + + + Patch change + + + +``` + diff --git a/__snapshots__/compas-scl-list.md b/__snapshots__/compas-scl-list.md new file mode 100644 index 0000000000..c9fd46f83f --- /dev/null +++ b/__snapshots__/compas-scl-list.md @@ -0,0 +1,17 @@ +# `compas-scl-list` + +#### `looks like the latest snapshot` + +```html + + + Loading... + + + +``` + diff --git a/__snapshots__/compas-scltype-list.md b/__snapshots__/compas-scltype-list.md new file mode 100644 index 0000000000..9a1cadcdbf --- /dev/null +++ b/__snapshots__/compas-scltype-list.md @@ -0,0 +1,17 @@ +# `compas-scltype-list` + +#### `looks like the latest snapshot` + +```html + + + Loading... + + + +``` + diff --git a/__snapshots__/compas-scltype-radiogroup.md b/__snapshots__/compas-scltype-radiogroup.md new file mode 100644 index 0000000000..4ddc6f7e85 --- /dev/null +++ b/__snapshots__/compas-scltype-radiogroup.md @@ -0,0 +1,17 @@ +# `compas-scltype-radiogroup` + +#### `looks like the latest snapshot` + +```html + + + Loading... + + + +``` + diff --git a/__snapshots__/open-scd.md b/__snapshots__/open-scd.md index ff3cc6214a..6ca8db2384 100644 --- a/__snapshots__/open-scd.md +++ b/__snapshots__/open-scd.md @@ -148,6 +148,57 @@ role="separator" > + + + folder_open + + + Open file + + + + + + + folder_open + + + Open from CoMPAS + + + + + + + folder_open + + + Save to CoMPAS + + + + + + folder_open + + Open file + + play_circle + + + @@ -522,6 +591,42 @@ tab + + + folder_open + + Open from CoMPAS + + play_circle + + + + + folder_open + + Save to CoMPAS + + play_circle + + { this.scls = Array.from(scls.querySelectorAll('Item') ?? [])}) } diff --git a/src/compas/CompasScltype.ts b/src/compas/CompasScltypeList.ts similarity index 51% rename from src/compas/CompasScltype.ts rename to src/compas/CompasScltypeList.ts index 20e020b6b2..6d4fd4d845 100644 --- a/src/compas/CompasScltype.ts +++ b/src/compas/CompasScltypeList.ts @@ -2,21 +2,15 @@ import {customElement, html, LitElement, property, TemplateResult} from "lit-ele import {get} from "lit-translate"; import {SingleSelectedEvent} from "@material/mwc-list/mwc-list-foundation"; import {newWizardEvent, Wizard, WizardActor} from '../foundation.js'; -import {listSclTypes} from "./CompasService.js"; +import {listSclTypesAndOrder} from "./CompasService.js"; import {listSclsWizard} from "./CompasScl.js"; -import {ListItemBase} from "@material/mwc-list/mwc-list-item-base"; @customElement('compas-scltype-list') export class CompasScltypeList extends LitElement { @property() sclTypes!: Element[]; - connectedCallback() { - super.connectedCallback(); - this.fetchData(); - } - - fetchData() { + firstUpdated() { listSclTypesAndOrder() .then(types => this.sclTypes = types) } @@ -56,62 +50,6 @@ export class CompasScltypeList extends LitElement { } } -@customElement('compas-scltype-radiogroup') -export class CompasScltypeRadiogroup extends LitElement { - @property({type: Document}) - sclTypes!:Element[]; - - connectedCallback() { - super.connectedCallback(); - this.fetchData(); - } - - fetchData() { - listSclTypesAndOrder() - .then(types => this.sclTypes = types) - } - - getSelectedValue() : string { - return (this.shadowRoot!.querySelector('mwc-list')!.selected).value; - } - - render(): TemplateResult { - if (!this.sclTypes) { - return html `Loading...` - } - - if (this.sclTypes.length <= 0) { - return html ` - - ${get("compas.open.noSclTypes")} - - ` - } - return html` - - ${this.sclTypes.map( type => { - const code = type.getElementsByTagName("Code").item(0); - const description = type.getElementsByTagName("Description").item(0); - return html` - ${description} (${code}) - `; - })} - ` - } -} - -function listSclTypesAndOrder(): Promise { - return listSclTypes() - .then(sclTypesDocument => { - return Array.from(sclTypesDocument.querySelectorAll('Type') ?? []) - .sort((type1, type2) => { - const description1 = type1.getElementsByTagName("Description")!.item(0)!.textContent ?? ""; - const description2 = type2.getElementsByTagName("Description")!.item(0)!.textContent ?? ""; - return description1.localeCompare(description2) - }); - }) -} - export function compasSclTypeListWizardActor(): WizardActor { return () => [() => compasSclTypeListWizard()]; } diff --git a/src/compas/CompasScltypeRadiogroup.ts b/src/compas/CompasScltypeRadiogroup.ts new file mode 100644 index 0000000000..6a2b8b5499 --- /dev/null +++ b/src/compas/CompasScltypeRadiogroup.ts @@ -0,0 +1,48 @@ +import {customElement, html, LitElement, property, TemplateResult} from "lit-element"; +import {get} from "lit-translate"; +import {listSclTypesAndOrder} from "./CompasService.js"; +import {ListItemBase} from "@material/mwc-list/mwc-list-item-base"; + +@customElement('compas-scltype-radiogroup') +export class CompasScltypeRadiogroup extends LitElement { + @property({type: Document}) + sclTypes!:Element[]; + + connectedCallback() { + super.connectedCallback(); + this.fetchData(); + } + + fetchData() { + listSclTypesAndOrder() + .then(types => this.sclTypes = types) + } + + getSelectedValue() : string { + return (this.shadowRoot!.querySelector('mwc-list')!.selected).value; + } + + render(): TemplateResult { + if (!this.sclTypes) { + return html `Loading...` + } + + if (this.sclTypes.length <= 0) { + return html ` + + ${get("compas.open.noSclTypes")} + + ` + } + return html` + + ${this.sclTypes.map( type => { + const code = type.getElementsByTagName("Code").item(0); + const description = type.getElementsByTagName("Description").item(0); + return html` + ${description} (${code}) + `; + })} + ` + } +} diff --git a/src/compas/CompasService.ts b/src/compas/CompasService.ts index e2aa5688e3..6986a07436 100644 --- a/src/compas/CompasService.ts +++ b/src/compas/CompasService.ts @@ -8,6 +8,18 @@ export function listSclTypes(): Promise { .then(str => new DOMParser().parseFromString(str, 'application/xml')) } +export function listSclTypesAndOrder(): Promise { + return listSclTypes() + .then(sclTypesDocument => { + return Array.from(sclTypesDocument.querySelectorAll('Type') ?? []) + .sort((type1, type2) => { + const description1 = type1.getElementsByTagName("Description")!.item(0)!.textContent ?? ""; + const description2 = type2.getElementsByTagName("Description")!.item(0)!.textContent ?? ""; + return description1.localeCompare(description2) + }); + }) +} + export function listScls(type: string): Promise { return fetch(baseUrl + '/scl/v1/' + type?.toUpperCase() + '/list') .then(response => response.text()) diff --git a/src/triggered/OpenCompas.ts b/src/triggered/OpenCompas.ts index b571efcb6e..3f78725d4c 100644 --- a/src/triggered/OpenCompas.ts +++ b/src/triggered/OpenCompas.ts @@ -1,6 +1,6 @@ import {LitElement} from 'lit-element'; import {newWizardEvent} from '../foundation.js'; -import {compasSclTypeListWizard} from "../compas/CompasScltype.js"; +import {compasSclTypeListWizard} from "../compas/CompasScltypeList.js"; export default class OpenCompasPlugin extends LitElement { async trigger(): Promise { diff --git a/test/unit/compas/CompasChangeSet.test.ts b/test/unit/compas/CompasChangeSet.test.ts new file mode 100644 index 0000000000..9718bd2391 --- /dev/null +++ b/test/unit/compas/CompasChangeSet.test.ts @@ -0,0 +1,30 @@ +import { fixture, html, expect } from '@open-wc/testing'; + +import "../../../src/compas/CompasChangeSet.js"; +import {CompasChangeSetRadiogroup} from "../../../src/compas/CompasChangeSet.js"; + +describe('compas-changeset-radiogroup', () => { + let element: CompasChangeSetRadiogroup; + beforeEach(async () => { + element = ( + await fixture( + html`` + ) + ); + }); + + it('has 3 item entries', () => { + expect(element.shadowRoot!.querySelectorAll('mwc-list > mwc-radio-list-item')) + .to.have.length(3) + }); + + it('has the correct value for MAJOR Item', () => { + expect(element.shadowRoot!.querySelectorAll('mwc-list > mwc-radio-list-item[value = "MAJOR"]')) + .to.have.text("Major change") + }); + + it('looks like the latest snapshot', () => { + expect(element).shadowDom + .to.equalSnapshot(); + }); +}); diff --git a/test/unit/compas/CompasScl.test.ts b/test/unit/compas/CompasScl.test.ts new file mode 100644 index 0000000000..bceb188e27 --- /dev/null +++ b/test/unit/compas/CompasScl.test.ts @@ -0,0 +1,21 @@ +import {expect, fixture, html} from '@open-wc/testing'; + +import "../../../src/compas/CompasScl.js"; +import {CompasScl} from "../../../src/compas/CompasScl.js"; + +describe('compas-scl-list', () => { + let element: CompasScl; + + beforeEach(async () => { + element = ( + await fixture( + html`` + ) + ); + }); + + it('looks like the latest snapshot', async () => { + expect(element).shadowDom + .to.equalSnapshot(); + }); +}); diff --git a/test/unit/compas/CompasScltypeList.test.ts b/test/unit/compas/CompasScltypeList.test.ts new file mode 100644 index 0000000000..9e2d019c89 --- /dev/null +++ b/test/unit/compas/CompasScltypeList.test.ts @@ -0,0 +1,21 @@ +import {expect, fixture, html} from '@open-wc/testing'; + +import "../../../src/compas/CompasScltypeList.js"; +import {CompasScltypeList} from "../../../src/compas/CompasScltypeList.js"; + +describe('compas-scltype-list', () => { + let element: CompasScltypeList; + + beforeEach(async () => { + element = ( + await fixture( + html`` + ) + ); + }); + + it('looks like the latest snapshot', async () => { + expect(element).shadowDom + .to.equalSnapshot(); + }); +}); diff --git a/test/unit/compas/CompasScltypeRadiogroup.test.ts b/test/unit/compas/CompasScltypeRadiogroup.test.ts new file mode 100644 index 0000000000..5f89691a16 --- /dev/null +++ b/test/unit/compas/CompasScltypeRadiogroup.test.ts @@ -0,0 +1,21 @@ +import {expect, fixture, html} from '@open-wc/testing'; + +import "../../../src/compas/CompasScltypeRadiogroup.js"; +import {CompasScltypeRadiogroup} from "../../../src/compas/CompasScltypeRadiogroup.js"; + +describe('compas-scltype-radiogroup', () => { + let element: CompasScltypeRadiogroup; + + beforeEach(async () => { + element = ( + await fixture( + html`` + ) + ); + }); + + it('looks like the latest snapshot', async () => { + expect(element).shadowDom + .to.equalSnapshot(); + }); +}); From eedd11e333760ee50a8830b6cb55d19bf43afb96 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 10 Jun 2021 11:33:52 +0200 Subject: [PATCH 018/246] Small improvement to make it more stable. Signed-off-by: Dennis Labordus --- src/Editing.ts | 5 +- src/Plugging.ts | 1 - src/compas/CompasChangeSet.ts | 22 +++-- src/compas/CompasSaveTo.ts | 114 +++++++++++++++++--------- src/compas/CompasScl.ts | 4 +- src/compas/CompasScltypeRadiogroup.ts | 25 +++++- src/compas/CompasService.ts | 4 +- src/foundation.ts | 6 +- src/translations/de.ts | 6 +- src/translations/en.ts | 6 +- src/triggered/SaveToCompas.ts | 5 +- 11 files changed, 133 insertions(+), 65 deletions(-) diff --git a/src/Editing.ts b/src/Editing.ts index eeb8df2c39..bf27b1ab38 100644 --- a/src/Editing.ts +++ b/src/Editing.ts @@ -52,10 +52,8 @@ export function Editing(Base: TBase) { doc: XMLDocument | null = null; /** The name of the current [[`doc`]] */ @property({ type: String }) docName = ''; - /** The UUID of the current [[`doc`]] */ + /** The ID of the current [[`doc`]] */ @property({ type: String }) docId = ''; - /** The type of the current [[`doc`]] */ - @property({ type: String }) docType = ''; private checkCreateValidity(create: Create): boolean { if (create.checkValidity !== undefined) return create.checkValidity(); @@ -264,7 +262,6 @@ export function Editing(Base: TBase) { this.doc = event.detail.doc; this.docName = event.detail.docName; this.docId = event.detail.docId ?? ''; - this.docType = event.detail.docType ?? ''; this.dispatchEvent( newLogEvent({ diff --git a/src/Plugging.ts b/src/Plugging.ts index 7141389a4f..6ddc13fc91 100644 --- a/src/Plugging.ts +++ b/src/Plugging.ts @@ -151,7 +151,6 @@ export function Plugging EditingElement>( .doc=${this.doc} .docName=${this.docName} .docId=${this.docId} - .docType=${this.docType} >`; }, }; diff --git a/src/compas/CompasChangeSet.ts b/src/compas/CompasChangeSet.ts index e983c9054b..e178ee0f47 100644 --- a/src/compas/CompasChangeSet.ts +++ b/src/compas/CompasChangeSet.ts @@ -17,16 +17,28 @@ const changeSetDetails = new Map([ @customElement('compas-changeset-radiogroup') export class CompasChangeSetRadiogroup extends LitElement { + private getSelectedListItem() : ListItemBase | null { + return this.shadowRoot!.querySelector('mwc-list')!.selected; + } + + getSelectedValue() : ChangeSet | null { + const changeSet = this.getSelectedListItem(); + if (changeSet) { + return changeSet.value; + } + return null; + } + + checkValidity(): boolean { + return this.getSelectedListItem() != null; + } + render(): TemplateResult { return html` ${Object.values(ChangeSet) - .map((key) => html `${changeSetDetails.get(key)!.description}`)} + .map((key) => html `${changeSetDetails.get(key)!.description}`)} ` } - - getSelectedValue() : ChangeSet { - return (this.shadowRoot!.querySelector('mwc-list')!.selected).value; - } } diff --git a/src/compas/CompasSaveTo.ts b/src/compas/CompasSaveTo.ts index d44235a8e9..87dc2297e5 100644 --- a/src/compas/CompasSaveTo.ts +++ b/src/compas/CompasSaveTo.ts @@ -1,5 +1,5 @@ import {customElement, html, LitElement, property, TemplateResult} from "lit-element"; -import {newWizardEvent, Wizard, WizardInput} from "../foundation.js"; +import {InfoDetail, newLogEvent, newWizardEvent, Wizard, WizardInput} from "../foundation.js"; import {get, translate} from "lit-translate"; import {TextFieldBase} from "@material/mwc-textfield/mwc-textfield-base"; @@ -17,14 +17,9 @@ export class CompasSaveTo extends LitElement { docName!: string; @property({type: String}) docId!: string; - @property({type: String}) - docType!: string; - - @property({type: String}) - errorMessage!: string; - getNameValue() : string { - return (this.shadowRoot!.querySelector('mwc-textfield[id="name"]')).value; + getNameField() : TextFieldBase { + return this.shadowRoot!.querySelector('mwc-textfield[id="name"]'); } getSclTypeRadioGroup() : CompasScltypeRadiogroup { @@ -37,19 +32,26 @@ export class CompasSaveTo extends LitElement { .querySelector("compas-changeset-radiogroup")) } + checkValidity(): boolean { + if (!this.docId) { + return this.getNameField().checkValidity() + && this.getSclTypeRadioGroup().checkValidity(); + } + return this.getChangeSetRadiogroup().checkValidity(); + } + render(): TemplateResult { return this.renderWizardPage(); } renderWizardPage(): TemplateResult { - if (!this.docId || !this.docType) { + if (!this.docId) { return html` -
    ${this.errorMessage}
    - + `; } return html ` @@ -58,66 +60,100 @@ export class CompasSaveTo extends LitElement { } } -function addSclToCompass(wizard: Element, doc: XMLDocument) { +function getTypeFromDocName(docName: string) { + if (docName!.lastIndexOf(".") == docName!.length - 4) { + return docName.substring(docName.lastIndexOf(".") + 1); + } + throw "Unable to determine type from document name!"; +} + +function addSclToCompass(wizard: Element, compasSaveTo: CompasSaveTo, doc: XMLDocument) { const openScd = document.querySelector('open-scd'); - const compasSaveTo = wizard.shadowRoot!.querySelector('compas-save-to') - let name = compasSaveTo.getNameValue(); + let name = compasSaveTo.getNameField()!.value; if (name!.lastIndexOf(".") == name!.length - 4) { name = name.substring(0, name.lastIndexOf(".")); } - const newDocType = compasSaveTo.getSclTypeRadioGroup().getSelectedValue(); - - openScd!.docType = newDocType; - openScd!.docName = name + "." + newDocType.toLowerCase() + const docType = compasSaveTo.getSclTypeRadioGroup().getSelectedValue(); + if (docType === null) { + return; + } - addSclDocument(newDocType, {sclName: name, doc: doc}) - .then(document => { - const id = Array.from(document.querySelectorAll('Id') ?? [])[0]; + openScd!.docName = name + "." + docType!.toLowerCase() + addSclDocument(docType, {sclName: name, doc: doc}) + .then(xmlResponse => { + const id = Array.from(xmlResponse.querySelectorAll('Id') ?? [])[0]; openScd!.docId = id.textContent ?? ""; - openScd!.docName = (id.textContent ?? "") + "." + newDocType.toLowerCase() - compasSaveTo.errorMessage = ""; + openScd!.docName = (id.textContent ?? "") + "." + docType.toLowerCase() + + document + .querySelector('open-scd')! + .dispatchEvent( + newLogEvent({ + kind: 'info', + title: get('compas.saveTo.addSuccess')})); // Close the Save Dialog. openScd!.dispatchEvent(newWizardEvent()); }) .catch(() => { - compasSaveTo.errorMessage = "Error adding SCL to CoMPAS!"; + document + .querySelector('open-scd')! + .dispatchEvent( + newLogEvent({ + kind: 'error', + title: get('compas.saveTo.addError')})); }); } -function updateSclInCompas(wizard: Element, docType: string, docId: string, doc: XMLDocument) { +function updateSclInCompas(wizard: Element, compasSaveTo: CompasSaveTo, docId: string, docName: string, doc: XMLDocument) { const openScd = document.querySelector('open-scd'); - const compasSaveTo = wizard.shadowRoot!.querySelector('compas-save-to') const changeSet = compasSaveTo.getChangeSetRadiogroup().getSelectedValue(); + if (changeSet === null) { + return; + } + const docType = getTypeFromDocName(docName); + updateSclDocument(docType.toUpperCase(), docId, {changeSet: changeSet, doc: doc}) .then(() => { - compasSaveTo.errorMessage = ""; + document + .querySelector('open-scd')! + .dispatchEvent( + newLogEvent({ + kind: 'info', + title: get('compas.saveTo.updateSuccess')})); // Close the Save Dialog. openScd!.dispatchEvent(newWizardEvent()); }) .catch(() => { - compasSaveTo.errorMessage = "Error updating SCL in CoMPAS!"; + document + .querySelector('open-scd')! + .dispatchEvent( + newLogEvent({ + kind: 'error', + title: get('compas.saveTo.updateError')})); }); } -function saveToCompass(doc: XMLDocument, docId: string, docType: string) { +function saveToCompass(docId: string, docName: string, doc: XMLDocument) { return function (inputs: WizardInput[], wizard: Element) { - if (doc) { - if (!docId || !docType) { - addSclToCompass(wizard, doc); - } else { - updateSclInCompas(wizard, docType, docId, doc); - } + const compasSaveTo = wizard.shadowRoot!.querySelector('compas-save-to') + if (!doc || !compasSaveTo.checkValidity()) { + return []; + } + + if (!docId) { + addSclToCompass(wizard, compasSaveTo, doc); + } else { + updateSclInCompas(wizard, compasSaveTo, docId, docName, doc); } return []; }; } export interface SaveToCompasWizardOptions { - docName: string, docId: string, - docType: string + docName: string } export function saveToCompasWizard(doc: XMLDocument, saveToOptions: SaveToCompasWizardOptions): Wizard { return [ @@ -126,11 +162,11 @@ export function saveToCompasWizard(doc: XMLDocument, saveToOptions: SaveToCompas primary: { icon: 'save', label: get('save'), - action: saveToCompass(doc, saveToOptions.docId, saveToOptions.docType), + action: saveToCompass(saveToOptions.docId, saveToOptions.docName, doc), }, content: [ html ` - + ` ], }, ]; diff --git a/src/compas/CompasScl.ts b/src/compas/CompasScl.ts index c37d1d4cfd..f018c6fb8d 100644 --- a/src/compas/CompasScl.ts +++ b/src/compas/CompasScl.ts @@ -15,7 +15,7 @@ export class CompasScl extends LitElement { firstUpdated() { listScls(this.type) - .then(scls => { this.scls = Array.from(scls.querySelectorAll('Item') ?? [])}) + .then(xmlResponse => { this.scls = Array.from(xmlResponse.querySelectorAll('Item') ?? [])}) } openScl(id?: string) { @@ -28,7 +28,7 @@ export class CompasScl extends LitElement { document .querySelector('open-scd')! - .dispatchEvent(newOpenDocEvent(doc, docName, {detail: {docId: id, docType: this.type?.toLowerCase()}})); + .dispatchEvent(newOpenDocEvent(doc, docName, {detail: {docId: id}})); } render(): TemplateResult { diff --git a/src/compas/CompasScltypeRadiogroup.ts b/src/compas/CompasScltypeRadiogroup.ts index 6a2b8b5499..92b6478d72 100644 --- a/src/compas/CompasScltypeRadiogroup.ts +++ b/src/compas/CompasScltypeRadiogroup.ts @@ -2,9 +2,13 @@ import {customElement, html, LitElement, property, TemplateResult} from "lit-ele import {get} from "lit-translate"; import {listSclTypesAndOrder} from "./CompasService.js"; import {ListItemBase} from "@material/mwc-list/mwc-list-item-base"; +import {List} from "@material/mwc-list"; @customElement('compas-scltype-radiogroup') export class CompasScltypeRadiogroup extends LitElement { + @property({type: String}) + value = ''; + @property({type: Document}) sclTypes!:Element[]; @@ -18,8 +22,20 @@ export class CompasScltypeRadiogroup extends LitElement { .then(types => this.sclTypes = types) } - getSelectedValue() : string { - return (this.shadowRoot!.querySelector('mwc-list')!.selected).value; + private getSelectedListItem() : ListItemBase | null { + return this.shadowRoot!.querySelector('mwc-list')!.selected; + } + + getSelectedValue() : string | null { + const listItem = this.getSelectedListItem(); + if (listItem) { + return listItem.value; + } + return null; + } + + checkValidity(): boolean { + return this.getSelectedListItem() != null; } render(): TemplateResult { @@ -37,9 +53,10 @@ export class CompasScltypeRadiogroup extends LitElement { return html` ${this.sclTypes.map( type => { - const code = type.getElementsByTagName("Code").item(0); + const code = type.getElementsByTagName("Code").item(0)!.textContent ?? ''; const description = type.getElementsByTagName("Description").item(0); - return html` + const selected = (code.toLowerCase() === this.value.toLowerCase()); + return html` ${description} (${code}) `; })} diff --git a/src/compas/CompasService.ts b/src/compas/CompasService.ts index 6986a07436..6d2a5fc299 100644 --- a/src/compas/CompasService.ts +++ b/src/compas/CompasService.ts @@ -10,8 +10,8 @@ export function listSclTypes(): Promise { export function listSclTypesAndOrder(): Promise { return listSclTypes() - .then(sclTypesDocument => { - return Array.from(sclTypesDocument.querySelectorAll('Type') ?? []) + .then(xmlResponse => { + return Array.from(xmlResponse.querySelectorAll('Type') ?? []) .sort((type1, type2) => { const description1 = type1.getElementsByTagName("Description")!.item(0)!.textContent ?? ""; const description2 = type2.getElementsByTagName("Description")!.item(0)!.textContent ?? ""; diff --git a/src/foundation.ts b/src/foundation.ts index 6973226a64..d608726519 100644 --- a/src/foundation.ts +++ b/src/foundation.ts @@ -3,6 +3,7 @@ import { directive, Part } from 'lit-html'; import { List } from '@material/mwc-list'; import { Select } from '@material/mwc-select'; +import { TextField } from '@material/mwc-textfield' import { WizardTextField } from './wizard-textfield.js'; @@ -133,8 +134,8 @@ export function newActionEvent( }); } -export const wizardInputSelector = 'wizard-textfield, mwc-select'; -export type WizardInput = WizardTextField | Select; +export const wizardInputSelector = 'wizard-textfield, mwc-textfield, mwc-select'; +export type WizardInput = WizardTextField | TextField | Select; export type WizardAction = EditorAction | (() => Wizard); @@ -266,7 +267,6 @@ export interface OpenDocDetail { doc: XMLDocument; docName: string; docId?: string; - docType?: string; } export type OpenDocEvent = CustomEvent; export function newOpenDocEvent( diff --git a/src/translations/de.ts b/src/translations/de.ts index 469ed62ca5..9722351e9c 100644 --- a/src/translations/de.ts +++ b/src/translations/de.ts @@ -264,7 +264,11 @@ export const de: Translations = { noScls: "???", }, saveTo: { - title: "???" + title: "???", + addError: '???', + addSuccess: '???', + updateError: '???', + updateSuccess: '???', } }, }; diff --git a/src/translations/en.ts b/src/translations/en.ts index 82c44121af..bc04c548f6 100644 --- a/src/translations/en.ts +++ b/src/translations/en.ts @@ -261,7 +261,11 @@ export const en = { noScls: 'No SCLs found', }, saveTo: { - title: "Save to Compas" + title: 'Save to Compas', + addError: 'Error adding SCL to CoMPAS!', + addSuccess: 'SCL added to CoMPAS.', + updateError: 'Error updating SCL in CoMPAS!', + updateSuccess: 'SCL updated in CoMPAS', } }, }; diff --git a/src/triggered/SaveToCompas.ts b/src/triggered/SaveToCompas.ts index 41ad05f799..e7a4adeb5d 100644 --- a/src/triggered/SaveToCompas.ts +++ b/src/triggered/SaveToCompas.ts @@ -4,12 +4,11 @@ import {saveToCompasWizard} from "../compas/CompasSaveTo.js"; export default class SaveCompasPlugin extends LitElement { doc!: XMLDocument; - docName!: string; docId!: string; - docType!: string; + docName!: string; async trigger(): Promise { - this.dispatchEvent(newWizardEvent(saveToCompasWizard(this.doc, {docName: this.docName, docId: this.docId, docType: this.docType}))); + this.dispatchEvent(newWizardEvent(saveToCompasWizard(this.doc, {docId: this.docId, docName: this.docName}))); } } From 4ffc3f31b9f9746c25f6462d10debc7c4bd5e69c Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 10 Jun 2021 11:46:43 +0200 Subject: [PATCH 019/246] Make the Compas open plugin a loader. Signed-off-by: Dennis Labordus --- public/js/plugins.js | 4 ++-- src/{triggered => loaders}/OpenCompas.ts | 2 +- src/{triggered => savers}/SaveToCompas.ts | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename src/{triggered => loaders}/OpenCompas.ts (89%) rename src/{triggered => savers}/SaveToCompas.ts (100%) diff --git a/public/js/plugins.js b/public/js/plugins.js index b129860cc1..70fa19cc6a 100644 --- a/public/js/plugins.js +++ b/public/js/plugins.js @@ -29,14 +29,14 @@ export const officialPlugins = [ }, { name: 'Open from CoMPAS', - src: '/src/triggered/OpenCompas.js', + src: '/src/loaders/OpenCompas.js', icon: 'folder_open', default: true, kind: 'loader' }, { name: 'Save to CoMPAS', - src: '/src/triggered/SaveToCompas.js', + src: '/src/savers/SaveToCompas.js', icon: 'folder_open', default: true, kind: 'triggered' diff --git a/src/triggered/OpenCompas.ts b/src/loaders/OpenCompas.ts similarity index 89% rename from src/triggered/OpenCompas.ts rename to src/loaders/OpenCompas.ts index 3f78725d4c..565ce66c57 100644 --- a/src/triggered/OpenCompas.ts +++ b/src/loaders/OpenCompas.ts @@ -3,7 +3,7 @@ import {newWizardEvent} from '../foundation.js'; import {compasSclTypeListWizard} from "../compas/CompasScltypeList.js"; export default class OpenCompasPlugin extends LitElement { - async trigger(): Promise { + async load(): Promise { this.dispatchEvent(newWizardEvent(compasSclTypeListWizard())); } } diff --git a/src/triggered/SaveToCompas.ts b/src/savers/SaveToCompas.ts similarity index 100% rename from src/triggered/SaveToCompas.ts rename to src/savers/SaveToCompas.ts From d362c564fa6ee9c280d83c9f240848fcd5e2143e Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 10 Jun 2021 11:51:29 +0200 Subject: [PATCH 020/246] Make the Compas save plugin a saver. Signed-off-by: Dennis Labordus --- public/js/plugins.js | 2 +- src/savers/SaveToCompas.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/js/plugins.js b/public/js/plugins.js index 70fa19cc6a..fa35eae124 100644 --- a/public/js/plugins.js +++ b/public/js/plugins.js @@ -39,7 +39,7 @@ export const officialPlugins = [ src: '/src/savers/SaveToCompas.js', icon: 'folder_open', default: true, - kind: 'triggered' + kind: 'saver' }, { name: 'Import IEDs', diff --git a/src/savers/SaveToCompas.ts b/src/savers/SaveToCompas.ts index e7a4adeb5d..6fd6e7e48c 100644 --- a/src/savers/SaveToCompas.ts +++ b/src/savers/SaveToCompas.ts @@ -7,7 +7,7 @@ export default class SaveCompasPlugin extends LitElement { docId!: string; docName!: string; - async trigger(): Promise { + async save(): Promise { this.dispatchEvent(newWizardEvent(saveToCompasWizard(this.doc, {docId: this.docId, docName: this.docName}))); } } From e37269e6309a0460d42f5366e6f32dd408d34eb2 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 10 Jun 2021 12:18:49 +0200 Subject: [PATCH 021/246] Missing snapshot. Signed-off-by: Dennis Labordus --- __snapshots__/open-scd.md | 866 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 866 insertions(+) create mode 100644 __snapshots__/open-scd.md diff --git a/__snapshots__/open-scd.md b/__snapshots__/open-scd.md new file mode 100644 index 0000000000..1424e5510b --- /dev/null +++ b/__snapshots__/open-scd.md @@ -0,0 +1,866 @@ +# `open-scd` + +#### `looks like its snapshot` + +```html + + + Menu + + +
  • +
  • + + + folder_open + + + Open project + + + + + + + folder_open + + + Open from CoMPAS + + + + + + + create_new_folder + + + New project + + + + + save_alt + + + Save + + + + + save + + + Save as + + +
  • +
  • + + + undo + + + Undo + + + + + redo + + + Redo + + + + + rule_folder + + + Validate project + + + + + rule + + + View log + + +
  • +
  • + + + folder_open + + + Save to CoMPAS + + + + + + + snippet_folder + + + Import IEDs + + + + + + + play_circle + + + Subscriber Update + + + + + + + merge_type + + + Merge Project + + + + + + + merge_type + + + Update Substation + + + + + + + sync_alt + + + Communication Mapping + + + + +
  • +
  • + + + settings + + + Settings + + + + + extension + + + Extensions + + +
    + + + +
    +
    + + + + + + +
    +
    + + + + + Save + + + Cancel + + +
    + +
    + New project +
    +
    + +
    + Open project +
    +
    +
    + + + + + + + + + + + + + Edits, errors, and other notifications will show up here. + + + info + + + + + + + + + Close + + + + + + + + + Show + + + + + + + Show + + + + + + + + + margin + + Substation + + tab + + + + + settings_ethernet + + Communication + + tab + + + + + copy_all + + Templates + + tab + + + + + folder_open + + Open project + + folder_open + + + + + folder_open + + Open from CoMPAS + + folder_open + + + + + folder_open + + Save to CoMPAS + + play_circle + + + + + snippet_folder + + Import IEDs + + play_circle + + + + + play_circle + + Subscriber Update + + play_circle + + + + + merge_type + + Merge Project + + play_circle + + + + + merge_type + + Update Substation + + play_circle + + + + + sync_alt + + Communication Mapping + + play_circle + + + + + + + + + + + +
    +

    + Here you may add remote extensions directly from a custom URL. + You do this at your own risk. +

    + + + + + Editor pane + + tab + + + + Menu entry + + play_circle + + + + + +
    + + + + +
    + + + + + +
    + + + English + + + German (Deutsch) + + + + + + +
    + + Cancel + + + Reset + + + Save + +
    + +``` + From b660a088ae59b81c7e36252d46cbe680dd91364b Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 10 Jun 2021 12:23:02 +0200 Subject: [PATCH 022/246] Revert package-lock, changes aren't needed. Signed-off-by: Dennis Labordus --- package-lock.json | 76 ----------------------------------------------- 1 file changed, 76 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4bbbadd8d9..f58d32f750 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5445,15 +5445,6 @@ "@types/sinon": "*" } }, - "@types/sinon-stub-promise": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@types/sinon-stub-promise/-/sinon-stub-promise-2.1.7.tgz", - "integrity": "sha512-61bXEDKZLappXuD+G1BnmhugnCjZ7JfGZ9T43Ku9+34pz6cpjN3C3nILq+2tP5EqCvfz/8fGtBEmQjNOxF+r9Q==", - "dev": true, - "requires": { - "@types/sinon": "*" - } - }, "@types/sinonjs__fake-timers": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz", @@ -8821,12 +8812,6 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, - "core-js": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.14.0.tgz", - "integrity": "sha512-3s+ed8er9ahK+zJpp9ZtuVcDoFzHNiZsPbNAAE4KXgrRHbjSqqNN6xGSXq6bq7TZIbKj4NLrLb6bJ5i+vSVjHA==", - "dev": true - }, "core-js-bundle": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/core-js-bundle/-/core-js-bundle-3.6.5.tgz", @@ -10481,43 +10466,6 @@ "reusify": "^1.0.4" } }, - "fetch-mock": { - "version": "9.11.0", - "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-9.11.0.tgz", - "integrity": "sha512-PG1XUv+x7iag5p/iNHD4/jdpxL9FtVSqRMUQhPab4hVDt80T1MH5ehzVrL2IdXO9Q2iBggArFvPqjUbHFuI58Q==", - "dev": true, - "requires": { - "@babel/core": "^7.0.0", - "@babel/runtime": "^7.0.0", - "core-js": "^3.0.0", - "debug": "^4.1.1", - "glob-to-regexp": "^0.4.0", - "is-subset": "^0.1.1", - "lodash.isequal": "^4.5.0", - "path-to-regexp": "^2.2.1", - "querystring": "^0.2.0", - "whatwg-url": "^6.5.0" - }, - "dependencies": { - "path-to-regexp": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.4.0.tgz", - "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==", - "dev": true - }, - "whatwg-url": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", - "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", - "dev": true, - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - } - } - }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -11410,12 +11358,6 @@ "is-glob": "^4.0.1" } }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, "glob-watcher": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", @@ -12512,12 +12454,6 @@ "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", "dev": true }, - "is-subset": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", - "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", - "dev": true - }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", @@ -13674,12 +13610,6 @@ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", - "dev": true - }, "lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", @@ -15264,12 +15194,6 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, - "querystring": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", - "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", - "dev": true - }, "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", From 3bf9b672d0e7ae265341ce1068bdd73c8577ed8a Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 10 Jun 2021 12:57:07 +0200 Subject: [PATCH 023/246] Small fix for New Project. Signed-off-by: Dennis Labordus --- src/open-scd.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/open-scd.ts b/src/open-scd.ts index aaae20fa0f..02b967e1a6 100644 --- a/src/open-scd.ts +++ b/src/open-scd.ts @@ -185,6 +185,7 @@ export class OpenSCD extends Setting( this.docName = inputs[0].value.match(/\.s[sc]d$/i) ? inputs[0].value : inputs[0].value + '.scd'; + this.docId = ''; const version = ( (wizard.shadowRoot!.querySelector('mwc-list')!.selected) .value From 2c25d7805393f5dc562562dd3a9b384cba9a9739 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 10 Jun 2021 16:01:15 +0200 Subject: [PATCH 024/246] Added Compas Setting (old style open-scd) to gui. Also refactor CompasService to use new CompasSetting. Signed-off-by: Dennis Labordus --- src/compas/CompasSaveTo.ts | 10 +- src/compas/CompasScl.ts | 6 +- src/compas/CompasScltypeList.ts | 4 +- src/compas/CompasScltypeRadiogroup.ts | 5 +- src/compas/CompasService.ts | 134 ++++++++++++++------------ src/compas/CompasSetting.ts | 107 ++++++++++++++++++++ src/open-scd.ts | 10 +- src/translations/de.ts | 4 + src/translations/en.ts | 4 + 9 files changed, 205 insertions(+), 79 deletions(-) create mode 100644 src/compas/CompasSetting.ts diff --git a/src/compas/CompasSaveTo.ts b/src/compas/CompasSaveTo.ts index 87dc2297e5..92a186c2b1 100644 --- a/src/compas/CompasSaveTo.ts +++ b/src/compas/CompasSaveTo.ts @@ -1,14 +1,14 @@ import {customElement, html, LitElement, property, TemplateResult} from "lit-element"; -import {InfoDetail, newLogEvent, newWizardEvent, Wizard, WizardInput} from "../foundation.js"; +import {newLogEvent, newWizardEvent, Wizard, WizardInput} from "../foundation.js"; import {get, translate} from "lit-translate"; import {TextFieldBase} from "@material/mwc-textfield/mwc-textfield-base"; import {OpenSCD} from "../open-scd.js"; import {CompasChangeSetRadiogroup} from "./CompasChangeSet.js"; import {CompasScltypeRadiogroup} from "./CompasScltypeRadiogroup.js"; -import {addSclDocument, updateSclDocument} from "./CompasService.js"; +import {CompasService} from "./CompasService.js"; -import '../compas/CompasChangeSet.js'; +import './CompasChangeSet.js'; import './CompasScltypeRadiogroup.js'; @customElement('compas-save-to') @@ -79,7 +79,7 @@ function addSclToCompass(wizard: Element, compasSaveTo: CompasSaveTo, doc: XMLDo } openScd!.docName = name + "." + docType!.toLowerCase() - addSclDocument(docType, {sclName: name, doc: doc}) + CompasService().addSclDocument(docType, {sclName: name, doc: doc}) .then(xmlResponse => { const id = Array.from(xmlResponse.querySelectorAll('Id') ?? [])[0]; openScd!.docId = id.textContent ?? ""; @@ -113,7 +113,7 @@ function updateSclInCompas(wizard: Element, compasSaveTo: CompasSaveTo, docId: s } const docType = getTypeFromDocName(docName); - updateSclDocument(docType.toUpperCase(), docId, {changeSet: changeSet, doc: doc}) + CompasService().updateSclDocument(docType.toUpperCase(), docId, {changeSet: changeSet, doc: doc}) .then(() => { document .querySelector('open-scd')! diff --git a/src/compas/CompasScl.ts b/src/compas/CompasScl.ts index f018c6fb8d..7e130913ea 100644 --- a/src/compas/CompasScl.ts +++ b/src/compas/CompasScl.ts @@ -2,7 +2,7 @@ import {customElement, html, LitElement, property, TemplateResult} from "lit-ele import {get} from "lit-translate"; import {newOpenDocEvent, newPendingStateEvent, newWizardEvent, Wizard} from "../foundation.js"; import {SingleSelectedEvent} from "@material/mwc-list/mwc-list-foundation"; -import {getSclDocument, listScls} from "./CompasService.js"; +import {CompasService} from "./CompasService.js"; import {compasSclTypeListWizardActor} from "./CompasScltypeList.js"; @customElement('compas-scl-list') @@ -14,7 +14,7 @@ export class CompasScl extends LitElement { scls!: Element[]; firstUpdated() { - listScls(this.type) + CompasService().listScls(this.type) .then(xmlResponse => { this.scls = Array.from(xmlResponse.querySelectorAll('Item') ?? [])}) } @@ -23,7 +23,7 @@ export class CompasScl extends LitElement { } private async getSclDocument(id?: string): Promise { - const doc = await getSclDocument(this.type, id ?? ''); + const doc = await CompasService().getSclDocument(this.type, id ?? ''); const docName = id + "." + this.type?.toLowerCase(); document diff --git a/src/compas/CompasScltypeList.ts b/src/compas/CompasScltypeList.ts index 6d4fd4d845..4f70399ec2 100644 --- a/src/compas/CompasScltypeList.ts +++ b/src/compas/CompasScltypeList.ts @@ -2,7 +2,7 @@ import {customElement, html, LitElement, property, TemplateResult} from "lit-ele import {get} from "lit-translate"; import {SingleSelectedEvent} from "@material/mwc-list/mwc-list-foundation"; import {newWizardEvent, Wizard, WizardActor} from '../foundation.js'; -import {listSclTypesAndOrder} from "./CompasService.js"; +import {CompasService} from "./CompasService.js"; import {listSclsWizard} from "./CompasScl.js"; @customElement('compas-scltype-list') @@ -11,7 +11,7 @@ export class CompasScltypeList extends LitElement { sclTypes!: Element[]; firstUpdated() { - listSclTypesAndOrder() + CompasService().listSclTypesAndOrder() .then(types => this.sclTypes = types) } diff --git a/src/compas/CompasScltypeRadiogroup.ts b/src/compas/CompasScltypeRadiogroup.ts index 92b6478d72..60cb921498 100644 --- a/src/compas/CompasScltypeRadiogroup.ts +++ b/src/compas/CompasScltypeRadiogroup.ts @@ -1,8 +1,7 @@ import {customElement, html, LitElement, property, TemplateResult} from "lit-element"; import {get} from "lit-translate"; -import {listSclTypesAndOrder} from "./CompasService.js"; +import {CompasService} from "./CompasService.js"; import {ListItemBase} from "@material/mwc-list/mwc-list-item-base"; -import {List} from "@material/mwc-list"; @customElement('compas-scltype-radiogroup') export class CompasScltypeRadiogroup extends LitElement { @@ -18,7 +17,7 @@ export class CompasScltypeRadiogroup extends LitElement { } fetchData() { - listSclTypesAndOrder() + CompasService().listSclTypesAndOrder() .then(types => this.sclTypes = types) } diff --git a/src/compas/CompasService.ts b/src/compas/CompasService.ts index 6d2a5fc299..04d9c77409 100644 --- a/src/compas/CompasService.ts +++ b/src/compas/CompasService.ts @@ -1,75 +1,83 @@ import {ChangeSet} from "./CompasChangeSet.js"; - -const baseUrl = 'http://localhost:9090/compas-scl-data-service'; - -export function listSclTypes(): Promise { - return fetch(baseUrl + '/common/v1/type/list') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')) -} - -export function listSclTypesAndOrder(): Promise { - return listSclTypes() - .then(xmlResponse => { - return Array.from(xmlResponse.querySelectorAll('Type') ?? []) - .sort((type1, type2) => { - const description1 = type1.getElementsByTagName("Description")!.item(0)!.textContent ?? ""; - const description2 = type2.getElementsByTagName("Description")!.item(0)!.textContent ?? ""; - return description1.localeCompare(description2) - }); - }) -} - -export function listScls(type: string): Promise { - return fetch(baseUrl + '/scl/v1/' + type?.toUpperCase() + '/list') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')) -} - -export function getSclDocument(type: string, id: string): Promise { - const sclUrl = baseUrl + '/scl/v1/' + type?.toUpperCase() + '/' + id + '/scl'; - return fetch(sclUrl) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')) -} +import {CompasSetting} from "./CompasSetting.js"; export interface CreateRequestBody { sclName: string, doc: Document } -export function addSclDocument(type: string, body: CreateRequestBody): Promise { - const sclUrl = baseUrl + '/scl/v1/' + type?.toUpperCase(); - return fetch(sclUrl, { - method: 'POST', - headers: { - 'Content-Type': 'application/xml' - }, - body: ` - - ${body.sclName} - ${new XMLSerializer().serializeToString(body.doc.documentElement)} - ` - }) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')) -} export interface UpdateRequestBody { changeSet: ChangeSet, doc: Document } -export function updateSclDocument(type: string, id: string, body: UpdateRequestBody): Promise { - const sclUrl = baseUrl + '/scl/v1/' + type?.toUpperCase() + '/' + id; - return fetch(sclUrl, { - method: 'PUT', - headers: { - 'Content-Type': 'application/xml' - }, - body: ` - - ${body.changeSet} - ${new XMLSerializer().serializeToString(body.doc.documentElement)} - ` - }) -} +export function CompasService() { + function getCompasSettings() { + return CompasSetting().compasSettings; + } + + return { + listSclTypes(): Promise { + return fetch(getCompasSettings().sclDataServiceUrl + '/common/v1/type/list') + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')) + }, + + listSclTypesAndOrder(): Promise { + return this.listSclTypes() + .then(xmlResponse => { + return Array.from(xmlResponse.querySelectorAll('Type') ?? []) + .sort((type1, type2) => { + const description1 = type1.getElementsByTagName("Description")!.item(0)!.textContent ?? ""; + const description2 = type2.getElementsByTagName("Description")!.item(0)!.textContent ?? ""; + return description1.localeCompare(description2) + }); + }) + }, + + listScls(type: string): Promise { + return fetch(getCompasSettings().sclDataServiceUrl + '/scl/v1/' + type?.toUpperCase() + '/list') + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')) + }, + + getSclDocument(type: string, id: string): Promise { + const sclUrl = getCompasSettings().sclDataServiceUrl + '/scl/v1/' + type?.toUpperCase() + '/' + id + '/scl'; + return fetch(sclUrl) + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')) + }, + + addSclDocument(type: string, body: CreateRequestBody): Promise { + const sclUrl = getCompasSettings().sclDataServiceUrl + '/scl/v1/' + type?.toUpperCase(); + return fetch(sclUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/xml' + }, + body: ` + + ${body.sclName} + ${new XMLSerializer().serializeToString(body.doc.documentElement)} + ` + }) + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')) + }, + + updateSclDocument(type: string, id: string, body: UpdateRequestBody): Promise { + const sclUrl = getCompasSettings().sclDataServiceUrl + '/scl/v1/' + type?.toUpperCase() + '/' + id; + return fetch(sclUrl, { + method: 'PUT', + headers: { + 'Content-Type': 'application/xml' + }, + body: ` + + ${body.changeSet} + ${new XMLSerializer().serializeToString(body.doc.documentElement)} + ` + }) + }, + } +} diff --git a/src/compas/CompasSetting.ts b/src/compas/CompasSetting.ts new file mode 100644 index 0000000000..57c97f2b30 --- /dev/null +++ b/src/compas/CompasSetting.ts @@ -0,0 +1,107 @@ +import {html, property, query, TemplateResult} from 'lit-element'; +import {translate} from 'lit-translate'; + +import {Dialog} from '@material/mwc-dialog'; + +import {ifImplemented, LitElementConstructor, Mixin} from '../foundation.js'; +import {TextField} from "@material/mwc-textfield"; + +export type CompasSettings = { + sclDataServiceUrl: string; +}; +export const defaults: CompasSettings = { sclDataServiceUrl: 'http://localhost:9090/compas-scl-data-service' }; + +export function CompasSetting() { + return { + /** Current [[`CompasSettings`]] in `localStorage`, default to [[`defaults`]]. */ + get compasSettings(): CompasSettings { + return { + sclDataServiceUrl: this.getCompasSetting('sclDataServiceUrl'), + }; + }, + + /** Update the `value` of `setting`, storing to `localStorage`. */ + setCompasSetting(setting: T, value: CompasSettings[T]): void { + localStorage.setItem(setting, (value)); + }, + + getCompasSetting(setting: T): CompasSettings[T] { + return ( + localStorage.getItem(setting) ?? defaults[setting] + ); + } + } +} + +/** Mixin that saves [[`CompasSettings`]] to `localStorage`, reflecting them in the + * `settings` property, setting them through `setSetting(setting, value)`. */ +export type CompasSettingElement = Mixin; + +export function CompasSettingUI(Base: TBase) { + class CompasSettingElement extends Base { + @property() + get compasSettings() { + return CompasSetting().compasSettings; + } + + @query('#compasSettings') + compasSettingsUI!: Dialog; + @query('#sclDataServiceUrl') + sclDataServiceUrlUI!: TextField; + + private onCompasClosing(ae: CustomEvent<{ action: string } | null>): void { + if (ae.detail?.action === 'reset') { + Object.keys(this.compasSettings).forEach(item => + localStorage.removeItem(item) + ); + this.requestUpdate('compasSettings'); + } else if (ae.detail?.action === 'save') { + CompasSetting().setCompasSetting('sclDataServiceUrl', this.sclDataServiceUrlUI.value); + this.requestUpdate('compasSettings'); + } + } + + render(): TemplateResult { + return html`${ifImplemented(super.render())} + + + +
    + + +
    + + ${translate('cancel')} + + + ${translate('reset')} + + + ${translate('save')} + +
    `; + } + } + + return CompasSettingElement; +} diff --git a/src/open-scd.ts b/src/open-scd.ts index 02b967e1a6..e7d3611465 100644 --- a/src/open-scd.ts +++ b/src/open-scd.ts @@ -55,6 +55,7 @@ import { SupportedVersion } from './schemas.js'; import { Editing, newEmptySCD } from './Editing.js'; import { Logging } from './Logging.js'; import { Setting } from './Setting.js'; +import { CompasSettingUI } from "./compas/CompasSetting.js"; import { InstalledPlugin, Plugging, pluginIcons } from './Plugging.js'; import { Validating } from './Validating.js'; import { Waiting } from './Waiting.js'; @@ -86,9 +87,7 @@ interface Saver { /** The `` custom element is the main entry point of the * Open Substation Configuration Designer. */ @customElement('open-scd') -export class OpenSCD extends Setting( - Wizarding(Waiting(Validating(Plugging(Editing(Logging(LitElement)))))) -) { +export class OpenSCD extends Setting(CompasSettingUI(Wizarding(Waiting(Validating(Plugging(Editing(Logging(LitElement)))))))) { /** The currently active editor tab. */ @property({ type: Number }) activeTab = 0; @@ -364,6 +363,11 @@ export class OpenSCD extends Setting( name: 'settings.name', action: (): void => this.settingsUI.show(), }, + { + icon: 'settings', + name: 'compas.settings.name', + action: (): void => this.compasSettingsUI.show(), + }, { icon: 'extension', name: 'plugins.heading', diff --git a/src/translations/de.ts b/src/translations/de.ts index 9722351e9c..d9ce901531 100644 --- a/src/translations/de.ts +++ b/src/translations/de.ts @@ -269,6 +269,10 @@ export const de: Translations = { addSuccess: '???', updateError: '???', updateSuccess: '???', + }, + settings: { + name: "CoMPAS Einstellungen", + sclDataServiceUrl: "CoMPAS SCL Data Service" } }, }; diff --git a/src/translations/en.ts b/src/translations/en.ts index bc04c548f6..3bf79582b8 100644 --- a/src/translations/en.ts +++ b/src/translations/en.ts @@ -266,6 +266,10 @@ export const en = { addSuccess: 'SCL added to CoMPAS.', updateError: 'Error updating SCL in CoMPAS!', updateSuccess: 'SCL updated in CoMPAS', + }, + settings: { + name: "CoMPAS Settings", + sclDataServiceUrl: "CoMPAS SCL Data Service" } }, }; From 58d2e6dc26cd7f1c7bf89915c4e2001a5c426d2a Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Mon, 14 Jun 2021 08:11:30 +0200 Subject: [PATCH 025/246] Processed review comments. Signed-off-by: Dennis Labordus --- __snapshots__/compas-changeset-radiogroup.md | 6 +-- __snapshots__/open-scd.md | 40 ++++++++++---------- src/compas/CompasChangeSet.ts | 7 ++-- src/compas/CompasSaveTo.ts | 38 ++++++++++--------- src/translations/de.ts | 5 +++ src/translations/en.ts | 7 +++- test/unit/compas/CompasChangeSet.test.ts | 5 --- 7 files changed, 59 insertions(+), 49 deletions(-) diff --git a/__snapshots__/compas-changeset-radiogroup.md b/__snapshots__/compas-changeset-radiogroup.md index 07eba0a639..cb638f85ec 100644 --- a/__snapshots__/compas-changeset-radiogroup.md +++ b/__snapshots__/compas-changeset-radiogroup.md @@ -12,7 +12,7 @@ tabindex="0" value="MAJOR" > - Major change + [compas.changeset.major]
    - Minor change + [compas.changeset.minor] - Patch change + [compas.changeset.patch]
    diff --git a/__snapshots__/open-scd.md b/__snapshots__/open-scd.md index 1424e5510b..b8e45d9953 100644 --- a/__snapshots__/open-scd.md +++ b/__snapshots__/open-scd.md @@ -51,6 +51,23 @@
    + + + folder_open + + + Save to CoMPAS + + + + - - - folder_open - - - Save to CoMPAS - - - - folder_open @@ -596,14 +596,14 @@ mwc-list-item="" selected="" tabindex="-1" - value="/src/triggered/SaveToCompas.js" + value="/src/savers/SaveToCompas.js" > folder_open Save to CoMPAS - play_circle + save ([ - [ChangeSet.MAJOR, {description: "Major change"}], - [ChangeSet.MINOR, {description: "Minor change"}], - [ChangeSet.PATCH, {description: "Patch change"}] + [ChangeSet.MAJOR, {description: get('compas.changeset.major')}], + [ChangeSet.MINOR, {description: get('compas.changeset.minor')}], + [ChangeSet.PATCH, {description: get('compas.changeset.patch')}] ]) @customElement('compas-changeset-radiogroup') diff --git a/src/compas/CompasSaveTo.ts b/src/compas/CompasSaveTo.ts index 87dc2297e5..c710792682 100644 --- a/src/compas/CompasSaveTo.ts +++ b/src/compas/CompasSaveTo.ts @@ -61,29 +61,33 @@ export class CompasSaveTo extends LitElement { } function getTypeFromDocName(docName: string) { - if (docName!.lastIndexOf(".") == docName!.length - 4) { + if (docName.lastIndexOf(".") == docName.length - 4) { return docName.substring(docName.lastIndexOf(".") + 1); } throw "Unable to determine type from document name!"; } -function addSclToCompass(wizard: Element, compasSaveTo: CompasSaveTo, doc: XMLDocument) { - const openScd = document.querySelector('open-scd'); - let name = compasSaveTo.getNameField()!.value; - if (name!.lastIndexOf(".") == name!.length - 4) { +function stripExtensionFromName(docName: string): string { + let name = docName; + const FILE_EXTENSION_LENGTH = 3; + // Check if the name includes a file extension, if the case remove it. + if (name.lastIndexOf(".") == name.length - (FILE_EXTENSION_LENGTH + 1)) { name = name.substring(0, name.lastIndexOf(".")); } + return name +} + +function addSclToCompas(wizard: Element, compasSaveTo: CompasSaveTo, doc: XMLDocument) { + const openScd = document.querySelector('open-scd'); + const name = stripExtensionFromName(compasSaveTo.getNameField().value); const docType = compasSaveTo.getSclTypeRadioGroup().getSelectedValue(); - if (docType === null) { - return; - } - openScd!.docName = name + "." + docType!.toLowerCase() - addSclDocument(docType, {sclName: name, doc: doc}) + openScd.docName = name + "." + docType!.toLowerCase() + addSclDocument(docType!, {sclName: name, doc: doc}) .then(xmlResponse => { const id = Array.from(xmlResponse.querySelectorAll('Id') ?? [])[0]; - openScd!.docId = id.textContent ?? ""; - openScd!.docName = (id.textContent ?? "") + "." + docType.toLowerCase() + openScd.docId = id.textContent ?? ""; + openScd.docName = (id.textContent ?? "") + "." + docType!.toLowerCase() document .querySelector('open-scd')! @@ -93,7 +97,7 @@ function addSclToCompass(wizard: Element, compasSaveTo: CompasSaveTo, doc: XMLDo title: get('compas.saveTo.addSuccess')})); // Close the Save Dialog. - openScd!.dispatchEvent(newWizardEvent()); + openScd.dispatchEvent(newWizardEvent()); }) .catch(() => { document @@ -123,7 +127,7 @@ function updateSclInCompas(wizard: Element, compasSaveTo: CompasSaveTo, docId: s title: get('compas.saveTo.updateSuccess')})); // Close the Save Dialog. - openScd!.dispatchEvent(newWizardEvent()); + openScd.dispatchEvent(newWizardEvent()); }) .catch(() => { document @@ -135,7 +139,7 @@ function updateSclInCompas(wizard: Element, compasSaveTo: CompasSaveTo, docId: s }); } -function saveToCompass(docId: string, docName: string, doc: XMLDocument) { +function saveToCompas(docId: string, docName: string, doc: XMLDocument) { return function (inputs: WizardInput[], wizard: Element) { const compasSaveTo = wizard.shadowRoot!.querySelector('compas-save-to') if (!doc || !compasSaveTo.checkValidity()) { @@ -143,7 +147,7 @@ function saveToCompass(docId: string, docName: string, doc: XMLDocument) { } if (!docId) { - addSclToCompass(wizard, compasSaveTo, doc); + addSclToCompas(wizard, compasSaveTo, doc); } else { updateSclInCompas(wizard, compasSaveTo, docId, docName, doc); } @@ -162,7 +166,7 @@ export function saveToCompasWizard(doc: XMLDocument, saveToOptions: SaveToCompas primary: { icon: 'save', label: get('save'), - action: saveToCompass(saveToOptions.docId, saveToOptions.docName, doc), + action: saveToCompas(saveToOptions.docId, saveToOptions.docName, doc), }, content: [ html ` diff --git a/src/translations/de.ts b/src/translations/de.ts index 9722351e9c..282e0da4df 100644 --- a/src/translations/de.ts +++ b/src/translations/de.ts @@ -257,6 +257,11 @@ export const de: Translations = { disconnect: 'Trennen', compas: { + changeset: { + major: "???", + minor: "???", + patch: "???", + }, open: { listSclTypes: '???', noSclTypes: '???', diff --git a/src/translations/en.ts b/src/translations/en.ts index bc04c548f6..ab5706518e 100644 --- a/src/translations/en.ts +++ b/src/translations/en.ts @@ -254,6 +254,11 @@ export const en = { disconnect: 'Disconnect', compas: { + changeset: { + major: "Major change", + minor: "Minor change", + patch: "Patch change", + }, open: { listSclTypes: 'Type of SCL', noSclTypes: 'No types found', @@ -261,7 +266,7 @@ export const en = { noScls: 'No SCLs found', }, saveTo: { - title: 'Save to Compas', + title: 'Save to CoMPAS', addError: 'Error adding SCL to CoMPAS!', addSuccess: 'SCL added to CoMPAS.', updateError: 'Error updating SCL in CoMPAS!', diff --git a/test/unit/compas/CompasChangeSet.test.ts b/test/unit/compas/CompasChangeSet.test.ts index 9718bd2391..bfec458468 100644 --- a/test/unit/compas/CompasChangeSet.test.ts +++ b/test/unit/compas/CompasChangeSet.test.ts @@ -18,11 +18,6 @@ describe('compas-changeset-radiogroup', () => { .to.have.length(3) }); - it('has the correct value for MAJOR Item', () => { - expect(element.shadowRoot!.querySelectorAll('mwc-list > mwc-radio-list-item[value = "MAJOR"]')) - .to.have.text("Major change") - }); - it('looks like the latest snapshot', () => { expect(element).shadowDom .to.equalSnapshot(); From 74d3500bbee9932d0e8b1b685ebe2731caecb0d1 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Mon, 14 Jun 2021 12:43:00 +0200 Subject: [PATCH 026/246] Added testing for the CompasSettings and CompasSaveTo. Signed-off-by: Dennis Labordus --- __snapshots__/compas-save-to-create.md | 18 ++++++++ __snapshots__/compas-save-to-update.md | 10 ++++ __snapshots__/open-scd.md | 51 +++++++++++++++++++++ src/compas/CompasSaveTo.ts | 6 +-- test/unit/compas/CompasSaveTo.test.ts | 63 ++++++++++++++++++++++++++ test/unit/compas/CompasSetting.test.ts | 55 ++++++++++++++++++++++ test/unit/mock-setter.ts | 7 +-- 7 files changed, 204 insertions(+), 6 deletions(-) create mode 100644 __snapshots__/compas-save-to-create.md create mode 100644 __snapshots__/compas-save-to-update.md create mode 100644 test/unit/compas/CompasSaveTo.test.ts create mode 100644 test/unit/compas/CompasSetting.test.ts diff --git a/__snapshots__/compas-save-to-create.md b/__snapshots__/compas-save-to-create.md new file mode 100644 index 0000000000..1d4ae27462 --- /dev/null +++ b/__snapshots__/compas-save-to-create.md @@ -0,0 +1,18 @@ +# `compas-save-to-create` + +#### `looks like the latest snapshot` + +```html + + + + + +``` + diff --git a/__snapshots__/compas-save-to-update.md b/__snapshots__/compas-save-to-update.md new file mode 100644 index 0000000000..1fa16692ed --- /dev/null +++ b/__snapshots__/compas-save-to-update.md @@ -0,0 +1,10 @@ +# `compas-save-to-update` + +#### `looks like the latest snapshot` + +```html + + + +``` + diff --git a/__snapshots__/open-scd.md b/__snapshots__/open-scd.md index b8e45d9953..d54fe2d4f9 100644 --- a/__snapshots__/open-scd.md +++ b/__snapshots__/open-scd.md @@ -288,6 +288,20 @@ Settings + + + settings + + + CoMPAS Settings + + + +
    + + +
    + + Cancel + + + Reset + + + Save + +
    { + it('when retrieve type from name, but name has no extension a exception is thrown', () => { + const name = 'just-some-station'; + expect(() => getTypeFromDocName(name)).to.throw('Unable to determine type from document name!'); + }) + + it('when retrieve type from nameand name has a extension, the extension will be the type', () => { + const name = 'just-some-station'; + const extension = 'scd'; + expect(getTypeFromDocName(name + '.' + extension)).to.be.equal(extension); + }); + + it('when name is passed without extenions the same name is returned', () => { + const name = 'just-some-station'; + expect(stripExtensionFromName(name)).to.be.equal(name); + }); + + it('when name is passed with extenions the same name is returned', () => { + const name = 'just-some-station'; + const extension = 'scd'; + expect(stripExtensionFromName(name + '.' + extension)).to.be.equal(name); + }); +}); + +describe('compas-save-to-create', () => { + let element: CompasSaveTo; + const docName = 'station123.scd'; + beforeEach(async () => { + element = ( + await fixture( + html`` + ) + ); + }); + + it('looks like the latest snapshot', () => { + expect(element).shadowDom + .to.equalSnapshot(); + }); +}); + +describe('compas-save-to-update', () => { + let element: CompasSaveTo; + const docName = 'station123.scd'; + const docId = '6a45ae97-5605-44f8-b4e6-25305bc6c036'; + beforeEach(async () => { + element = ( + await fixture( + html`` + ) + ); + }); + + it('looks like the latest snapshot', () => { + expect(element).shadowDom + .to.equalSnapshot(); + }); +}); diff --git a/test/unit/compas/CompasSetting.test.ts b/test/unit/compas/CompasSetting.test.ts new file mode 100644 index 0000000000..b7584f75c9 --- /dev/null +++ b/test/unit/compas/CompasSetting.test.ts @@ -0,0 +1,55 @@ +import {expect, fixture, html} from '@open-wc/testing'; +import {registerTranslateConfig, use} from 'lit-translate'; + +import {Button} from '@material/mwc-button'; + +import {CompasSetting, CompasSettingElement, defaults} from "../../../src/compas/CompasSetting.js"; +import '../mock-setter.js'; + +describe('CompasSettingElement', () => { + let element: CompasSettingElement; + beforeEach(async () => { + localStorage.clear(); + element = await fixture(html``); + }); + + it('initially has default settings', () => { + expect(element).to.have.deep.property('compasSettings', defaults); + }); + + it('stores settings to localStorage', () => { + CompasSetting().setCompasSetting('sclDataServiceUrl', 'http://localhost:9090/compas-scl-data-service'); + expect(localStorage.getItem('sclDataServiceUrl')).to.equal('http://localhost:9090/compas-scl-data-service'); + }); + + it('retrieves settings from localStorage', () => { + localStorage.setItem('sclDataServiceUrl', 'http://localhost:9090/compas-scl-data-service'); + expect(CompasSetting().compasSettings).to.have.property('sclDataServiceUrl', 'http://localhost:9090/compas-scl-data-service'); + }); + + it('saves chosen settings on save button click', async () => { + element.compasSettingsUI.show(); + element.sclDataServiceUrlUI.value = 'http://localhost:9091/compas-scl-data-service'; + await element.sclDataServiceUrlUI.updateComplete; + await (