Skip to content
This repository was archived by the owner on Aug 8, 2025. It is now read-only.

Commit f32710b

Browse files
refactor: scope plugins element
1 parent 30a1f83 commit f32710b

11 files changed

+2601
-1126
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Test on PR branch
2+
on: pull_request
3+
4+
jobs:
5+
runs-on: ubuntu-20.04
6+
steps:
7+
- name: Checkout
8+
uses: actions/checkout@v3
9+
10+
- name: Set up Node.js
11+
uses: actions/setup-node@v3
12+
with:
13+
node-version: '20'
14+
15+
- name: Install dependencies
16+
run: npm ci
17+
18+
- name: Install playwright browsers
19+
run: npx playwright install chromium
20+
21+
- name: Run unit tests
22+
run: npm run-script test

.github/workflows/test.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Test On Push
2+
on: push
3+
4+
jobs:
5+
runs-on: ubuntu-20.04
6+
steps:
7+
- name: Checkout
8+
uses: actions/checkout@v3
9+
10+
- name: Set up Node.js
11+
uses: actions/setup-node@v3
12+
with:
13+
node-version: '20'
14+
15+
- name: Install dependencies
16+
run: npm ci
17+
18+
- name: Install playwright browsers
19+
run: npx playwright install chromium
20+
21+
- name: Run unit tests
22+
run: npm run-script test

generate-templates.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { cyrb64 } from '@openscd/open-scd-core';
2-
import type { TreeSelection } from '@openscd/oscd-tree-grid';
1+
// eslint-disable-next-line import/no-extraneous-dependencies
2+
import { cyrb64 } from '@openenergytools/open-scd-core';
3+
import type { TreeSelection } from '@openenergytools/tree-grid';
34

45
function describeEnumType(element: Element): { vals: Record<string, string> } {
56
const vals: Record<string, string> = {};

index.html

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
<title>oscd-template-generator demo</title>
2-
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@300&family=Roboto:wght@300;400;500&display=swap">
3-
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons&display=block">
4-
<open-scd plugins='{"editor": [{"name": "Template Generator", "translations": {"de": "Template Generator"}, "icon": "add_box", "active": true, "src": "/dist/oscd-template-generator.js"}, {"name": "Template Editor", "translations": {"de": "Template Editor"}, "icon": "edit", "active": true, "src": "https://openscd.github.io/src/editors/Templates.js"}], "menu": [{"name": "Open File", "translations": {"de": "Datei öffnen"}, "icon": "folder_open", "active": true, "src": "https://openscd.github.io/oscd-open/oscd-open.js"}, {"name": "Save File", "translations": {"de": "Datei öffnen"}, "icon": "save", "active": true, "src": "https://openscd.github.io/oscd-save/oscd-save.js"}]}'></open-scd>
1+
<html>
2+
<head>
3+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@300&family=Roboto:wght@300;400;500&display=swap">
4+
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined">
5+
</head>
6+
<body>
7+
<open-scd plugins='{"editor": [{"name": "Template Generator", "translations": {"de": "Template Generator"}, "icon": "add_box", "active": true, "src": "/dist/oscd-template-generator.js"}, {"name": "Template Editor", "translations": {"de": "Template Editor"}, "icon": "edit", "active": true, "src": "https://openscd.github.io/src/editors/Templates.js"}], "menu": [{"name": "Open File", "translations": {"de": "Datei öffnen"}, "icon": "folder_open", "active": true, "src": "https://openscd.github.io/oscd-open/oscd-open.js"}, {"name": "Save File", "translations": {"de": "Datei öffnen"}, "icon": "save", "active": true, "src": "https://openscd.github.io/oscd-save/oscd-save.js"}]}'></open-scd>
58

69
<script type="module">
7-
import '@openscd/open-scd-core/open-scd.js';
10+
import '@openenergytools/open-scd-core/open-scd.js';
811

912
const editor = document.querySelector('open-scd');
1013
const params = (new URL(document.location)).searchParams;
@@ -32,3 +35,6 @@
3235
background: white;
3336
}
3437
</style>
38+
39+
</body>
40+
</html>s

oscd-template-generator.spec.ts

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
import { html } from 'lit';
2-
import { fixture, expect } from '@open-wc/testing';
3-
import { restore, fake, SinonSpy } from 'sinon';
4-
5-
import { ListItem } from '@material/mwc-list/mwc-list-item.js';
1+
import { fixture, expect, html } from '@open-wc/testing';
2+
import { restore, SinonSpy, spy } from 'sinon';
63

74
import TemplateGenerator from './oscd-template-generator.js';
85

@@ -20,7 +17,7 @@ describe('TemplateGenerator', () => {
2017
});
2118

2219
it('displays no action button', () =>
23-
expect(element.shadowRoot?.querySelector('mwc-fab')).to.not.exist);
20+
expect(element.shadowRoot?.querySelector('md-fab')).to.not.exist);
2421

2522
it('starts with LPHD selected', () => {
2623
expect(element).to.have.property('lNodeType', 'LPHD');
@@ -31,8 +28,8 @@ describe('TemplateGenerator', () => {
3128
let listener: SinonSpy;
3229
afterEach(restore);
3330
beforeEach(async () => {
34-
listener = fake();
35-
element.addEventListener('oscd-edit', listener);
31+
listener = spy();
32+
element.addEventListener('oscd-edit-v2', listener);
3633
element.doc = new DOMParser().parseFromString(
3734
sclDocString,
3835
'application/xml'
@@ -41,10 +38,10 @@ describe('TemplateGenerator', () => {
4138
});
4239

4340
it('displays an action button', () =>
44-
expect(element.shadowRoot?.querySelector('mwc-fab')).to.exist);
41+
expect(element.shadowRoot?.querySelector('md-fab')).to.exist);
4542

4643
it('adds Templates on action button click', () => {
47-
element.shadowRoot?.querySelector('mwc-fab')?.click();
44+
(element.shadowRoot?.querySelector('md-fab') as HTMLElement).click();
4845

4946
/* expect five calls for
5047
- LPHD and its mandatory DOTypes
@@ -55,40 +52,42 @@ describe('TemplateGenerator', () => {
5552
*/
5653
expect(listener).property('args').to.have.lengthOf(5);
5754
listener.args.forEach(args => {
58-
expect(args[0])
59-
.property('detail')
60-
.to.have.property(
61-
'parent',
62-
element.doc?.querySelector('DataTypeTemplates')
63-
);
64-
expect(args[0]).property('detail').to.have.property('node');
55+
const { edit } = args[0].detail;
56+
expect(edit).to.have.property(
57+
'parent',
58+
element.doc?.querySelector('DataTypeTemplates')
59+
);
60+
expect(edit).to.have.property('node');
6561
});
6662
});
6763

6864
it('adds missing DataTypeTemplates section on action button click', () => {
6965
element.doc?.querySelector('DataTypeTemplates')?.remove();
70-
element.shadowRoot?.querySelector('mwc-fab')?.click();
66+
(element.shadowRoot?.querySelector('md-fab') as HTMLElement).click();
7167

7268
// expect one more call for the DTT section
7369
expect(listener).property('args').to.have.lengthOf(6);
7470
expect(listener.args[0][0])
7571
.property('detail')
72+
.property('edit')
7673
.to.have.property('parent', element.doc?.documentElement);
7774
expect(listener.args[0][0])
7875
.property('detail')
76+
.property('edit')
7977
.property('node')
8078
.to.have.property('tagName', 'DataTypeTemplates');
8179
});
8280

8381
it('adds LNodeTypes, DOTypes, DATypes, and EnumTypes as requested', async () => {
8482
element.lNodeType = 'LLN0';
83+
element.reset();
8584
await element.lNodeTypeUI?.updateComplete;
8685
await element.updateComplete;
8786

8887
async function selectAll(column: number) {
89-
const item = element.treeUI.shadowRoot?.querySelector<ListItem>(
90-
`mwc-list:nth-of-type(${column + 1}) > mwc-list-item:first-of-type`
91-
);
88+
const item = element.treeUI.shadowRoot?.querySelector(
89+
`md-list:nth-of-type(${column + 1}) > md-list-item:first-of-type`
90+
) as HTMLElement;
9291
item?.click();
9392
await element.treeUI.updateComplete;
9493
await element.updateComplete;
@@ -100,7 +99,7 @@ describe('TemplateGenerator', () => {
10099
await selectAll(4);
101100
await selectAll(5);
102101

103-
element.shadowRoot?.querySelector('mwc-fab')?.click();
102+
(element.shadowRoot?.querySelector('md-fab') as HTMLElement).click();
104103

105104
/* expect 30 calls for
106105
LNodeType LLN0
@@ -135,7 +134,7 @@ describe('TemplateGenerator', () => {
135134
subVal
136135
*/
137136
expect(listener).property('args').to.have.lengthOf(30);
138-
const elms = listener.args.map(args => args[0].detail.node);
137+
const elms = listener.args.map(args => args[0].detail.edit.node);
139138
expect(elms.filter(e => e.tagName === 'LNodeType')).to.have.lengthOf(1);
140139
expect(elms.filter(e => e.tagName === 'DOType')).to.have.lengthOf(13);
141140
expect(elms.filter(e => e.tagName === 'DAType')).to.have.lengthOf(8);

oscd-template-generator.ts

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable import/no-extraneous-dependencies */
12
/* eslint-disable @typescript-eslint/no-unused-vars */
23
/* eslint-disable no-plusplus */
34
/* eslint-disable no-loop-func */
@@ -6,15 +7,16 @@ import { LitElement, html, css } from 'lit';
67
import { state, query } from 'lit/decorators.js';
78
import { until } from 'lit/directives/until.js';
89

9-
import { newEditEvent } from '@openscd/open-scd-core';
10+
import { ScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js';
1011

11-
import type { Select } from '@material/mwc-select';
12-
import type { TreeGrid, TreeSelection } from '@openscd/oscd-tree-grid';
12+
import { newEditEvent } from '@openenergytools/open-scd-core';
1313

14-
import '@material/mwc-fab';
15-
import '@material/mwc-select';
16-
import '@material/mwc-list/mwc-list-item.js';
17-
import '@openscd/oscd-tree-grid';
14+
import { TreeGrid, TreeSelection } from '@openenergytools/tree-grid';
15+
16+
import { MdFab } from '@scopedelement/material-web/fab/MdFab.js';
17+
import { MdIcon } from '@scopedelement/material-web/icon/MdIcon.js';
18+
import { MdFilledSelect } from '@scopedelement/material-web/select/MdFilledSelect.js';
19+
import { MdSelectOption } from '@scopedelement/material-web/select/MdSelectOption.js';
1820

1921
import { generateTemplates } from './generate-templates.js';
2022

@@ -61,15 +63,24 @@ function getDTTReference(parent: Element, tag: Tag) {
6163
return nextSibling ?? null;
6264
}
6365

64-
export default class TemplateGenerator extends LitElement {
66+
export default class TemplateGenerator extends ScopedElementsMixin(LitElement) {
67+
static scopedElements = {
68+
'tree-grid': TreeGrid,
69+
'md-filled-select': MdFilledSelect,
70+
'md-select-option': MdSelectOption,
71+
'md-fab': MdFab,
72+
'md-icon': MdIcon,
73+
};
74+
6575
@state()
6676
doc?: XMLDocument;
6777

68-
@query('oscd-tree-grid')
78+
@query('tree-grid')
6979
treeUI!: TreeGrid;
7080

7181
@state()
7282
get selection(): TreeSelection {
83+
if (!this.treeUI) return {};
7384
return this.treeUI.selection;
7485
}
7586

@@ -79,15 +90,16 @@ export default class TemplateGenerator extends LitElement {
7990

8091
@state()
8192
get filter(): string {
93+
if (!this.treeUI) return '';
8294
return this.treeUI.filter ?? '';
8395
}
8496

8597
set filter(filter: string) {
8698
this.treeUI.filter = filter;
8799
}
88100

89-
@query('mwc-select')
90-
lNodeTypeUI?: Select;
101+
@query('md-filled-select')
102+
lNodeTypeUI?: MdFilledSelect;
91103

92104
@state()
93105
get lNodeType(): string {
@@ -129,9 +141,13 @@ export default class TemplateGenerator extends LitElement {
129141

130142
if (templates.ownerDocument !== this.doc) {
131143
this.dispatchEvent(
132-
newEditEvent({ parent: this.doc.documentElement, node: templates })
144+
newEditEvent({
145+
parent: this.doc.documentElement,
146+
node: templates,
147+
reference: null,
148+
})
133149
);
134-
this.dispatchEvent(newCreateEvent(this.doc.documentElement, templates));
150+
// this.dispatchEvent(newCreateEvent(this.doc.documentElement, templates));
135151
}
136152

137153
// delete this.treeUI.selection['']; // workaround for UI bug
@@ -148,7 +164,7 @@ export default class TemplateGenerator extends LitElement {
148164
this.dispatchEvent(
149165
newEditEvent({ parent: templates, node: element, reference })
150166
);
151-
this.dispatchEvent(newCreateEvent(templates, element, reference));
167+
// this.dispatchEvent(newCreateEvent(templates, element, reference));
152168
}
153169
});
154170

@@ -165,40 +181,64 @@ export default class TemplateGenerator extends LitElement {
165181
}
166182

167183
render() {
168-
return html`<div>
169-
<mwc-select @selected=${() => this.reset()}>
184+
return html`<div class="container">
185+
<md-filled-select @input=${() => this.reset()}>
170186
${Object.keys(tree).map(
171187
lNodeType =>
172-
html`<mwc-list-item value=${lNodeType}
173-
>${lNodeType}</mwc-list-item
188+
html`<md-select-option value=${lNodeType}
189+
>${lNodeType}</md-select-option
174190
>`
175191
)}
176-
</mwc-select>
177-
<oscd-tree-grid></oscd-tree-grid>
192+
</md-filled-select>
193+
<tree-grid></tree-grid>
178194
</div>
179195
${this.doc
180-
? html`<mwc-fab
196+
? html`<md-fab
197+
variant="secondary"
181198
extended
182-
icon="${this.addedLNode ? 'done' : 'add'}"
183199
label="${this.addedLNode || 'Add Type'}"
184-
?showIconAtEnd=${this.addedLNode}
185200
@click=${() => this.saveTemplates()}
186-
></mwc-fab>`
201+
>
202+
<md-icon slot="icon">${this.addedLNode ? 'done' : 'add'}</md-icon>
203+
</md-fab>`
187204
: html``}`;
188205
}
189206

190207
static styles = css`
191-
div {
208+
* {
209+
--md-sys-color-primary: var(--oscd-primary);
210+
--md-sys-color-secondary: var(--oscd-secondary);
211+
--md-sys-typescale-body-large-font: var(--oscd-theme-text-font);
212+
--md-outlined-text-field-input-text-color: var(--oscd-base01);
213+
214+
--md-sys-color-surface: var(--oscd-base3);
215+
--md-sys-color-on-surface: var(--oscd-base00);
216+
--md-sys-color-on-primary: var(--oscd-base2);
217+
--md-sys-color-on-surface-variant: var(--oscd-base00);
218+
--md-menu-container-color: var(--oscd-base3);
219+
font-family: var(--oscd-theme-text-font);
220+
--md-sys-color-surface-container-highest: var(--oscd-base2);
221+
--md-list-item-activated-background: rgb(
222+
from var(--oscd-primary) r g b / 0.38
223+
);
224+
--md-menu-item-selected-container-color: rgb(
225+
from var(--oscd-primary) r g b / 0.38
226+
);
227+
--md-list-container-color: var(--oscd-base2);
228+
--md-fab-container-color: var(--oscd-secondary);
229+
}
230+
231+
.container {
192232
margin: 12px;
193233
}
194234
195-
mwc-fab {
235+
md-fab {
196236
position: fixed;
197237
bottom: 32px;
198238
right: 32px;
199239
}
200240
201-
mwc-select {
241+
md-filled-select {
202242
position: absolute;
203243
left: 300px;
204244
}

0 commit comments

Comments
 (0)