Skip to content

Commit 8b4bfe9

Browse files
author
Dennis Labordus
committed
Added SCL Auto Alignment Menu.
Signed-off-by: Dennis Labordus <[email protected]>
1 parent 9501b12 commit 8b4bfe9

File tree

16 files changed

+446
-38
lines changed

16 files changed

+446
-38
lines changed

.github/workflows/build-project.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ on:
44
push:
55
branches:
66
- '**'
7-
- '!main'
87
pull_request:
98
branches:
109
- 'main'
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# `compas-auto-alignment`
2+
3+
## `document with substations`
4+
5+
#### `looks like the latest snapshot`
6+
7+
```html
8+
<section tabindex="0">
9+
<mwc-list
10+
multi=""
11+
required=""
12+
>
13+
<mwc-check-list-item
14+
aria-disabled="false"
15+
graphic="control"
16+
left=""
17+
mwc-list-item=""
18+
tabindex="0"
19+
value="_af9a4ae3-ba2e-4c34-8e47-5af894ee20f4"
20+
>
21+
_af9a4ae3-ba2e-4c34-8e47-5af894ee20f4
22+
(Substation 1)
23+
</mwc-check-list-item>
24+
<mwc-check-list-item
25+
aria-disabled="false"
26+
graphic="control"
27+
left=""
28+
mwc-list-item=""
29+
tabindex="-1"
30+
value="_974565b1-ac55-4901-9f48-afc7ef5486df"
31+
>
32+
_974565b1-ac55-4901-9f48-afc7ef5486df
33+
(Sub3)
34+
</mwc-check-list-item>
35+
<mwc-check-list-item
36+
aria-disabled="false"
37+
graphic="control"
38+
left=""
39+
mwc-list-item=""
40+
tabindex="-1"
41+
value="_d6056127-34f1-43a9-b029-23fddb913bd5"
42+
>
43+
_d6056127-34f1-43a9-b029-23fddb913bd5
44+
(Sub4)
45+
</mwc-check-list-item>
46+
<mwc-check-list-item
47+
aria-disabled="false"
48+
graphic="control"
49+
left=""
50+
mwc-list-item=""
51+
tabindex="-1"
52+
value="_b3e5b4de-b74d-43b4-8db9-784302a12acf"
53+
>
54+
_b3e5b4de-b74d-43b4-8db9-784302a12acf
55+
(Sub5)
56+
</mwc-check-list-item>
57+
</mwc-list>
58+
</section>
59+
60+
```
61+
62+
## `document without substations`
63+
64+
#### `looks like the latest snapshot`
65+
66+
```html
67+
<section tabindex="0">
68+
<span style="color: var(--base1)">
69+
[compas.autoAlignment.missing]
70+
</span>
71+
</section>
72+
73+
```
74+

__snapshots__/compas-settings.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@
1919
value="/compas-cim-mapping"
2020
>
2121
</mwc-textfield>
22+
<mwc-textfield
23+
dialoginitialfocus=""
24+
id="sclAutoAlignmentServiceUrl"
25+
label="[compas.settings.sclAutoAlignmentServiceUrl]"
26+
required=""
27+
value="/compas-scl-auto-alignment"
28+
>
29+
</mwc-textfield>
2230
<mwc-button style="--mdc-theme-primary: var(--mdc-theme-error)">
2331
[reset]
2432
</mwc-button>

__snapshots__/open-scd.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,24 @@
270270
<mwc-linear-progress indeterminate="">
271271
</mwc-linear-progress>
272272
</mwc-list-item>
273+
<mwc-list-item
274+
aria-disabled="true"
275+
class="middle"
276+
disabled=""
277+
graphic="icon"
278+
iconid="dashboard"
279+
mwc-list-item=""
280+
tabindex="-1"
281+
>
282+
<mwc-icon slot="graphic">
283+
dashboard
284+
</mwc-icon>
285+
<span>
286+
Auto Align SLD
287+
</span>
288+
<mwc-linear-progress indeterminate="">
289+
</mwc-linear-progress>
290+
</mwc-list-item>
273291
<li
274292
divider=""
275293
padded=""
@@ -860,6 +878,22 @@
860878
</mwc-icon>
861879
Update Substation
862880
</mwc-check-list-item>
881+
<mwc-check-list-item
882+
aria-disabled="false"
883+
class="official"
884+
graphic="control"
885+
hasmeta=""
886+
left=""
887+
mwc-list-item=""
888+
selected=""
889+
tabindex="-1"
890+
value="/src/menu/CompasAutoAlignment.js"
891+
>
892+
<mwc-icon slot="meta">
893+
dashboard
894+
</mwc-icon>
895+
Auto Align SLD
896+
</mwc-check-list-item>
863897
<li
864898
divider=""
865899
inset=""

public/js/plugins.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,15 @@ export const officialPlugins = [
112112
requireDoc: true,
113113
position: 'middle'
114114
},
115+
{
116+
name: 'Auto Align SLD',
117+
src: '/src/menu/CompasAutoAlignment.js',
118+
icon: 'dashboard',
119+
default: true,
120+
kind: 'menu',
121+
requireDoc: true,
122+
position: 'middle'
123+
},
115124
{
116125
name: 'CoMPAS Settings',
117126
src: '/src/menu/CompasSettings.js',
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {CompasSettings} from "../compas/CompasSettings.js";
2+
import {extractSclFromResponse, handleError, handleResponse, parseXml} from "./foundation.js";
3+
4+
export const SAA_NAMESPACE = 'https://www.lfenergy.org/compas/SclAutoAlignmentService/v1';
5+
6+
export function CompasSclAutoAlignmentService() {
7+
function getCompasSettings() {
8+
return CompasSettings().compasSettings;
9+
}
10+
11+
return {
12+
updateSCL(doc: Document, substationNames: string[]): Promise<Document> {
13+
const saaUrl = getCompasSettings().sclAutoAlignmentServiceUrl + '/auto/alignment/v1';
14+
return fetch(saaUrl, {
15+
method: 'POST',
16+
headers: {
17+
'Content-Type': 'application/xml'
18+
},
19+
body: `<?xml version="1.0" encoding="UTF-8"?>
20+
<saa:SclAutoAlignRequest xmlns:saa="${SAA_NAMESPACE}">
21+
${substationNames.map(substationName => {
22+
return `
23+
<saa:SubstationName>${substationName}</saa:SubstationName>
24+
`;
25+
})}
26+
<saa:SclData><![CDATA[${new XMLSerializer().serializeToString(doc.documentElement)}]]></saa:SclData>
27+
</saa:SclAutoAlignRequest>`
28+
}).catch(handleError)
29+
.then(handleResponse)
30+
.then(parseXml)
31+
.then(extractSclFromResponse);
32+
},
33+
}
34+
}

src/compas/CompasAutoAlignment.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import {customElement, html, LitElement, property, TemplateResult} from "lit-element";
2+
import {get, translate} from "lit-translate";
3+
4+
import {newLogEvent, newOpenDocEvent, newWizardEvent} from "../foundation.js";
5+
import {getOpenScdElement} from "./foundation.js";
6+
7+
import {CompasSclAutoAlignmentService} from "../compas-services/CompasSclAutoAlignmentService.js";
8+
import {createLogEvent} from "../compas-services/foundation.js";
9+
10+
@customElement('compas-auto-alignment')
11+
export default class CompasAutoAlignmentElement extends LitElement {
12+
@property({type: Document})
13+
doc!: XMLDocument;
14+
@property({type: String})
15+
docName!: string;
16+
@property({type: String})
17+
docId?: string;
18+
19+
getSelectedValues() : string[] {
20+
const selectedItems: string[] = [];
21+
this.shadowRoot!.querySelectorAll('mwc-check-list-item').forEach((item, key) => {
22+
if (item.selected) {
23+
selectedItems[key] = item.value;
24+
}
25+
});
26+
return selectedItems;
27+
}
28+
29+
valid(): boolean {
30+
return this.getSelectedValues().length > 0;
31+
}
32+
33+
async execute(): Promise<void> {
34+
if (this.valid()) {
35+
await CompasSclAutoAlignmentService().updateSCL(this.doc, this.getSelectedValues())
36+
.then(sclDocument => {
37+
const openScd = getOpenScdElement();
38+
openScd.dispatchEvent(newLogEvent({kind: 'reset'}));
39+
openScd.dispatchEvent(newOpenDocEvent(sclDocument, this.docName, {detail: {docId: this.docId}}));
40+
41+
openScd.dispatchEvent(
42+
newLogEvent({
43+
kind: 'info',
44+
title: get('compas.autoAlignment.success')
45+
}));
46+
47+
// Close the Save Dialog.
48+
this.dispatchEvent(newWizardEvent());
49+
})
50+
.catch(createLogEvent);
51+
52+
// Close the Save Dialog.
53+
this.dispatchEvent(newWizardEvent());
54+
}
55+
}
56+
57+
render(): TemplateResult {
58+
return html `
59+
${this.doc?.querySelector(':root > Substation')
60+
? html`
61+
<section tabindex="0">
62+
<mwc-list multi required>
63+
${Array.from(this.doc.querySelectorAll(':root > Substation') ?? [])
64+
.map(substation =>
65+
html`
66+
<mwc-check-list-item left value="${substation.getAttribute('name')}">
67+
${substation.getAttribute('name')}
68+
${substation.hasAttribute('desc') ? html `(${substation.getAttribute('desc')})`: html ``}
69+
</mwc-check-list-item>
70+
`
71+
)}
72+
</mwc-list>
73+
</section>
74+
`
75+
: html`
76+
<section tabindex="0">
77+
<span style="color: var(--base1)">${translate('compas.autoAlignment.missing')}</span>
78+
</section>
79+
`}
80+
`;
81+
}
82+
}

src/compas/CompasSave.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import './CompasChangeSetRadiogroup.js';
1717
import './CompasSclTypeRadiogroup.js';
1818

1919
@customElement('compas-save')
20-
export class CompasSaveElement extends CompasExistsIn(LitElement) {
20+
export default class CompasSaveElement extends CompasExistsIn(LitElement) {
2121
@property({type: Document})
2222
doc!: XMLDocument;
2323

src/compas/CompasSettings.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {getOpenScdElement} from "./foundation.js";
88
export type CompasSettingsRecord = {
99
sclDataServiceUrl: string;
1010
cimMappingServiceUrl: string;
11+
sclAutoAlignmentServiceUrl: string;
1112
};
1213

1314
export function CompasSettings() {
@@ -17,13 +18,15 @@ export function CompasSettings() {
1718
return {
1819
sclDataServiceUrl: this.getCompasSetting('sclDataServiceUrl'),
1920
cimMappingServiceUrl: this.getCompasSetting('cimMappingServiceUrl'),
21+
sclAutoAlignmentServiceUrl: this.getCompasSetting('sclAutoAlignmentServiceUrl'),
2022
};
2123
},
2224

2325
get defaultSettings(): CompasSettingsRecord {
2426
return {
2527
sclDataServiceUrl: '/compas-scl-data-service',
26-
cimMappingServiceUrl: '/compas-cim-mapping'
28+
cimMappingServiceUrl: '/compas-cim-mapping',
29+
sclAutoAlignmentServiceUrl: '/compas-scl-auto-alignment'
2730
}
2831
},
2932

@@ -55,9 +58,14 @@ export class CompasSettingsElement extends LitElement {
5558
return <TextFieldBase>this.shadowRoot!.querySelector('mwc-textfield[id="cimMappingServiceUrl"]');
5659
}
5760

61+
getSclAutoAlignmentServiceUrlField(): TextFieldBase {
62+
return <TextFieldBase>this.shadowRoot!.querySelector('mwc-textfield[id="sclAutoAlignmentServiceUrl"]');
63+
}
64+
5865
valid(): boolean {
5966
return this.getSclDataServiceUrlField().checkValidity()
60-
&& this.getCimMappingServiceUrlField().checkValidity();
67+
&& this.getCimMappingServiceUrlField().checkValidity()
68+
&& this.getSclAutoAlignmentServiceUrlField().checkValidity();
6169
}
6270

6371
save(): boolean {
@@ -68,6 +76,7 @@ export class CompasSettingsElement extends LitElement {
6876
// Update settings from TextField.
6977
CompasSettings().setCompasSetting('sclDataServiceUrl', this.getSclDataServiceUrlField().value);
7078
CompasSettings().setCompasSetting('cimMappingServiceUrl', this.getCimMappingServiceUrlField().value);
79+
CompasSettings().setCompasSetting('sclAutoAlignmentServiceUrl', this.getSclAutoAlignmentServiceUrlField().value);
7180
return true;
7281
}
7382

@@ -94,6 +103,10 @@ export class CompasSettingsElement extends LitElement {
94103
label="${translate('compas.settings.cimMappingServiceUrl')}"
95104
value="${this.compasSettings.cimMappingServiceUrl}" required>
96105
</mwc-textfield>
106+
<mwc-textfield dialogInitialFocus id="sclAutoAlignmentServiceUrl"
107+
label="${translate('compas.settings.sclAutoAlignmentServiceUrl')}"
108+
value="${this.compasSettings.sclAutoAlignmentServiceUrl}" required>
109+
</mwc-textfield>
97110
98111
<mwc-button style="--mdc-theme-primary: var(--mdc-theme-error)"
99112
@click=${() => {

src/menu/CompasAutoAlignment.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {html, LitElement} from 'lit-element';
2+
import {get} from "lit-translate";
3+
4+
import {newPendingStateEvent, newWizardEvent, Wizard, WizardInput} from '../foundation.js';
5+
6+
import CompasAutoAlignmentElement from "../compas/CompasAutoAlignment.js";
7+
import {getOpenScdElement} from "../compas/foundation.js";
8+
9+
import "../compas/CompasAutoAlignment.js";
10+
11+
export default class CompasAutoAlignmentMenuPlugin extends LitElement {
12+
doc!: XMLDocument;
13+
docName!: string;
14+
docId?: string;
15+
16+
private autoAlignmentCompasWizard(): Wizard {
17+
function execute() {
18+
return function (inputs: WizardInput[], wizard: Element) {
19+
const compasAutoAlignmentElement = <CompasAutoAlignmentElement>wizard.shadowRoot!.querySelector('compas-auto-alignment')
20+
if (!compasAutoAlignmentElement.valid()) {
21+
return [];
22+
}
23+
24+
getOpenScdElement().dispatchEvent(newPendingStateEvent(compasAutoAlignmentElement.execute()));
25+
return [];
26+
};
27+
}
28+
29+
return [
30+
{
31+
title: get('compas.autoAlignment.title'),
32+
primary: {
33+
icon: 'dashboard',
34+
label: get('compas.autoAlignment.button'),
35+
action: execute(),
36+
},
37+
content: [
38+
html `
39+
<compas-auto-alignment .doc="${this.doc}" .docName="${this.docName}" .docId="${this.docId}">
40+
</compas-auto-alignment>
41+
`,
42+
],
43+
},
44+
];
45+
}
46+
47+
async run(): Promise<void> {
48+
this.dispatchEvent(newWizardEvent(this.autoAlignmentCompasWizard()));
49+
}
50+
}

0 commit comments

Comments
 (0)