diff --git a/.gitmodules b/.gitmodules index 964e47d214..a452e17113 100644 --- a/.gitmodules +++ b/.gitmodules @@ -26,3 +26,7 @@ path = packages/external-plugins/scl-bay-template url = https://github.com/com-pas/scl-bay-template branch = deploy +[submodule "packages/external-plugins/scl-wizarding"] + path = packages/external-plugins/scl-wizarding + url = https://github.com/openenergytools/scl-wizarding + branch = deploy diff --git a/packages/compas-open-scd/package.json b/packages/compas-open-scd/package.json index d97173918e..88612dd150 100644 --- a/packages/compas-open-scd/package.json +++ b/packages/compas-open-scd/package.json @@ -70,7 +70,7 @@ "release:major": "standard-version --release-as major", "build:test": "npm run test && npm run build && cp .nojekyll build/", "build": "npm run doc && npm run build:only && cp .nojekyll build/", - "build:only": "snowpack build && workbox generateSW workbox-config.cjs", + "build:only": "npx rimraf node_modules/.cache/snowpack/build/lit@2.8.0 && snowpack build && workbox generateSW workbox-config.cjs", "__comment:start": "snowpack dev fails if the lit package is cached. I don't know why, but we have to delete it before starting", "start": "npx rimraf node_modules/.cache/snowpack/build/lit@2.8.0 && snowpack dev" }, diff --git a/packages/compas-open-scd/public/js/plugins.js b/packages/compas-open-scd/public/js/plugins.js index 81196156cf..8be1795270 100644 --- a/packages/compas-open-scd/public/js/plugins.js +++ b/packages/compas-open-scd/public/js/plugins.js @@ -339,6 +339,15 @@ export const officialPlugins = [ requireDoc: true, position: 'middle', }, + { + name: 'Wizarding', + src: '/external-plugins/scl-wizarding/scl-wizarding.js', + icon: 'edit', + activeByDefault: true, + kind: 'menu', + requireDoc: true, + position: 'middle', + }, { name: 'Show SCL History', src: '/plugins/src/menu/SclHistory.js', diff --git a/packages/compas-open-scd/src/addons/CompasLayout.ts b/packages/compas-open-scd/src/addons/CompasLayout.ts index 7db59a7689..53cbea9225 100644 --- a/packages/compas-open-scd/src/addons/CompasLayout.ts +++ b/packages/compas-open-scd/src/addons/CompasLayout.ts @@ -44,7 +44,7 @@ import { OscdPluginManager } from '@openscd/open-scd/src/addons/plugin-manager/p import '@openscd/open-scd/src/addons/plugin-manager/plugin-manager'; import { OscdCustomPluginDialog } from '@openscd/open-scd/src/addons/plugin-manager/custom-plugin-dialog'; import '@openscd/open-scd/src/addons/plugin-manager/custom-plugin-dialog'; -import { nothing } from 'lit'; +import { pluginTag } from '../plugin-tag.js'; // TODO: What happens with this? export function compasOpenMenuEvent(): CustomEvent { @@ -77,6 +77,7 @@ export class CompasLayout extends LitElement { @state() shouldValidate = false; @query('#menu') menuUI!: Drawer; + @query('#menuContent') menuContent!: List; @query('#pluginManager') pluginUI!: OscdPluginManager; @query('#pluginList') pluginList!: List; @query('#pluginAdd') pluginDownloadUI!: OscdCustomPluginDialog; @@ -89,8 +90,8 @@ export class CompasLayout extends LitElement { @oscd-run-menu=${this.handleRunMenuByEvent} > - ${this.renderHeader()} ${this.renderAside()} ${this.renderContent()} - ${this.renderLanding()} ${this.renderPlugging()} + ${this.renderHeader()} ${this.renderAside()} ${this.renderMenuContent()} + ${this.renderContent()} ${this.renderLanding()} ${this.renderPlugging()} `; } @@ -99,6 +100,11 @@ export class CompasLayout extends LitElement { return html` ${this.renderPluginUI()} ${this.renderDownloadUI()} `; } + private getMenuContent(src: string) { + const tag = pluginTag(src); + return this.menuContent.querySelector(tag); + } + /** Renders the "Add Custom Plug-in" UI*/ protected renderDownloadUI(): TemplateResult { return html` @@ -271,8 +277,17 @@ export class CompasLayout extends LitElement { this.menuUI .querySelector('mwc-list')! .items.filter(item => item.className === 'validator') - .map(item => - ((item.nextElementSibling)).validate() + .map(item => { + const src = item.dataset.src ?? ''; + + const menuContentElement = this.getMenuContent(src); + + if (!menuContentElement) { + return; + } + + return (menuContentElement as unknown as Validator).validate() + } ) ).then(); this.dispatchEvent(newPendingStateEvent(this.validated)); @@ -293,16 +308,14 @@ export class CompasLayout extends LitElement { return { icon: plugin.icon || pluginIcons['menu'], name: plugin.name, + src: plugin.src, action: ae => { - this.dispatchEvent( - newPendingStateEvent( - (( - (( - (ae.target).items[ae.detail.index].nextElementSibling - )) - )).run() - ) - ); + const menuContentElement = this.getMenuContent(plugin.src); + if (!menuContentElement) { + return; + } + + this.dispatchEvent(newPendingStateEvent((menuContentElement as unknown as MenuPlugin).run())) }, disabled: (): boolean => plugin.requireDoc! && this.doc === null, content: () => { @@ -319,18 +332,16 @@ export class CompasLayout extends LitElement { return { icon: plugin.icon || pluginIcons['validator'], name: plugin.name, + src: plugin.src, action: ae => { this.dispatchEvent(newEmptyIssuesEvent(plugin.src)); - this.dispatchEvent( - newPendingStateEvent( - (( - (( - (ae.target).items[ae.detail.index].nextElementSibling - )) - )).validate() - ) - ); + const menuContentElement = this.getMenuContent(plugin.src); + if (!menuContentElement) { + return; + } + + this.dispatchEvent(newPendingStateEvent((menuContentElement as unknown as Validator).validate())) }, disabled: (): boolean => this.doc === null, content: plugin.content ?? (() => html``), @@ -347,13 +358,23 @@ export class CompasLayout extends LitElement { const hasActionItem = me !== 'divider' && me.actionItem; if (isDivider(me)) { return html`
  • `; } - if (hasActionItem){ return html``; } + if (hasActionItem){ + return html``; + } + + /* + if (me.kind === 'validator') { + console.log('rendering validator with data') + console.log(me) + } + */ return html` ${me.icon} ${get(me.name)} @@ -361,7 +382,6 @@ export class CompasLayout extends LitElement { ? html`${me.hint}` : ''} - ${me.content ? me.content() : nothing} `; } @@ -406,6 +426,18 @@ export class CompasLayout extends LitElement { `; } + protected renderMenuContent(): TemplateResult { + return html` + + `; + } + /** * Renders a drawer toolbar featuring the scl filename, enabled menu plugins, * settings, help, scl history and plug-ins management @@ -505,14 +537,16 @@ export class CompasLayout extends LitElement { } private handleRunMenuByEvent(e: CustomEvent<{name: string}>): void { - // TODO: this is a workaround, fix it this.menuUI.open = true; const menuEntry = this.menuUI.querySelector(`[data-name="${e.detail.name}"]`) as HTMLElement - const menuElement = menuEntry.nextElementSibling - if(!menuElement){ return; } // TODO: log error - (menuElement as unknown as MenuPlugin).run() + const menuContentElement = this.getMenuContent(menuEntry.dataset.src ?? ''); + if (!menuContentElement) { + return; + } + + (menuContentElement as unknown as MenuPlugin).run() } /** diff --git a/packages/compas-open-scd/src/menu/CompasOpen.ts b/packages/compas-open-scd/src/menu/CompasOpen.ts index 8fe7b7fc57..9c7963432d 100644 --- a/packages/compas-open-scd/src/menu/CompasOpen.ts +++ b/packages/compas-open-scd/src/menu/CompasOpen.ts @@ -28,9 +28,6 @@ export default class CompasOpenMenuPlugin extends LitElement { this.compasOpenElement.selectedType = undefined; await this.compasOpenElement.requestUpdate(); - // TODO: Fix for dialog, the menu has to be open to see the dialog - this.dispatchEvent(compasOpenMenuEvent()); - this.dialog.show(); } diff --git a/packages/compas-open-scd/src/plugin-tag.ts b/packages/compas-open-scd/src/plugin-tag.ts new file mode 100644 index 0000000000..ec957e4e92 --- /dev/null +++ b/packages/compas-open-scd/src/plugin-tag.ts @@ -0,0 +1,18 @@ +export function pluginTag(uri: string): string { + let h1 = 0xdeadbeef, + h2 = 0x41c6ce57; + for (let i = 0, ch; i < uri.length; i++) { + ch = uri.charCodeAt(i); + h1 = Math.imul(h1 ^ ch, 2654435761); + h2 = Math.imul(h2 ^ ch, 1597334677); + } + h1 = + Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ + Math.imul(h2 ^ (h2 >>> 13), 3266489909); + h2 = + Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ + Math.imul(h1 ^ (h1 >>> 13), 3266489909); + return 'oscd-plugin' + + ((h2 >>> 0).toString(16).padStart(8, '0') + + (h1 >>> 0).toString(16).padStart(8, '0')) +} diff --git a/packages/external-plugins/scl-wizarding b/packages/external-plugins/scl-wizarding new file mode 160000 index 0000000000..58d0d7d384 --- /dev/null +++ b/packages/external-plugins/scl-wizarding @@ -0,0 +1 @@ +Subproject commit 58d0d7d384cfa17d5b3d7d905cbf958b728ac515 diff --git a/packages/openscd/src/open-scd.ts b/packages/openscd/src/open-scd.ts index 1e1aff301f..10cd9ff869 100644 --- a/packages/openscd/src/open-scd.ts +++ b/packages/openscd/src/open-scd.ts @@ -493,6 +493,7 @@ declare global { export interface MenuItem { icon: string; name: string; + src?: string; hint?: string; actionItem?: boolean; action?: (event: CustomEvent) => void;