Skip to content

Commit a78b712

Browse files
author
Dennis Labordus
committed
Merge branch 'refactor-loading-nsdoc' into load_nsdoc_backend
2 parents a455c6e + 8b45754 commit a78b712

File tree

14 files changed

+1499
-110
lines changed

14 files changed

+1499
-110
lines changed

src/Logging.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
245245

246246
this.undo = this.undo.bind(this);
247247
this.redo = this.redo.bind(this);
248-
249248
this.onLog = this.onLog.bind(this);
249+
250250
this.addEventListener('log', this.onLog);
251251
this.addEventListener('issue', this.onIssue);
252252
this.addEventListener('open-doc', this.onLoadHistoryFromDoc);

src/Setting.ts

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,25 @@ type NsdVersions = {
5454
'IEC 61850-8-1': NsdVersion;
5555
}
5656

57+
/** Represents a document to be opened. */
58+
export interface LoadNsdocDetail {
59+
nsdoc: string;
60+
filename: string;
61+
}
62+
export type LoadNsdocEvent = CustomEvent<LoadNsdocDetail>;
63+
export function newLoadNsdocEvent(
64+
nsdoc: string,
65+
filename: string,
66+
eventInitDict?: CustomEventInit<Partial<LoadNsdocDetail>>
67+
): LoadNsdocEvent {
68+
return new CustomEvent<LoadNsdocDetail>('load-nsdoc', {
69+
bubbles: true,
70+
composed: true,
71+
...eventInitDict,
72+
detail: { nsdoc, filename, ...eventInitDict?.detail },
73+
});
74+
}
75+
5776
/** Mixin that saves [[`Settings`]] to `localStorage`, reflecting them in the
5877
* `settings` property, setting them through `setSetting(setting, value)`. */
5978
export type SettingElement = Mixin<typeof Setting>;
@@ -168,7 +187,7 @@ export function Setting<TBase extends LitElementConstructor>(Base: TBase) {
168187
private renderFileSelect(): TemplateResult {
169188
return html `
170189
<input id="nsdoc-file" accept=".nsdoc" type="file" hidden required multiple
171-
@change=${(evt: Event) => this.loadNsdocFile(evt)}}>
190+
@change=${(evt: Event) => this.uploadNsdocFile(evt)}}>
172191
<mwc-button label="${translate('settings.selectFileButton')}"
173192
id="selectFileButton"
174193
@click=${() => {
@@ -179,50 +198,63 @@ export function Setting<TBase extends LitElementConstructor>(Base: TBase) {
179198
`;
180199
}
181200

182-
private async loadNsdocFile(evt: Event): Promise<void> {
183-
const nsdVersions = await this.nsdVersions();
201+
private async uploadNsdocFile(evt: Event): Promise<void> {
184202
const files = Array.from(
185203
(<HTMLInputElement | null>evt.target)?.files ?? []
186204
);
187-
205+
188206
if (files.length == 0) return;
189-
files.forEach(async file => {
207+
for (const file of files) {
190208
const text = await file.text();
191-
const nsdocElement = this.parseToXmlObject(text).querySelector('NSDoc');
192-
const id = nsdocElement?.getAttribute('id');
193-
if (!id) {
194-
document
209+
document
195210
.querySelector('open-scd')!
196211
.dispatchEvent(
197-
newLogEvent({ kind: 'error', title: get('settings.invalidFileNoIdFound') })
198-
);
199-
return;
200-
}
201-
const nsdVersion = nsdVersions[id as keyof NsdVersions];
202-
const nsdocVersion = {
203-
version: nsdocElement!.getAttribute('version') ?? '',
204-
revision: nsdocElement!.getAttribute('revision') ?? '',
205-
release: nsdocElement!.getAttribute('release') ?? ''
206-
}
212+
newLoadNsdocEvent(text, file.name)
213+
);
214+
}
215+
216+
this.nsdocFileUI.value = '';
217+
this.requestUpdate();
218+
}
219+
220+
private async onLoadNsdoc(event: LoadNsdocEvent) {
221+
const nsdocElement = this.parseToXmlObject(event.detail.nsdoc).querySelector('NSDoc');
207222

208-
if (!this.isEqual(nsdVersion, nsdocVersion)) {
209-
document
223+
const id = nsdocElement?.getAttribute('id');
224+
if (!id) {
225+
document
210226
.querySelector('open-scd')!
211227
.dispatchEvent(
212-
newLogEvent({ kind: 'error', title: get('settings.invalidNsdocVersion', {
228+
newLogEvent({ kind: 'error', title: get('settings.invalidFileNoIdFound', {
229+
filename: event.detail.filename
230+
}) })
231+
);
232+
return;
233+
}
234+
235+
const nsdVersions = await this.nsdVersions();
236+
const nsdVersion = nsdVersions[id as keyof NsdVersions];
237+
const nsdocVersion = {
238+
version: nsdocElement!.getAttribute('version') ?? '',
239+
revision: nsdocElement!.getAttribute('revision') ?? '',
240+
release: nsdocElement!.getAttribute('release') ?? ''
241+
}
242+
243+
if (!this.isEqual(nsdVersion, nsdocVersion)) {
244+
document
245+
.querySelector('open-scd')!
246+
.dispatchEvent(
247+
newLogEvent({ kind: 'error', title: get('settings.invalidNsdocVersion', {
213248
id: id,
249+
filename: event.detail.filename,
214250
nsdVersion: `${nsdVersion.version}${nsdVersion.revision}${nsdVersion.release}`,
215251
nsdocVersion: `${nsdocVersion.version}${nsdocVersion.revision}${nsdocVersion.release}`
216252
}) })
217-
);
218-
return;
219-
}
220-
221-
this.setSetting(id as keyof Settings, text);
222-
})
253+
);
254+
return;
255+
}
223256

224-
this.nsdocFileUI.value = '';
225-
this.requestUpdate();
257+
this.setSetting(id as keyof Settings, event.detail.nsdoc);
226258
}
227259

228260
/**
@@ -245,7 +277,7 @@ export function Setting<TBase extends LitElementConstructor>(Base: TBase) {
245277
let nsdVersion: string | undefined | null;
246278
let nsdRevision: string | undefined | null;
247279
let nsdRelease: string | undefined | null;
248-
280+
249281
if (nsdSetting) {
250282
const nsdoc = this.parseToXmlObject(nsdSetting)!.querySelector('NSDoc');
251283
nsdVersion = nsdoc?.getAttribute('version');
@@ -273,6 +305,8 @@ export function Setting<TBase extends LitElementConstructor>(Base: TBase) {
273305

274306
registerTranslateConfig({ loader, empty: key => key });
275307
use(this.settings.language);
308+
309+
(<any>this).addEventListener('load-nsdoc', this.onLoadNsdoc);
276310
}
277311

278312
render(): TemplateResult {

src/translations/de.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,9 @@ export const de: Translations = {
7070
showieds: 'Zeige IEDs im Substation-Editor',
7171
selectFileButton: 'Datei auswählen',
7272
loadNsdTranslations: 'NSDoc-Dateien hochladen',
73-
invalidFileNoIdFound:
74-
"Ungültiges NSDoc; kein 'id'-Attribut in der Datei gefunden",
73+
invalidFileNoIdFound: "Ungültiges NSDoc ({{ filename }}); kein 'id'-Attribut in der Datei gefunden",
7574
invalidNsdocVersion:
76-
'Die Version {{ id }} NSD ({{ nsdVersion }}) passt nicht zu der geladenen NSDoc ({{ nsdocVersion }})',
75+
'Die Version {{ id }} NSD ({{ nsdVersion }}) passt nicht zu der geladenen NSDoc ({{ filename }}, {{ nsdocVersion }})',
7776
},
7877
menu: {
7978
new: 'Neues projekt',

src/translations/en.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ export const en = {
6767
mode: 'Pro mode',
6868
showieds: 'Show IEDs in substation editor',
6969
selectFileButton: 'Select file',
70-
loadNsdTranslations: 'Uploading NSDoc files',
71-
invalidFileNoIdFound: "Invalid NSDoc; no 'id' attribute found in file",
70+
loadNsdTranslations: 'Uploaded NSDoc files',
71+
invalidFileNoIdFound: "Invalid NSDoc ({{ filename }}); no 'id' attribute found in file",
7272
invalidNsdocVersion:
73-
'The version of {{ id }} NSD ({{ nsdVersion }}) does not correlate with the version of the corresponding NSDoc ({{ nsdocVersion }})',
73+
'The version of {{ id }} NSD ({{ nsdVersion }}) does not correlate with the version of the corresponding NSDoc ({{ filename }}, {{ nsdocVersion }})',
7474
},
7575
menu: {
7676
new: 'New project',

test/integration/Setting.test.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { html, fixture, expect } from '@open-wc/testing';
2+
3+
import '../../src/open-scd.js';
4+
5+
import { OpenSCD } from '../../src/open-scd.js';
6+
import { newLoadNsdocEvent } from "../../src/Setting.js";
7+
import { cleanLocalStorageForNsdocFiles } from "../unit/foundation/nsdoc.test.js";
8+
9+
describe('Setting', () => {
10+
let element: OpenSCD;
11+
12+
beforeEach(async () => {
13+
cleanLocalStorageForNsdocFiles();
14+
15+
element = await fixture(html`
16+
<open-scd></open-scd>
17+
18+
<link href="public/google/fonts/roboto-v27.css" rel="stylesheet" />
19+
<link href="public/google/fonts/roboto-mono-v13.css" rel="stylesheet" />
20+
<link href="public/google/icons/material-icons-outlined.css" rel="stylesheet" />
21+
`);
22+
});
23+
24+
it('opens the log on log menu entry click', async () => {
25+
await (<HTMLElement>(
26+
element.shadowRoot!.querySelector('mwc-list-item[iconid="history"]')!
27+
)).click();
28+
expect(element.logUI).to.have.property('open', true);
29+
});
30+
31+
it('upload .nsdoc file using event and looks like latest snapshot', async () => {
32+
element.settingsUI.show();
33+
await element.settingsUI.updateComplete;
34+
35+
const nsdocFile = await fetch('/test/testfiles/nsdoc/IEC_61850-7-2.nsdoc')
36+
.then(response => response.text())
37+
38+
element.dispatchEvent(
39+
newLoadNsdocEvent(nsdocFile, 'IEC_61850-7-2.nsdoc')
40+
);
41+
42+
await element.requestUpdate();
43+
await element.updateComplete;
44+
45+
expect(localStorage.getItem('IEC 61850-7-2')).to.eql(nsdocFile);
46+
expect(element).shadowDom.to.equalSnapshot();
47+
});
48+
49+
it('upload invalid .nsdoc file using event and log event fired', async () => {
50+
element.settingsUI.show();
51+
await element.settingsUI.updateComplete;
52+
53+
const nsdocFile = await fetch('/test/testfiles/nsdoc/invalid.nsdoc')
54+
.then(response => response.text())
55+
56+
element.dispatchEvent(
57+
newLoadNsdocEvent(nsdocFile, 'invalid.nsdoc')
58+
);
59+
60+
await element.requestUpdate();
61+
await element.updateComplete;
62+
63+
expect(element.history.length).to.be.equal(1);
64+
expect(element.history[0].title).to.be.equal('Invalid NSDoc (invalid.nsdoc); no \'id\' attribute found in file');
65+
});
66+
67+
it('upload .nsdoc file with wrong version using event and log event fired', async () => {
68+
element.settingsUI.show();
69+
await element.settingsUI.updateComplete;
70+
71+
const nsdocFile = await fetch('/test/testfiles/nsdoc/wrong-version.nsdoc')
72+
.then(response => response.text())
73+
74+
element.dispatchEvent(
75+
newLoadNsdocEvent(nsdocFile, 'wrong-version.nsdoc')
76+
);
77+
78+
await element.requestUpdate();
79+
await element.updateComplete;
80+
81+
expect(element.history.length).to.be.equal(1);
82+
expect(element.history[0].title).to.be.equal('The version of IEC 61850-7-3 NSD (2007B3) does not correlate ' +
83+
'with the version of the corresponding NSDoc (wrong-version.nsdoc, 2007B4)');
84+
});
85+
}).timeout(4000);

0 commit comments

Comments
 (0)