Skip to content

Commit

Permalink
feat(editors/publisher): add read only data set element editor (#911)
Browse files Browse the repository at this point in the history
* feat(editors/publisher): add read only data set element editor

* refactor(editors/publisher): resolve review comments
  • Loading branch information
JakobVogelsang authored Jul 27, 2022
1 parent ed0e71d commit 45b5440
Show file tree
Hide file tree
Showing 19 changed files with 1,640 additions and 494 deletions.
2 changes: 1 addition & 1 deletion src/editors/Publisher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export default class PublisherPlugin extends LitElement {
}
.publishertypeselector {
margin: 4px 8px 16px;
margin: 4px 8px 8px;
background-color: var(--mdc-theme-surface);
width: calc(100% - 16px);
justify-content: space-around;
Expand Down
86 changes: 67 additions & 19 deletions src/editors/publisher/data-set-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,63 @@ import {
html,
LitElement,
property,
query,
state,
TemplateResult,
} from 'lit-element';
import { compareNames, identity } from '../../foundation.js';
import { translate } from 'lit-translate';

import '@material/mwc-button';
import '@material/mwc-list/mwc-list-item';
import { Button } from '@material/mwc-button';
import { ListItem } from '@material/mwc-list/mwc-list-item';

import './data-set-element-editor.js';
import '../../filtered-list.js';
import { FilteredList } from '../../filtered-list.js';

import { compareNames, identity, selector } from '../../foundation.js';
import { styles } from './foundation.js';

@customElement('data-set-editor')
export class DataSetEditor extends LitElement {
/** The document being edited as provided to plugins by [[`OpenSCD`]]. */
@property({ attribute: false })
doc!: XMLDocument;

renderList(): TemplateResult {
@state()
selectedDataSet?: Element;

@query('.selectionlist') selectionList!: FilteredList;
@query('mwc-button') selectDataSetButton!: Button;

private selectDataSet(evt: Event): void {
const id = ((evt.target as FilteredList).selected as ListItem).value;
const dataSet = this.doc.querySelector(selector('DataSet', id));

if (dataSet) {
this.selectedDataSet = dataSet;
(evt.target as FilteredList).classList.add('hidden');
this.selectDataSetButton.classList.remove('hidden');
}
}

private renderElementEditorContainer(): TemplateResult {
if (this.selectedDataSet)
return html`<div class="elementeditorcontainer">
<data-set-element-editor
.element=${this.selectedDataSet}
></data-set-element-editor>
</div>`;

return html``;
}

private renderSelectionList(): TemplateResult {
return html`<filtered-list
activatable
@action=${this.selectDataSet}
class="selectionlist"
>${Array.from(this.doc.querySelectorAll('IED'))
.sort(compareNames)
.flatMap(ied => {
Expand All @@ -36,10 +81,10 @@ export class DataSetEditor extends LitElement {
<li divider role="separator"></li>`;
const dataSets = Array.from(ied.querySelectorAll('DataSet')).map(
reportCb =>
html`<mwc-list-item twoline value="${identity(reportCb)}"
><span>${reportCb.getAttribute('name')}</span
><span slot="secondary">${identity(reportCb)}</span>
dataSet =>
html`<mwc-list-item twoline value="${identity(dataSet)}"
><span>${dataSet.getAttribute('name')}</span
><span slot="secondary">${identity(dataSet)}</span>
</mwc-list-item>`
);
Expand All @@ -48,22 +93,25 @@ export class DataSetEditor extends LitElement {
>`;
}

private renderToggleButton(): TemplateResult {
return html`<mwc-button
outlined
label="${translate('publisher.selectbutton', { type: 'DataSet' })}"
@click=${() => {
this.selectionList.classList.remove('hidden');
this.selectDataSetButton.classList.add('hidden');
}}
></mwc-button>`;
}

render(): TemplateResult {
return html`${this.renderList()}`;
return html`${this.renderToggleButton()}
<div class="content">
${this.renderSelectionList()}${this.renderElementEditorContainer()}
</div>`;
}

static styles = css`
filtered-list {
margin: 4px 8px 16px;
background-color: var(--mdc-theme-surface);
}
.listitem.header {
font-weight: 500;
}
mwc-list-item.hidden[noninteractive] + li[divider] {
display: none;
}
${styles}
`;
}
117 changes: 117 additions & 0 deletions src/editors/publisher/data-set-element-editor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import {
css,
customElement,
html,
LitElement,
property,
state,
TemplateResult,
} from 'lit-element';
import { translate } from 'lit-translate';

import '@material/mwc-list/mwc-list-item';

import '../../wizard-textfield.js';
import '../../filtered-list.js';

import { identity } from '../../foundation.js';

@customElement('data-set-element-editor')
export class DataSetElementEditor extends LitElement {
@property({ attribute: false })
element!: Element | null;

@state()
private get name(): string | null {
return this.element ? this.element.getAttribute('name') : 'UNDEFINED';
}
@state()
private get desc(): string | null {
return this.element ? this.element.getAttribute('desc') : 'UNDEFINED';
}

render(): TemplateResult {
if (this.element)
return html`<div class="content">
<h2>
<div>DataSet</div>
<div class="headersubtitle">${identity(this.element)}</div>
</h2>
<wizard-textfield
label="name"
.maybeValue=${this.name}
helper="${translate('scl.name')}"
required
>
</wizard-textfield>
<wizard-textfield
label="desc"
.maybeValue=${this.desc}
helper="${translate('scl.desc')}"
nullable
>
</wizard-textfield>
<filtered-list
>${Array.from(this.element.querySelectorAll('FCDA')).map(fcda => {
const [ldInst, prefix, lnClass, lnInst, doName, daName] = [
'ldInst',
'prefix',
'lnClass',
'lnInst',
'doName',
'daName',
].map(attributeName => fcda.getAttribute(attributeName) ?? '');
return html`<mwc-list-item
selected
twoline
value="${identity(fcda)}"
><span>${doName + '.' + daName}</span
><span slot="secondary"
>${ldInst + '/' + prefix + lnClass + lnInst}</span
>
</mwc-list-item>`;
})}</filtered-list
>
</div>`;

return html`<div class="content">
<h2>${translate('publisher.nodataset')}</h2>
</div>`;
}

static styles = css`
.content {
display: flex;
flex-direction: column;
background-color: var(--mdc-theme-surface);
}
.content > * {
display: block;
margin: 4px 8px 16px;
}
h2 {
color: var(--mdc-theme-on-surface);
font-family: 'Roboto', sans-serif;
font-weight: 300;
margin: 0px;
padding-left: 0.3em;
transition: background-color 150ms linear;
}
.headersubtitle {
font-size: 16px;
font-weight: 200;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
*[iconTrailing='search'] {
--mdc-shape-small: 28px;
}
`;
}
70 changes: 70 additions & 0 deletions src/editors/publisher/foundation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { css } from 'lit-element';

export const styles = css`
.content {
display: flex;
height: calc(100vh - 184px);
}
.selectionlist {
flex: 35%;
margin: 4px 4px 4px 8px;
background-color: var(--mdc-theme-surface);
overflow-y: scroll;
}
.elementeditorcontainer {
flex: 65%;
margin: 4px 8px 4px 4px;
background-color: var(--mdc-theme-surface);
overflow-y: scroll;
display: flex;
}
data-set-element-editor {
width: calc(100% - 6px);
}
.listitem.header {
font-weight: 500;
}
mwc-list-item.hidden[noninteractive] + li[divider] {
display: none;
}
mwc-button {
display: none;
}
@media (max-width: 599px) {
.content {
height: 100%;
}
.selectionlist {
position: absolute;
width: calc(100% - 32px);
height: auto;
top: 110px;
left: 8px;
background-color: var(--mdc-theme-surface);
z-index: 1;
box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2);
}
data-set-element-editor {
width: calc(100% - 16px);
}
.selectionlist.hidden {
display: none;
}
mwc-button {
display: flex;
margin: 4px 8px 8px;
}
}
`;
Loading

0 comments on commit 45b5440

Please sign in to comment.