diff --git a/packages/open-scd/src/editors/IED.ts b/packages/open-scd/src/editors/IED.ts index 196587751..296411a0d 100644 --- a/packages/open-scd/src/editors/IED.ts +++ b/packages/open-scd/src/editors/IED.ts @@ -32,6 +32,7 @@ export default class IedPlugin extends LitElement { /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ @property() doc!: XMLDocument; + @property({ type: Number }) editCount = -1; @@ -69,6 +70,12 @@ export default class IedPlugin extends LitElement { uniqueLNClassList.push(lnClass); return true; }) + .sort((a, b) => { + const aLnClass = a.getAttribute('lnClass') ?? ''; + const bLnClass = b.getAttribute('lnClass') ?? ''; + + return aLnClass.localeCompare(bLnClass); + }) .map(element => { const lnClass = element.getAttribute('lnClass'); const label = this.nsdoc.getDataDescription(element).label; @@ -92,17 +99,28 @@ export default class IedPlugin extends LitElement { return undefined; } + lNClassListOpenedOnce = false; + protected updated(_changedProperties: PropertyValues): void { super.updated(_changedProperties); - // When the document is updated, we reset the selected IED. - if ( + // When the document is updated, we reset the selected IED if it no longer exists + const isDocumentUpdated = _changedProperties.has('doc') || _changedProperties.has('editCount') || - _changedProperties.has('nsdoc') - ) { + _changedProperties.has('nsdoc'); + + if (isDocumentUpdated) { + // if the IED exists, retain selection + const iedExists = this.doc?.querySelector( + `IED[name="${this.selectedIEDs[0]}"]` + ); + + if (iedExists) return; + this.selectedIEDs = []; this.selectedLNClasses = []; + this.lNClassListOpenedOnce = false; const iedList = this.iedList; if (iedList.length > 0) { @@ -111,12 +129,22 @@ export default class IedPlugin extends LitElement { this.selectedIEDs = [iedName]; } } - this.selectedLNClasses = this.lnClassList.map( - lnClassInfo => lnClassInfo[0] - ); } } + private calcSelectedLNClasses(): string[] { + const somethingSelected = this.selectedLNClasses.length > 0; + const lnClasses = this.lnClassList.map( lnClassInfo => lnClassInfo[0] ); + + let selectedLNClasses = lnClasses; + + if(somethingSelected){ + selectedLNClasses = lnClasses.filter( lnClass => this.selectedLNClasses.includes(lnClass)); + } + + return selectedLNClasses; + } + render(): TemplateResult { const iedList = this.iedList; if (iedList.length > 0) { @@ -129,10 +157,25 @@ export default class IedPlugin extends LitElement { icon="developer_board" .header=${translate('iededitor.iedSelector')} @selected-items-changed="${(e: SelectedItemsChangedEvent) => { - this.selectedIEDs = e.detail.selectedItems; - this.selectedLNClasses = this.lnClassList.map( - lnClassInfo => lnClassInfo[0] + const equalArrays = (first: T[], second: T[]): boolean => { + return ( + first.length === second.length && + first.every((val, index) => val === second[index]) + ); + }; + + const selectionChanged = !equalArrays( + this.selectedIEDs, + e.detail.selectedItems ); + + if (!selectionChanged) { + return; + } + + this.lNClassListOpenedOnce = false; + this.selectedIEDs = e.detail.selectedItems; + this.selectedLNClasses = []; this.requestUpdate('selectedIed'); }}" > @@ -160,6 +203,7 @@ export default class IedPlugin extends LitElement { multi="true" .header="${translate('iededitor.lnFilter')}" @selected-items-changed="${(e: SelectedItemsChangedEvent) => { + this.selectedLNClasses = e.detail.selectedItems; this.requestUpdate('selectedIed'); }}" @@ -184,7 +228,7 @@ export default class IedPlugin extends LitElement { .editCount=${this.editCount} .doc=${this.doc} .element=${this.selectedIed} - .selectedLNClasses=${this.selectedLNClasses} + .selectedLNClasses=${this.calcSelectedLNClasses()} .nsdoc=${this.nsdoc} > `; diff --git a/packages/open-scd/test/integration/editors/IED.test.ts b/packages/open-scd/test/integration/editors/IED.test.ts index a83eb038d..e8c7f47ce 100644 --- a/packages/open-scd/test/integration/editors/IED.test.ts +++ b/packages/open-scd/test/integration/editors/IED.test.ts @@ -145,14 +145,66 @@ describe('IED Plugin', () => { ).length ).to.eql(5); - await deselectLNClasses('CSWI'); + await selectLNClasses('CSWI'); await new Promise(resolve => setTimeout(resolve, 100)); // await animation expect( getLDeviceContainer(getIedContainer()).shadowRoot!.querySelectorAll( 'ln-container' ).length - ).to.eql(3); + ).to.eql(2); + }); + + it('when other IED selected, all LNs are selected by default', async () => { + await selectLNClasses('XCBR'); + + await selectIed('IED3'); + await new Promise(resolve => setTimeout(resolve, 100)); // await animation + + expect( + element.shadowRoot?.querySelectorAll('ied-container').length + ).to.eql(1); + expect( + getIedContainer().shadowRoot?.querySelector('action-pane')!.shadowRoot + ?.innerHTML + ).to.include('IED3'); + + expect( + getLDeviceContainer(getIedContainer()).shadowRoot!.querySelectorAll( + 'ln-container' + ).length + ).to.eql(9); + }); + + it('when filtering LNs, if none are selected, all are selected', async () => { + await selectIed('IED3'); + + const oscdFilterButton = ( + element.shadowRoot!.querySelector( + 'oscd-filter-button[id="lnClassesFilter"]' + ) + ); + const filterButton = ( + oscdFilterButton!.shadowRoot!.querySelector('mwc-icon-button') + ); + filterButton.click(); + await element.updateComplete; + + const primaryButton = ( + oscdFilterButton!.shadowRoot!.querySelector( + 'mwc-button[slot="primaryAction"]' + ) + ); + primaryButton.click(); + await element.updateComplete; + + await new Promise(resolve => setTimeout(resolve, 100)); // await animation + + expect( + getLDeviceContainer(getIedContainer()).shadowRoot!.querySelectorAll( + 'ln-container' + ).length + ).to.eql(9); }); it('then renders the path of elements correctly', async () => { @@ -277,7 +329,7 @@ describe('IED Plugin', () => { ); } - async function deselectLNClasses(lnClass: string): Promise { + async function selectLNClasses(lnClass: string): Promise { const oscdFilterButton = ( element.shadowRoot!.querySelector( 'oscd-filter-button[id="lnClassesFilter"]' diff --git a/packages/open-scd/test/integration/editors/__snapshots__/IED.test.snap.js b/packages/open-scd/test/integration/editors/__snapshots__/IED.test.snap.js index 0ed73255d..b07ca7929 100644 --- a/packages/open-scd/test/integration/editors/__snapshots__/IED.test.snap.js +++ b/packages/open-scd/test/integration/editors/__snapshots__/IED.test.snap.js @@ -116,51 +116,46 @@ snapshots["IED Plugin with a doc loaded containing IEDs looks like the latest sn aria-disabled="false" graphic="control" mwc-list-item="" - selected="" tabindex="0" - value="LLN0" + value="CILO" > - LLN0 + CILO - XCBR + CSWI - CSWI + LLN0 - XSWI + XCBR - CILO + XSWI