@@ -5,281 +5,20 @@ import {
5
5
html ,
6
6
property ,
7
7
} from 'lit-element' ;
8
- import { ifDefined } from 'lit-html/directives/if-defined' ;
9
- import { translate , get } from 'lit-translate' ;
10
8
11
- import '@material/mwc-checkbox' ;
12
9
import '@material/mwc-fab' ;
13
- import '@material/mwc-formfield' ;
14
- import '@material/mwc-list/mwc-list-item' ;
15
- import '@material/mwc-list/mwc-check-list-item' ;
16
- import '@material/mwc-icon' ;
17
- import { Checkbox } from '@material/mwc-checkbox' ;
18
- import { List } from '@material/mwc-list' ;
19
- import { ListItemBase } from '@material/mwc-list/mwc-list-item-base' ;
20
10
21
11
import '../../action-icon.js' ;
22
- import '../../wizard-textfield.js' ;
23
- import '../../filtered-list.js' ;
24
- import {
25
- EditorAction ,
26
- newWizardEvent ,
27
- Wizard ,
28
- WizardActor ,
29
- WizardInput ,
30
- newActionEvent ,
31
- compareNames ,
32
- getValue ,
33
- createElement ,
34
- ComplexAction ,
35
- } from '../../foundation.js' ;
36
- import { selectors } from './foundation.js' ;
37
- import {
38
- getTypes ,
39
- typePattern ,
40
- typeNullable ,
41
- typeMaxLength ,
42
- } from './p-types.js' ;
43
-
44
- /** Data needed to uniquely identify an `AccessPoint` */
45
- interface apAttributes {
46
- iedName : string ;
47
- apName : string ;
48
- }
49
-
50
- /** Description of a `ListItem` representing an `IED` and `AccessPoint` */
51
- interface ItemDescription {
52
- value : apAttributes ;
53
- connected ?: boolean ;
54
- }
55
-
56
- /** Sorts disabled `ListItem`s to the bottom. */
57
- function compareListItemConnection (
58
- a : ItemDescription ,
59
- b : ItemDescription
60
- ) : number {
61
- if ( a . connected !== b . connected ) return b . connected ? - 1 : 1 ;
62
- return 0 ;
63
- }
64
-
65
- function isEqualAddress ( oldAddr : Element , newAdddr : Element ) : boolean {
66
- return (
67
- Array . from ( oldAddr . querySelectorAll ( selectors . Address + ' > P' ) ) . filter (
68
- pType =>
69
- ! newAdddr
70
- . querySelector ( `Address > P[type="${ pType . getAttribute ( 'type' ) } "]` )
71
- ?. isEqualNode ( pType )
72
- ) . length === 0
73
- ) ;
74
- }
75
-
76
- function createAddressElement (
77
- inputs : WizardInput [ ] ,
78
- parent : Element ,
79
- instType : boolean
80
- ) : Element {
81
- const element = createElement ( parent . ownerDocument , 'Address' , { } ) ;
82
-
83
- inputs
84
- . filter ( input => getValue ( input ) !== null )
85
- . forEach ( validInput => {
86
- const type = validInput . label ;
87
- const child = createElement ( parent . ownerDocument , 'P' , { type } ) ;
88
- if ( instType )
89
- child . setAttributeNS (
90
- 'http://www.w3.org/2001/XMLSchema-instance' ,
91
- 'xsi:type' ,
92
- 'tP_' + type
93
- ) ;
94
- child . textContent = getValue ( validInput ) ;
95
- element . appendChild ( child ) ;
96
- } ) ;
97
-
98
- return element ;
99
- }
100
-
101
- function createConnectedApAction ( parent : Element ) : WizardActor {
102
- return (
103
- inputs : WizardInput [ ] ,
104
- wizard : Element ,
105
- list ?: List | null
106
- ) : EditorAction [ ] => {
107
- if ( ! list ) return [ ] ;
108
-
109
- const apValue = ( < ListItemBase [ ] > list . selected ) . map (
110
- item => < apAttributes > JSON . parse ( item . value )
111
- ) ;
112
-
113
- const actions = apValue . map (
114
- value =>
115
- < EditorAction > {
116
- new : {
117
- parent,
118
- element : createElement ( parent . ownerDocument , 'ConnectedAP' , {
119
- iedName : value . iedName ,
120
- apName : value . apName ,
121
- } ) ,
122
- } ,
123
- }
124
- ) ;
125
-
126
- return actions ;
127
- } ;
128
- }
129
-
130
- function renderWizardPage ( element : Element ) : TemplateResult {
131
- const doc = element . ownerDocument ;
132
-
133
- const accPoints = Array . from ( doc . querySelectorAll ( ':root > IED' ) )
134
- . sort ( compareNames )
135
- . flatMap ( ied =>
136
- Array . from ( ied . querySelectorAll ( ':root > IED > AccessPoint' ) )
137
- )
138
- . map ( accP => {
139
- return {
140
- iedName : accP . parentElement ! . getAttribute ( 'name' ) ! ,
141
- apName : accP . getAttribute ( 'name' ) ! ,
142
- } ;
143
- } ) ;
144
-
145
- const accPointDescription = accPoints
146
- . map ( value => {
147
- return {
148
- value,
149
- connected :
150
- doc ?. querySelector (
151
- `:root > Communication > SubNetwork > ConnectedAP[iedName="${ value . iedName } "][apName="${ value . apName } "]`
152
- ) !== null ,
153
- } ;
154
- } )
155
- . sort ( compareListItemConnection ) ;
156
-
157
- if ( accPointDescription . length )
158
- return html ` < filtered-list id ="apList " multi
159
- > ${ accPointDescription . map (
160
- item => html `< mwc-check-list-item
161
- value ="${ JSON . stringify ( item . value ) } "
162
- twoline
163
- ?disabled =${ item . connected }
164
- > < span > ${ item . value . apName } </ span
165
- > < span slot ="secondary "
166
- > ${ item . value . iedName } </ span
167
- > </ mwc-check-list-item
168
- > `
169
- ) }
170
- </ filtered-list > ` ;
171
-
172
- return html `< mwc-list-item disabled graphic ="icon ">
173
- < span > ${ translate ( 'lnode.wizard.placeholder' ) } </ span >
174
- < mwc-icon slot ="graphic "> info</ mwc-icon >
175
- </ mwc-list-item > ` ;
176
- }
177
-
178
- /** @returns a Wizard for creating `element` `ConnectedAP`. */
179
- export function createConnectedApWizard ( element : Element ) : Wizard {
180
- return [
181
- {
182
- title : get ( 'connectedap.wizard.title.connect' ) ,
183
- primary : {
184
- icon : 'save' ,
185
- label : get ( 'save' ) ,
186
- action : createConnectedApAction ( element ) ,
187
- } ,
188
- content : [ renderWizardPage ( element ) ] ,
189
- } ,
190
- ] ;
191
- }
192
-
193
- export function editConnectedApAction ( parent : Element ) : WizardActor {
194
- return ( inputs : WizardInput [ ] , wizard : Element ) : EditorAction [ ] => {
195
- const instType : boolean =
196
- ( < Checkbox > wizard . shadowRoot ?. querySelector ( '#instType' ) ) ?. checked ??
197
- false ;
198
-
199
- const newAddress = createAddressElement ( inputs , parent , instType ) ;
200
-
201
- const complexAction : ComplexAction = {
202
- actions : [ ] ,
203
- title : get ( 'connectedap.action.addaddress' , {
204
- iedName : parent . getAttribute ( 'iedName' ) ?? '' ,
205
- apName : parent . getAttribute ( 'apName' ) ?? '' ,
206
- } ) ,
207
- } ;
208
-
209
- const oldAddress = parent . querySelector ( selectors . Address ) ;
210
-
211
- if ( oldAddress !== null && ! isEqualAddress ( oldAddress , newAddress ) ) {
212
- // We cannot use updateAction on address as both address child elements P are changed
213
- complexAction . actions . push ( {
214
- old : {
215
- parent,
216
- element : oldAddress ,
217
- reference : oldAddress . nextSibling ,
218
- } ,
219
- } ) ;
220
- complexAction . actions . push ( {
221
- new : {
222
- parent,
223
- element : newAddress ,
224
- reference : oldAddress . nextSibling ,
225
- } ,
226
- } ) ;
227
- } else if ( oldAddress === null )
228
- complexAction . actions . push ( {
229
- new : {
230
- parent : parent ,
231
- element : newAddress ,
232
- } ,
233
- } ) ;
234
-
235
- return [ complexAction ] ;
236
- } ;
237
- }
238
-
239
- function editConnectedApWizard ( element : Element ) : Wizard {
240
- return [
241
- {
242
- title : get ( 'connectedap.wizard.title.edit' ) ,
243
- element,
244
- primary : {
245
- icon : 'save' ,
246
- label : get ( 'save' ) ,
247
- action : editConnectedApAction ( element ) ,
248
- } ,
249
- content : [
250
- html `< mwc-formfield
251
- label ="${ translate ( 'connectedap.wizard.addschemainsttype' ) } "
252
- >
253
- < mwc-checkbox
254
- id ="instType "
255
- ?checked ="${ Array . from (
256
- element . querySelectorAll ( selectors . Address + ' > P' )
257
- ) . filter ( pType => pType . getAttribute ( 'xsi:type' ) ) . length > 0 } "
258
- > </ mwc-checkbox > </ mwc-formfield
259
- > ${ getTypes ( element ) . map (
260
- ptype =>
261
- html `< wizard-textfield
262
- label ="${ ptype } "
263
- pattern ="${ ifDefined ( typePattern [ ptype ] ) } "
264
- ?nullable =${ typeNullable [ ptype ] }
265
- .maybeValue =${ element . querySelector (
266
- `:root > Communication > SubNetwork > ConnectedAP > Address > P[type="${ ptype } "]`
267
- ) ?. innerHTML ?? null }
268
- maxLength="${ ifDefined ( typeMaxLength [ ptype ] ) } "
269
- > </ wizard-textfield > `
270
- ) } `,
271
- ] ,
272
- } ,
273
- ] ;
274
- }
12
+ import { newWizardEvent , newActionEvent } from '../../foundation.js' ;
13
+ import { editConnectedApWizard } from '../../wizards/connectedap.js' ;
275
14
276
15
/** [[`Communication`]] subeditor for a `ConnectedAP` element. */
277
16
@customElement ( 'connectedap-editor' )
278
17
export class ConnectedAPEditor extends LitElement {
279
18
/** SCL element ConnectedAP */
280
19
@property ( { attribute : false } )
281
20
element ! : Element ;
282
- /** ConductingEquipment apName attribute */
21
+ /** ConnectedAP attribute apName */
283
22
@property ( { type : String } )
284
23
get apName ( ) : string {
285
24
return this . element . getAttribute ( 'apName' ) ?? 'UNDEFINED' ;
0 commit comments