Skip to content

Commit

Permalink
feat(wizards/eqsubfunction): add create wizard (#757)
Browse files Browse the repository at this point in the history
  • Loading branch information
JakobVogelsang committed May 19, 2022
1 parent 322305a commit 64bf40a
Show file tree
Hide file tree
Showing 10 changed files with 664 additions and 4 deletions.
65 changes: 64 additions & 1 deletion src/editors/substation/eq-function-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,34 @@ import {
property,
customElement,
state,
query,
} from 'lit-element';
import { translate } from 'lit-translate';

import '@material/mwc-icon-button';
import '@material/mwc-list/mwc-list-item';
import '@material/mwc-menu';
import { IconButton } from '@material/mwc-icon-button';
import { ListItem } from '@material/mwc-list/mwc-list-item';
import { Menu } from '@material/mwc-menu';

import '../../action-pane.js';
import './eq-sub-function-editor.js';
import { getChildElementsByTagName } from '../../foundation.js';
import {
getChildElementsByTagName,
newWizardEvent,
SCLTag,
tags,
} from '../../foundation.js';
import { emptyWizard, wizards } from '../../wizards/wizard-library.js';

function childTags(element: Element | null | undefined): SCLTag[] {
if (!element) return [];

return tags[<SCLTag>element.tagName].children.filter(
child => wizards[child].create !== emptyWizard
);
}

/** Pane rendering `EqFunction` element with its children */
@customElement('eq-function-editor')
Expand All @@ -26,6 +49,19 @@ export class EqFunctionEditor extends LitElement {
return `${name}${desc ? ` - ${desc}` : ''}${type ? ` (${type})` : ''}`;
}

@query('mwc-menu') addMenu!: Menu;
@query('mwc-icon-button[icon="playlist_add"]') addButton!: IconButton;

private openCreateWizard(tagName: string): void {
const wizard = wizards[<SCLTag>tagName].create(this.element!);

if (wizard) this.dispatchEvent(newWizardEvent(wizard));
}

firstUpdated(): void {
this.addMenu.anchor = <HTMLElement>this.addButton;
}

private renderEqSubFunctions(): TemplateResult {
const eqSubFunctions = getChildElementsByTagName(
this.element,
Expand All @@ -39,12 +75,39 @@ export class EqFunctionEditor extends LitElement {
)}`;
}

private renderAddButtons(): TemplateResult[] {
return childTags(this.element).map(
child =>
html`<mwc-list-item value="${child}"
><span>${child}</span></mwc-list-item
>`
);
}

render(): TemplateResult {
return html`<action-pane
label="${this.header}"
icon="functions"
secondary
highlighted
><abbr
slot="action"
style="position:relative;"
title="${translate('add')}"
>
<mwc-icon-button
icon="playlist_add"
@click=${() => (this.addMenu.open = true)}
></mwc-icon-button
><mwc-menu
corner="BOTTOM_RIGHT"
menuCorner="END"
@selected=${(e: Event) => {
const tagName = (<ListItem>(<Menu>e.target).selected).value;
this.openCreateWizard(tagName);
}}
>${this.renderAddButtons()}</mwc-menu
></abbr
>${this.renderEqSubFunctions()}</action-pane
>`;
}
Expand Down
65 changes: 64 additions & 1 deletion src/editors/substation/eq-sub-function-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,34 @@ import {
property,
customElement,
state,
query,
} from 'lit-element';

import { translate } from 'lit-translate';

import '@material/mwc-icon-button';
import '@material/mwc-list/mwc-list-item';
import '@material/mwc-menu';
import { IconButton } from '@material/mwc-icon-button';
import { ListItem } from '@material/mwc-list/mwc-list-item';
import { Menu } from '@material/mwc-menu';

import '../../action-pane.js';
import { getChildElementsByTagName } from '../../foundation.js';
import {
getChildElementsByTagName,
newWizardEvent,
SCLTag,
tags,
} from '../../foundation.js';
import { emptyWizard, wizards } from '../../wizards/wizard-library.js';

function childTags(element: Element | null | undefined): SCLTag[] {
if (!element) return [];

return tags[<SCLTag>element.tagName].children.filter(
child => wizards[child].create !== emptyWizard
);
}
/** Pane rendering `EqSubFunction` element with its children */
@customElement('eq-sub-function-editor')
export class EqSubFunctionEditor extends LitElement {
Expand All @@ -25,6 +48,19 @@ export class EqSubFunctionEditor extends LitElement {
return `${name}${desc ? ` - ${desc}` : ''}${type ? ` (${type})` : ''}`;
}

@query('mwc-menu') addMenu!: Menu;
@query('mwc-icon-button[icon="playlist_add"]') addButton!: IconButton;

private openCreateWizard(tagName: string): void {
const wizard = wizards[<SCLTag>tagName].create(this.element!);

if (wizard) this.dispatchEvent(newWizardEvent(wizard));
}

firstUpdated(): void {
this.addMenu.anchor = <HTMLElement>this.addButton;
}

private renderEqSubFunctions(): TemplateResult {
const eqSubFunctions = getChildElementsByTagName(
this.element,
Expand All @@ -38,8 +74,35 @@ export class EqSubFunctionEditor extends LitElement {
)}`;
}

private renderAddButtons(): TemplateResult[] {
return childTags(this.element).map(
child =>
html`<mwc-list-item value="${child}"
><span>${child}</span></mwc-list-item
>`
);
}

render(): TemplateResult {
return html`<action-pane label="${this.header}" icon="functions" secondary
><abbr
slot="action"
style="position:relative;"
title="${translate('add')}"
>
<mwc-icon-button
icon="playlist_add"
@click=${() => (this.addMenu.open = true)}
></mwc-icon-button
><mwc-menu
corner="BOTTOM_RIGHT"
menuCorner="END"
@selected=${(e: Event) => {
const tagName = (<ListItem>(<Menu>e.target).selected).value;
this.openCreateWizard(tagName);
}}
>${this.renderAddButtons()}</mwc-menu
></abbr
>${this.renderEqSubFunctions()}</action-pane
>`;
}
Expand Down
56 changes: 56 additions & 0 deletions src/wizards/eqsubfunction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { get } from 'lit-translate';

import {
createElement,
getValue,
Wizard,
WizardActor,
WizardInputElement,
} from '../foundation.js';
import { contentFunctionWizard } from './function.js';

function createEqSubFunctionAction(parent: Element): WizardActor {
return (inputs: WizardInputElement[]) => {
const eqSubFunctionAttrs: Record<string, string | null> = {};
const eqSubFunctionKeys = ['name', 'desc', 'type'];
eqSubFunctionKeys.forEach(key => {
eqSubFunctionAttrs[key] = getValue(inputs.find(i => i.label === key)!);
});

const eqSubFunction = createElement(
parent.ownerDocument,
'EqSubFunction',
eqSubFunctionAttrs
);

return [{ new: { parent, element: eqSubFunction } }];
};
}

export function createEqSubFunctionWizard(parent: Element): Wizard {
const name = '';
const desc = null;
const type = null;
const reservedNames = Array.from(
parent.querySelectorAll('EqSubFunction')
).map(eqSubFunction => eqSubFunction.getAttribute('name')!);

return [
{
title: get('wizard.title.add', { tagName: 'EqSubFunction' }),
primary: {
icon: 'save',
label: get('save'),
action: createEqSubFunctionAction(parent),
},
content: [
...contentFunctionWizard({
name,
desc,
type,
reservedNames,
}),
],
},
];
}
4 changes: 2 additions & 2 deletions src/wizards/wizard-library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ import { editTrgOpsWizard } from './trgops.js';
import { createDaWizard } from './da.js';
import { editDAIWizard } from './dai.js';
import { createFunctionWizard } from './function.js';
import { createEqSubFunctionWizard } from './eqsubfunction.js';
import { createEqFunctionWizard } from './eqfunction.js';
import { createSubFunctionWizard } from './subfunction.js';


type SclElementWizard = (
element: Element,
instanceElement?: Element
Expand Down Expand Up @@ -195,7 +195,7 @@ export const wizards: Record<
},
EqSubFunction: {
edit: emptyWizard,
create: emptyWizard,
create: createEqSubFunctionWizard,
},
ExtRef: {
edit: emptyWizard,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { fixture, html, expect } from '@open-wc/testing';

import '../../../mock-wizard-editor.js';
import { MockWizardEditor } from '../../../mock-wizard-editor.js';

import '../../../../src/editors/substation/eq-function-editor.js';
import { EqFunctionEditor } from '../../../../src/editors/substation/eq-function-editor.js';
import { WizardTextField } from '../../../../src/wizard-textfield.js';

describe('eq-function-editor wizarding editing integration', () => {
describe('open create wizard for element EqSubFunction', () => {
let doc: XMLDocument;
let parent: MockWizardEditor;
let element: EqFunctionEditor | null;

let nameField: WizardTextField;
let primaryAction: HTMLElement;

beforeEach(async () => {
doc = await fetch('/test/testfiles/zeroline/functions.scd')
.then(response => response.text())
.then(str => new DOMParser().parseFromString(str, 'application/xml'));
parent = <MockWizardEditor>(
await fixture(
html`<mock-wizard-editor
><eq-function-editor
.element=${doc.querySelector(
'ConductingEquipment[name="QA1"] > EqFunction'
)}
></eq-function-editor
></mock-wizard-editor>`
)
);

element = parent.querySelector('eq-function-editor');

(<HTMLElement>(
element?.shadowRoot?.querySelector(
'mwc-list-item[value="EqSubFunction"]'
)
)).click();
await parent.updateComplete;

nameField = <WizardTextField>(
parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]')
);

primaryAction = <HTMLElement>(
parent.wizardUI.dialog?.querySelector(
'mwc-button[slot="primaryAction"]'
)
);
});

it('does not add EqSubFunction if name attribute is not unique', async () => {
expect(
doc.querySelector(
'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqSubFunc"]'
)
).to.exist;

nameField.value = 'myEqSubFunc';
primaryAction.click();
await parent.updateComplete;

expect(
doc.querySelectorAll(
'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqSubFunc"]'
).length
).to.equal(1);
});

it('does add EqFunction if name attribute is unique', async () => {
expect(
doc.querySelector(
'ConductingEquipment[name="QA1"] EqSubFunction[name="someNewEqSubFunction"]'
)
).to.not.exist;

nameField.value = 'someNewEqSubFunction';
await parent.updateComplete;
primaryAction.click();

expect(
doc.querySelector(
'ConductingEquipment[name="QA1"] EqSubFunction[name="someNewEqSubFunction"]'
)
).to.exist;
});
});
});
Loading

0 comments on commit 64bf40a

Please sign in to comment.