Skip to content

Commit

Permalink
feat: allow for plugins being passed down as props to <open-scd> (#…
Browse files Browse the repository at this point in the history
…1486)

* feat: allow open-scd to have plugins being passed down as props

Signed-off-by: Juan Munoz <juancho0202@gmail.com>

* test: added integration snapshot test for plugins prop

Signed-off-by: Juan Munoz <juancho0202@gmail.com>

* chore: refactor to implement "tasks" section on issue #1418

Signed-off-by: Juan Munoz <juancho0202@gmail.com>

* chore: remove unnecessary default attribute from core's Plugin interface

Signed-off-by: Juan Munoz <juancho0202@gmail.com>

* chore: change position attr to accomodate for editor plug-in positions

Signed-off-by: Juan Munoz <juancho0202@gmail.com>

* chore: fixing prop "default" to "active" and adding snapshot test with an editor plugin

Signed-off-by: Juan Munoz <juancho0202@gmail.com>

* chore: fixing casting of CorePlugin type into Plugin type

Signed-off-by: Juan Munoz <juancho0202@gmail.com>

* chore: updating with snapshots from main

Signed-off-by: Juan Munoz <juancho0202@gmail.com>

---------

Signed-off-by: Juan Munoz <juancho0202@gmail.com>
Co-authored-by: Steffen van den Driest <35229971+Stef3st@users.noreply.github.com>
  • Loading branch information
juancho0202 and Stef3st committed May 7, 2024
1 parent 24f4b25 commit 01bcc01
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 111 deletions.
2 changes: 1 addition & 1 deletion packages/core/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ export type {
export { cyrb64 } from './foundation/cyrb64.js';

export { Editing } from './mixins/Editing.js';
export { Plugging } from './mixins/Plugging.js';
export type { Plugin, PluginSet } from './foundation/plugin.js';
12 changes: 12 additions & 0 deletions packages/core/foundation/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { targetLocales } from '../locales.js';

export type Plugin = {
name: string;
translations?: Record<(typeof targetLocales)[number], string>;
src: string;
icon: string;
requireDoc?: boolean;
active?: boolean;
position: ('top' | 'middle' | 'bottom') | number;
};
export type PluginSet = { menu: Plugin[]; editor: Plugin[] };
71 changes: 0 additions & 71 deletions packages/core/mixins/Plugging.ts

This file was deleted.

3 changes: 3 additions & 0 deletions packages/open-scd/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ module.exports = {
'no-duplicate-imports': 'off',
'tsdoc/syntax': 'warn'
},
env: {
browser: true,
},
};
107 changes: 68 additions & 39 deletions packages/open-scd/src/open-scd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { ActionDetail, List } from '@material/mwc-list';
import { officialPlugins } from './plugins.js';
import { initializeNsdoc, Nsdoc } from './foundation/nsdoc.js';
import { UndoRedoChangedEvent } from './addons/History.js';
import type { PluginSet, Plugin as CorePlugin } from '@openscd/core';

// HOSTING INTERFACES

Expand Down Expand Up @@ -178,6 +179,7 @@ export type Plugin = {
name: string;
src: string;
icon?: string;
default?: boolean;
kind: PluginKind;
requireDoc?: boolean;
position?: MenuPosition;
Expand All @@ -198,9 +200,6 @@ function withoutContent<P extends Plugin | InstalledOfficialPlugin>(
return { ...plugin, content: undefined };
}

function storePlugins(plugins: Array<Plugin | InstalledOfficialPlugin>) {
localStorage.setItem('plugins', JSON.stringify(plugins.map(withoutContent)));
}

export const pluginIcons: Record<PluginKind | MenuPosition, string> = {
editor: 'tab',
Expand All @@ -211,18 +210,6 @@ export const pluginIcons: Record<PluginKind | MenuPosition, string> = {
bottom: 'play_circle',
};

function resetPlugins(): void {
storePlugins(
officialPlugins.map(plugin => {
return {
src: plugin.src,
installed: plugin.default ?? false,
official: true,
};
})
);
}

const menuOrder: (PluginKind | MenuPosition)[] = [
'editor',
'top',
Expand Down Expand Up @@ -290,22 +277,18 @@ export class OpenSCD extends LitElement {
if (src.startsWith('blob:')) URL.revokeObjectURL(src);
}

constructor() {
super();

this.updatePlugins();
this.requestUpdate();
}

connectedCallback(): void {
super.connectedCallback();
this.addEventListener('reset-plugins', resetPlugins);
this.addEventListener('reset-plugins', this.resetPlugins);
this.addEventListener('add-external-plugin', (e: AddExternalPluginEvent) => {
this.addExternalPlugin(e.detail.plugin);
});
this.addEventListener('set-plugins', (e: SetPluginsEvent) => {
this.setPlugins(e.detail.indices);
});

this.updatePlugins();
this.requestUpdate();
}

render(): TemplateResult {
Expand All @@ -330,7 +313,7 @@ export class OpenSCD extends LitElement {
.doc=${this.doc}
.docName=${this.docName}
.editCount=${this.editCount}
.plugins=${this.plugins}
.plugins=${this._sortedStoredPlugins}
>
</oscd-layout>
</oscd-editor>
Expand All @@ -340,14 +323,56 @@ export class OpenSCD extends LitElement {
</oscd-waiter>`;
}

@state()
get plugins(): Plugin[] {
private storePlugins(plugins: Array<Plugin | InstalledOfficialPlugin>) {
localStorage.setItem('plugins', JSON.stringify(plugins.map(withoutContent)));
this._sortedStoredPlugins = this.sortedStoredPlugins;
}
private resetPlugins(): void {
this.storePlugins(
(officialPlugins as Plugin[]).concat(this.parsedPlugins).map(plugin => {
return {
src: plugin.src,
installed: plugin.default ?? false,
official: true,
};
})
);
}

/**
* @prop {PluginSet} plugins - Set of plugins that are used by OpenSCD
*/
@property({ type: Object })
plugins: PluginSet = { menu: [], editor: [] };

get parsedPlugins(): Plugin[] {
return this.plugins.menu
.map((p: CorePlugin) => ({
...p,
position:
typeof p.position !== 'number'
? (p.position as MenuPosition)
: undefined,
kind: 'menu' as PluginKind,
installed: p.active ?? false,
}))
.concat(
this.plugins.editor.map((p: CorePlugin) => ({
...p,
position: undefined,
kind: 'editor' as PluginKind,
installed: p.active ?? false,
}))
);
}

private get sortedStoredPlugins(): Plugin[] {
return this.storedPlugins
.map(plugin => {
if (!plugin.official) return plugin;
const officialPlugin = officialPlugins.find(
needle => needle.src === plugin.src
);
const officialPlugin = (officialPlugins as Plugin[])
.concat(this.parsedPlugins)
.find(needle => needle.src === plugin.src);
return <Plugin>{
...officialPlugin,
...plugin,
Expand All @@ -357,9 +382,8 @@ export class OpenSCD extends LitElement {
.sort(menuCompare);
}

set plugins(plugins: Plugin[]) {
storePlugins(plugins);
}
@state()
_sortedStoredPlugins: Plugin[] = [];

private get storedPlugins(): Plugin[] {
return <Plugin[]>(
Expand All @@ -385,17 +409,20 @@ export class OpenSCD extends LitElement {
}

private setPlugins(indices: Set<number>) {
const newPlugins = this.plugins.map((plugin, index) => {
const newPlugins = this.sortedStoredPlugins.map((plugin, index) => {
return { ...plugin, installed: indices.has(index) };
});
storePlugins(newPlugins);
this.storePlugins(newPlugins);
this.requestUpdate();
}

private updatePlugins() {
const stored: Plugin[] = this.storedPlugins;
const officialStored = stored.filter(p => p.official);
const newOfficial: Array<Plugin | InstalledOfficialPlugin> = officialPlugins
const newOfficial: Array<Plugin | InstalledOfficialPlugin> = (
officialPlugins as Plugin[]
)
.concat(this.parsedPlugins)
.filter(p => !officialStored.find(o => o.src === p.src))
.map(plugin => {
return {
Expand All @@ -405,22 +432,24 @@ export class OpenSCD extends LitElement {
};
});
const oldOfficial = officialStored.filter(
p => !officialPlugins.find(o => p.src === o.src)
p =>
!(officialPlugins as Plugin[])
.concat(this.parsedPlugins)
.find(o => p.src === o.src)
);
const newPlugins: Array<Plugin | InstalledOfficialPlugin> = stored.filter(
p => !oldOfficial.find(o => p.src === o.src)
);
newOfficial.map(p => newPlugins.push(p));
storePlugins(newPlugins);
this.storePlugins(newPlugins);
}

private async addExternalPlugin(plugin: Omit<Plugin, 'content'>): Promise<void> {
if (this.storedPlugins.some(p => p.src === plugin.src)) return;

const newPlugins: Omit<Plugin, 'content'>[] = this.storedPlugins;
newPlugins.push(plugin);
this.plugins = newPlugins;
await this.requestUpdate();
this.storePlugins(newPlugins);
}

private addContent(plugin: Omit<Plugin, 'content'>): Plugin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,38 @@ snapshots["open-scd looks like its snapshot"] =
`;
/* end snapshot open-scd looks like its snapshot */

snapshots["open-scd renders menu plugins passed down as props and it looks like its snapshot"] =
`<oscd-waiter>
<oscd-settings>
<oscd-wizards>
<oscd-history>
<oscd-editor>
<oscd-layout>
</oscd-layout>
</oscd-editor>
</oscd-history>
</oscd-wizards>
</oscd-settings>
</oscd-waiter>
`;
/* end snapshot open-scd renders menu plugins passed down as props and it looks like its snapshot */

snapshots["open-scd renders editor plugins passed down as props and it looks like its snapshot"] =
`<oscd-waiter>
<oscd-settings>
<oscd-wizards>
<oscd-history>
<oscd-editor>
<oscd-layout>
</oscd-layout>
</oscd-editor>
</oscd-history>
</oscd-wizards>
</oscd-settings>
</oscd-waiter>
`;
/* end snapshot open-scd renders editor plugins passed down as props and it looks like its snapshot */

snapshots["open-scd layout looks like its snapshot"] =
`<slot>
</slot>
Expand Down
Loading

0 comments on commit 01bcc01

Please sign in to comment.