diff --git a/packages/compas-open-scd/src/addons/CompasSettings.ts b/packages/compas-open-scd/src/addons/CompasSettings.ts deleted file mode 100644 index df62437241..0000000000 --- a/packages/compas-open-scd/src/addons/CompasSettings.ts +++ /dev/null @@ -1,524 +0,0 @@ -import { - html, - property, - query, - TemplateResult, - customElement, - LitElement, - css, -} from 'lit-element'; -import { get, registerTranslateConfig, use } from 'lit-translate'; - -import '@material/mwc-button'; -import '@material/mwc-dialog'; -import '@material/mwc-formfield'; -import '@material/mwc-list/mwc-list-item'; -import '@material/mwc-select'; -import '@material/mwc-switch'; - -import { Dialog } from '@material/mwc-dialog'; -import { Select } from '@material/mwc-select'; -import { Switch } from '@material/mwc-switch'; - -import { getTheme } from '@openscd/open-scd/src/themes.js'; - -import { newLogEvent } from '@openscd/core/foundation/deprecated/history.js'; -import { - Settings, - SettingsUIEvent, - Language, - NsdVersions, - NsdVersion, - LoadNsdocEvent, - newLoadNsdocEvent -} from '@openscd/core/foundation/deprecated/settings.js'; -import { languages, loader } from '../translations/loader.js'; - -import '@openscd/open-scd/src/WizardDivider.js'; -import { WizardDialog } from '@openscd/open-scd/src/wizard-dialog.js'; - -import { - iec6185072, - iec6185073, - iec6185074, - iec6185081, -} from '@openscd/open-scd/src/foundation/nsd.js'; -import { initializeNsdoc, Nsdoc } from '@openscd/open-scd/src/foundation/nsdoc.js'; - -export const defaults: Settings = { - language: 'en', - theme: 'light', - mode: 'safe', - showieds: 'off', - 'IEC 61850-7-2': undefined, - 'IEC 61850-7-3': undefined, - 'IEC 61850-7-4': undefined, - 'IEC 61850-8-1': undefined, -}; - -@customElement('compas-settings-addon') -export class CompasSettings extends LitElement { - /** Current [[`Settings`]] in `localStorage`, default to [[`defaults`]]. */ - @property() - get settings(): Settings { - return { - language: this.getSetting('language'), - theme: this.getSetting('theme'), - mode: this.getSetting('mode'), - showieds: this.getSetting('showieds'), - 'IEC 61850-7-2': this.getSetting('IEC 61850-7-2'), - 'IEC 61850-7-3': this.getSetting('IEC 61850-7-3'), - 'IEC 61850-7-4': this.getSetting('IEC 61850-7-4'), - 'IEC 61850-8-1': this.getSetting('IEC 61850-8-1'), - }; - } - /** Object containing all *.nsdoc files and a function extracting element's label form them*/ - @property({ attribute: false }) - nsdoc: Nsdoc = initializeNsdoc(); - - @property({ - type: Object, - }) - host!: HTMLElement; - - @property({ type: Boolean }) - nsdUploadButton = true; - - /** - * Get the versions of the current OpenSCD NSD files. - * @returns Current version, revision and release for all current OpenSCD NSD files. - */ - private async nsdVersions(): Promise { - const [nsd72, nsd73, nsd74, nsd81] = await Promise.all([ - iec6185072, - iec6185073, - iec6185074, - iec6185081, - ]); - const [nsd72Ns, nsd73Ns, nsd74Ns, nsd81Ns] = [ - nsd72.querySelector('NS'), - nsd73.querySelector('NS'), - nsd74.querySelector('NS'), - nsd81.querySelector('ServiceNS'), - ]; - - return { - 'IEC 61850-7-2': { - version: nsd72Ns?.getAttribute('version') ?? undefined, - revision: nsd72Ns?.getAttribute('revision') ?? undefined, - release: nsd72Ns?.getAttribute('release') ?? undefined, - }, - 'IEC 61850-7-3': { - version: nsd73Ns?.getAttribute('version') ?? undefined, - revision: nsd73Ns?.getAttribute('revision') ?? undefined, - release: nsd73Ns?.getAttribute('release') ?? undefined, - }, - 'IEC 61850-7-4': { - version: nsd74Ns?.getAttribute('version') ?? undefined, - revision: nsd74Ns?.getAttribute('revision') ?? undefined, - release: nsd74Ns?.getAttribute('release') ?? undefined, - }, - 'IEC 61850-8-1': { - version: nsd81Ns?.getAttribute('version') ?? undefined, - revision: nsd81Ns?.getAttribute('revision') ?? undefined, - release: nsd81Ns?.getAttribute('release') ?? undefined, - }, - }; - } - - @query('#settings') - settingsUI!: Dialog; - @query('#language') - languageUI!: Select; - @query('#dark') - darkThemeUI!: Switch; - @query('#mode') - modeUI!: Switch; - @query('#showieds') - showiedsUI!: Switch; - - @query('#nsdoc-file') - private nsdocFileUI!: HTMLInputElement; - - private getSetting(setting: T): Settings[T] { - return ( - localStorage.getItem(setting) ?? defaults[setting] - ); - } - - /** Update the `value` of `setting`, storing to `localStorage`. */ - setSetting(setting: T, value: Settings[T]): void { - localStorage.setItem(setting, (value)); - this.shadowRoot - ?.querySelector('wizard-dialog') - ?.requestUpdate(); - this.requestUpdate(); - } - - /** Remove the `setting` in `localStorage`. */ - removeSetting(setting: T): void { - localStorage.removeItem(setting); - this.shadowRoot - ?.querySelector('wizard-dialog') - ?.requestUpdate(); - this.requestUpdate(); - - this.nsdoc = initializeNsdoc(); // update nsdoc - } - - private onClosing(ae: CustomEvent<{ action: string } | null>): void { - if (ae.detail?.action === 'reset') { - Object.keys(this.settings).forEach(item => localStorage.removeItem(item)); - this.requestUpdate('settings'); - } else if (ae.detail?.action === 'save') { - this.setSetting('language', this.languageUI.value); - this.setSetting('theme', this.darkThemeUI.checked ? 'dark' : 'light'); - this.setSetting('mode', this.modeUI.checked ? 'pro' : 'safe'); - this.setSetting('showieds', this.showiedsUI.checked ? 'on' : 'off'); - this.requestUpdate('settings'); - } - } - - updated(changedProperties: Map): void { - super.updated(changedProperties); - if (changedProperties.has('settings')) use(this.settings.language); - } - - private renderFileSelect(): TemplateResult { - return html` - - { - const input = ( - this.shadowRoot!.querySelector('#nsdoc-file') - ); - input?.click(); - }} - > - - `; - } - - private async uploadNsdocFile(evt: Event): Promise { - const files = Array.from( - (evt.target)?.files ?? [] - ); - - if (files.length == 0) return; - for (const file of files) { - const text = await file.text(); - this.dispatchEvent(newLoadNsdocEvent(text, file.name)); - } - - this.nsdocFileUI.value = ''; - this.requestUpdate(); - } - - private async onLoadNsdoc(event: LoadNsdocEvent) { - const nsdocElement = this.parseToXmlObject( - event.detail.nsdoc - ).querySelector('NSDoc'); - - const id = nsdocElement?.getAttribute('id'); - if (!id) { - this.dispatchEvent( - newLogEvent({ - kind: 'error', - title: get('settings.invalidFileNoIdFound', { - filename: event.detail.filename, - }), - }) - ); - return; - } - - const nsdVersions = await this.nsdVersions(); - const nsdVersion = nsdVersions[id as keyof NsdVersions]; - const nsdocVersion = { - version: nsdocElement!.getAttribute('version') ?? '', - revision: nsdocElement!.getAttribute('revision') ?? '', - release: nsdocElement!.getAttribute('release') ?? '', - }; - - if (!this.isEqual(nsdVersion, nsdocVersion)) { - this.dispatchEvent( - newLogEvent({ - kind: 'error', - title: get('settings.invalidNsdocVersion', { - id: id, - filename: event.detail.filename, - nsdVersion: `${nsdVersion.version}${nsdVersion.revision}${nsdVersion.release}`, - nsdocVersion: `${nsdocVersion.version}${nsdocVersion.revision}${nsdocVersion.release}`, - }), - }) - ); - return; - } - - this.setSetting(id as keyof Settings, event.detail.nsdoc); - this.nsdoc = initializeNsdoc(); // update nsdoc - } - - /** - * Check the equality of two NsdVersions. - * @param versionA - First version to compare. - * @param versionB - Second version to compare. - * @returns Are they equal or not. - */ - private isEqual(versionA: NsdVersion, versionB: NsdVersion): boolean { - return ( - versionA.version == versionB.version && - versionA.revision == versionB.revision && - versionA.release == versionB.release - ); - } - - /** - * Render one .nsdoc item in the Settings wizard - * @param key - The key of the nsdoc file in the settings. - * @returns a .nsdoc item for the Settings wizard - */ - private renderNsdocItem(key: T): TemplateResult { - const nsdSetting = this.settings[key]; - let nsdVersion: string | undefined | null; - let nsdRevision: string | undefined | null; - let nsdRelease: string | undefined | null; - - if (nsdSetting) { - const nsdoc = this.parseToXmlObject(nsdSetting)!.querySelector('NSDoc'); - nsdVersion = nsdoc?.getAttribute('version'); - nsdRevision = nsdoc?.getAttribute('revision'); - nsdRelease = nsdoc?.getAttribute('release'); - } - - return html` - ${key} - ${nsdSetting - ? html`${nsdVersion}${nsdRevision}${nsdRelease}` - : html``} - ${nsdSetting - ? html`done` - : html`close`} - ${nsdSetting - ? html` { - this.removeSetting(key); - }} - >delete` - : html``} - `; - } - - private parseToXmlObject(text: string): XMLDocument { - return new DOMParser().parseFromString(text, 'application/xml'); - } - - constructor() { - super(); - - registerTranslateConfig({ loader, empty: key => key }); - use(this.settings.language); - } - - connectedCallback(): void { - super.connectedCallback(); - if (this.host) { - this.host!.addEventListener('oscd-settings', (evt: SettingsUIEvent) => { - evt.detail.show ? this.settingsUI.show() : this.settingsUI.close(); - }); - (this.host).addEventListener('load-nsdoc', (evt: LoadNsdocEvent) => - this.onLoadNsdoc(evt) - ); - } - } - - render(): TemplateResult { - return html` -
- - ${Object.keys(languages).map( - lang => - html`${get(`settings.languages.${lang}`)}` - )} - - - - - - - - - - -
- - ${this.nsdUploadButton - ? html`
-

${get('settings.loadNsdTranslations')}

- ${this.renderFileSelect()} -
` - : html``} - - ${this.renderNsdocItem('IEC 61850-7-2')} - ${this.renderNsdocItem('IEC 61850-7-3')} - ${this.renderNsdocItem('IEC 61850-7-4')} - ${this.renderNsdocItem('IEC 61850-8-1')} - - - ${get('cancel')} - - - ${get('reset')} - - - ${get('save')} - -
- - ${getTheme(this.settings.theme)}`; - } - - static styles = css` - mwc-top-app-bar-fixed { - --mdc-theme-text-disabled-on-light: rgba(255, 255, 255, 0.38); - } /* hack to fix disabled icon buttons rendering black */ - - mwc-tab { - background-color: var(--primary); - --mdc-theme-primary: var(--mdc-theme-on-primary); - } - - input[type='file'] { - display: none; - } - - mwc-dialog { - --mdc-dialog-max-width: 98vw; - } - - mwc-dialog > form { - display: flex; - flex-direction: column; - } - - mwc-dialog > form > * { - display: block; - margin-top: 16px; - } - - mwc-linear-progress { - position: fixed; - --mdc-linear-progress-buffer-color: var(--primary); - --mdc-theme-primary: var(--secondary); - left: 0px; - top: 0px; - width: 100%; - pointer-events: none; - z-index: 1000; - } - - tt { - font-family: 'Roboto Mono', monospace; - font-weight: 300; - } - - .landing { - position: absolute; - text-align: center; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 100%; - } - - .landing_icon:hover { - box-shadow: 0 12px 17px 2px rgba(0, 0, 0, 0.14), - 0 5px 22px 4px rgba(0, 0, 0, 0.12), 0 7px 8px -4px rgba(0, 0, 0, 0.2); - } - - .landing_icon { - margin: 12px; - border-radius: 16px; - width: 160px; - height: 140px; - text-align: center; - color: var(--mdc-theme-on-secondary); - background: var(--secondary); - --mdc-icon-button-size: 100px; - --mdc-icon-size: 100px; - --mdc-ripple-color: rgba(0, 0, 0, 0); - box-shadow: rgb(0 0 0 / 14%) 0px 6px 10px 0px, - rgb(0 0 0 / 12%) 0px 1px 18px 0px, rgb(0 0 0 / 20%) 0px 3px 5px -1px; - transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1); - } - - .landing_label { - width: 160px; - height: 50px; - margin-top: 100px; - margin-left: -30px; - font-family: 'Roboto', sans-serif; - } - - .plugin.menu { - display: flex; - } - - .plugin.validator { - display: flex; - } - `; -} diff --git a/packages/compas-open-scd/src/open-scd.ts b/packages/compas-open-scd/src/open-scd.ts index 828391abcb..d25ee22312 100644 --- a/packages/compas-open-scd/src/open-scd.ts +++ b/packages/compas-open-scd/src/open-scd.ts @@ -13,9 +13,9 @@ import { newPendingStateEvent } from '@openscd/core/foundation/deprecated/waiter import './addons/CompasSession.js'; import './addons/CompasHistory.js'; import './addons/CompasLayout.js'; -import './addons/CompasSettings.js'; import '@openscd/open-scd/src/addons/Waiter.js'; +import '@openscd/open-scd/src/addons/Settings.js'; import { HistoryState, historyStateEvent, @@ -44,6 +44,7 @@ import { pluginTag } from '@openscd/open-scd/src/plugin-tag.js'; import packageJson from '../package.json'; import { CompasSclDataService } from './compas-services/CompasSclDataService.js'; import { createLogEvent } from './compas-services/foundation.js'; +import { languages, loader } from './translations/loader.js'; const LNODE_LIB_DOC_ID = 'fc55c46d-c109-4ccd-bf66-9f1d0e135689'; @@ -51,10 +52,15 @@ const LNODE_LIB_DOC_ID = 'fc55c46d-c109-4ccd-bf66-9f1d0e135689'; * Open Substation Configuration Designer. */ @customElement('open-scd') export class OpenSCD extends LitElement { + private languageConfig = { loader, languages }; render(): TemplateResult { return html` - + - + `; }