diff --git a/packages/core/foundation/plugin.ts b/packages/core/foundation/plugin.ts index 300bb19adc..712c666912 100644 --- a/packages/core/foundation/plugin.ts +++ b/packages/core/foundation/plugin.ts @@ -1,12 +1,28 @@ import { targetLocales } from '../locales.js'; export type Plugin = { + // name defines the name of the plugin name: string; - translations?: Record<(typeof targetLocales)[number], string>; + // src defines the path to the plugins source file src: string; - icon: string; - requireDoc?: boolean; + // kind defines the type of the plugin + kind: PluginKind; + // activeByDefault configures if the plugin should be active by default + // this is will be user when users resets the plugins + activeByDefault: boolean; + // icon stores the icon name of the Material Icon + icon?: string; + // active shows if the plugin currently is active active?: boolean; - position: ('top' | 'middle' | 'bottom') | number; + // requireDoc shows if the plugin requires a document to be loaded + requireDoc?: boolean; + // position defines the position of menu plugins + position?: MenuPosition + translations?: Record<(typeof targetLocales)[number], string>; }; + export type PluginSet = { menu: Plugin[]; editor: Plugin[] }; +export type PluginKind = 'editor' | 'menu' | 'validator'; +export const menuPosition = ['top', 'middle', 'bottom'] as const; +export type MenuPosition = (typeof menuPosition)[number]; + diff --git a/packages/openscd/package.json b/packages/openscd/package.json index 7105750f0b..d4da5135ba 100644 --- a/packages/openscd/package.json +++ b/packages/openscd/package.json @@ -62,6 +62,7 @@ "test:manual": "web-test-runner --manual", "test:watch": "web-test-runner --watch", "test:unit": "web-test-runner --watch --group unit", + "test:unit:headless": "web-test-runner --watch --group unit --concurrency 1 --headless", "test:integration": "web-test-runner --watch --group integration", "doc:clean": "npx rimraf doc", "doc:typedoc": "typedoc --plugin none --out doc --entryPointStrategy expand ./src", diff --git a/packages/openscd/src/addons/Layout.ts b/packages/openscd/src/addons/Layout.ts index 68055f25f7..78c0cce4b3 100644 --- a/packages/openscd/src/addons/Layout.ts +++ b/packages/openscd/src/addons/Layout.ts @@ -54,10 +54,41 @@ import '@material/mwc-select'; import '@material/mwc-textfield'; import { nothing } from 'lit'; +import {OscdPluginManager} from "./plugin-manager/plugin-manager.js"; +import "./plugin-manager/plugin-manager.js"; +import {OscdCustomPluginDialog} from "./plugin-manager/custom-plugin-dialog.js"; +import "./plugin-manager/custom-plugin-dialog.js"; + @customElement('oscd-layout') export class OscdLayout extends LitElement { + /** The `XMLDocument` to be edited */ + @property({ attribute: false }) doc: XMLDocument | null = null; + /** The name of the current [[`doc`]] */ + @property({ type: String }) docName = ''; + /** Index of the last [[`EditorAction`]] applied. */ + @property({ type: Number }) editCount = -1; + /** The currently active editor tab. */ + @property({ type: Number }) activeTab = 0; + + /** The plugins to render the layout. */ + @property({ type: Array }) plugins: Plugin[] = []; + + /** The open-scd host element */ + @property({ type: Object }) host!: HTMLElement; + + @property({ type: Object }) historyState!: HistoryState; + + @state() validated: Promise = Promise.resolve(); + @state() shouldValidate = false; + + @query('#menu') menuUI!: Drawer; + @query('#pluginManager') pluginUI!: OscdPluginManager; + @query('#pluginList') pluginList!: List; + @query('#pluginAdd') pluginDownloadUI!: OscdCustomPluginDialog; + + render(): TemplateResult { return html`
= Promise.resolve(); + private renderPlugging(): TemplateResult { + return html` ${this.renderPluginUI()} ${this.renderDownloadUI()} `; + } - @state() - shouldValidate = false; + /** Renders the "Add Custom Plug-in" UI*/ + protected renderDownloadUI(): TemplateResult { + return html` + + ` + } - @query('#menu') - menuUI!: Drawer; - @query('#pluginManager') - pluginUI!: Dialog; - @query('#pluginList') - pluginList!: List; - @query('#pluginAdd') - pluginDownloadUI!: Dialog; + /** + * Renders the plug-in management UI (turning plug-ins on/off) + */ + protected renderPluginUI(): TemplateResult { + return html` + + ` + } // Computed properties get validators(): Plugin[] { return this.plugins.filter( - plugin => plugin.installed && plugin.kind === 'validator' + plugin => plugin.active && plugin.kind === 'validator' ); } get menuEntries(): Plugin[] { return this.plugins.filter( - plugin => plugin.installed && plugin.kind === 'menu' + plugin => plugin.active && plugin.kind === 'menu' ); } get topMenu(): Plugin[] { @@ -226,7 +238,7 @@ export class OscdLayout extends LitElement { get editors(): Plugin[] { return this.plugins.filter( - plugin => plugin.installed && plugin.kind === 'editor' + plugin => plugin.active && plugin.kind === 'editor' ); } @@ -250,50 +262,6 @@ export class OscdLayout extends LitElement { fn(); } - private handleAddPlugin() { - const pluginSrcInput = ( - this.pluginDownloadUI.querySelector('#pluginSrcInput') - ); - const pluginNameInput = ( - this.pluginDownloadUI.querySelector('#pluginNameInput') - ); - const pluginKindList = ( - this.pluginDownloadUI.querySelector('#pluginKindList') - ); - const requireDoc = ( - this.pluginDownloadUI.querySelector('#requireDoc') - ); - const positionList =