From 7e2791acda2780b7d95521bab81dd532481092ff Mon Sep 17 00:00:00 2001 From: Piotr Gawron <p.gawron@atcomp.pl> Date: Thu, 31 Oct 2024 10:27:36 +0100 Subject: [PATCH] allow to load plugin with panel --- CHANGELOG | 1 + docs/plugins/plugins.md | 12 ++++++----- index.d.ts | 4 +--- src/redux/plugins/plugins.reducers.test.ts | 8 +++++++- src/redux/plugins/plugins.thunks.ts | 16 ++++++++++++--- src/services/pluginsManager/pluginsManager.ts | 20 ++++++++++++------- .../pluginsManager/pluginsManager.types.ts | 5 +++-- src/types/models.ts | 2 +- 8 files changed, 46 insertions(+), 22 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6edee4e1..38c549d2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ minerva-front (19.0.0~alpha.0) stable; urgency=medium * Feature: support for matomo (#289) + * Feature: allow plugin to not have a panel (#306) -- Piotr Gawron <piotr.gawron@uni.lu> Fri, 18 Oct 2024 13:00:00 +0200 diff --git a/docs/plugins/plugins.md b/docs/plugins/plugins.md index 1636f258..6613bb03 100644 --- a/docs/plugins/plugins.md +++ b/docs/plugins/plugins.md @@ -11,6 +11,7 @@ Your plugin should utilize the `window.minerva.plugins.registerPlugin` method fo pluginName: string; pluginVersion: string; pluginUrl: string; + withoutPanel: boolean | undefined; } ``` @@ -21,6 +22,7 @@ window.minerva.plugins.registerPlugin({ pluginName: 'Your Plugin Name', pluginVersion: '1.8.3', pluginUrl: 'https://example.com/plugins/plugin.js', + withoutPanel: false, }); ``` @@ -28,17 +30,17 @@ window.minerva.plugins.registerPlugin({ The `window.minerva.plugins.registerPlugin` method returns object with `element` property which is a DOM element, allowing your plugin to append its HTML content to the DOM. Use this element to create and modify the HTML structure of your plugin. -``` +```javascript // Plugin registration const { element } = window.minerva.plugins.registerPlugin({ - pluginName: "Your Plugin Name", - pluginVersion: "1.0.0", - pluginUrl: "your-plugin-url", + pluginName: 'Your Plugin Name', + pluginVersion: '1.0.0', + pluginUrl: 'your-plugin-url', }); // Modify plugin's HTML structure const yourContent = document.createElement('div'); -yourContent.textContent = "Your Plugin Content"; +yourContent.textContent = 'Your Plugin Content'; element.appendChild(yourContent); ``` diff --git a/index.d.ts b/index.d.ts index a18511ed..2e109d80 100644 --- a/index.d.ts +++ b/index.d.ts @@ -3,15 +3,12 @@ import { fitBounds } from '@/services/pluginsManager/map/fitBounds'; import { getOpenMapId } from '@/services/pluginsManager/map/getOpenMapId'; import { triggerSearch } from '@/services/pluginsManager/map/triggerSearch'; import { MinervaConfiguration } from '@/services/pluginsManager/pluginsManager'; -import { MapInstance } from '@/types/map'; import { getModels } from '@/services/pluginsManager/map/models/getModels'; import { openMap } from '@/services/pluginsManager/map/openMap'; import { getCenter } from '@/services/pluginsManager/map/position/getCenter'; import { setCenter } from '@/services/pluginsManager/map/position/setCenter'; -import { triggerSearch } from '@/services/pluginsManager/map/triggerSearch'; import { getZoom } from '@/services/pluginsManager/map/zoom/getZoom'; import { setZoom } from '@/services/pluginsManager/map/zoom/setZoom'; -import { MinervaConfiguration } from '@/services/pluginsManager/pluginsManager'; import { getDisease } from '@/services/pluginsManager/project/data/getDisease'; import { getName } from '@/services/pluginsManager/project/data/getName'; import { getOrganism } from '@/services/pluginsManager/project/data/getOrganism'; @@ -29,6 +26,7 @@ type Plugin = { pluginName: string; pluginVersion: string; pluginUrl: string; + withoutPanel: boolean | undefined; }; type RegisterPlugin = ({ pluginName, pluginVersion, pluginUrl }: Plugin) => { diff --git a/src/redux/plugins/plugins.reducers.test.ts b/src/redux/plugins/plugins.reducers.test.ts index d5a7f010..0d282876 100644 --- a/src/redux/plugins/plugins.reducers.test.ts +++ b/src/redux/plugins/plugins.reducers.test.ts @@ -47,13 +47,14 @@ describe('plugins reducer', () => { pluginUrl: pluginFixture.urls[0], pluginVersion: pluginFixture.version, extendedPluginName: pluginFixture.name, + withoutPanel: false, }), ); expect(type).toBe('plugins/registerPlugin/fulfilled'); const { data, pluginsId } = store.getState().plugins.activePlugins; - expect(data[pluginFixture.hash]).toEqual(pluginFixture); + expect(data[pluginFixture.hash]).toEqual({ ...pluginFixture, withoutPanel: false }); expect(pluginsId).toContain(pluginFixture.hash); }); @@ -68,6 +69,7 @@ describe('plugins reducer', () => { pluginUrl: pluginFixture.urls[0], pluginVersion: pluginFixture.version, extendedPluginName: pluginFixture.name, + withoutPanel: false, }), ); @@ -93,6 +95,7 @@ describe('plugins reducer', () => { pluginUrl: pluginFixture.urls[0], pluginVersion: pluginFixture.version, extendedPluginName: pluginFixture.name, + withoutPanel: false, }), ); @@ -113,6 +116,7 @@ describe('plugins reducer', () => { pluginUrl: pluginFixture.urls[0], pluginVersion: pluginFixture.version, extendedPluginName, + withoutPanel: false, }), ); @@ -122,6 +126,7 @@ describe('plugins reducer', () => { [pluginFixture.hash]: { ...pluginFixture, name: extendedPluginName, + withoutPanel: false, }, }); }); @@ -136,6 +141,7 @@ describe('plugins reducer', () => { pluginUrl: pluginFixture.urls[0], pluginVersion: pluginFixture.version, extendedPluginName: pluginFixture.name, + withoutPanel: false, }), ); diff --git a/src/redux/plugins/plugins.thunks.ts b/src/redux/plugins/plugins.thunks.ts index 9a8e2888..8a33022e 100644 --- a/src/redux/plugins/plugins.thunks.ts +++ b/src/redux/plugins/plugins.thunks.ts @@ -23,6 +23,7 @@ type RegisterPlugin = { pluginVersion: string; isPublic: boolean; extendedPluginName: string; + withoutPanel: boolean | undefined; }; export const registerPlugin = createAsyncThunk< @@ -31,12 +32,20 @@ export const registerPlugin = createAsyncThunk< ThunkConfig >( 'plugins/registerPlugin', - async ({ hash, isPublic, pluginName, pluginUrl, pluginVersion, extendedPluginName }) => { + async ({ + hash, + isPublic, + pluginName, + pluginUrl, + pluginVersion, + extendedPluginName, + withoutPanel, + }) => { try { - const hashWihtoutPrefix = getPluginHashWithoutPrefix(hash); + const hashWithoutPrefix = getPluginHashWithoutPrefix(hash); const payload = { - hash: hashWihtoutPrefix, + hash: hashWithoutPrefix, url: pluginUrl, name: pluginName, version: pluginVersion, @@ -58,6 +67,7 @@ export const registerPlugin = createAsyncThunk< ...response.data, hash, name: extendedPluginName, + withoutPanel, }; } diff --git a/src/services/pluginsManager/pluginsManager.ts b/src/services/pluginsManager/pluginsManager.ts index 5653cd02..78f09d96 100644 --- a/src/services/pluginsManager/pluginsManager.ts +++ b/src/services/pluginsManager/pluginsManager.ts @@ -161,7 +161,7 @@ export const PluginsManager: PluginsManagerType = { PluginsManager.pluginsOccurrences[hash] = ZERO; } }, - registerPlugin({ pluginName, pluginVersion, pluginUrl }) { + registerPlugin({ pluginName, pluginVersion, pluginUrl, withoutPanel }) { const hash = PluginsManager.hashedPlugins[pluginUrl]; const extendedHash = PluginsManager.getExtendedPluginHash(hash); @@ -182,12 +182,16 @@ export const PluginsManager: PluginsManagerType = { pluginName, pluginUrl, pluginVersion, + withoutPanel, }), ); - const element = PluginsManager.createAndGetPluginContent({ - hash: extendedHash, - }); + const element = PluginsManager.createAndGetPluginContent( + { + hash: extendedHash, + }, + !!withoutPanel, + ); return { element, @@ -202,12 +206,14 @@ export const PluginsManager: PluginsManagerType = { }, }; }, - createAndGetPluginContent({ hash }) { + createAndGetPluginContent({ hash }, detached) { const element = document.createElement('div'); element.setAttribute(PLUGINS_CONTENT_ELEMENT_ATTR_NAME, hash); - const wrapper = document.querySelector(`#${PLUGINS_CONTENT_ELEMENT_ID}`); - wrapper?.append(element); + if (!detached) { + const wrapper = document.querySelector(`#${PLUGINS_CONTENT_ELEMENT_ID}`); + wrapper?.append(element); + } return element; }, diff --git a/src/services/pluginsManager/pluginsManager.types.ts b/src/services/pluginsManager/pluginsManager.types.ts index 2d959cf2..1da8b315 100644 --- a/src/services/pluginsManager/pluginsManager.types.ts +++ b/src/services/pluginsManager/pluginsManager.types.ts @@ -6,6 +6,7 @@ export type RegisterPlugin = { pluginName: string; pluginVersion: string; pluginUrl: string; + withoutPanel?: boolean | undefined; }; export type MinervaConfiguration = ReturnType<typeof configurationMapper>; @@ -16,10 +17,10 @@ export type PluginsManagerType = { }; setHashedPlugin({ pluginUrl, pluginScript }: { pluginUrl: string; pluginScript: string }): string; init(): Unsubscribe; - registerPlugin({ pluginName, pluginVersion, pluginUrl }: RegisterPlugin): { + registerPlugin({ pluginName, pluginVersion, pluginUrl, withoutPanel }: RegisterPlugin): { element: HTMLDivElement; }; - createAndGetPluginContent(plugin: Pick<MinervaPlugin, 'hash'>): HTMLDivElement; + createAndGetPluginContent(plugin: Pick<MinervaPlugin, 'hash'>, detached: boolean): HTMLDivElement; removePluginContent(plugin: Pick<MinervaPlugin, 'hash'>): void; activePlugins: { [pluginId: string]: string[]; diff --git a/src/types/models.ts b/src/types/models.ts index e06cbbfb..1b09b1d9 100644 --- a/src/types/models.ts +++ b/src/types/models.ts @@ -143,7 +143,7 @@ export type PublicationsResponse = z.infer<typeof publicationsResponseSchema>; export type Publication = z.infer<typeof publicationSchema>; export type ExportNetwork = z.infer<typeof exportNetworkchema>; export type ExportElements = z.infer<typeof exportElementsSchema>; -export type MinervaPlugin = z.infer<typeof pluginSchema>; // Plugin type interfers with global Plugin type +export type MinervaPlugin = z.infer<typeof pluginSchema>; // Plugin type interferes with global Plugin type export type GeneVariant = z.infer<typeof geneVariant>; export type TargetSearchNameResult = z.infer<typeof targetSearchNameResult>; export type TargetElement = z.infer<typeof targetElementSchema>; -- GitLab