From e8f4d5abbf122d33c171135d7bce180bc95e52d6 Mon Sep 17 00:00:00 2001
From: Dennis Labordus
Date: Tue, 27 Sep 2022 08:47:03 +0200
Subject: [PATCH 1/3] Add filtering on labesl when opening SCL File and small
improvements in Save menu items
Signed-off-by: Dennis Labordus
---
src/compas/CompasOpen.ts | 6 +-
src/compas/CompasSave.ts | 47 +++--
src/compas/CompasSclList.ts | 166 ++++++++++++++----
src/menu/CompasCompareIED.ts | 2 +-
src/menu/CompasImportIEDs.ts | 29 +--
src/menu/CompasMerge.ts | 36 ++--
src/menu/CompasOpen.ts | 95 ++++++----
src/menu/CompasSave.ts | 23 +--
src/menu/CompasSaveAs.ts | 29 +--
src/menu/CompasUpdateSubstation.ts | 2 +-
src/oscd-filter-button.ts | 8 +-
src/translations/de.ts | 5 +
src/translations/en.ts | 7 +-
.../oscd-filter-button.test.snap.js | 44 +++++
.../compas/CompasSclDataServiceResponses.ts | 35 +++-
test/unit/compas/CompasSclList.test.ts | 117 ++++++++++--
.../__snapshots__/CompasSclList.test.snap.js | 96 ++++++++--
test/unit/menu/CompasOpen.test.ts | 19 ++
.../__snapshots__/CompasOpen.test.snap.js | 22 +++
test/unit/oscd-filter-button.test.ts | 29 +++
20 files changed, 644 insertions(+), 173 deletions(-)
create mode 100644 test/unit/menu/CompasOpen.test.ts
create mode 100644 test/unit/menu/__snapshots__/CompasOpen.test.snap.js
diff --git a/src/compas/CompasOpen.ts b/src/compas/CompasOpen.ts
index 5b310fbf6..4473bf4b6 100644
--- a/src/compas/CompasOpen.ts
+++ b/src/compas/CompasOpen.ts
@@ -21,7 +21,7 @@ import '../WizardDivider.js';
import './CompasSclTypeList.js';
import './CompasSclList.js';
-/* Event that will be used when a SCL Document is retrieved. */
+/* Event that will be used when an SCL Document is retrieved. */
export interface DocRetrievedDetail {
localFile: boolean;
doc: Document;
@@ -33,7 +33,7 @@ export function newDocRetrievedEvent(
doc: Document,
docName?: string
): DocRetrievedEvent {
- return new CustomEvent('docRetrieved', {
+ return new CustomEvent('doc-retrieved', {
bubbles: true,
composed: true,
detail: { localFile, doc, docName },
@@ -110,7 +110,7 @@ export default class CompasOpenElement extends LitElement {
type: this.selectedType ?? '',
})}
+ @scl-selected=${(evt: SclSelectedEvent) =>
this.dispatchEvent(
newPendingStateEvent(
this.getSclDocument(evt.detail.docId)
diff --git a/src/compas/CompasSave.ts b/src/compas/CompasSave.ts
index a35b08c09..d223d4977 100644
--- a/src/compas/CompasSave.ts
+++ b/src/compas/CompasSave.ts
@@ -4,6 +4,7 @@ import {
html,
LitElement,
property,
+ PropertyValues,
query,
TemplateResult,
} from 'lit-element';
@@ -42,6 +43,15 @@ import './CompasLabelsField.js';
import './CompasLoading.js';
import './CompasSclTypeSelect.js';
+/* Event that will be used when an SCL Document is saved. */
+export type DocSavedEvent = CustomEvent;
+export function newDocSavedEvent(): DocSavedEvent {
+ return new CustomEvent('doc-saved', {
+ bubbles: true,
+ composed: true,
+ });
+}
+
@customElement('compas-save')
export default class CompasSaveElement extends CompasExistsIn(LitElement) {
@property()
@@ -62,6 +72,17 @@ export default class CompasSaveElement extends CompasExistsIn(LitElement) {
@query('compas-labels-field')
private labelsField!: CompasLabelsFieldElement;
+ protected updated(_changedProperties: PropertyValues): void {
+ super.updated(_changedProperties);
+
+ // When the document is updated, we reset the selected IED.
+ if (_changedProperties.has('doc')) {
+ if (this.commentField) {
+ this.commentField.value = null;
+ }
+ }
+ }
+
valid(): boolean {
if (!this.existInCompas) {
return this.nameField.checkValidity() && this.sclTypeRadioGroup.valid();
@@ -79,16 +100,14 @@ export default class CompasSaveElement extends CompasExistsIn(LitElement) {
this.labelsField.updateLabelsInPrivateElement(privateElement!);
}
- private async addSclToCompas(doc: XMLDocument): Promise {
+ private async addSclToCompas(doc: XMLDocument): Promise {
const name = stripExtensionFromName(this.nameField.value);
const comment = this.commentField.value;
const docType = this.sclTypeRadioGroup.getSelectedValue() ?? '';
- let success = false;
await CompasSclDataService()
.addSclDocument(docType, { sclName: name, comment: comment, doc: doc })
.then(sclDocument => {
- this.commentField.value = null;
updateDocumentInOpenSCD(this, sclDocument);
this.dispatchEvent(
@@ -97,22 +116,20 @@ export default class CompasSaveElement extends CompasExistsIn(LitElement) {
title: get('compas.save.addSuccess'),
})
);
- success = true;
+
+ this.dispatchEvent(newDocSavedEvent());
})
.catch(reason => createLogEvent(this, reason));
-
- return success;
}
private async updateSclInCompas(
docId: string,
docName: string,
doc: XMLDocument
- ): Promise {
+ ): Promise {
const changeSet = this.changeSetRadiogroup.getSelectedValue();
const comment = this.commentField.value;
const docType = getTypeFromDocName(docName);
- let success = false;
await CompasSclDataService()
.updateSclDocument(docType, docId, {
@@ -121,7 +138,6 @@ export default class CompasSaveElement extends CompasExistsIn(LitElement) {
doc: doc,
})
.then(sclDocument => {
- this.commentField.value = null;
updateDocumentInOpenSCD(this, sclDocument);
this.dispatchEvent(
@@ -130,19 +146,18 @@ export default class CompasSaveElement extends CompasExistsIn(LitElement) {
title: get('compas.save.updateSuccess'),
})
);
- success = true;
+
+ this.dispatchEvent(newDocSavedEvent());
})
.catch(reason => createLogEvent(this, reason));
-
- return success;
}
- async saveToCompas(): Promise {
+ async saveToCompas(): Promise {
this.updateLabels();
if (!this.docId || !this.existInCompas) {
- return this.addSclToCompas(this.doc);
+ await this.addSclToCompas(this.doc);
} else {
- return this.updateSclInCompas(this.docId, this.docName, this.doc);
+ await this.updateSclInCompas(this.docId, this.docName, this.doc);
}
}
@@ -153,6 +168,8 @@ export default class CompasSaveElement extends CompasExistsIn(LitElement) {
@click=${() => {
this.updateLabels();
saveDocumentToFile(this.doc, this.docName);
+
+ this.dispatchEvent(newDocSavedEvent());
}}
>
diff --git a/src/compas/CompasSclList.ts b/src/compas/CompasSclList.ts
index 76ff97b7f..767ab1cdc 100644
--- a/src/compas/CompasSclList.ts
+++ b/src/compas/CompasSclList.ts
@@ -1,8 +1,11 @@
import {
+ css,
customElement,
html,
LitElement,
property,
+ PropertyValues,
+ state,
TemplateResult,
} from 'lit-element';
import { translate } from 'lit-translate';
@@ -10,6 +13,11 @@ import { translate } from 'lit-translate';
import '@material/mwc-list';
import '@material/mwc-list/mwc-list-item';
+import { SelectedItemsChangedEvent } from '../oscd-filter-button.js';
+
+import '../filtered-list.js';
+import '../oscd-filter-button.js';
+
import {
CompasSclDataService,
SDS_NAMESPACE,
@@ -21,7 +29,7 @@ export interface SclSelectedDetail {
}
export type SclSelectedEvent = CustomEvent;
export function newSclSelectedEvent(docId: string): SclSelectedEvent {
- return new CustomEvent('sclSelected', {
+ return new CustomEvent('scl-selected', {
bubbles: true,
composed: true,
detail: { docId },
@@ -30,54 +38,146 @@ export function newSclSelectedEvent(docId: string): SclSelectedEvent {
@customElement('compas-scl-list')
export class CompasSclList extends LitElement {
- @property({ type: String })
- type = '';
-
@property()
- scls!: Element[];
+ type?: string;
+
+ @state()
+ private items?: Element[];
+
+ @state()
+ private labels: string[] = [];
+
+ @state()
+ private selectedLabels: string[] = [];
+
+ @state()
+ private get filteredItems(): Element[] | undefined {
+ // If items are still being retrieved, return undefined.
+ if (!this.items) {
+ return undefined;
+ }
+
+ // If all labels are selected, show all items, including the ones not having a Label.
+ if (this.labels.length === this.selectedLabels.length) {
+ return this.items;
+ }
+
+ return this.items.filter(item => {
+ const labels = Array.from(item.querySelectorAll('Label') ?? [])
+ .map(element => element.textContent)
+ .filter(value => !!value) as string[];
+ return (
+ labels.filter(label => this.selectedLabels.includes(label)).length > 0
+ );
+ });
+ }
firstUpdated(): void {
this.fetchData();
}
+ protected updated(_changedProperties: PropertyValues): void {
+ super.updated(_changedProperties);
+
+ // When the document is updated, we reset the selected IED.
+ if (_changedProperties.has('type')) {
+ this.items = undefined;
+ this.labels = [];
+ this.selectedLabels = [];
+ this.fetchData();
+ }
+ }
+
fetchData(): void {
- CompasSclDataService()
- .listScls(this.type)
- .then(xmlResponse => {
- this.scls = Array.from(xmlResponse.querySelectorAll('Item') ?? []);
- });
+ if (this.type) {
+ CompasSclDataService()
+ .listScls(this.type)
+ .then(xmlResponse => {
+ this.items = Array.from(xmlResponse.querySelectorAll('Item') ?? []);
+ this.labels = Array.from(
+ new Set(
+ Array.from(xmlResponse.querySelectorAll('Label') ?? [])
+ .map(element => element.textContent)
+ .filter(value => !!value)
+ )
+ ) as string[];
+ this.selectedLabels = this.labels;
+ });
+ }
}
render(): TemplateResult {
- if (!this.scls) {
+ if (!this.items) {
return html` `;
}
- if (this.scls?.length <= 0) {
+ if (this.items?.length <= 0) {
return html`
${translate('compas.noScls')}
`;
}
- return html`
- ${this.scls.map(item => {
- const id =
- item.getElementsByTagNameNS(SDS_NAMESPACE, 'Id').item(0)!
- .textContent ?? '';
- let name =
- item.getElementsByTagNameNS(SDS_NAMESPACE, 'Name').item(0)!
- .textContent ?? '';
- if (name === '') {
- name = id;
- }
- const version =
- item.getElementsByTagNameNS(SDS_NAMESPACE, 'Version').item(0)!
- .textContent ?? '';
- return html` this.dispatchEvent(newSclSelectedEvent(id))}
+ const filteredItems = this.filteredItems;
+ return html`
+ ${translate('compas.sclFilter')}
+ {
+ this.selectedLabels = e.detail.selectedItems;
+ this.requestUpdate('items');
+ this.requestUpdate('filteredItems');
+ }}"
>
- ${name} (${version})
- `;
- })}
- `;
+ ${this.labels.map(label => {
+ return html`
+ ${label}
+ `;
+ })}
+
+
+ ${filteredItems && filteredItems.length > 0
+ ? html`
+ ${filteredItems.map(item => {
+ const id =
+ item.getElementsByTagNameNS(SDS_NAMESPACE, 'Id').item(0)!
+ .textContent ?? '';
+ let name =
+ item.getElementsByTagNameNS(SDS_NAMESPACE, 'Name').item(0)!
+ .textContent ?? '';
+ if (name === '') {
+ name = id;
+ }
+ const version =
+ item.getElementsByTagNameNS(SDS_NAMESPACE, 'Version').item(0)!
+ .textContent ?? '';
+ return html` this.dispatchEvent(newSclSelectedEvent(id))}
+ >
+ ${name} (${version})
+ `;
+ })}
+ `
+ : html`
+
+ ${translate('compas.noFilteredScls')}
+
+ `} `;
}
+
+ static styles = css`
+ .filters {
+ padding-left: var(--mdc-list-side-padding, 16px);
+ display: flex;
+ }
+
+ .filters > span {
+ line-height: 48px;
+ }
+ `;
}
diff --git a/src/menu/CompasCompareIED.ts b/src/menu/CompasCompareIED.ts
index 8c986e58e..8ada7662f 100644
--- a/src/menu/CompasCompareIED.ts
+++ b/src/menu/CompasCompareIED.ts
@@ -15,7 +15,7 @@ export default class CompasCompareIEDPlugin extends CompareIEDPlugin {
*/
protected renderSelectTemplateFile(): TemplateResult {
return html` {
+ @doc-retrieved=${(evt: DocRetrievedEvent) => {
this.templateDoc = evt.detail.doc;
}}
>
diff --git a/src/menu/CompasImportIEDs.ts b/src/menu/CompasImportIEDs.ts
index 86f5c3a68..63f4ddb3b 100644
--- a/src/menu/CompasImportIEDs.ts
+++ b/src/menu/CompasImportIEDs.ts
@@ -1,12 +1,12 @@
-import {html, LitElement} from 'lit-element';
-import {get} from "lit-translate";
+import { html, LitElement } from 'lit-element';
+import { get } from 'lit-translate';
-import {newWizardEvent, Wizard} from '../foundation.js';
+import { newWizardEvent, Wizard } from '../foundation.js';
-import {DocRetrievedEvent} from "../compas/CompasOpen.js";
-import {prepareImportIEDs} from "./ImportIEDs.js";
+import { DocRetrievedEvent } from '../compas/CompasOpen.js';
+import { prepareImportIEDs } from './ImportIEDs.js';
-import "../compas/CompasOpen.js";
+import '../compas/CompasOpen.js';
export default class CompasImportIEDSMenuPlugin extends LitElement {
doc!: XMLDocument;
@@ -17,12 +17,13 @@ export default class CompasImportIEDSMenuPlugin extends LitElement {
{
title: get('compas.importIEDS.title'),
content: [
- html` {
- await prepareImportIEDs(parent, event.detail.doc, doc);
- parent.dispatchEvent(newWizardEvent());
- }}>
-
- `,
+ html` {
+ await prepareImportIEDs(parent, event.detail.doc, doc);
+ parent.dispatchEvent(newWizardEvent());
+ }}
+ >
+ `,
],
},
];
@@ -33,6 +34,8 @@ export default class CompasImportIEDSMenuPlugin extends LitElement {
}
async run(): Promise {
- this.dispatchEvent(newWizardEvent(this.importIEDsCompasWizard(this.parent, this.doc)));
+ this.dispatchEvent(
+ newWizardEvent(this.importIEDsCompasWizard(this.parent, this.doc))
+ );
}
}
diff --git a/src/menu/CompasMerge.ts b/src/menu/CompasMerge.ts
index 2a08af63c..e4297089c 100644
--- a/src/menu/CompasMerge.ts
+++ b/src/menu/CompasMerge.ts
@@ -1,12 +1,12 @@
-import {html, LitElement} from 'lit-element';
-import {get} from "lit-translate";
+import { html, LitElement } from 'lit-element';
+import { get } from 'lit-translate';
-import {newWizardEvent, Wizard} from '../foundation.js';
-import {mergeWizard} from "../wizards.js";
+import { newWizardEvent, Wizard } from '../foundation.js';
+import { mergeWizard } from '../wizards.js';
-import {DocRetrievedEvent} from "../compas/CompasOpen.js";
+import { DocRetrievedEvent } from '../compas/CompasOpen.js';
-import "../compas/CompasOpen.js";
+import '../compas/CompasOpen.js';
export default class CompasMergeMenuPlugin extends LitElement {
doc!: XMLDocument;
@@ -17,16 +17,20 @@ export default class CompasMergeMenuPlugin extends LitElement {
{
title: get('compas.merge.title'),
content: [
- html` {
- this.parent.dispatchEvent(
- newWizardEvent(
- mergeWizard(this.doc.documentElement, evt.detail.doc.documentElement)
- )
- );
- this.parent.dispatchEvent(newWizardEvent());
- }}>
-
- `,
+ html` {
+ this.parent.dispatchEvent(
+ newWizardEvent(
+ mergeWizard(
+ this.doc.documentElement,
+ evt.detail.doc.documentElement
+ )
+ )
+ );
+ this.parent.dispatchEvent(newWizardEvent());
+ }}
+ >
+ `,
],
},
];
diff --git a/src/menu/CompasOpen.ts b/src/menu/CompasOpen.ts
index c050551d1..b84567049 100644
--- a/src/menu/CompasOpen.ts
+++ b/src/menu/CompasOpen.ts
@@ -1,55 +1,74 @@
-import { html, LitElement } from 'lit-element';
-import { get } from 'lit-translate';
+import { css, html, LitElement, query, TemplateResult } from 'lit-element';
+import { translate } from 'lit-translate';
+
+import '@material/mwc-button';
+import '@material/mwc-dialog';
+import { Dialog } from '@material/mwc-dialog';
import {
newLogEvent,
newOpenDocEvent,
newPendingStateEvent,
- newWizardEvent,
- Wizard,
} from '../foundation.js';
-import { DocRetrievedEvent } from '../compas/CompasOpen.js';
+import CompasOpenElement, { DocRetrievedEvent } from '../compas/CompasOpen.js';
import { updateDocumentInOpenSCD } from '../compas/foundation.js';
import '../compas/CompasOpen.js';
export default class CompasOpenMenuPlugin extends LitElement {
- private openCompasWizard(): Wizard {
- async function openDoc(
- plugin: CompasOpenMenuPlugin,
- event: DocRetrievedEvent
- ): Promise {
- if (event.detail.localFile) {
- plugin.dispatchEvent(newLogEvent({ kind: 'reset' }));
- plugin.dispatchEvent(
- newOpenDocEvent(event.detail.doc, event.detail.docName!, {
- detail: { docId: undefined },
- })
- );
- plugin.dispatchEvent(newWizardEvent());
- } else {
- updateDocumentInOpenSCD(plugin, event.detail.doc, event.detail.docName);
- plugin.dispatchEvent(newWizardEvent());
- }
- }
+ @query('mwc-dialog#compas-open-dlg')
+ dialog!: Dialog;
- return [
- {
- title: get('compas.open.title'),
- content: [
- html` {
- this.dispatchEvent(newPendingStateEvent(openDoc(this, event)));
- }}
- >
- `,
- ],
- },
- ];
- }
+ @query('compas-open')
+ compasOpenElement!: CompasOpenElement;
async run(): Promise {
- this.dispatchEvent(newWizardEvent(this.openCompasWizard()));
+ this.compasOpenElement.selectedType = undefined;
+ await this.compasOpenElement.requestUpdate();
+ this.dialog.show();
+ }
+
+ private async openDoc(event: DocRetrievedEvent): Promise {
+ if (event.detail.localFile) {
+ this.dispatchEvent(newLogEvent({ kind: 'reset' }));
+ this.dispatchEvent(
+ newOpenDocEvent(event.detail.doc, event.detail.docName!, {
+ detail: { docId: undefined },
+ })
+ );
+ } else {
+ updateDocumentInOpenSCD(this, event.detail.doc, event.detail.docName);
+ }
+ this.dialog.close();
+ }
+
+ render(): TemplateResult {
+ return html`
+ {
+ this.dispatchEvent(newPendingStateEvent(this.openDoc(event)));
+ }}
+ >
+
+
+
+ `;
}
+
+ static styles = css`
+ mwc-dialog {
+ --mdc-dialog-min-width: 23vw;
+ --mdc-dialog-max-width: 92vw;
+ }
+ `;
}
diff --git a/src/menu/CompasSave.ts b/src/menu/CompasSave.ts
index 4e798d62c..bfa892787 100644
--- a/src/menu/CompasSave.ts
+++ b/src/menu/CompasSave.ts
@@ -8,12 +8,15 @@ import {
} from 'lit-element';
import { translate } from 'lit-translate';
+import '@material/mwc-button';
+import '@material/mwc-dialog';
+import { Dialog } from '@material/mwc-dialog';
+
import { newPendingStateEvent } from '../foundation.js';
import CompasSaveElement from '../compas/CompasSave.js';
import '../compas/CompasSave.js';
-import { Dialog } from '@material/mwc-dialog';
export default class CompasSaveMenuPlugin extends LitElement {
@property()
@@ -23,7 +26,7 @@ export default class CompasSaveMenuPlugin extends LitElement {
@property()
docId?: string;
- @query('mwc-dialog')
+ @query('mwc-dialog#compas-save-dlg')
dialog!: Dialog;
@query('compas-save')
@@ -31,14 +34,7 @@ export default class CompasSaveMenuPlugin extends LitElement {
async run(): Promise {
await this.compasSaveElement.requestUpdate();
- this.dialog.open = true;
- }
-
- private async saveToCoMPAS(): Promise {
- const success = await this.compasSaveElement.saveToCompas();
- if (success) {
- this.dialog.close();
- }
+ this.dialog.show();
}
render(): TemplateResult {
@@ -53,6 +49,9 @@ export default class CompasSaveMenuPlugin extends LitElement {
.doc="${this.doc}"
.docName="${this.docName}"
.docId="${this.docId}"
+ @doc-saved=${() => {
+ this.dialog.close();
+ }}
>
{
if (this.compasSaveElement.valid()) {
- this.dispatchEvent(newPendingStateEvent(this.saveToCoMPAS()));
+ this.dispatchEvent(
+ newPendingStateEvent(this.compasSaveElement.saveToCompas())
+ );
}
}}
>
diff --git a/src/menu/CompasSaveAs.ts b/src/menu/CompasSaveAs.ts
index b4407ba26..e065c2f82 100644
--- a/src/menu/CompasSaveAs.ts
+++ b/src/menu/CompasSaveAs.ts
@@ -8,12 +8,15 @@ import {
} from 'lit-element';
import { translate } from 'lit-translate';
+import '@material/mwc-button';
+import '@material/mwc-dialog';
+import { Dialog } from '@material/mwc-dialog';
+
import { newPendingStateEvent } from '../foundation.js';
import CompasSaveElement from '../compas/CompasSave.js';
import '../compas/CompasSave.js';
-import { Dialog } from '@material/mwc-dialog';
export default class CompasSaveAsMenuPlugin extends LitElement {
@property()
@@ -21,21 +24,15 @@ export default class CompasSaveAsMenuPlugin extends LitElement {
@property()
docName!: string;
- @query('mwc-dialog')
+ @query('mwc-dialog#compas-save-as-dlg')
dialog!: Dialog;
@query('compas-save')
compasSaveElement!: CompasSaveElement;
async run(): Promise {
- this.dialog.open = true;
- }
-
- private async saveToCoMPAS(): Promise {
- const success = await this.compasSaveElement.saveToCompas();
- if (success) {
- this.dialog.close();
- }
+ await this.compasSaveElement.requestUpdate();
+ this.dialog.show();
}
render(): TemplateResult {
@@ -46,7 +43,13 @@ export default class CompasSaveAsMenuPlugin extends LitElement {
${!this.doc || !this.docName
? html``
: html`
-
+ {
+ this.dialog.close();
+ }}
+ >
{
if (this.compasSaveElement.valid()) {
- this.dispatchEvent(newPendingStateEvent(this.saveToCoMPAS()));
+ this.dispatchEvent(
+ newPendingStateEvent(this.compasSaveElement.saveToCompas())
+ );
}
}}
>
diff --git a/src/menu/CompasUpdateSubstation.ts b/src/menu/CompasUpdateSubstation.ts
index 2706fba07..f0ac105b7 100644
--- a/src/menu/CompasUpdateSubstation.ts
+++ b/src/menu/CompasUpdateSubstation.ts
@@ -18,7 +18,7 @@ export default class CompasUpdateSubstationMenuPlugin extends LitElement {
title: get('compas.updateSubstation.title'),
content: [
html` {
+ @doc-retrieved=${(evt: DocRetrievedEvent) => {
mergeSubstation(this, this.doc, evt.detail.doc);
this.dispatchEvent(newWizardEvent());
}}
diff --git a/src/oscd-filter-button.ts b/src/oscd-filter-button.ts
index 424938e06..c3135f95f 100644
--- a/src/oscd-filter-button.ts
+++ b/src/oscd-filter-button.ts
@@ -26,6 +26,8 @@ export class FilterButton extends FilteredList {
header!: TemplateResult | string;
@property()
icon!: string;
+ @property({ type: Boolean })
+ disabled = false;
@query('#filterDialog')
private filterDialog!: Dialog;
@@ -48,7 +50,11 @@ export class FilterButton extends FilteredList {
render(): TemplateResult {
return html`
-
+
+
+
+
+
+
+
+
+ [close]
+
+
+`;
+/* end snapshot oscd-filter-button is disabled looks like its latest snapshot */
+
diff --git a/test/unit/compas/CompasSclDataServiceResponses.ts b/test/unit/compas/CompasSclDataServiceResponses.ts
index a2d7b3f2b..a70996c1d 100644
--- a/test/unit/compas/CompasSclDataServiceResponses.ts
+++ b/test/unit/compas/CompasSclDataServiceResponses.ts
@@ -1,5 +1,5 @@
-import {SDS_NAMESPACE} from "../../../src/compas-services/CompasSclDataService.js";
-import sinon, {SinonStub} from "sinon";
+import { SDS_NAMESPACE } from '../../../src/compas-services/CompasSclDataService.js';
+import sinon, { SinonStub } from 'sinon';
export const TYPE_ENTRY_ELEMENT_NAME = 'Type';
export const BASIC_TYPE_LIST_RESPONSE = `
@@ -28,6 +28,23 @@ export const BASIC_ITEM_LIST_RESPONSE = `
1.3.0
`;
+export const ITEM_LIST_WITH_LABELS_RESPONSE = `
+
+ -
+ 9883eabb-2e3c-471c-9036-95045d01e3fc
+ Station-Utrecht-0001
+ 2.1.0
+
+
+
+ -
+ 771d8940-9024-4c8b-a103-9566f1ba845e
+ Station-Amsterdam-0001
+ 1.3.0
+
+
+
+ `;
export const VERSION_ENTRY_ELEMENT_NAME = 'HistoryItem';
export const BASIC_VERSIONS_LIST_RESPONSE = `
@@ -57,15 +74,17 @@ export const BASIC_VERSIONS_LIST_RESPONSE = `
`;
-export function stubFetchResponseFunction(element: any,
- functionName: string,
- response: string | undefined,
- listElementName: string,
- callback: (result: Element[]) => any): SinonStub {
+export function stubFetchResponseFunction(
+ element: any,
+ functionName: string,
+ response: string | undefined,
+ listElementName: string,
+ callback: (result: Element[]) => any
+): SinonStub {
return sinon.stub(element, functionName).callsFake(() => {
if (response) {
const parser = new DOMParser();
- const document = parser.parseFromString(response, "text/xml");
+ const document = parser.parseFromString(response, 'text/xml');
callback(Array.from(document.querySelectorAll(listElementName) ?? []));
} else {
callback([]);
diff --git a/test/unit/compas/CompasSclList.test.ts b/test/unit/compas/CompasSclList.test.ts
index 97a7fb8c6..b7ee5c851 100644
--- a/test/unit/compas/CompasSclList.test.ts
+++ b/test/unit/compas/CompasSclList.test.ts
@@ -5,6 +5,7 @@ import { ListItem } from '@material/mwc-list/mwc-list-item';
import {
BASIC_ITEM_LIST_RESPONSE,
ITEM_ENTRY_ELEMENT_NAME,
+ ITEM_LIST_WITH_LABELS_RESPONSE,
stubFetchResponseFunction,
} from './CompasSclDataServiceResponses.js';
import { CompasSclList } from '../../../src/compas/CompasSclList.js';
@@ -17,7 +18,7 @@ describe('compas-scl-list', () => {
let element: CompasSclList;
let stub: SinonStub;
- describe('show-loading', () => {
+ describe('when list still needs to be loaded', () => {
beforeEach(async () => {
element = fixtureSync(
html``
@@ -45,7 +46,7 @@ describe('compas-scl-list', () => {
});
});
- describe('no-items-in-list', () => {
+ describe('when there are no items found in CoMPAS', () => {
beforeEach(async () => {
element = fixtureSync(
html``
@@ -57,12 +58,12 @@ describe('compas-scl-list', () => {
undefined,
ITEM_ENTRY_ELEMENT_NAME,
(result: Element[]) => {
- element.scls = result;
+ element['items'] = result;
}
);
await element;
- await waitUntil(() => element.scls !== undefined);
+ await waitUntil(() => element['items'] !== undefined);
});
afterEach(() => {
@@ -75,7 +76,7 @@ describe('compas-scl-list', () => {
});
});
- describe('after-list-loaded', () => {
+ describe('when there items without labels', () => {
beforeEach(async () => {
element = fixtureSync(
html``
@@ -87,12 +88,12 @@ describe('compas-scl-list', () => {
BASIC_ITEM_LIST_RESPONSE,
ITEM_ENTRY_ELEMENT_NAME,
(result: Element[]) => {
- element.scls = result;
+ element['items'] = result;
}
);
await element;
- await waitUntil(() => element.scls !== undefined);
+ await waitUntil(() => element['items'] !== undefined);
});
afterEach(() => {
@@ -101,16 +102,22 @@ describe('compas-scl-list', () => {
it('has 2 item entries', () => {
expect(
- element.shadowRoot!.querySelectorAll('mwc-list > mwc-list-item')
+ element.shadowRoot!.querySelectorAll('filtered-list > mwc-list-item')
).to.have.length(2);
});
+ it('filter button for labels is disabled', () => {
+ expect(
+ element.shadowRoot!.querySelector('oscd-filter-button#labelsFilter')
+ ).to.have.attribute('disabled');
+ });
+
it('selecting the first row will cause open scl method to be called', async () => {
const eventSpy = sinon.spy();
- element.addEventListener('sclSelected', eventSpy);
+ element.addEventListener('scl-selected', eventSpy);
((
- element.shadowRoot!.querySelectorAll('mwc-list > mwc-list-item')[0]
+ element.shadowRoot!.querySelectorAll('filtered-list > mwc-list-item')[0]
)).click();
await element.updateComplete;
@@ -122,4 +129,94 @@ describe('compas-scl-list', () => {
sinon.assert.calledOnce(stub);
});
});
+
+ describe('when there items with labels', () => {
+ beforeEach(async () => {
+ element = fixtureSync(
+ html``
+ );
+
+ stub = stubFetchResponseFunction(
+ element,
+ FETCH_FUNCTION,
+ ITEM_LIST_WITH_LABELS_RESPONSE,
+ ITEM_ENTRY_ELEMENT_NAME,
+ (result: Element[]) => {
+ element['items'] = result;
+
+ const labels = Array.from(
+ new Set(
+ result
+ .map(item => Array.from(item.querySelectorAll('Label')))
+ .flatMap(label => label)
+ .filter(label => !!label)
+ .map(label => label!.textContent)
+ .filter(labelValue => !!labelValue) as string[]
+ )
+ );
+ if (labels) {
+ element['labels'] = labels;
+ element['selectedLabels'] = labels;
+ }
+ }
+ );
+
+ await element;
+ await waitUntil(() => element['items'] !== undefined);
+ });
+
+ afterEach(() => {
+ sinon.restore();
+ });
+
+ it('has 3 labels found', () => {
+ expect(element['labels']).to.have.length(3);
+ expect(element['selectedLabels']).to.have.length(3);
+ });
+
+ it('filter button for labels is enabled', () => {
+ expect(
+ element.shadowRoot!.querySelector('oscd-filter-button#labelsFilter')
+ ).to.have.not.attribute('disabled');
+ });
+
+ it('has 2 item entries', () => {
+ expect(
+ element.shadowRoot!.querySelectorAll('filtered-list > mwc-list-item')
+ ).to.have.length(2);
+ });
+
+ it('when filtering on labels only 1 item is shown', async () => {
+ const filterButton = (
+ element.shadowRoot!.querySelector('oscd-filter-button#labelsFilter')
+ );
+ ((
+ filterButton.shadowRoot!.querySelector('mwc-icon-button')
+ )).click();
+ await element.updateComplete;
+
+ Array.from(
+ element.shadowRoot!.querySelectorAll(
+ 'oscd-filter-button#labelsFilter > mwc-check-list-item'
+ )
+ )
+ .filter(element => element.getAttribute('value') !== 'Amsterdam')
+ .forEach(element => (element).click());
+ ((
+ filterButton.shadowRoot!.querySelector(
+ 'mwc-button[slot="primaryAction"]'
+ )
+ )).click();
+ await element.updateComplete;
+
+ expect(
+ element.shadowRoot!.querySelectorAll('filtered-list > mwc-list-item')
+ ).to.have.length(1);
+ });
+
+ it('looks like the latest snapshot', async () => {
+ await expect(element).shadowDom.to.equalSnapshot();
+ sinon.assert.calledOnce(stub);
+ });
+ });
});
diff --git a/test/unit/compas/__snapshots__/CompasSclList.test.snap.js b/test/unit/compas/__snapshots__/CompasSclList.test.snap.js
index f3959e5bc..3547b4908 100644
--- a/test/unit/compas/__snapshots__/CompasSclList.test.snap.js
+++ b/test/unit/compas/__snapshots__/CompasSclList.test.snap.js
@@ -1,14 +1,16 @@
/* @web/test-runner snapshot v1 */
export const snapshots = {};
-snapshots["compas-scl-list show-loading looks like the latest snapshot"] =
-`
+snapshots[
+ 'compas-scl-list when list still needs to be loaded looks like the latest snapshot'
+] = `
`;
-/* end snapshot compas-scl-list show-loading looks like the latest snapshot */
+/* end snapshot compas-scl-list when list still needs to be loaded looks like the latest snapshot */
-snapshots["compas-scl-list no-items-in-list looks like the latest snapshot"] =
-`
+snapshots[
+ 'compas-scl-list when there are no items found in CoMPAS looks like the latest snapshot'
+] = `
`;
-/* end snapshot compas-scl-list no-items-in-list looks like the latest snapshot */
+/* end snapshot compas-scl-list when there are no items found in CoMPAS looks like the latest snapshot */
-snapshots["compas-scl-list after-list-loaded looks like the latest snapshot"] =
-`
+snapshots[
+ 'compas-scl-list when there items without labels looks like the latest snapshot'
+] = `
+
+ [compas.sclFilter]
+
+
+
+
+
Station-Utrecht-0002 (1.3.0)
-
+
`;
-/* end snapshot compas-scl-list after-list-loaded looks like the latest snapshot */
+/* end snapshot compas-scl-list when there items without labels looks like the latest snapshot */
+snapshots[
+ 'compas-scl-list when there items with labels looks like the latest snapshot'
+] = `
+
+ [compas.sclFilter]
+
+
+
+ Netherlands
+
+
+ Utrecht
+
+
+ Amsterdam
+
+
+
+
+
+ Station-Utrecht-0001 (2.1.0)
+
+
+ Station-Amsterdam-0001 (1.3.0)
+
+
+`;
+/* end snapshot compas-scl-list when there items with labels looks like the latest snapshot */
diff --git a/test/unit/menu/CompasOpen.test.ts b/test/unit/menu/CompasOpen.test.ts
new file mode 100644
index 000000000..0bc6e4024
--- /dev/null
+++ b/test/unit/menu/CompasOpen.test.ts
@@ -0,0 +1,19 @@
+import { expect, fixture, html } from '@open-wc/testing';
+
+import CompasOpenMenuPlugin from '../../../src/menu/CompasOpen.js';
+
+describe('compas-open-menu', () => {
+ if (customElements.get('compare-open-menu') === undefined)
+ customElements.define('compare-open-menu', CompasOpenMenuPlugin);
+
+ let plugin: CompasOpenMenuPlugin;
+
+ beforeEach(async () => {
+ plugin = await fixture(html``);
+ await plugin.updateComplete;
+ });
+
+ it('looks like the latest snapshot', async () => {
+ await expect(plugin).shadowDom.to.equalSnapshot();
+ });
+});
diff --git a/test/unit/menu/__snapshots__/CompasOpen.test.snap.js b/test/unit/menu/__snapshots__/CompasOpen.test.snap.js
new file mode 100644
index 000000000..88597b1d1
--- /dev/null
+++ b/test/unit/menu/__snapshots__/CompasOpen.test.snap.js
@@ -0,0 +1,22 @@
+/* @web/test-runner snapshot v1 */
+export const snapshots = {};
+
+snapshots["compas-open-menu looks like the latest snapshot"] =
+`
+
+
+
+
+
+`;
+/* end snapshot compas-open-menu looks like the latest snapshot */
+
diff --git a/test/unit/oscd-filter-button.test.ts b/test/unit/oscd-filter-button.test.ts
index 7379b16be..32566f6b5 100644
--- a/test/unit/oscd-filter-button.test.ts
+++ b/test/unit/oscd-filter-button.test.ts
@@ -141,4 +141,33 @@ describe('oscd-filter-button', () => {
await expect(element).shadowDom.to.equalSnapshot();
});
});
+
+ describe('is disabled', () => {
+ beforeEach(async () => {
+ element = await fixture(
+ html`
+ ${Array.from(listItems).map(
+ item =>
+ html`
+ ${item.prim}
+ `
+ )}
+ `
+ );
+ await element.requestUpdate();
+ await element.updateComplete;
+ });
+
+ it('looks like its latest snapshot', async () => {
+ await expect(element).shadowDom.to.equalSnapshot();
+ });
+ });
});
From a1f2f6a6792bfc06e13e1cd67934b80ffe797b41 Mon Sep 17 00:00:00 2001
From: Dennis Labordus
Date: Tue, 27 Sep 2022 08:58:41 +0200
Subject: [PATCH 2/3] Sorted list of labels.
Signed-off-by: Dennis Labordus
---
src/compas/CompasSclList.ts | 3 ++-
test/unit/compas/CompasSclList.test.ts | 5 ++++-
.../compas/__snapshots__/CompasSclList.test.snap.js | 12 ++++++------
3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/compas/CompasSclList.ts b/src/compas/CompasSclList.ts
index 767ab1cdc..90244b201 100644
--- a/src/compas/CompasSclList.ts
+++ b/src/compas/CompasSclList.ts
@@ -98,7 +98,8 @@ export class CompasSclList extends LitElement {
new Set(
Array.from(xmlResponse.querySelectorAll('Label') ?? [])
.map(element => element.textContent)
- .filter(value => !!value)
+ .filter(label => !!label)
+ .sort((label1, label2) => label1!.localeCompare(label2!))
)
) as string[];
this.selectedLabels = this.labels;
diff --git a/test/unit/compas/CompasSclList.test.ts b/test/unit/compas/CompasSclList.test.ts
index b7ee5c851..0d00ea9b2 100644
--- a/test/unit/compas/CompasSclList.test.ts
+++ b/test/unit/compas/CompasSclList.test.ts
@@ -151,7 +151,10 @@ describe('compas-scl-list', () => {
.flatMap(label => label)
.filter(label => !!label)
.map(label => label!.textContent)
- .filter(labelValue => !!labelValue) as string[]
+ .filter(labelValue => !!labelValue)
+ .sort((label1, label2) =>
+ label1!.localeCompare(label2!)
+ ) as string[]
)
);
if (labels) {
diff --git a/test/unit/compas/__snapshots__/CompasSclList.test.snap.js b/test/unit/compas/__snapshots__/CompasSclList.test.snap.js
index 3547b4908..a6f73442e 100644
--- a/test/unit/compas/__snapshots__/CompasSclList.test.snap.js
+++ b/test/unit/compas/__snapshots__/CompasSclList.test.snap.js
@@ -74,9 +74,9 @@ snapshots[
mwc-list-item=""
selected=""
tabindex="0"
- value="Netherlands"
+ value="Amsterdam"
>
- Netherlands
+ Amsterdam
- Utrecht
+ Netherlands
- Amsterdam
+ Utrecht
From ebe32fc506a47517f0bf139314b01f9aafc25e1b Mon Sep 17 00:00:00 2001
From: Dennis Labordus
Date: Tue, 27 Sep 2022 12:11:17 +0200
Subject: [PATCH 3/3] Used 2 different icons to show filterin is on/off.
Signed-off-by: Dennis Labordus
---
src/compas/CompasSclList.ts | 20 ++-
test/unit/compas/CompasSclList.test.ts | 29 +++-
.../__snapshots__/CompasSclList.test.snap.js | 150 ++++++++++++++++--
3 files changed, 176 insertions(+), 23 deletions(-)
diff --git a/src/compas/CompasSclList.ts b/src/compas/CompasSclList.ts
index 90244b201..e5bae67a4 100644
--- a/src/compas/CompasSclList.ts
+++ b/src/compas/CompasSclList.ts
@@ -10,6 +10,7 @@ import {
} from 'lit-element';
import { translate } from 'lit-translate';
+import '@material/mwc-icon';
import '@material/mwc-list';
import '@material/mwc-list/mwc-list-item';
@@ -117,11 +118,11 @@ export class CompasSclList extends LitElement {
`;
}
const filteredItems = this.filteredItems;
- return html`
+ return html`
+
${translate('compas.sclFilter')}
+
+
+ ${this.labels.length != this.selectedLabels.length
+ ? 'label'
+ : 'label_off'}
+
+
${this.labels.map(label => {
- return html`
@@ -156,7 +165,7 @@ export class CompasSclList extends LitElement {
const version =
item.getElementsByTagNameNS(SDS_NAMESPACE, 'Version').item(0)!
.textContent ?? '';
- return html` this.dispatchEvent(newSclSelectedEvent(id))}
>
@@ -168,7 +177,8 @@ export class CompasSclList extends LitElement {
${translate('compas.noFilteredScls')}
- `} `;
+ `}
+ `;
}
static styles = css`
diff --git a/test/unit/compas/CompasSclList.test.ts b/test/unit/compas/CompasSclList.test.ts
index 0d00ea9b2..28391eb1c 100644
--- a/test/unit/compas/CompasSclList.test.ts
+++ b/test/unit/compas/CompasSclList.test.ts
@@ -76,7 +76,7 @@ describe('compas-scl-list', () => {
});
});
- describe('when there items without labels', () => {
+ describe('when there are items without labels', () => {
beforeEach(async () => {
element = fixtureSync(
html``
@@ -130,7 +130,7 @@ describe('compas-scl-list', () => {
});
});
- describe('when there items with labels', () => {
+ describe('when there are items with labels', () => {
beforeEach(async () => {
element = fixtureSync(
html``
@@ -215,6 +215,31 @@ describe('compas-scl-list', () => {
expect(
element.shadowRoot!.querySelectorAll('filtered-list > mwc-list-item')
).to.have.length(1);
+ await expect(element).shadowDom.to.equalSnapshot();
+ });
+
+ it('when filtering on labels and all items are hidden', async () => {
+ const filterButton = (
+ element.shadowRoot!.querySelector('oscd-filter-button#labelsFilter')
+ );
+ ((
+ filterButton.shadowRoot!.querySelector('mwc-icon-button')
+ )).click();
+ await element.updateComplete;
+
+ Array.from(
+ element.shadowRoot!.querySelectorAll(
+ 'oscd-filter-button#labelsFilter > mwc-check-list-item'
+ )
+ ).forEach(element => (element).click());
+ ((
+ filterButton.shadowRoot!.querySelector(
+ 'mwc-button[slot="primaryAction"]'
+ )
+ )).click();
+ await element.updateComplete;
+
+ await expect(element).shadowDom.to.equalSnapshot();
});
it('looks like the latest snapshot', async () => {
diff --git a/test/unit/compas/__snapshots__/CompasSclList.test.snap.js b/test/unit/compas/__snapshots__/CompasSclList.test.snap.js
index a6f73442e..abc920b79 100644
--- a/test/unit/compas/__snapshots__/CompasSclList.test.snap.js
+++ b/test/unit/compas/__snapshots__/CompasSclList.test.snap.js
@@ -1,16 +1,14 @@
/* @web/test-runner snapshot v1 */
export const snapshots = {};
-snapshots[
- 'compas-scl-list when list still needs to be loaded looks like the latest snapshot'
-] = `
+snapshots["compas-scl-list when list still needs to be loaded looks like the latest snapshot"] =
+`
`;
/* end snapshot compas-scl-list when list still needs to be loaded looks like the latest snapshot */
-snapshots[
- 'compas-scl-list when there are no items found in CoMPAS looks like the latest snapshot'
-] = `
+snapshots["compas-scl-list when there are no items found in CoMPAS looks like the latest snapshot"] =
+`
+snapshots["compas-scl-list when there are items without labels looks like the latest snapshot"] =
+`
[compas.sclFilter]
+
+
+ label_off
+
+
@@ -55,19 +56,135 @@ snapshots[
`;
-/* end snapshot compas-scl-list when there items without labels looks like the latest snapshot */
+/* end snapshot compas-scl-list when there are items without labels looks like the latest snapshot */
-snapshots[
- 'compas-scl-list when there items with labels looks like the latest snapshot'
-] = `
+snapshots["compas-scl-list when there are items with labels when filtering on labels only 1 item is shown"] =
+`
[compas.sclFilter]
+
+
+ label
+
+
+
+ Amsterdam
+
+
+ Netherlands
+
+
+ Utrecht
+
+
+
+
+
+ Station-Amsterdam-0001 (1.3.0)
+
+
+`;
+/* end snapshot compas-scl-list when there are items with labels when filtering on labels only 1 item is shown */
+
+snapshots["compas-scl-list when there are items with labels when filtering on labels and all items are hidden"] =
+`
+
+ [compas.sclFilter]
+
+
+
+
+ label
+
+
+
+ Amsterdam
+
+
+ Netherlands
+
+
+ Utrecht
+
+
+
+
+
+
+ [compas.noFilteredScls]
+
+
+
+`;
+/* end snapshot compas-scl-list when there are items with labels when filtering on labels and all items are hidden */
+
+snapshots["compas-scl-list when there are items with labels looks like the latest snapshot"] =
+`
+
+ [compas.sclFilter]
+
+
+
+
+ label_off
+
+
`;
-/* end snapshot compas-scl-list when there items with labels looks like the latest snapshot */
+/* end snapshot compas-scl-list when there are items with labels looks like the latest snapshot */
+