diff --git a/src/components/FunctionalArea/MapNavigation/MapNavigation.component.tsx b/src/components/FunctionalArea/MapNavigation/MapNavigation.component.tsx
index 8bb19a16424e70d0c3a0dba4efc6d302308c80d0..293fba3afa23d0b794be74c90a7fe10966f011d8 100644
--- a/src/components/FunctionalArea/MapNavigation/MapNavigation.component.tsx
+++ b/src/components/FunctionalArea/MapNavigation/MapNavigation.component.tsx
@@ -1,12 +1,12 @@
-import { MouseEvent } from 'react';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { MAIN_MAP } from '@/redux/map/map.constants';
 import { mapModelIdSelector, mapOpenedMapsSelector } from '@/redux/map/map.selectors';
 import { closeMap, closeMapAndSetMainMapActive, setActiveMap } from '@/redux/map/map.slice';
 import { OppenedMap } from '@/redux/map/map.types';
 import { Button } from '@/shared/Button';
 import { Icon } from '@/shared/Icon';
-import { MAIN_MAP } from '@/redux/map/map.constants';
+import { MouseEvent } from 'react';
 import { twMerge } from 'tailwind-merge';
 
 export const MapNavigation = (): JSX.Element => {
diff --git a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsSearch/PublicationsSearch.component.tsx b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsSearch/PublicationsSearch.component.tsx
index be28bcdd044d53098e45c8ed29ad87c958d445b6..dd90e7d2739b3749bcef54b53bf28775fc44b73c 100644
--- a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsSearch/PublicationsSearch.component.tsx
+++ b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsSearch/PublicationsSearch.component.tsx
@@ -1,6 +1,6 @@
 import { ChangeEvent, useCallback, useEffect, useState } from 'react';
 import lensIcon from '@/assets/vectors/icons/lens.svg';
-import { useDebounce } from '@/hooks/useDebounce';
+import { useDebounce } from 'use-debounce';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { getPublications } from '@/redux/publications/publications.thunks';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
@@ -14,11 +14,13 @@ import Image from 'next/image';
 import { setPublicationSearchValue } from '@/redux/publications/publications.slice';
 import { DEFAULT_PAGE_SIZE } from '../PublicationsTable/PublicationsTable.constants';
 
+const DEFAULT_DELAY = 500;
+
 export const PublicationsSearch = (): JSX.Element => {
   const dispatch = useAppDispatch();
   const isLoading = useAppSelector(isLoadingSelector);
   const [value, setValue] = useState('');
-  const debouncedValue = useDebounce<string>(value);
+  const [debouncedValue] = useDebounce<string>(value, DEFAULT_DELAY);
   const sortColumn = useAppSelector(sortColumnSelector);
   const sortOrder = useAppSelector(sortOrderSelector);
   const selectedId = useAppSelector(selectedModelIdSelector);
diff --git a/src/components/FunctionalArea/NavBar/NavBar.component.tsx b/src/components/FunctionalArea/NavBar/NavBar.component.tsx
index 41177e15ebdf3dccdb1d870f0e78acf59c98f71d..f3ea9be4c88be844e78ff92b44c5965b42059e4b 100644
--- a/src/components/FunctionalArea/NavBar/NavBar.component.tsx
+++ b/src/components/FunctionalArea/NavBar/NavBar.component.tsx
@@ -4,6 +4,7 @@ import { openDrawer } from '@/redux/drawer/drawer.slice';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { openLegend } from '@/redux/legend/legend.slice';
 import { openLoginModal } from '@/redux/modal/modal.slice';
+import { openPluginsDrawer } from '@/redux/plugins/plugins.slice';
 import { IconButton } from '@/shared/IconButton';
 import Image from 'next/image';
 
@@ -16,6 +17,7 @@ export const NavBar = (): JSX.Element => {
 
   const openDrawerPlugins = (): void => {
     dispatch(openDrawer('available-plugins'));
+    dispatch(openPluginsDrawer());
   };
 
   const openDrawerExport = (): void => {
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/AvailablePluginsDrawer.component.test.tsx b/src/components/Map/Drawer/AvailablePluginsDrawer/AvailablePluginsDrawer.component.test.tsx
index 06d70d35abe59da6cf05b3c3700d991746cc3db8..436f89c6a9a4cd4737c4d4eb4627c2ffb65799fc 100644
--- a/src/components/Map/Drawer/AvailablePluginsDrawer/AvailablePluginsDrawer.component.test.tsx
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/AvailablePluginsDrawer.component.test.tsx
@@ -34,20 +34,23 @@ describe('AvailablePluginsDrawer - component', () => {
       expect(loadPluginFromUrlInput).toBeInTheDocument();
     });
 
-    it.each(PLUGINS_MOCK)('should render render all public plugins', currentPlugin => {
-      renderComponent({
-        ...INITIAL_STORE_STATE_MOCK,
-        plugins: {
-          ...INITIAL_STORE_STATE_MOCK.plugins,
-          list: {
-            ...INITIAL_STORE_STATE_MOCK.plugins.list,
-            data: PLUGINS_MOCK,
+    it.each(PLUGINS_MOCK.filter(p => p.isPublic))(
+      'should render render all public plugins',
+      currentPlugin => {
+        renderComponent({
+          ...INITIAL_STORE_STATE_MOCK,
+          plugins: {
+            ...INITIAL_STORE_STATE_MOCK.plugins,
+            list: {
+              ...INITIAL_STORE_STATE_MOCK.plugins.list,
+              data: PLUGINS_MOCK,
+            },
           },
-        },
-      });
+        });
 
-      const pluginLabel = screen.getByText(currentPlugin.name);
-      expect(pluginLabel).toBeInTheDocument();
-    });
+        const pluginLabel = screen.getByText(currentPlugin.name);
+        expect(pluginLabel).toBeInTheDocument();
+      },
+    );
   });
 });
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.test.tsx b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.test.tsx
index ba8ea94c6ced7739c43e902ac3ac60020959b57a..ca74841a981e53d189e46e52b9a859ca73856620 100644
--- a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.test.tsx
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.test.tsx
@@ -1,16 +1,19 @@
 /* eslint-disable no-magic-numbers */
 import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
 import { PLUGINS_MOCK } from '@/models/mocks/pluginsMock';
-import { render, screen } from '@testing-library/react';
-import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
-import { InitialStoreState } from '@/utils/testing/getReduxStoreActionsListener';
+import { apiPath } from '@/redux/apiPath';
+import {
+  PLUGINS_INITIAL_STATE_LIST_MOCK,
+  PLUGINS_INITIAL_STATE_MOCK,
+} from '@/redux/plugins/plugins.mock';
 import { StoreType } from '@/redux/store';
 import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
-import MockAdapter from 'axios-mock-adapter';
+import { InitialStoreState } from '@/utils/testing/getReduxStoreActionsListener';
+import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
+import { render, screen } from '@testing-library/react';
 import axios, { HttpStatusCode } from 'axios';
-import { apiPath } from '@/redux/apiPath';
+import MockAdapter from 'axios-mock-adapter';
 import { act } from 'react-dom/test-utils';
-import { PLUGINS_INITIAL_STATE_LIST_MOCK } from '@/redux/plugins/plugins.mock';
 import { LoadPlugin, Props } from './LoadPlugin.component';
 
 const mockedAxiosApiClient = mockNetworkResponse();
@@ -56,6 +59,7 @@ describe('LoadPlugin - component', () => {
         { plugin },
         {
           plugins: {
+            ...PLUGINS_INITIAL_STATE_MOCK,
             activePlugins: {
               data: {
                 [plugin.hash]: plugin,
@@ -81,6 +85,7 @@ describe('LoadPlugin - component', () => {
         { plugin },
         {
           plugins: {
+            ...PLUGINS_INITIAL_STATE_MOCK,
             activePlugins: {
               data: {
                 [plugin.hash]: plugin,
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.tsx b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.tsx
index f129d79d0797827601fbff4068bec1b27e5fca2e..72ec131e851a51671c7f8b9934948613937421fb 100644
--- a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.tsx
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/LoadPlugin.component.tsx
@@ -1,4 +1,6 @@
 /* eslint-disable no-magic-numbers */
+import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
+import { setCurrentDrawerPluginHash } from '@/redux/plugins/plugins.slice';
 import { Button } from '@/shared/Button';
 import { MinervaPlugin } from '@/types/models';
 import { useLoadPlugin } from './hooks/useLoadPlugin';
@@ -8,9 +10,14 @@ export interface Props {
 }
 
 export const LoadPlugin = ({ plugin }: Props): JSX.Element => {
+  const dispatch = useAppDispatch();
+
   const { isPluginActive, togglePlugin, isPluginLoading } = useLoadPlugin({
     hash: plugin.hash,
     pluginUrl: plugin.urls[0],
+    onPluginLoaded: () => {
+      dispatch(setCurrentDrawerPluginHash(plugin.hash));
+    },
   });
 
   return (
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/hooks/useLoadPlugin.test.ts b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/hooks/useLoadPlugin.test.ts
index 04245fbf3a2191bdfc1344bee1c12d75137339c9..0ea19da098cf1edb70be6367ba25b12d06b7e992 100644
--- a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/hooks/useLoadPlugin.test.ts
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/hooks/useLoadPlugin.test.ts
@@ -1,12 +1,12 @@
 /* eslint-disable no-magic-numbers */
+import { pluginFixture } from '@/models/fixtures/pluginFixture';
+import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
+import { PluginsManager } from '@/services/pluginsManager';
+import { getReduxStoreWithActionsListener } from '@/utils/testing/getReduxStoreActionsListener';
 import { renderHook, waitFor } from '@testing-library/react';
-import { act } from 'react-dom/test-utils';
 import axios, { HttpStatusCode } from 'axios';
-import { getReduxStoreWithActionsListener } from '@/utils/testing/getReduxStoreActionsListener';
-import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
 import MockAdapter from 'axios-mock-adapter';
-import { PluginsManager } from '@/services/pluginsManager';
-import { pluginFixture } from '@/models/fixtures/pluginFixture';
+import { act } from 'react-dom/test-utils';
 import { useLoadPlugin } from './useLoadPlugin';
 
 const mockedAxiosClient = new MockAdapter(axios);
@@ -20,6 +20,7 @@ describe('useLoadPlugin', () => {
     const { Wrapper, store } = getReduxStoreWithActionsListener({
       ...INITIAL_STORE_STATE_MOCK,
       plugins: {
+        ...INITIAL_STORE_STATE_MOCK.plugins,
         activePlugins: {
           pluginsId: [pluginFixture.hash],
           data: {
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/hooks/useLoadPlugin.ts b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/hooks/useLoadPlugin.ts
index d1b04f6549b8eb8b790302a7ff3ee31b45c822f7..454347303ae79a4683debd742c0108152eef805b 100644
--- a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/hooks/useLoadPlugin.ts
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/hooks/useLoadPlugin.ts
@@ -1,12 +1,20 @@
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
-import { isPluginActiveSelector, isPluginLoadingSelector } from '@/redux/plugins/plugins.selectors';
+import {
+  isPluginActiveSelector,
+  isPluginLoadingSelector,
+  isPluginSelectedSelector,
+} from '@/redux/plugins/plugins.selectors';
 import { removePlugin } from '@/redux/plugins/plugins.slice';
 import { PluginsManager } from '@/services/pluginsManager';
 import axios from 'axios';
 
 type UseLoadPluginReturnType = {
   togglePlugin: () => void;
+  loadPlugin: () => Promise<void>;
+  unloadPlugin: () => void;
+  reloadPlugin: () => void;
+  isPluginSelected: boolean;
   isPluginActive: boolean;
   isPluginLoading: boolean;
 };
@@ -14,11 +22,17 @@ type UseLoadPluginReturnType = {
 type UseLoadPluginProps = {
   hash: string;
   pluginUrl: string;
+  onPluginLoaded?(): void;
 };
 
-export const useLoadPlugin = ({ hash, pluginUrl }: UseLoadPluginProps): UseLoadPluginReturnType => {
+export const useLoadPlugin = ({
+  hash,
+  pluginUrl,
+  onPluginLoaded,
+}: UseLoadPluginProps): UseLoadPluginReturnType => {
   const isPluginActive = useAppSelector(state => isPluginActiveSelector(state, hash));
   const isPluginLoading = useAppSelector(state => isPluginLoadingSelector(state, hash));
+  const isPluginSelected = useAppSelector(state => isPluginSelectedSelector(state, hash));
 
   const dispatch = useAppDispatch();
 
@@ -35,10 +49,20 @@ export const useLoadPlugin = ({ hash, pluginUrl }: UseLoadPluginProps): UseLoadP
     });
 
     loadPlugin();
+
+    if (onPluginLoaded) {
+      onPluginLoaded();
+    }
   };
 
   const handleUnloadPlugin = (): void => {
     dispatch(removePlugin({ pluginId: hash }));
+    PluginsManager.removePluginContent({ hash });
+  };
+
+  const handleReloadPlugin = async (): Promise<void> => {
+    handleUnloadPlugin();
+    await handleLoadPlugin();
   };
 
   const togglePlugin = (): void => {
@@ -50,7 +74,11 @@ export const useLoadPlugin = ({ hash, pluginUrl }: UseLoadPluginProps): UseLoadP
   };
 
   return {
+    isPluginSelected,
     togglePlugin,
+    loadPlugin: handleLoadPlugin,
+    unloadPlugin: handleUnloadPlugin,
+    reloadPlugin: handleReloadPlugin,
     isPluginActive,
     isPluginLoading,
   };
diff --git a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPluginFromUrl/LoadPluginFromUrl.component.test.tsx b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPluginFromUrl/LoadPluginFromUrl.component.test.tsx
index 10d387fbba06a482aa6a79be309671efaabfd01c..b74995ed19be857c1ae509c14fd7f27c32bbfda5 100644
--- a/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPluginFromUrl/LoadPluginFromUrl.component.test.tsx
+++ b/src/components/Map/Drawer/AvailablePluginsDrawer/LoadPluginFromUrl/LoadPluginFromUrl.component.test.tsx
@@ -1,15 +1,18 @@
 /* eslint-disable no-magic-numbers */
-import { fireEvent, render, screen } from '@testing-library/react';
-import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
-import { InitialStoreState } from '@/utils/testing/getReduxStoreActionsListener';
+import { pluginFixture } from '@/models/fixtures/pluginFixture';
+import { apiPath } from '@/redux/apiPath';
+import {
+  PLUGINS_INITIAL_STATE_LIST_MOCK,
+  PLUGINS_INITIAL_STATE_MOCK,
+} from '@/redux/plugins/plugins.mock';
 import { StoreType } from '@/redux/store';
 import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
-import MockAdapter from 'axios-mock-adapter';
+import { InitialStoreState } from '@/utils/testing/getReduxStoreActionsListener';
+import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
+import { fireEvent, render, screen } from '@testing-library/react';
 import axios, { HttpStatusCode } from 'axios';
-import { apiPath } from '@/redux/apiPath';
-import { pluginFixture } from '@/models/fixtures/pluginFixture';
+import MockAdapter from 'axios-mock-adapter';
 import { act } from 'react-dom/test-utils';
-import { PLUGINS_INITIAL_STATE_LIST_MOCK } from '@/redux/plugins/plugins.mock';
 import { LoadPluginFromUrl } from './LoadPluginFromUrl.component';
 
 const mockedAxiosApiClient = mockNetworkResponse();
@@ -68,7 +71,7 @@ describe('LoadPluginFromUrl - component', () => {
       const input = screen.getByTestId('load-plugin-input-url');
       expect(input).toBeVisible();
 
-      act(() => {
+      await act(() => {
         fireEvent.change(input, { target: { value: pluginFixture.urls[0] } });
       });
 
@@ -77,7 +80,7 @@ describe('LoadPluginFromUrl - component', () => {
       const button = screen.queryByTestId('load-plugin-button');
       expect(button).toBeVisible();
 
-      act(() => {
+      await act(() => {
         button?.click();
       });
 
@@ -94,6 +97,7 @@ describe('LoadPluginFromUrl - component', () => {
 
       const { store } = renderComponent({
         plugins: {
+          ...PLUGINS_INITIAL_STATE_MOCK,
           activePlugins: {
             pluginsId: [plugin.hash],
             data: {
diff --git a/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx b/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx
index 2d60852eae90f9bb1e2912beca4ba75806913b93..6f3af87274b155a787252d1b46c6501c8f16ed52 100644
--- a/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx
+++ b/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx
@@ -4,6 +4,7 @@ import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { DrawerHeading } from '@/shared/DrawerHeading';
 import { AnnotationItem } from './AnnotationItem';
 import { AssociatedSubmap } from './AssociatedSubmap';
+import { OverlayData } from './OverlayData';
 
 export const BioEntityDrawer = (): React.ReactNode => {
   const bioEntityData = useAppSelector(searchedFromMapBioEntityElement);
@@ -15,7 +16,7 @@ export const BioEntityDrawer = (): React.ReactNode => {
   const isReferenceAvailable = bioEntityData.references.length > ZERO;
 
   return (
-    <div className="h-full max-h-full" data-testid="bioentity-drawer">
+    <div className="h-calc-drawer" data-testid="bioentity-drawer">
       <DrawerHeading
         title={
           <>
@@ -24,7 +25,7 @@ export const BioEntityDrawer = (): React.ReactNode => {
           </>
         }
       />
-      <div className="flex flex-col gap-6 p-6">
+      <div className="flex max-h-full flex-col gap-6 overflow-y-auto p-6">
         <div className="text-sm font-normal">
           Compartment: <b className="font-semibold">{bioEntityData.compartmentName}</b>
         </div>
@@ -47,6 +48,7 @@ export const BioEntityDrawer = (): React.ReactNode => {
             />
           ))}
         <AssociatedSubmap />
+        <OverlayData />
       </div>
     </div>
   );
diff --git a/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/GeneVariantsTable/GeneVariantsTable.component.test.tsx b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/GeneVariantsTable/GeneVariantsTable.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..8b31bae3b2194b80e86bfd8e688506b9df9bfaac
--- /dev/null
+++ b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/GeneVariantsTable/GeneVariantsTable.component.test.tsx
@@ -0,0 +1,37 @@
+import { GENE_VARIANTS_MOCK } from '@/models/mocks/geneVariantsMock';
+import { GeneVariant } from '@/types/models';
+import { render, screen } from '@testing-library/react';
+import { GeneVariantsTable } from './GeneVariantsTable.component';
+
+const renderComponent = (data: GeneVariant[]): void => {
+  render(<GeneVariantsTable data={data} />);
+};
+
+describe('GeneVariantsTable - component', () => {
+  beforeEach(() => {
+    renderComponent(GENE_VARIANTS_MOCK);
+  });
+
+  it('should render header', () => {
+    expect(screen.getByText('Contig')).toBeInTheDocument();
+    expect(screen.getByText('Position')).toBeInTheDocument();
+    expect(screen.getByText('From')).toBeInTheDocument();
+    expect(screen.getByText('To')).toBeInTheDocument();
+    expect(screen.getByText('rsID')).toBeInTheDocument();
+  });
+
+  it.each(GENE_VARIANTS_MOCK)(
+    'should render row',
+    ({ contig, position, originalDna, modifiedDna, variantIdentifier }) => {
+      const elements = [
+        screen.getAllByText(contig),
+        screen.getAllByText(position),
+        screen.getAllByText(originalDna),
+        screen.getAllByText(modifiedDna),
+        screen.getAllByText(variantIdentifier),
+      ].flat();
+
+      elements.forEach(element => expect(element).toBeInTheDocument());
+    },
+  );
+});
diff --git a/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/GeneVariantsTable/GeneVariantsTable.component.tsx b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/GeneVariantsTable/GeneVariantsTable.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..32eca4e581bd42c39657c1c267f60cd8659a6ef7
--- /dev/null
+++ b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/GeneVariantsTable/GeneVariantsTable.component.tsx
@@ -0,0 +1,35 @@
+import { TWO } from '@/constants/common';
+import { GeneVariant } from '@/types/models';
+import { twMerge } from 'tailwind-merge';
+
+interface Props {
+  data: GeneVariant[];
+}
+
+export const GeneVariantsTable = ({ data }: Props): JSX.Element => {
+  return (
+    <table className="rounded-lg text-xs shadow-tableBorderDivide">
+      <tr className="border-b border-divide text-left text-[#6A6977]">
+        <th className="py-4 pl-4 pt-5 font-light ">Contig</th>
+        <th className="py-4 pt-5 font-light">Position</th>
+        <th className="py-4 pt-5 font-light">From</th>
+        <th className="py-4 pt-5 font-light">To</th>
+        <th className="py-4 pr-4 pt-5 font-light">rsID</th>
+      </tr>
+      {data.map((variant, index) => {
+        const isOdd = index % TWO;
+        const isEven = !isOdd;
+
+        return (
+          <tr key={variant.position} className={twMerge('font-semibold', isEven && 'bg-[#F3F3F3]')}>
+            <td className="py-4 pl-4">{variant.contig}</td>
+            <td className="py-4">{variant.position}</td>
+            <td className="py-4">{variant.originalDna}</td>
+            <td className="py-4">{variant.modifiedDna}</td>
+            <td className="py-4 pr-4">{variant.variantIdentifier}</td>
+          </tr>
+        );
+      })}
+    </table>
+  );
+};
diff --git a/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/GeneVariantsTable/index.ts b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/GeneVariantsTable/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..810de4490a88f99a80c901720ae07aee11a21967
--- /dev/null
+++ b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/GeneVariantsTable/index.ts
@@ -0,0 +1 @@
+export { GeneVariantsTable } from './GeneVariantsTable.component';
diff --git a/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/OverlayAxis.component.test.tsx b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/OverlayAxis.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..0bfa8529c292b9f36d8753f760631701f752328d
--- /dev/null
+++ b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/OverlayAxis.component.test.tsx
@@ -0,0 +1,180 @@
+/* eslint-disable no-magic-numbers */
+import { ZERO } from '@/constants/common';
+import { GENE_VARIANTS_MOCK } from '@/models/mocks/geneVariantsMock';
+import { act, render, screen } from '@testing-library/react';
+import { OverlayDataAxis } from '../OverlayData.types';
+import { OverlayAxis } from './OverlayAxis.component';
+
+const renderComponent = (axis: OverlayDataAxis): void => {
+  render(<OverlayAxis axis={axis} />);
+};
+
+const BASE_AXIS: OverlayDataAxis = {
+  id: 123,
+  title: 'axis title',
+  value: 2137,
+  color: '#FFFFFF',
+  geneVariants: undefined,
+};
+
+describe('OverlayAxis - component', () => {
+  describe('when always', () => {
+    beforeEach(() => {
+      renderComponent(BASE_AXIS);
+    });
+
+    it('renders title', () => {
+      expect(screen.getByText('axis title')).toBeInTheDocument();
+    });
+
+    it('renders background with valid color', () => {
+      expect(screen.getByTestId('overlay-axis-bg')).toBeInTheDocument();
+      expect(screen.getByTestId('overlay-axis-bg').getAttribute('style')).toContain(
+        'background: rgba(255, 255, 255, 0.102);',
+      );
+    });
+
+    it('renders valid value title (when no gene variants)', () => {
+      expect(screen.getByTestId('overlay-axis-value')).toBeInTheDocument();
+      expect(screen.getByTestId('overlay-axis-value').innerHTML).toContain('2137');
+    });
+  });
+
+  describe('when value is positive', () => {
+    beforeEach(() => {
+      renderComponent({
+        ...BASE_AXIS,
+        value: 0.564234344,
+        color: '#FF0000',
+      });
+    });
+
+    it('renders bar with valid color and width', () => {
+      const axis = screen.getByTestId('overlay-axis-bg');
+      const bar = axis.childNodes[0] as HTMLElement;
+
+      expect(bar).toBeInTheDocument();
+      expect(bar?.getAttribute('class')).toContain('rounded-r');
+      expect(bar?.getAttribute('class')).toContain('left-1/2');
+      expect(bar?.getAttribute('style')).toContain('width: 28.211717200000002%;');
+      expect(bar?.getAttribute('style')).toContain('background: rgb(255, 0, 0);');
+    });
+
+    it('renders valid value title (when no gene variants)', () => {
+      expect(screen.getByTestId('overlay-axis-value')).toBeInTheDocument();
+      expect(screen.getByTestId('overlay-axis-value').innerHTML).toContain('0.56');
+    });
+  });
+
+  describe('when value is negative', () => {
+    beforeEach(() => {
+      renderComponent({
+        ...BASE_AXIS,
+        value: -0.3255323223,
+        color: '#00FF00',
+      });
+    });
+
+    it('renders bar with valid color and width', () => {
+      const axis = screen.getByTestId('overlay-axis-bg');
+      const bar = axis.childNodes[0] as HTMLElement;
+
+      expect(bar).toBeInTheDocument();
+      expect(bar?.getAttribute('class')).toContain('rounded-l');
+      expect(bar?.getAttribute('class')).toContain('right-1/2');
+      expect(bar?.getAttribute('style')).toContain('width: 16.276616115%;');
+      expect(bar?.getAttribute('style')).toContain('background: rgb(0, 255, 0);');
+    });
+
+    it('renders valid value title (when no gene variants)', () => {
+      expect(screen.getByTestId('overlay-axis-value')).toBeInTheDocument();
+      expect(screen.getByTestId('overlay-axis-value').innerHTML).toContain('-0.33');
+    });
+  });
+
+  describe('when value is zero', () => {
+    beforeEach(() => {
+      renderComponent({
+        ...BASE_AXIS,
+        value: 0,
+        color: '#0000FF',
+      });
+    });
+
+    it('renders bar with valid color and width', () => {
+      const axis = screen.getByTestId('overlay-axis-bg');
+      const bar = axis.childNodes[0] as HTMLElement;
+
+      expect(bar).toBeInTheDocument();
+      expect(bar?.getAttribute('class')).not.toContain('right-1/2');
+      expect(bar?.getAttribute('class')).not.toContain('rounded-l');
+      expect(bar?.getAttribute('class')).not.toContain('right-1/2');
+      expect(bar?.getAttribute('style')).toContain('width: 0%;');
+    });
+
+    it('renders valid value title (when no gene variants)', () => {
+      expect(screen.getByTestId('overlay-axis-value')).toBeInTheDocument();
+      expect(screen.getByTestId('overlay-axis-value').innerHTML).toContain('-');
+    });
+  });
+
+  describe('when value is undefined', () => {
+    beforeEach(() => {
+      renderComponent({
+        ...BASE_AXIS,
+        value: undefined,
+      });
+    });
+
+    it('renders bar with valid color and width', () => {
+      const axis = screen.getByTestId('overlay-axis-bg');
+      const bar = axis.childNodes[0] as HTMLElement;
+
+      expect(bar).toBeInTheDocument();
+      expect(bar?.getAttribute('class')).toContain('w-full');
+      expect(bar?.getAttribute('style')).toContain('width: 100%;');
+      expect(bar?.getAttribute('style')).toContain('background: rgb(255, 255, 255);');
+    });
+
+    it('renders valid value title (when no gene variants)', () => {
+      expect(screen.getByTestId('overlay-axis-value')).toBeInTheDocument();
+      expect(screen.getByTestId('overlay-axis-value').innerHTML).toContain('-');
+    });
+  });
+
+  describe('when there is gene variants', () => {
+    beforeEach(() => {
+      renderComponent({
+        ...BASE_AXIS,
+        geneVariants: GENE_VARIANTS_MOCK,
+      });
+    });
+
+    it('renders gene variants icon button', () => {
+      expect(screen.getByTestId('overlay-axis-icon')).toBeInTheDocument();
+    });
+
+    it('renders gene variants info icon', () => {
+      const infoIconWrapper = screen.getByTitle(
+        'Number of variants mapped to this gene. See their details in the tabular view below.',
+      );
+      const icon = infoIconWrapper.childNodes[1] as HTMLElement;
+
+      expect(infoIconWrapper).toBeInTheDocument();
+      expect(icon).toBeInTheDocument();
+    });
+
+    it('shows gene variants table on gene variants icon button click', () => {
+      const geneVariantsTable = screen.queryAllByText('Contig');
+      expect(geneVariantsTable.length).toEqual(ZERO);
+
+      const iconButton = screen.getByTestId('overlay-axis-icon');
+      act(() => {
+        iconButton.click();
+      });
+
+      const geneVariantsTableVisible = screen.getByText('Contig');
+      expect(geneVariantsTableVisible).toBeInTheDocument();
+    });
+  });
+});
diff --git a/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/OverlayAxis.component.tsx b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/OverlayAxis.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..7253c4d19f61646328575b14a85021e2513fa2a6
--- /dev/null
+++ b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/OverlayAxis.component.tsx
@@ -0,0 +1,70 @@
+import { Icon } from '@/shared/Icon';
+import { IconButton } from '@/shared/IconButton';
+import { useState } from 'react';
+import { twMerge } from 'tailwind-merge';
+import { OverlayDataAxis } from '../OverlayData.types';
+import { GeneVariantsTable } from './GeneVariantsTable';
+import { getOverlayAxisData } from './utils/getOverlayAxisProps';
+
+interface Props {
+  axis: OverlayDataAxis;
+}
+
+export const OverlayAxis = ({ axis }: Props): JSX.Element => {
+  const [showGeneVariants, setShowGeneVariants] = useState<boolean>(false);
+  const { title, background, bar, value } = getOverlayAxisData(axis);
+
+  const toggleShowGeneVariants = (): void => {
+    setShowGeneVariants(v => !v);
+  };
+
+  return (
+    <>
+      <div className="flex items-center gap-2 text-xs">
+        <div className="flex w-48 items-center justify-between gap-2 font-semibold">
+          <div>{title}</div>
+          {axis.geneVariants && (
+            <IconButton
+              icon={showGeneVariants ? 'chevron-up' : 'chevron-down'}
+              data-testid="overlay-axis-icon"
+              className="h-6 w-6 flex-shrink-0 bg-transparent p-0"
+              onClick={toggleShowGeneVariants}
+            />
+          )}
+        </div>
+        <div
+          className="relative h-6 w-full overflow-hidden rounded"
+          style={{ background: background.color }}
+          data-testid="overlay-axis-bg"
+        >
+          <div
+            className={twMerge(
+              'absolute h-full',
+              value.isPositive && 'left-1/2 rounded-r',
+              value.isNegative && 'right-1/2 rounded-l',
+              value.isUndefined && 'w-full',
+            )}
+            style={{ background: bar.color, width: `${bar.percentage}%` }}
+          />
+        </div>
+        <div
+          className="flex h-6 w-12 flex-shrink-0 items-center justify-center rounded border border-divide p-1 text-center font-semibold"
+          title={
+            axis.geneVariants
+              ? 'Number of variants mapped to this gene. See their details in the tabular view below.'
+              : undefined
+          }
+          data-testid="overlay-axis-value"
+        >
+          {value.title}
+          {axis.geneVariants && (
+            <span className="ml-[2px] flex">
+              <Icon name="info" className="h-3 w-3 fill-black" />
+            </span>
+          )}
+        </div>
+      </div>
+      {axis.geneVariants && showGeneVariants && <GeneVariantsTable data={axis.geneVariants} />}
+    </>
+  );
+};
diff --git a/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/index.ts b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ce74e82b2073179d8811d55546f9acdbcc3f23e8
--- /dev/null
+++ b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/index.ts
@@ -0,0 +1 @@
+export { OverlayAxis } from './OverlayAxis.component';
diff --git a/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/utils/getOverlayAxisProps.ts b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/utils/getOverlayAxisProps.ts
new file mode 100644
index 0000000000000000000000000000000000000000..20c00c194dfb97705137222012b427cfe2e0f17e
--- /dev/null
+++ b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayAxis/utils/getOverlayAxisProps.ts
@@ -0,0 +1,61 @@
+import { ONE_DECIMAL, ONE_HUNDRED, TWO, ZERO } from '@/constants/common';
+import { HALF } from '@/constants/dividers';
+import { addAlphaToHexString } from '@/utils/convert/addAlphaToHexString';
+import { OverlayDataAxis } from '../../OverlayData.types';
+
+interface OverlayAxisProps {
+  title: string;
+  background: {
+    color: string;
+  };
+  bar: {
+    color: string;
+    percentage: number;
+  };
+  value: {
+    title: string;
+    isPositive: boolean;
+    isNegative: boolean;
+    isUndefined: boolean;
+  };
+}
+
+const FULL_WIDTH = 100;
+const DEFAULT_VALUE_TITLE = '-';
+
+const getBarPercentage = (value?: number): number => {
+  const valueNormalized = value || ZERO;
+  const isValueUndefined = typeof value === 'undefined';
+
+  const valuePositivePercentage = Math.abs(valueNormalized) * ONE_HUNDRED;
+  const valuePositivePercentageHalf = valuePositivePercentage / HALF; // 100% = full width of posivie OR negative chart SIDE
+
+  return isValueUndefined ? FULL_WIDTH : valuePositivePercentageHalf; // axis without value = 100% both sides width
+};
+
+const getValueTitle = (axis: OverlayDataAxis): string => {
+  if (axis?.geneVariants) {
+    return axis.geneVariants.length.toString();
+  }
+
+  return axis.value ? axis.value.toFixed(TWO) : DEFAULT_VALUE_TITLE;
+};
+
+export const getOverlayAxisData = (axis: OverlayDataAxis): OverlayAxisProps => {
+  return {
+    title: axis.title,
+    background: {
+      color: addAlphaToHexString(axis.color, ONE_DECIMAL),
+    },
+    bar: {
+      color: axis.color,
+      percentage: getBarPercentage(axis.value),
+    },
+    value: {
+      title: getValueTitle(axis),
+      isUndefined: typeof axis.value === 'undefined',
+      isPositive: axis.value ? axis.value > ZERO : false,
+      isNegative: axis.value ? axis.value < ZERO : false,
+    },
+  };
+};
diff --git a/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayData.component.test.tsx b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayData.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..ac239c2fc2e98eeb77c5ff51d07d4b95c07725d9
--- /dev/null
+++ b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayData.component.test.tsx
@@ -0,0 +1,116 @@
+/* eslint-disable no-magic-numbers */
+import { ZERO } from '@/constants/common';
+import { bioEntitiesContentFixture } from '@/models/fixtures/bioEntityContentsFixture';
+import { overlayFixture } from '@/models/fixtures/overlaysFixture';
+import { GENE_VARIANTS_MOCK } from '@/models/mocks/geneVariantsMock';
+import { CORE_PD_MODEL_MOCK } from '@/models/mocks/modelsMock';
+import { initialMapStateFixture } from '@/redux/map/map.fixtures';
+import { MODELS_INITIAL_STATE_MOCK } from '@/redux/models/models.mock';
+import {
+  MOCKED_OVERLAY_BIO_ENTITY_RENDER,
+  OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK,
+} from '@/redux/overlayBioEntity/overlayBioEntity.mock';
+import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
+import { StoreType } from '@/redux/store';
+import { InitialStoreState } from '@/utils/testing/getReduxStoreActionsListener';
+import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
+import { render, screen } from '@testing-library/react';
+import { OverlayData } from './OverlayData.component';
+
+const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
+  const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState);
+
+  return (
+    render(
+      <Wrapper>
+        <OverlayData />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+describe('OverlayData - component', () => {
+  describe('when axes list is empty', () => {
+    beforeEach(() => {
+      renderComponent({});
+    });
+
+    it('should not render component', () => {
+      expect(screen.queryAllByText('Overlay data:').length).toEqual(ZERO);
+    });
+  });
+
+  describe('when axes list is present', () => {
+    beforeEach(() => {
+      const OVERLAY_ID = overlayFixture.idObject;
+      const BIO_ENTITY = MOCKED_OVERLAY_BIO_ENTITY_RENDER[0];
+
+      renderComponent({
+        ...INITIAL_STORE_STATE_MOCK,
+        map: {
+          ...initialMapStateFixture,
+          data: { ...initialMapStateFixture.data, modelId: CORE_PD_MODEL_MOCK.idObject },
+        },
+        overlays: {
+          ...INITIAL_STORE_STATE_MOCK.overlays,
+          data: [{ ...overlayFixture, name: 'axis name' }],
+        },
+        bioEntity: {
+          data: [
+            {
+              searchQueryElement: '',
+              loading: 'pending',
+              error: { name: '', message: '' },
+              data: [
+                {
+                  ...bioEntitiesContentFixture[0],
+                  bioEntity: {
+                    ...bioEntitiesContentFixture[0].bioEntity,
+                    id: BIO_ENTITY.id,
+                  },
+                },
+              ],
+            },
+          ],
+          loading: 'pending',
+          error: { name: '', message: '' },
+        },
+        overlayBioEntity: {
+          ...OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK,
+          overlaysId: [OVERLAY_ID],
+          data: {
+            [OVERLAY_ID]: {
+              [CORE_PD_MODEL_MOCK.idObject]: [
+                {
+                  ...BIO_ENTITY,
+                  geneVariants: GENE_VARIANTS_MOCK,
+                  modelId: CORE_PD_MODEL_MOCK.idObject,
+                  overlayId: OVERLAY_ID,
+                },
+              ],
+            },
+          },
+        },
+        models: { ...MODELS_INITIAL_STATE_MOCK, data: [CORE_PD_MODEL_MOCK] },
+        drawer: {
+          ...INITIAL_STORE_STATE_MOCK.drawer,
+          bioEntityDrawerState: {
+            ...INITIAL_STORE_STATE_MOCK.drawer.bioEntityDrawerState,
+            bioentityId: BIO_ENTITY.id,
+          },
+        },
+      });
+    });
+
+    it('should render title', () => {
+      expect(screen.getByText('Overlay data:')).toBeInTheDocument();
+    });
+
+    it('should render axis title', () => {
+      expect(screen.getByText('axis name')).toBeInTheDocument();
+    });
+  });
+});
diff --git a/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayData.component.tsx b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayData.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..b4c193f2b23e57a1087b983d53ff00cc99736b4f
--- /dev/null
+++ b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayData.component.tsx
@@ -0,0 +1,22 @@
+import { ZERO } from '@/constants/common';
+import { OverlayAxis } from './OverlayAxis';
+import { useOverlaysAxes } from './utils/useOverlaysAxes';
+
+export const OverlayData = (): JSX.Element | null => {
+  const axes = useOverlaysAxes();
+
+  if (axes.length === ZERO) {
+    return null;
+  }
+
+  return (
+    <div>
+      <h3 className="mb-2 font-semibold">Overlay data:</h3>
+      <div className="flex flex-col gap-2 rounded-lg border border-divide p-4">
+        {axes.map(axis => (
+          <OverlayAxis key={axis.title} axis={axis} />
+        ))}
+      </div>
+    </div>
+  );
+};
diff --git a/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayData.types.ts b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayData.types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4f78ef6121607c3a6fd06c7dc17303f8652075d0
--- /dev/null
+++ b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/OverlayData.types.ts
@@ -0,0 +1,9 @@
+import { GeneVariant } from '@/types/models';
+
+export interface OverlayDataAxis {
+  id: number;
+  title: string;
+  value?: number;
+  color: string;
+  geneVariants?: GeneVariant[] | null;
+}
diff --git a/src/components/Map/Drawer/BioEntityDrawer/OverlayData/index.ts b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0b003968ce0f0849e234c5db6d47301cfa412cd4
--- /dev/null
+++ b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/index.ts
@@ -0,0 +1 @@
+export { OverlayData } from './OverlayData.component';
diff --git a/src/components/Map/Drawer/BioEntityDrawer/OverlayData/utils/useOverlaysAxes.ts b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/utils/useOverlaysAxes.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d7735979501adc9e868b6195bf97a2b856cd2b34
--- /dev/null
+++ b/src/components/Map/Drawer/BioEntityDrawer/OverlayData/utils/useOverlaysAxes.ts
@@ -0,0 +1,32 @@
+import { useGetOverlayColor } from '@/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor';
+import { ONE } from '@/constants/common';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import {
+  overlaysBioEntityForCurrentBioEntityAndCurrentModelSelector,
+  overlaysOpenedSelector,
+} from '@/redux/overlayBioEntity/overlayBioEntity.selector';
+import { useSelector } from 'react-redux';
+import { OverlayDataAxis } from '../OverlayData.types';
+
+export const useOverlaysAxes = (): OverlayDataAxis[] => {
+  const openedOverlays = useSelector(overlaysOpenedSelector);
+  const currentBioEntityOverlaysForCurrentBioEntity = useAppSelector(
+    overlaysBioEntityForCurrentBioEntityAndCurrentModelSelector,
+  );
+
+  const { getOverlayBioEntityColorByAvailableProperties } = useGetOverlayColor({
+    forceOpacityValue: ONE,
+  });
+
+  return currentBioEntityOverlaysForCurrentBioEntity.map((overlayBioEntity): OverlayDataAxis => {
+    const overlay = openedOverlays.find(o => o.idObject === overlayBioEntity.overlayId);
+
+    return {
+      id: overlayBioEntity.id,
+      title: overlay?.name || '',
+      value: overlayBioEntity.value || undefined,
+      color: getOverlayBioEntityColorByAvailableProperties(overlayBioEntity),
+      geneVariants: overlayBioEntity?.geneVariants,
+    };
+  });
+};
diff --git a/src/components/Map/Legend/LegendImages/LegendImages.component.tsx b/src/components/Map/Legend/LegendImages/LegendImages.component.tsx
index 04516e4450660af1b005f40926612fb2a7eb108b..dfc49d8fe3d51cee153d75a2adc952fe9f6541e6 100644
--- a/src/components/Map/Legend/LegendImages/LegendImages.component.tsx
+++ b/src/components/Map/Legend/LegendImages/LegendImages.component.tsx
@@ -16,7 +16,7 @@ export const LegendImages: React.FC = () => {
           key={imageUrl}
           src={`${BASE_MAP_IMAGES_URL}/minerva/${imageUrl}`}
           alt={imageUrl}
-          className="h-[400px]"
+          className="h-[400px] max-h-[50vh]"
         />
       ))}
     </div>
diff --git a/src/components/Map/Map.component.tsx b/src/components/Map/Map.component.tsx
index 36ac1a1f14fe6f6f65ec250f55ee29c396c69128..72d18ebf86457d7f39ad4298f86ed6a3adea8395 100644
--- a/src/components/Map/Map.component.tsx
+++ b/src/components/Map/Map.component.tsx
@@ -3,6 +3,7 @@ import { Legend } from '@/components/Map/Legend';
 import { MapAdditionalActions } from './MapAdditionalActions';
 import { MapAdditionalOptions } from './MapAdditionalOptions';
 import { MapViewer } from './MapViewer/MapViewer.component';
+import { PluginsDrawer } from './PluginsDrawer';
 
 export const Map = (): JSX.Element => (
   <div
@@ -11,6 +12,7 @@ export const Map = (): JSX.Element => (
   >
     <MapAdditionalOptions />
     <Drawer />
+    <PluginsDrawer />
     <MapViewer />
     <Legend />
     <MapAdditionalActions />
diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.ts
index 64518c5e005318aca9f21c9635478e735043330b..46d7190721fbb14929d055cdeead41208bde90d3 100644
--- a/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.ts
+++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.ts
@@ -1,4 +1,4 @@
-import { useCallback, useMemo } from 'react';
+import { ONE, ZERO } from '@/constants/common';
 import { WHITE_HEX_OPACITY_0 } from '@/constants/hexColors';
 import {
   maxColorValSelector,
@@ -8,11 +8,11 @@ import {
   simpleColorValSelector,
 } from '@/redux/configuration/configuration.selectors';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
-import { getHexTricolorGradientColorWithAlpha } from '@/utils/convert/getHexTricolorGradientColorWithAlpha';
-import { ONE, ZERO } from '@/constants/common';
 import { OverlayBioEntityRender } from '@/types/OLrendering';
 import { addAlphaToHexString } from '@/utils/convert/addAlphaToHexString';
 import { getHexStringColorFromRGBIntWithAlpha } from '@/utils/convert/getHexStringColorFromRGBIntWithAlpha';
+import { getHexTricolorGradientColorWithAlpha } from '@/utils/convert/getHexTricolorGradientColorWithAlpha';
+import { useCallback, useMemo } from 'react';
 
 type GetOverlayBioEntityColorByAvailableProperties = (entity: OverlayBioEntityRender) => string;
 
@@ -20,12 +20,17 @@ type UseTriColorLerpReturn = {
   getOverlayBioEntityColorByAvailableProperties: GetOverlayBioEntityColorByAvailableProperties;
 };
 
-export const useGetOverlayColor = (): UseTriColorLerpReturn => {
+interface Props {
+  forceOpacityValue?: number;
+}
+
+export const useGetOverlayColor = ({ forceOpacityValue }: Props = {}): UseTriColorLerpReturn => {
   const minColorValHexString = useAppSelector(minColorValSelector) || '';
   const maxColorValHexString = useAppSelector(maxColorValSelector) || '';
   const neutralColorValHexString = useAppSelector(neutralColorValSelector) || '';
-  const overlayOpacityValue = useAppSelector(overlayOpacitySelector) || ONE;
   const simpleColorValue = useAppSelector(simpleColorValSelector) || WHITE_HEX_OPACITY_0;
+  const overlayOpacityDefaultValue = useAppSelector(overlayOpacitySelector);
+  const overlayOpacityValue = forceOpacityValue || overlayOpacityDefaultValue || ONE;
 
   const getHex3ColorGradientColorWithAlpha = useCallback(
     (position: number) =>
diff --git a/src/components/Map/PluginsDrawer/PluginContent/PluginContent.component.test.tsx b/src/components/Map/PluginsDrawer/PluginContent/PluginContent.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..94f0d4f0b417e010935fd2296bfa45111e64130a
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginContent/PluginContent.component.test.tsx
@@ -0,0 +1,44 @@
+import { PLUGINS_CONTENT_ELEMENT_ID } from '@/constants/plugins';
+import { PLUGINS_INITIAL_STATE_MOCK } from '@/redux/plugins/plugins.mock';
+import { StoreType } from '@/redux/store';
+import { InitialStoreState } from '@/utils/testing/getReduxStoreActionsListener';
+import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
+import { render, screen } from '@testing-library/react';
+import { PluginContent } from './PluginContent.component';
+
+const renderComponent = (initialStore?: InitialStoreState): { store: StoreType } => {
+  const { Wrapper, store } = getReduxWrapperWithStore(initialStore);
+  return (
+    render(
+      <Wrapper>
+        <PluginContent />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+describe('PluginContent - component', () => {
+  describe('when always', () => {
+    beforeEach(() => {
+      renderComponent({
+        plugins: {
+          ...PLUGINS_INITIAL_STATE_MOCK,
+        },
+      });
+    });
+
+    it('should render plugins content', () => {
+      const element = screen.getByTestId('drawer-plugins-content');
+      expect(element).toBeInTheDocument();
+      expect(element.id).toBe(PLUGINS_CONTENT_ELEMENT_ID);
+    });
+  });
+
+  /*
+    NOTE:
+    Testing of <style jsx global> is not possible in Jest
+  */
+});
diff --git a/src/components/Map/PluginsDrawer/PluginContent/PluginContent.component.tsx b/src/components/Map/PluginsDrawer/PluginContent/PluginContent.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..143111c73513f1839bc13ef8782cc5905ebb291b
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginContent/PluginContent.component.tsx
@@ -0,0 +1,19 @@
+import { PLUGINS_CONTENT_ELEMENT_ID } from '@/constants/plugins';
+import { selectedDrawerPluginSelector } from '@/redux/plugins/plugins.selectors';
+import { useSelector } from 'react-redux';
+import { getPluginContentStyle } from './utils/getPluginContentStyle';
+
+export const PluginContent = (): JSX.Element => {
+  const selectedPlugin = useSelector(selectedDrawerPluginSelector);
+
+  return (
+    <>
+      <style jsx global>
+        {`
+          ${getPluginContentStyle(selectedPlugin)}
+        `}
+      </style>
+      <div id={PLUGINS_CONTENT_ELEMENT_ID} data-testid="drawer-plugins-content" />
+    </>
+  );
+};
diff --git a/src/components/Map/PluginsDrawer/PluginContent/PluginContent.constants.ts b/src/components/Map/PluginsDrawer/PluginContent/PluginContent.constants.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3ae40067bebcde4fc3c044fe157ec7ac1396e5d9
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginContent/PluginContent.constants.ts
@@ -0,0 +1,13 @@
+import { PLUGINS_CONTENT_ELEMENT_ATTR_NAME } from '@/constants/plugins';
+
+export const HIDE_ALL_ELEMENTS_STYLE = `
+    div[${PLUGINS_CONTENT_ELEMENT_ATTR_NAME}] {
+        display: none;
+    }
+`;
+
+export const SHOW_SELECTED_PLUGIN_ELEMENT_STYLE = (hash: string): string => `
+    div[${PLUGINS_CONTENT_ELEMENT_ATTR_NAME}='${hash}'] {
+        display: unset;
+    }
+`;
diff --git a/src/components/Map/PluginsDrawer/PluginContent/index.ts b/src/components/Map/PluginsDrawer/PluginContent/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f9abaf2a060404190f50b12a5c09f47420fba366
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginContent/index.ts
@@ -0,0 +1 @@
+export { PluginContent } from './PluginContent.component';
diff --git a/src/components/Map/PluginsDrawer/PluginContent/utils/getPluginContentStyle.test.ts b/src/components/Map/PluginsDrawer/PluginContent/utils/getPluginContentStyle.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..137c33be0961f593b34dcb11dd6e15ccdbe7cff5
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginContent/utils/getPluginContentStyle.test.ts
@@ -0,0 +1,26 @@
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { PLUGINS_MOCK } from '@/models/mocks/pluginsMock';
+import {
+  HIDE_ALL_ELEMENTS_STYLE,
+  SHOW_SELECTED_PLUGIN_ELEMENT_STYLE,
+} from '../PluginContent.constants';
+import { getPluginContentStyle } from './getPluginContentStyle';
+
+describe('getPluginContentStyle - util', () => {
+  describe('when selectedPlugin is NOT present', () => {
+    it('should return valid value', () => {
+      expect(getPluginContentStyle(undefined)).toBe(HIDE_ALL_ELEMENTS_STYLE);
+    });
+  });
+
+  describe('when selectedPlugin is present', () => {
+    const selectedPlugin = PLUGINS_MOCK[FIRST_ARRAY_ELEMENT];
+
+    it('should return valid value', () => {
+      const result = getPluginContentStyle(selectedPlugin);
+
+      expect(result.includes(HIDE_ALL_ELEMENTS_STYLE)).toBeTruthy();
+      expect(result.includes(SHOW_SELECTED_PLUGIN_ELEMENT_STYLE(selectedPlugin.hash))).toBeTruthy();
+    });
+  });
+});
diff --git a/src/components/Map/PluginsDrawer/PluginContent/utils/getPluginContentStyle.ts b/src/components/Map/PluginsDrawer/PluginContent/utils/getPluginContentStyle.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c6befb4538b127e16f95a8ddd4d179ed4896e175
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginContent/utils/getPluginContentStyle.ts
@@ -0,0 +1,16 @@
+import { MinervaPlugin } from '@/types/models';
+import {
+  HIDE_ALL_ELEMENTS_STYLE,
+  SHOW_SELECTED_PLUGIN_ELEMENT_STYLE,
+} from '../PluginContent.constants';
+
+export const getPluginContentStyle = (selectedPlugin?: MinervaPlugin): string => {
+  if (!selectedPlugin) {
+    return HIDE_ALL_ELEMENTS_STYLE;
+  }
+
+  return `
+    ${HIDE_ALL_ELEMENTS_STYLE}
+    ${SHOW_SELECTED_PLUGIN_ELEMENT_STYLE(selectedPlugin.hash)}
+  `;
+};
diff --git a/src/components/Map/PluginsDrawer/PluginsDrawer.component.test.tsx b/src/components/Map/PluginsDrawer/PluginsDrawer.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..47fde9e052c6d8703833d8f07854b951aa38b029
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsDrawer.component.test.tsx
@@ -0,0 +1,88 @@
+import { StoreType } from '@/redux/store';
+import { InitialStoreState } from '@/utils/testing/getReduxStoreActionsListener';
+import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
+
+import { PLUGINS_INITIAL_STATE_MOCK } from '@/redux/plugins/plugins.mock';
+import { render, screen } from '@testing-library/react';
+import { PluginsDrawer } from './PluginsDrawer.component';
+import { PLUGINS_DRAWER_ROLE } from './PluginsDrawer.constants';
+
+const renderComponent = (initialStore?: InitialStoreState): { store: StoreType } => {
+  const { Wrapper, store } = getReduxWrapperWithStore(initialStore);
+  return (
+    render(
+      <Wrapper>
+        <PluginsDrawer />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+describe('PluginsDrawer - component', () => {
+  describe('when drawer is open', () => {
+    beforeEach(() => {
+      renderComponent({
+        plugins: {
+          ...PLUGINS_INITIAL_STATE_MOCK,
+          drawer: {
+            ...PLUGINS_INITIAL_STATE_MOCK.drawer,
+            isOpen: false,
+          },
+        },
+      });
+    });
+
+    it('should render component without show class', () => {
+      const drawer = screen.getByRole(PLUGINS_DRAWER_ROLE);
+
+      expect(drawer).not.toHaveClass('translate-x-0');
+    });
+  });
+
+  describe('when drawer is NOT open', () => {
+    beforeEach(() => {
+      renderComponent({
+        plugins: {
+          ...PLUGINS_INITIAL_STATE_MOCK,
+          drawer: {
+            ...PLUGINS_INITIAL_STATE_MOCK.drawer,
+            isOpen: true,
+          },
+        },
+      });
+    });
+
+    it('should render component without show class', () => {
+      const drawer = screen.getByRole(PLUGINS_DRAWER_ROLE);
+      expect(drawer).toHaveClass('translate-x-0');
+    });
+  });
+
+  describe('when always', () => {
+    beforeEach(() => {
+      renderComponent({
+        plugins: {
+          ...PLUGINS_INITIAL_STATE_MOCK,
+        },
+      });
+    });
+
+    it('should render plugins tab', () => {
+      const element = screen.getByTestId('drawer-plugins-tab');
+      expect(element).toBeInTheDocument();
+    });
+
+    it('should render plugins tab', () => {
+      const element = screen.getByTestId('drawer-plugins-header');
+      expect(element).toBeInTheDocument();
+    });
+
+    it('should render plugins content', () => {
+      const element = screen.getByTestId('drawer-plugins-content');
+      expect(element).toBeInTheDocument();
+    });
+  });
+});
diff --git a/src/components/Map/PluginsDrawer/PluginsDrawer.component.tsx b/src/components/Map/PluginsDrawer/PluginsDrawer.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..c06d9774d177c066f0061b32c875f0d9d5abdbb9
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsDrawer.component.tsx
@@ -0,0 +1,25 @@
+import { pluginsDrawerSelector } from '@/redux/plugins/plugins.selectors';
+import { useSelector } from 'react-redux';
+import { twMerge } from 'tailwind-merge';
+import { PluginContent } from './PluginContent';
+import { PLUGINS_DRAWER_ROLE } from './PluginsDrawer.constants';
+import { PluginsHeader } from './PluginsHeader';
+import { PluginsTabs } from './PluginsTabs/PluginsTabs.component';
+
+export const PluginsDrawer = (): JSX.Element => {
+  const { isOpen } = useSelector(pluginsDrawerSelector);
+
+  return (
+    <div
+      className={twMerge(
+        'absolute bottom-0 right-0 top-[104px] z-20 h-calc-drawer w-[432px] translate-x-full transform border border-divide bg-white-pearl text-font-500 transition-all duration-500',
+        isOpen && 'translate-x-0',
+      )}
+      role={PLUGINS_DRAWER_ROLE}
+    >
+      <PluginsTabs />
+      <PluginsHeader />
+      <PluginContent />
+    </div>
+  );
+};
diff --git a/src/components/Map/PluginsDrawer/PluginsDrawer.constants.ts b/src/components/Map/PluginsDrawer/PluginsDrawer.constants.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4ce466ee6411f84378ae21ec8eacaae6cdbad573
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsDrawer.constants.ts
@@ -0,0 +1,2 @@
+export const PLUGINS_DRAWER_ROLE = 'plugins-drawer';
+export const CLOSE_PLUGINS_DRAWER_BUTTON_ROLE = 'close-plugins-drawer-drawer-button';
diff --git a/src/components/Map/PluginsDrawer/PluginsHeader/PluginHeaderInfo/PluginHeaderInfo.component.test.tsx b/src/components/Map/PluginsDrawer/PluginsHeader/PluginHeaderInfo/PluginHeaderInfo.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..fa013b073f5244e1197cf346cccb29aa26ffa770
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsHeader/PluginHeaderInfo/PluginHeaderInfo.component.test.tsx
@@ -0,0 +1,104 @@
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { PLUGINS_MOCK } from '@/models/mocks/pluginsMock';
+import {
+  PLUGINS_INITIAL_STATE_LIST_MOCK,
+  PLUGINS_INITIAL_STATE_MOCK,
+} from '@/redux/plugins/plugins.mock';
+import { AppDispatch, RootState } from '@/redux/store';
+import { PluginsManager } from '@/services/pluginsManager';
+import { MinervaPlugin } from '@/types/models';
+import {
+  InitialStoreState,
+  getReduxStoreWithActionsListener,
+} from '@/utils/testing/getReduxStoreActionsListener';
+import { render, screen, waitFor } from '@testing-library/react';
+import axios, { HttpStatusCode } from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import { MockStoreEnhanced } from 'redux-mock-store';
+import { PluginHeaderInfo } from './PluginHeaderInfo.component';
+import { RELOAD_PLUGIN_DRAWER_BUTTON_ROLE } from './PluginHeaderInfo.constants';
+
+const mockedAxiosClient = new MockAdapter(axios);
+
+const renderComponent = (
+  initialStore: InitialStoreState,
+  plugin: MinervaPlugin,
+): { store: MockStoreEnhanced<Partial<RootState>, AppDispatch> } => {
+  const { Wrapper, store } = getReduxStoreWithActionsListener(initialStore);
+  return (
+    render(
+      <Wrapper>
+        <PluginHeaderInfo plugin={plugin} />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+const removePluginContentSpy = jest.spyOn(PluginsManager, 'removePluginContent');
+const setHashedPluginSpy = jest.spyOn(PluginsManager, 'setHashedPlugin');
+
+const PLUGIN = PLUGINS_MOCK[FIRST_ARRAY_ELEMENT];
+
+const STATE = {
+  plugins: {
+    ...PLUGINS_INITIAL_STATE_MOCK,
+    drawer: {
+      ...PLUGINS_INITIAL_STATE_MOCK.drawer,
+      currentPluginHash: PLUGIN.hash,
+    },
+    activePlugins: {
+      data: {
+        [PLUGIN.hash]: PLUGIN,
+      },
+      pluginsId: [PLUGIN.hash],
+    },
+    list: PLUGINS_INITIAL_STATE_LIST_MOCK,
+  },
+};
+
+describe('PluginHeaderInfo - component', () => {
+  it('renders plugin title and name', () => {
+    renderComponent(STATE, PLUGIN);
+
+    const title = screen.getByText(`Plugin:`, { exact: false });
+    const pluginName = screen.getByText(PLUGIN.name, { exact: false });
+
+    expect(title).toBeInTheDocument();
+    expect(pluginName).toBeInTheDocument();
+  });
+
+  it('renders plugin reload button', () => {
+    renderComponent(STATE, PLUGIN);
+
+    const button = screen.getByRole(RELOAD_PLUGIN_DRAWER_BUTTON_ROLE);
+    expect(button).toBeInTheDocument();
+  });
+
+  it('reload plugin on reload button', async () => {
+    const { store } = renderComponent(STATE, PLUGIN);
+    mockedAxiosClient.onGet(PLUGIN.urls[FIRST_ARRAY_ELEMENT]).reply(HttpStatusCode.Ok, '');
+
+    const button = screen.getByRole(RELOAD_PLUGIN_DRAWER_BUTTON_ROLE);
+    button.click();
+
+    const actions = store.getActions();
+
+    expect(removePluginContentSpy).toHaveBeenCalledWith({
+      hash: PLUGIN.hash,
+    });
+
+    expect(actions).toEqual([
+      { payload: { pluginId: '5e3fcb59588cc311ef9839feea6382eb' }, type: 'plugins/removePlugin' },
+    ]);
+
+    await waitFor(() => {
+      expect(setHashedPluginSpy).toHaveBeenCalledWith({
+        pluginScript: '',
+        pluginUrl: 'https://minerva-service.lcsb.uni.lu/plugins/disease-associations/plugin.js',
+      });
+    });
+  });
+});
diff --git a/src/components/Map/PluginsDrawer/PluginsHeader/PluginHeaderInfo/PluginHeaderInfo.component.tsx b/src/components/Map/PluginsDrawer/PluginsHeader/PluginHeaderInfo/PluginHeaderInfo.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..43844ab06cec1fd88be84d6672985ff625b5bc31
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsHeader/PluginHeaderInfo/PluginHeaderInfo.component.tsx
@@ -0,0 +1,32 @@
+import { useLoadPlugin } from '@/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/hooks/useLoadPlugin';
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
+import { setCurrentDrawerPluginHash } from '@/redux/plugins/plugins.slice';
+import { Icon } from '@/shared/Icon';
+import { MinervaPlugin } from '@/types/models';
+import { RELOAD_PLUGIN_DRAWER_BUTTON_ROLE } from './PluginHeaderInfo.constants';
+
+interface Props {
+  plugin: MinervaPlugin;
+}
+
+export const PluginHeaderInfo = ({ plugin }: Props): JSX.Element => {
+  const dispatch = useAppDispatch();
+
+  const { reloadPlugin } = useLoadPlugin({
+    hash: plugin.hash,
+    pluginUrl: plugin.urls[FIRST_ARRAY_ELEMENT],
+    onPluginLoaded: () => {
+      dispatch(setCurrentDrawerPluginHash(plugin.hash));
+    },
+  });
+
+  return (
+    <>
+      Plugin: <b>{plugin.name}</b>
+      <button type="button" onClick={reloadPlugin} role={RELOAD_PLUGIN_DRAWER_BUTTON_ROLE}>
+        <Icon name="reload" />
+      </button>
+    </>
+  );
+};
diff --git a/src/components/Map/PluginsDrawer/PluginsHeader/PluginHeaderInfo/PluginHeaderInfo.constants.ts b/src/components/Map/PluginsDrawer/PluginsHeader/PluginHeaderInfo/PluginHeaderInfo.constants.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5dd2302271dd9a6d6946f5929081443bfa9fa1e3
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsHeader/PluginHeaderInfo/PluginHeaderInfo.constants.ts
@@ -0,0 +1 @@
+export const RELOAD_PLUGIN_DRAWER_BUTTON_ROLE = 'reload-plugin-drawer-button';
diff --git a/src/components/Map/PluginsDrawer/PluginsHeader/PluginHeaderInfo/index.ts b/src/components/Map/PluginsDrawer/PluginsHeader/PluginHeaderInfo/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..188cbbd6016b438e813e359f32dcbbd4204e3cdf
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsHeader/PluginHeaderInfo/index.ts
@@ -0,0 +1 @@
+export { PluginHeaderInfo } from './PluginHeaderInfo.component';
diff --git a/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/LoadPluginElement/LoadPluginElement.component.test.tsx b/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/LoadPluginElement/LoadPluginElement.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..9f6d9e24759913f389b5e83d78f77f2c1e241327
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/LoadPluginElement/LoadPluginElement.component.test.tsx
@@ -0,0 +1,82 @@
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { PLUGINS_MOCK } from '@/models/mocks/pluginsMock';
+import {
+  PLUGINS_INITIAL_STATE_LIST_MOCK,
+  PLUGINS_INITIAL_STATE_MOCK,
+} from '@/redux/plugins/plugins.mock';
+import { AppDispatch, RootState } from '@/redux/store';
+import { PluginsManager } from '@/services/pluginsManager';
+import { MinervaPlugin } from '@/types/models';
+import {
+  InitialStoreState,
+  getReduxStoreWithActionsListener,
+} from '@/utils/testing/getReduxStoreActionsListener';
+import { render, screen, waitFor } from '@testing-library/react';
+import axios, { HttpStatusCode } from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import { MockStoreEnhanced } from 'redux-mock-store';
+import { LoadPluginElement } from './LoadPluginElement.component';
+
+const mockedAxiosClient = new MockAdapter(axios);
+
+const renderComponent = (
+  initialStore: InitialStoreState,
+  plugin: MinervaPlugin,
+): { store: MockStoreEnhanced<Partial<RootState>, AppDispatch> } => {
+  const { Wrapper, store } = getReduxStoreWithActionsListener(initialStore);
+  return (
+    render(
+      <Wrapper>
+        <LoadPluginElement plugin={plugin} />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+const setHashedPluginSpy = jest.spyOn(PluginsManager, 'setHashedPlugin');
+
+const PLUGIN = PLUGINS_MOCK[FIRST_ARRAY_ELEMENT];
+
+const STATE = {
+  plugins: {
+    ...PLUGINS_INITIAL_STATE_MOCK,
+    drawer: {
+      ...PLUGINS_INITIAL_STATE_MOCK.drawer,
+      currentPluginHash: PLUGIN.hash,
+    },
+    activePlugins: {
+      data: {
+        [PLUGIN.hash]: PLUGIN,
+      },
+      pluginsId: [PLUGIN.hash],
+    },
+    list: PLUGINS_INITIAL_STATE_LIST_MOCK,
+  },
+};
+
+describe('LoadPluginButton - component', () => {
+  beforeEach(() => {
+    renderComponent(STATE, PLUGIN);
+  });
+
+  it('renders plugin button element', () => {
+    const element = screen.getByText(PLUGIN.name);
+    expect(element).toBeInTheDocument();
+  });
+
+  it('loads plugin on button click', async () => {
+    mockedAxiosClient.onGet(PLUGIN.urls[FIRST_ARRAY_ELEMENT]).reply(HttpStatusCode.Ok, '');
+    const button = screen.getByText(PLUGIN.name);
+    button.click();
+
+    await waitFor(() => {
+      expect(setHashedPluginSpy).toHaveBeenCalledWith({
+        pluginScript: '',
+        pluginUrl: 'https://minerva-service.lcsb.uni.lu/plugins/disease-associations/plugin.js',
+      });
+    });
+  });
+});
diff --git a/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/LoadPluginElement/LoadPluginElement.component.tsx b/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/LoadPluginElement/LoadPluginElement.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..cdd827c84de9d89450bda307781fcecc2d2c81b4
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/LoadPluginElement/LoadPluginElement.component.tsx
@@ -0,0 +1,35 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
+import { useLoadPlugin } from '@/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/hooks/useLoadPlugin';
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
+import { setCurrentDrawerPluginHash } from '@/redux/plugins/plugins.slice';
+import { MinervaPlugin } from '@/types/models';
+
+interface LoadPluginButtonProps {
+  plugin: MinervaPlugin;
+}
+
+export const LoadPluginElement = ({ plugin }: LoadPluginButtonProps): JSX.Element => {
+  const { hash, name, urls } = plugin;
+  const dispatch = useAppDispatch();
+
+  const { loadPlugin } = useLoadPlugin({
+    hash,
+    pluginUrl: urls[FIRST_ARRAY_ELEMENT],
+    onPluginLoaded: () => {
+      dispatch(setCurrentDrawerPluginHash(hash));
+    },
+  });
+
+  return (
+    <li
+      key={hash}
+      className="flex cursor-pointer flex-col border-t px-4 py-2 shadow-sm"
+      onClick={loadPlugin}
+    >
+      {name}
+    </li>
+  );
+};
diff --git a/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/LoadPluginElement/index.ts b/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/LoadPluginElement/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3e90898777837db2bbfeaba99c3965b7e148a57e
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/LoadPluginElement/index.ts
@@ -0,0 +1 @@
+export { LoadPluginElement } from './LoadPluginElement.component';
diff --git a/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/PluginOpenButton.component.test.tsx b/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/PluginOpenButton.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..01f6e7fc0af2f4da942ba98bedbed1a05a9b3241
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/PluginOpenButton.component.test.tsx
@@ -0,0 +1,76 @@
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { PLUGINS_MOCK } from '@/models/mocks/pluginsMock';
+import { PLUGINS_INITIAL_STATE_MOCK } from '@/redux/plugins/plugins.mock';
+import { AppDispatch, RootState } from '@/redux/store';
+import {
+  InitialStoreState,
+  getReduxStoreWithActionsListener,
+} from '@/utils/testing/getReduxStoreActionsListener';
+import { render, screen } from '@testing-library/react';
+import { MockStoreEnhanced } from 'redux-mock-store';
+import { PluginOpenButton } from './PluginOpenButton.component';
+
+const renderComponent = (
+  initialStore: InitialStoreState,
+): { store: MockStoreEnhanced<Partial<RootState>, AppDispatch> } => {
+  const { Wrapper, store } = getReduxStoreWithActionsListener(initialStore);
+  return (
+    render(
+      <Wrapper>
+        <PluginOpenButton />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+const PLUGIN = PLUGINS_MOCK[FIRST_ARRAY_ELEMENT];
+
+const STATE = {
+  plugins: {
+    ...PLUGINS_INITIAL_STATE_MOCK,
+    drawer: {
+      ...PLUGINS_INITIAL_STATE_MOCK.drawer,
+      currentPluginHash: PLUGIN.hash,
+    },
+    activePlugins: {
+      data: {
+        [PLUGIN.hash]: PLUGIN,
+      },
+      pluginsId: [PLUGIN.hash],
+    },
+  },
+};
+
+describe('PluginOpenButton - component', () => {
+  describe('when public plugins list is empty', () => {});
+
+  describe('when public plugins list is present', () => {
+    const publicPlugins = PLUGINS_MOCK.filter(p => p.isPublic);
+
+    beforeEach(() => {
+      renderComponent({
+        ...STATE,
+        plugins: {
+          ...STATE.plugins,
+          list: {
+            ...PLUGINS_INITIAL_STATE_MOCK.list,
+            data: PLUGINS_MOCK,
+          },
+        },
+      });
+    });
+
+    it.each(publicPlugins)('should render load plugin button for public plugins', plugin => {
+      const element = screen.getByText(plugin.name, { exact: false });
+      expect(element).toBeInTheDocument();
+    });
+
+    it('should render open new plugin button', () => {
+      const element = screen.getByText('Open new plugin', { exact: false });
+      expect(element).toBeInTheDocument();
+    });
+  });
+});
diff --git a/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/PluginOpenButton.component.tsx b/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/PluginOpenButton.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..c61328b48f69b4cda7c5dc9e71e5f6ff912de6ee
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/PluginOpenButton.component.tsx
@@ -0,0 +1,37 @@
+import { ZERO } from '@/constants/common';
+import { publicPluginsListWithoutActiveSelector } from '@/redux/plugins/plugins.selectors';
+import { Button } from '@/shared/Button';
+import { MinervaPlugin } from '@/types/models';
+import { useSelect } from 'downshift';
+import { useSelector } from 'react-redux';
+import { LoadPluginElement } from './LoadPluginElement';
+
+export const PluginOpenButton = (): JSX.Element | null => {
+  const publicPlugins = useSelector(publicPluginsListWithoutActiveSelector);
+
+  const { isOpen, getToggleButtonProps, getMenuProps } = useSelect({
+    items: publicPlugins,
+  });
+
+  return (
+    <div className="relative" data-testid="open-new-plugin-list">
+      {publicPlugins.length === ZERO ? null : (
+        <>
+          <Button icon="plus" isIcon isFrontIcon {...getToggleButtonProps()}>
+            Open new plugin
+          </Button>
+          <ul
+            className={`absolute -left-1/2 z-10 max-h-80 w-48 translate-x-1/4 overflow-x-hidden overflow-y-scroll rounded-sm border bg-white p-0 ps-0 ${
+              !isOpen && 'hidden'
+            }`}
+            {...getMenuProps()}
+          >
+            {publicPlugins.map((plugin: MinervaPlugin) => (
+              <LoadPluginElement key={plugin.hash} plugin={plugin} />
+            ))}
+          </ul>
+        </>
+      )}
+    </div>
+  );
+};
diff --git a/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/index.ts b/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1de83e5a4ca90d70c458e009ed48c1fdb73e63c7
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsHeader/PluginOpenButton/index.ts
@@ -0,0 +1 @@
+export { PluginOpenButton } from './PluginOpenButton.component';
diff --git a/src/components/Map/PluginsDrawer/PluginsHeader/PluginsHeader.component.test.tsx b/src/components/Map/PluginsDrawer/PluginsHeader/PluginsHeader.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..864f1d963690ad2cd888ecd4e0b760d272464fc4
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsHeader/PluginsHeader.component.test.tsx
@@ -0,0 +1,124 @@
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { PLUGINS_MOCK } from '@/models/mocks/pluginsMock';
+import {
+  PLUGINS_INITIAL_STATE_LIST_MOCK,
+  PLUGINS_INITIAL_STATE_MOCK,
+} from '@/redux/plugins/plugins.mock';
+import { AppDispatch, RootState } from '@/redux/store';
+import {
+  InitialStoreState,
+  getReduxStoreWithActionsListener,
+} from '@/utils/testing/getReduxStoreActionsListener';
+import { render, screen } from '@testing-library/react';
+import { MockStoreEnhanced } from 'redux-mock-store';
+import { CLOSE_PLUGINS_DRAWER_BUTTON_ROLE } from '../PluginsDrawer.constants';
+import { PluginsHeader } from './PluginsHeader.component';
+
+const renderComponent = (
+  initialStore?: InitialStoreState,
+): { store: MockStoreEnhanced<Partial<RootState>, AppDispatch> } => {
+  const { Wrapper, store } = getReduxStoreWithActionsListener(initialStore);
+  return (
+    render(
+      <Wrapper>
+        <PluginsHeader />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+describe('PluginsHeader - component', () => {
+  describe('when currentPlugin is NOT present', () => {
+    beforeEach(() => {
+      renderComponent({
+        plugins: {
+          ...PLUGINS_INITIAL_STATE_MOCK,
+          drawer: {
+            ...PLUGINS_INITIAL_STATE_MOCK.drawer,
+            currentPluginHash: undefined,
+          },
+        },
+      });
+    });
+
+    it('should render no plugin selected info', () => {
+      const element = screen.getByText('No plugin selected');
+      expect(element).toBeInTheDocument();
+    });
+  });
+
+  describe('when currentPlugin is present', () => {
+    const plugin = PLUGINS_MOCK[FIRST_ARRAY_ELEMENT];
+
+    beforeEach(() => {
+      renderComponent({
+        plugins: {
+          ...PLUGINS_INITIAL_STATE_MOCK,
+          drawer: {
+            ...PLUGINS_INITIAL_STATE_MOCK.drawer,
+            currentPluginHash: plugin.hash,
+          },
+          activePlugins: {
+            data: {
+              [plugin.hash]: plugin,
+            },
+            pluginsId: [plugin.hash],
+          },
+          list: PLUGINS_INITIAL_STATE_LIST_MOCK,
+        },
+      });
+    });
+
+    it('should render header info', () => {
+      const title = screen.getByText(`Plugin:`, { exact: false });
+      const pluginName = screen.getByText(plugin.name, { exact: false });
+
+      expect(title).toBeInTheDocument();
+      expect(pluginName).toBeInTheDocument();
+    });
+  });
+
+  describe('when always', () => {
+    it('should render close plugins drawer button', () => {
+      renderComponent({
+        plugins: {
+          ...PLUGINS_INITIAL_STATE_MOCK,
+        },
+      });
+
+      const element = screen.getByRole(CLOSE_PLUGINS_DRAWER_BUTTON_ROLE);
+      expect(element).toBeInTheDocument();
+    });
+
+    it('should render plugin open button', () => {
+      renderComponent({
+        plugins: {
+          ...PLUGINS_INITIAL_STATE_MOCK,
+        },
+      });
+
+      const element = screen.getByTestId('open-new-plugin-list');
+      expect(element).toBeInTheDocument();
+    });
+
+    it('should dispatch close plugins drawer on button click', () => {
+      const { store } = renderComponent({
+        plugins: {
+          ...PLUGINS_INITIAL_STATE_MOCK,
+        },
+      });
+
+      const element = screen.getByRole(CLOSE_PLUGINS_DRAWER_BUTTON_ROLE);
+      element.click();
+
+      const actions = store.getActions();
+      expect(actions[FIRST_ARRAY_ELEMENT]).toStrictEqual({
+        payload: undefined,
+        type: 'plugins/closePluginsDrawer',
+      });
+    });
+  });
+});
diff --git a/src/components/Map/PluginsDrawer/PluginsHeader/PluginsHeader.component.tsx b/src/components/Map/PluginsDrawer/PluginsHeader/PluginsHeader.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..b8706250a73ad82f6e930ade48aa14fac0b725ad
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsHeader/PluginsHeader.component.tsx
@@ -0,0 +1,38 @@
+import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
+import { selectedDrawerPluginSelector } from '@/redux/plugins/plugins.selectors';
+import { closePluginsDrawer } from '@/redux/plugins/plugins.slice';
+import { IconButton } from '@/shared/IconButton';
+import { useSelector } from 'react-redux';
+import { CLOSE_PLUGINS_DRAWER_BUTTON_ROLE } from '../PluginsDrawer.constants';
+import { PluginHeaderInfo } from './PluginHeaderInfo';
+import { PluginOpenButton } from './PluginOpenButton';
+
+export const PluginsHeader = (): JSX.Element => {
+  const dispatch = useAppDispatch();
+  const currentPlugin = useSelector(selectedDrawerPluginSelector);
+
+  const onCloseButtonClick = (): void => {
+    dispatch(closePluginsDrawer());
+  };
+
+  return (
+    <div
+      className="flex flex-col items-start gap-4 border-b border-b-divide bg-white-pearl p-6"
+      data-testid="drawer-plugins-header"
+    >
+      <div className="flex w-full justify-between">
+        <div className="flex items-center gap-2 text-xl">
+          {currentPlugin ? <PluginHeaderInfo plugin={currentPlugin} /> : <>No plugin selected</>}
+        </div>
+        <IconButton
+          className="h-auto w-auto bg-white-pearl p-0"
+          classNameIcon="fill-font-500"
+          icon="close"
+          role={CLOSE_PLUGINS_DRAWER_BUTTON_ROLE}
+          onClick={onCloseButtonClick}
+        />
+      </div>
+      <PluginOpenButton />
+    </div>
+  );
+};
diff --git a/src/components/Map/PluginsDrawer/PluginsHeader/index.ts b/src/components/Map/PluginsDrawer/PluginsHeader/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1d6261a4873000ba737e2e77803cf3a3b143f618
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsHeader/index.ts
@@ -0,0 +1 @@
+export { PluginsHeader } from './PluginsHeader.component';
diff --git a/src/components/Map/PluginsDrawer/PluginsTabs/PluginSingleTab/PluginSingleTab.component.test.tsx b/src/components/Map/PluginsDrawer/PluginsTabs/PluginSingleTab/PluginSingleTab.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..157d4220526bcd10a9078f44b97e45672f9d50fa
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsTabs/PluginSingleTab/PluginSingleTab.component.test.tsx
@@ -0,0 +1,138 @@
+import { FIRST_ARRAY_ELEMENT, SECOND_ARRAY_ELEMENT, THIRD_ARRAY_ELEMENT } from '@/constants/common';
+import { PLUGINS_MOCK } from '@/models/mocks/pluginsMock';
+import {
+  PLUGINS_INITIAL_STATE_LIST_MOCK,
+  PLUGINS_INITIAL_STATE_MOCK,
+} from '@/redux/plugins/plugins.mock';
+import { AppDispatch, RootState } from '@/redux/store';
+import { PluginsManager } from '@/services/pluginsManager';
+import { MinervaPlugin } from '@/types/models';
+import {
+  InitialStoreState,
+  getReduxStoreWithActionsListener,
+} from '@/utils/testing/getReduxStoreActionsListener';
+import { render, screen } from '@testing-library/react';
+import { MockStoreEnhanced } from 'redux-mock-store';
+import { PluginSingleTab } from './PluginSingleTab.component';
+
+const renderComponent = (
+  initialStore: InitialStoreState,
+  plugin: MinervaPlugin,
+): { store: MockStoreEnhanced<Partial<RootState>, AppDispatch> } => {
+  const { Wrapper, store } = getReduxStoreWithActionsListener(initialStore);
+  return (
+    render(
+      <Wrapper>
+        <PluginSingleTab plugin={plugin} />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+const removePluginContentSpy = jest.spyOn(PluginsManager, 'removePluginContent');
+
+const PLUGIN = PLUGINS_MOCK[FIRST_ARRAY_ELEMENT];
+const PLUGIN_2 = PLUGINS_MOCK[SECOND_ARRAY_ELEMENT];
+const PLUGIN_3 = PLUGINS_MOCK[THIRD_ARRAY_ELEMENT];
+
+const STATE = {
+  plugins: {
+    ...PLUGINS_INITIAL_STATE_MOCK,
+    drawer: {
+      ...PLUGINS_INITIAL_STATE_MOCK.drawer,
+      currentPluginHash: PLUGIN.hash,
+    },
+    activePlugins: {
+      data: {
+        [PLUGIN.hash]: PLUGIN,
+      },
+      pluginsId: [PLUGIN.hash],
+    },
+    list: PLUGINS_INITIAL_STATE_LIST_MOCK,
+  },
+};
+
+describe('PluginSingleTab - component', () => {
+  describe('when always', () => {
+    it('should render plugin name', () => {
+      renderComponent(STATE, PLUGIN);
+
+      const element = screen.getByText(PLUGIN.name);
+      expect(element).toBeInTheDocument();
+    });
+
+    it('should render close button', () => {
+      renderComponent(STATE, PLUGIN);
+
+      const element = screen.getByTestId('close-icon');
+      expect(element).toBeInTheDocument();
+    });
+
+    it('should dispatch close action on close btn click', () => {
+      const { store } = renderComponent(STATE, PLUGIN);
+      const element = screen.getByTestId('close-icon');
+      element.click();
+
+      const actions = store.getActions();
+
+      expect(removePluginContentSpy).toHaveBeenCalledWith({
+        hash: PLUGIN.hash,
+      });
+
+      expect(actions).toEqual([
+        { payload: { pluginId: '5e3fcb59588cc311ef9839feea6382eb' }, type: 'plugins/removePlugin' },
+      ]);
+    });
+
+    it('should dispatch close action on close btn click and new current drawer on last active plugin', () => {
+      const { store } = renderComponent(
+        {
+          ...STATE,
+          plugins: {
+            ...PLUGINS_INITIAL_STATE_MOCK,
+            activePlugins: {
+              data: {
+                [PLUGIN.hash]: PLUGIN,
+                [PLUGIN_2.hash]: PLUGIN_2,
+                [PLUGIN_3.hash]: PLUGIN_3,
+              },
+              pluginsId: [PLUGIN.hash, PLUGIN_2.hash, PLUGIN_3.hash],
+            },
+          },
+        },
+        PLUGIN,
+      );
+      const element = screen.getByTestId('close-icon');
+      element.click();
+
+      const actions = store.getActions();
+
+      expect(removePluginContentSpy).toHaveBeenCalledWith({
+        hash: PLUGIN.hash,
+      });
+
+      expect(actions).toEqual([
+        { payload: { pluginId: '5e3fcb59588cc311ef9839feea6382eb' }, type: 'plugins/removePlugin' },
+        {
+          payload: '5314b9f996e56e67f0dad65e7df8b73b',
+          type: 'plugins/setCurrentDrawerPluginHash',
+        },
+      ]);
+    });
+
+    it('should dispatch set current drawer on tab click', () => {
+      const { store } = renderComponent(STATE, PLUGIN);
+      const element = screen.getByText(PLUGIN.name);
+      element.click();
+
+      const actions = store.getActions();
+
+      expect(actions).toStrictEqual([
+        { payload: '5e3fcb59588cc311ef9839feea6382eb', type: 'plugins/setCurrentDrawerPluginHash' },
+      ]);
+    });
+  });
+});
diff --git a/src/components/Map/PluginsDrawer/PluginsTabs/PluginSingleTab/PluginSingleTab.component.tsx b/src/components/Map/PluginsDrawer/PluginsTabs/PluginSingleTab/PluginSingleTab.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..c1a4c58af8aac6a90fa55d21fc3334771f361f41
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsTabs/PluginSingleTab/PluginSingleTab.component.tsx
@@ -0,0 +1,61 @@
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+import { useLoadPlugin } from '@/components/Map/Drawer/AvailablePluginsDrawer/LoadPlugin/hooks/useLoadPlugin';
+import { FIRST_ARRAY_ELEMENT, ZERO } from '@/constants/common';
+import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { allActivePluginsSelector } from '@/redux/plugins/plugins.selectors';
+import { setCurrentDrawerPluginHash } from '@/redux/plugins/plugins.slice';
+import { Button } from '@/shared/Button';
+import { Icon } from '@/shared/Icon';
+import { MinervaPlugin } from '@/types/models';
+import { twMerge } from 'tailwind-merge';
+
+interface Props {
+  plugin: MinervaPlugin;
+}
+
+export const PluginSingleTab = ({ plugin }: Props): JSX.Element => {
+  const dispatch = useAppDispatch();
+  const allActivePlugins = useAppSelector(allActivePluginsSelector);
+
+  const { unloadPlugin, isPluginSelected } = useLoadPlugin({
+    hash: plugin.hash,
+    pluginUrl: plugin.urls[FIRST_ARRAY_ELEMENT],
+  });
+
+  const onPluginTabClick = (): void => {
+    dispatch(setCurrentDrawerPluginHash(plugin.hash));
+  };
+
+  const onPluginUnload = (event: React.MouseEvent<HTMLDivElement>): void => {
+    event.stopPropagation();
+    unloadPlugin();
+
+    const newAllActivePlugins = allActivePlugins.filter(p => p.hash !== plugin.hash);
+    const lastActivePlugin = newAllActivePlugins.pop();
+    if (lastActivePlugin) {
+      dispatch(setCurrentDrawerPluginHash(lastActivePlugin.hash));
+    }
+  };
+
+  return (
+    <Button
+      className={twMerge(
+        'h-10 whitespace-nowrap',
+        isPluginSelected ? 'bg-[#EBF4FF]' : 'font-normal',
+      )}
+      variantStyles={isPluginSelected ? 'secondary' : 'ghost'}
+      onClick={(): void => onPluginTabClick()}
+    >
+      {plugin.name}
+      <div
+        onClick={(event): void => onPluginUnload(event)}
+        data-testid="close-icon"
+        role="button"
+        tabIndex={ZERO}
+      >
+        <Icon name="close" className="ml-3 h-5 w-5 fill-font-400" />
+      </div>
+    </Button>
+  );
+};
diff --git a/src/components/Map/PluginsDrawer/PluginsTabs/PluginSingleTab/index.ts b/src/components/Map/PluginsDrawer/PluginsTabs/PluginSingleTab/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2b6e0df29625351374fd96b0cd9bfcbb1938c81f
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsTabs/PluginSingleTab/index.ts
@@ -0,0 +1 @@
+export { PluginSingleTab } from './PluginSingleTab.component';
diff --git a/src/components/Map/PluginsDrawer/PluginsTabs/PluginsTabs.component.test.tsx b/src/components/Map/PluginsDrawer/PluginsTabs/PluginsTabs.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..64bc467055f57bfa940ce5750522da38a439e144
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsTabs/PluginsTabs.component.test.tsx
@@ -0,0 +1,86 @@
+import { FIRST_ARRAY_ELEMENT, SECOND_ARRAY_ELEMENT } from '@/constants/common';
+import { PLUGINS_MOCK } from '@/models/mocks/pluginsMock';
+import {
+  PLUGINS_INITIAL_STATE_LIST_MOCK,
+  PLUGINS_INITIAL_STATE_MOCK,
+} from '@/redux/plugins/plugins.mock';
+import { AppDispatch, RootState } from '@/redux/store';
+import {
+  InitialStoreState,
+  getReduxStoreWithActionsListener,
+} from '@/utils/testing/getReduxStoreActionsListener';
+import { render, screen } from '@testing-library/react';
+import { MockStoreEnhanced } from 'redux-mock-store';
+import { PluginsTabs } from './PluginsTabs.component';
+
+const renderComponent = (
+  initialStore?: InitialStoreState,
+): { store: MockStoreEnhanced<Partial<RootState>, AppDispatch> } => {
+  const { Wrapper, store } = getReduxStoreWithActionsListener(initialStore);
+  return (
+    render(
+      <Wrapper>
+        <PluginsTabs />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+const PLUGIN = PLUGINS_MOCK[FIRST_ARRAY_ELEMENT];
+const PLUGIN_2 = PLUGINS_MOCK[SECOND_ARRAY_ELEMENT];
+
+describe('PluginsTabs - component', () => {
+  describe('when active plugins list is empty', () => {
+    beforeEach(() => {
+      renderComponent({
+        plugins: {
+          ...PLUGINS_INITIAL_STATE_MOCK,
+          drawer: {
+            ...PLUGINS_INITIAL_STATE_MOCK.drawer,
+            currentPluginHash: PLUGIN.hash,
+          },
+          activePlugins: {
+            data: {},
+            pluginsId: [],
+          },
+          list: PLUGINS_INITIAL_STATE_LIST_MOCK,
+        },
+      });
+    });
+
+    it('should render empty plugin info', () => {
+      const element = screen.getByText(`You don't have any opened plugin yet`);
+      expect(element).toBeInTheDocument();
+    });
+  });
+
+  describe('when active plugins list is present', () => {
+    beforeEach(() => {
+      renderComponent({
+        plugins: {
+          ...PLUGINS_INITIAL_STATE_MOCK,
+          drawer: {
+            ...PLUGINS_INITIAL_STATE_MOCK.drawer,
+            currentPluginHash: PLUGIN.hash,
+          },
+          activePlugins: {
+            data: {
+              [PLUGIN.hash]: PLUGIN,
+              [PLUGIN_2.hash]: PLUGIN_2,
+            },
+            pluginsId: [PLUGIN.hash, PLUGIN_2.hash],
+          },
+          list: PLUGINS_INITIAL_STATE_LIST_MOCK,
+        },
+      });
+    });
+
+    it.each([PLUGIN, PLUGIN_2])('should render plugins tabs', plugin => {
+      const element = screen.getByText(plugin.name);
+      expect(element).toBeInTheDocument();
+    });
+  });
+});
diff --git a/src/components/Map/PluginsDrawer/PluginsTabs/PluginsTabs.component.tsx b/src/components/Map/PluginsDrawer/PluginsTabs/PluginsTabs.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..0ed9089edcc613b1d414a56887cde5e68ad2acbe
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsTabs/PluginsTabs.component.tsx
@@ -0,0 +1,33 @@
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+import { ZERO } from '@/constants/common';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { allActivePluginsSelector } from '@/redux/plugins/plugins.selectors';
+import { useMemo } from 'react';
+import { PluginSingleTab } from './PluginSingleTab';
+
+export const PluginsTabs = (): JSX.Element => {
+  const allActivePlugins = useAppSelector(allActivePluginsSelector);
+  const isPluginsEmpty = allActivePlugins.length === ZERO;
+
+  const pluginsTabs = allActivePlugins.map(plugin => (
+    <PluginSingleTab plugin={plugin} key={plugin.hash} />
+  ));
+
+  const pluginsEmptyInfo = useMemo(
+    () => (
+      <div className="flex h-10 items-center px-4 text-[#979797]">
+        You don&apos;t have any opened plugin yet
+      </div>
+    ),
+    [],
+  );
+
+  return (
+    <div
+      className="flex h-10 w-full flex-row flex-nowrap justify-start border-b border-b-divide bg-white-pearl text-xs"
+      data-testid="drawer-plugins-tab"
+    >
+      {isPluginsEmpty ? pluginsEmptyInfo : pluginsTabs}
+    </div>
+  );
+};
diff --git a/src/components/Map/PluginsDrawer/PluginsTabs/index.ts b/src/components/Map/PluginsDrawer/PluginsTabs/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..89b612832c1dbc789e1f71e10827b85f13b5eab0
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/PluginsTabs/index.ts
@@ -0,0 +1 @@
+export { PluginsTabs as PluginsList } from './PluginsTabs.component';
diff --git a/src/components/Map/PluginsDrawer/index.ts b/src/components/Map/PluginsDrawer/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8858fdbe0d2b7c33f6ce041fbf382b887d4e4281
--- /dev/null
+++ b/src/components/Map/PluginsDrawer/index.ts
@@ -0,0 +1 @@
+export { PluginsDrawer } from './PluginsDrawer.component';
diff --git a/src/constants/common.ts b/src/constants/common.ts
index 00220963e428965dbee6767b1715359ac15bbd02..5f3261398871bc194e0bef40a79a5bbcdbb91a1a 100644
--- a/src/constants/common.ts
+++ b/src/constants/common.ts
@@ -8,6 +8,11 @@ export const FIRST_ARRAY_ELEMENT = 0;
 export const ONE = 1;
 export const SECOND_ARRAY_ELEMENT = 1;
 
+export const TWO = 2;
+
 export const THIRD_ARRAY_ELEMENT = 2;
 
 export const NOOP = (): void => {};
+
+export const ONE_DECIMAL = 0.1;
+export const ONE_HUNDRED = 100;
diff --git a/src/constants/plugins.ts b/src/constants/plugins.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8da8b37f72573ecdb6c28023a1cac8491cbdb6b8
--- /dev/null
+++ b/src/constants/plugins.ts
@@ -0,0 +1,2 @@
+export const PLUGINS_CONTENT_ELEMENT_ATTR_NAME = 'data-hash';
+export const PLUGINS_CONTENT_ELEMENT_ID = 'plugins';
diff --git a/src/hooks/useDebounce.ts b/src/hooks/useDebounce.ts
deleted file mode 100644
index 9742ab926a92a1944252b5b44e6426542bcb74aa..0000000000000000000000000000000000000000
--- a/src/hooks/useDebounce.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { useEffect, useState } from 'react';
-
-const DEFAULT_DELAY = 500;
-
-export const useDebounce = <T>(value: T, delay?: number): T => {
-  const [debouncedValue, setDebouncedValue] = useState<T>(value);
-
-  useEffect(() => {
-    const timer = setTimeout(() => setDebouncedValue(value), delay || DEFAULT_DELAY);
-
-    return () => {
-      clearTimeout(timer);
-    };
-  }, [value, delay]);
-
-  return debouncedValue;
-};
diff --git a/src/models/geneVariant.ts b/src/models/geneVariant.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3df425e504d0bd6e92f597358d00072ce309d2cd
--- /dev/null
+++ b/src/models/geneVariant.ts
@@ -0,0 +1,11 @@
+import { z } from 'zod';
+
+export const geneVariant = z.object({
+  position: z.number(),
+  originalDna: z.string(),
+  modifiedDna: z.string(),
+  contig: z.string(),
+  allelFrequency: z.number(),
+  aminoAcidChange: z.string(),
+  variantIdentifier: z.string(),
+});
diff --git a/src/models/mocks/geneVariantsMock.ts b/src/models/mocks/geneVariantsMock.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0002828e1c5c0aae1081da489d47e21e9d37acad
--- /dev/null
+++ b/src/models/mocks/geneVariantsMock.ts
@@ -0,0 +1,130 @@
+import { GeneVariant } from '@/types/models';
+
+export const GENE_VARIANTS_MOCK: GeneVariant[] = [
+  {
+    position: 162394349,
+    originalDna: 'G',
+    modifiedDna: 'A',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.162394349G>A:p.T240M',
+    variantIdentifier: 'rs137853054',
+  },
+  {
+    position: 161771219,
+    originalDna: 'G',
+    modifiedDna: 'A',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.161771219G>A:p.P437L',
+    variantIdentifier: 'rs149953814',
+  },
+  {
+    position: 162206852,
+    originalDna: 'G',
+    modifiedDna: 'A',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.162206852G>A:p.R275W',
+    variantIdentifier: 'rs34424986',
+  },
+  {
+    position: 162394349,
+    originalDna: 'G',
+    modifiedDna: 'C',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.162394349G>C:p.T240R',
+    variantIdentifier: 'rs137853054',
+  },
+  {
+    position: 161771171,
+    originalDna: 'C',
+    modifiedDna: 'T',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.161771171C>T:p.W453*',
+    variantIdentifier: 'rs137853056',
+  },
+  {
+    position: 162683694,
+    originalDna: 'G',
+    modifiedDna: 'A',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.162683694G>A:p.A92V',
+    variantIdentifier: 'rs566229879',
+  },
+  {
+    position: 162206914,
+    originalDna: 'T',
+    modifiedDna: 'C',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.162206914T>C:p.N254S',
+    variantIdentifier: 'rs139600787',
+  },
+  {
+    position: 162394349,
+    originalDna: 'G',
+    modifiedDna: 'C',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.162394349G>C:p.T240R',
+    variantIdentifier: 'rs137853054',
+  },
+  {
+    position: 162206825,
+    originalDna: 'C',
+    modifiedDna: 'G',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.162206825C>G:p.G284R',
+    variantIdentifier: 'rs751037529',
+  },
+  {
+    position: 162394338,
+    originalDna: 'C',
+    modifiedDna: 'T',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.162394338C>T:p.V244I',
+    variantIdentifier: 'rs771259513',
+  },
+  {
+    position: 161781201,
+    originalDna: 'G',
+    modifiedDna: 'A',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.161781201G>A:p.R402C',
+    variantIdentifier: 'rs55830907',
+  },
+  {
+    position: 162622239,
+    originalDna: 'G',
+    modifiedDna: 'C',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.162622239G>C:p.P153R',
+    variantIdentifier: 'rs55654276',
+  },
+  {
+    position: 161807855,
+    originalDna: 'C',
+    modifiedDna: 'G',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.161807855C>G:p.V380L',
+    variantIdentifier: 'rs1801582',
+  },
+  {
+    position: 161771237,
+    originalDna: 'C',
+    modifiedDna: 'A',
+    contig: 'chr6',
+    allelFrequency: 0.8,
+    aminoAcidChange: 'PRKN:NC_000006.11:g.161771237C>A:p.C431F',
+    variantIdentifier: 'rs397514694',
+  },
+];
diff --git a/src/models/mocks/pluginsMock.ts b/src/models/mocks/pluginsMock.ts
index f5c91eafdb32833dff36caedddfc4b85d9bac2f6..39963669594ad3e4d21345d19b56b0244cbcec83 100644
--- a/src/models/mocks/pluginsMock.ts
+++ b/src/models/mocks/pluginsMock.ts
@@ -5,7 +5,7 @@ export const PLUGINS_MOCK: MinervaPlugin[] = [
     hash: '5e3fcb59588cc311ef9839feea6382eb',
     name: 'Disease-variant associations',
     version: '1.0.0',
-    isPublic: true,
+    isPublic: false,
     isDefault: false,
     urls: ['https://minerva-service.lcsb.uni.lu/plugins/disease-associations/plugin.js'],
   },
@@ -13,7 +13,7 @@ export const PLUGINS_MOCK: MinervaPlugin[] = [
     hash: '20df86476c311824bbfe73d1034af89e',
     name: 'GSEA',
     version: '0.9.2',
-    isPublic: true,
+    isPublic: false,
     isDefault: false,
     urls: ['https://minerva-service.lcsb.uni.lu/plugins/gsea/plugin.js'],
   },
diff --git a/src/models/overlayRightBioEntitySchema.ts b/src/models/overlayRightBioEntitySchema.ts
index 970271c56a9942521cb00987932a4d2bdd9857dd..20b03f8fb19bc6f0ed481a746fce6d6308150604 100644
--- a/src/models/overlayRightBioEntitySchema.ts
+++ b/src/models/overlayRightBioEntitySchema.ts
@@ -1,5 +1,6 @@
 import { z } from 'zod';
 import { colorSchema } from './colorSchema';
+import { geneVariant } from './geneVariant';
 
 export const overlayRightBioEntitySchema = z.object({
   id: z.number(),
@@ -11,4 +12,5 @@ export const overlayRightBioEntitySchema = z.object({
   value: z.number().nullable(),
   color: colorSchema.nullable(),
   description: z.string().nullable(),
+  geneVariants: z.array(geneVariant).optional().nullable(),
 });
diff --git a/src/redux/overlayBioEntity/overlayBioEntity.selector.ts b/src/redux/overlayBioEntity/overlayBioEntity.selector.ts
index 94f18b3a0b177154aae455a7d905055c72411ec4..e42ee1cba731c1c9fe3edc05dcf225e3ceeeeb9f 100644
--- a/src/redux/overlayBioEntity/overlayBioEntity.selector.ts
+++ b/src/redux/overlayBioEntity/overlayBioEntity.selector.ts
@@ -1,5 +1,6 @@
 import { OverlayBioEntityRender } from '@/types/OLrendering';
 import { createSelector } from '@reduxjs/toolkit';
+import { currentSearchedBioEntityId } from '../drawer/drawer.selectors';
 import { currentModelIdSelector } from '../models/models.selectors';
 import { overlaysDataSelector, overlaysIdsAndOrderSelector } from '../overlays/overlays.selectors';
 import { rootSelector } from '../root/root.selectors';
@@ -66,3 +67,20 @@ export const getOverlayOrderSelector = createSelector(
     return calculateOvarlaysOrder(activeOverlaysIdsAndOrder);
   },
 );
+
+export const overlaysOpenedIdsSelector = createSelector(
+  rootSelector,
+  state => state.overlayBioEntity.overlaysId,
+);
+
+export const overlaysOpenedSelector = createSelector(
+  overlaysDataSelector,
+  overlaysOpenedIdsSelector,
+  (data, ids) => data.filter(entity => ids.includes(entity.idObject)),
+);
+
+export const overlaysBioEntityForCurrentBioEntityAndCurrentModelSelector = createSelector(
+  overlayBioEntitiesForCurrentModelSelector,
+  currentSearchedBioEntityId,
+  (data, currentBioEntityId) => data.filter(entity => entity.id === currentBioEntityId),
+);
diff --git a/src/redux/overlayBioEntity/overlayBioEntity.utils.ts b/src/redux/overlayBioEntity/overlayBioEntity.utils.ts
index 6656d725badcafef167e19d63226804077ca4a21..b765ff8de4471783e7eca9ffa73ec405b9829118 100644
--- a/src/redux/overlayBioEntity/overlayBioEntity.utils.ts
+++ b/src/redux/overlayBioEntity/overlayBioEntity.utils.ts
@@ -32,6 +32,7 @@ export const parseOverlayBioEntityToOlRenderingFormat = (
         value: entity.right.value,
         overlayId,
         color: entity.right.color,
+        geneVariants: entity.right.geneVariants,
       });
     }
 
diff --git a/src/redux/plugins/plugins.constants.ts b/src/redux/plugins/plugins.constants.ts
index c3365278b4f0cfc8eaedb8832ad14afbf2d3cad9..cdd616c5580b1f31c7837bfc2cc84e3d1d7940cb 100644
--- a/src/redux/plugins/plugins.constants.ts
+++ b/src/redux/plugins/plugins.constants.ts
@@ -10,4 +10,8 @@ export const PLUGINS_INITIAL_STATE: PluginsState = {
     data: {},
     pluginsId: [],
   },
+  drawer: {
+    isOpen: false,
+    currentPluginHash: undefined,
+  },
 };
diff --git a/src/redux/plugins/plugins.mock.ts b/src/redux/plugins/plugins.mock.ts
index 9b6b9c8f12621dfa722ed20e45d6aec0c69408ba..11091195ccdd0098dbc9cbd72bad1cd2be9405be 100644
--- a/src/redux/plugins/plugins.mock.ts
+++ b/src/redux/plugins/plugins.mock.ts
@@ -1,5 +1,5 @@
 import { DEFAULT_ERROR } from '@/constants/errors';
-import { ActivePlugins, PluginsList, PluginsState } from './plugins.types';
+import { ActivePlugins, PluginsDrawer, PluginsList, PluginsState } from './plugins.types';
 
 export const PLUGINS_INITIAL_STATE_ACTIVE_PLUGINS_MOCK: ActivePlugins = {
   data: {},
@@ -12,7 +12,13 @@ export const PLUGINS_INITIAL_STATE_LIST_MOCK: PluginsList = {
   error: DEFAULT_ERROR,
 };
 
+export const PLUGINS_INITIAL_STATE_DRAWER_MOCK: PluginsDrawer = {
+  isOpen: false,
+  currentPluginHash: undefined,
+};
+
 export const PLUGINS_INITIAL_STATE_MOCK: PluginsState = {
   list: PLUGINS_INITIAL_STATE_LIST_MOCK,
   activePlugins: PLUGINS_INITIAL_STATE_ACTIVE_PLUGINS_MOCK,
+  drawer: PLUGINS_INITIAL_STATE_DRAWER_MOCK,
 };
diff --git a/src/redux/plugins/plugins.reducers.ts b/src/redux/plugins/plugins.reducers.ts
index f046459c4c9e88879b6d7b9ee88a755e7e29ddc1..ac8ddae548cc3ea8077e39d1dd2ad7fc8a00e40e 100644
--- a/src/redux/plugins/plugins.reducers.ts
+++ b/src/redux/plugins/plugins.reducers.ts
@@ -1,6 +1,10 @@
 import type { ActionReducerMapBuilder } from '@reduxjs/toolkit';
-import type { PluginsState, RemovePluginAction } from './plugins.types';
-import { registerPlugin, getAllPlugins } from './plugins.thunks';
+import { getAllPlugins, registerPlugin } from './plugins.thunks';
+import type {
+  PluginsState,
+  RemovePluginAction,
+  SetCurrentDrawerPluginHashAction,
+} from './plugins.types';
 
 export const removePluginReducer = (state: PluginsState, action: RemovePluginAction): void => {
   const { pluginId } = action.payload;
@@ -38,3 +42,18 @@ export const getAllPluginsReducer = (builder: ActionReducerMapBuilder<PluginsSta
     // TODO to discuss manage state of failure
   });
 };
+
+export const openPluginsDrawerReducer = (state: PluginsState): void => {
+  state.drawer.isOpen = true;
+};
+
+export const closePluginsDrawerReducer = (state: PluginsState): void => {
+  state.drawer.isOpen = false;
+};
+
+export const setCurrentDrawerPluginHashReducer = (
+  state: PluginsState,
+  action: SetCurrentDrawerPluginHashAction,
+): void => {
+  state.drawer.currentPluginHash = action.payload;
+};
diff --git a/src/redux/plugins/plugins.selectors.ts b/src/redux/plugins/plugins.selectors.ts
index 1bf37c638ee768446fe26c5229f4e4a51e134f14..3c829c642c9bb5807858d9ce99dd8657c1ec7967 100644
--- a/src/redux/plugins/plugins.selectors.ts
+++ b/src/redux/plugins/plugins.selectors.ts
@@ -1,5 +1,5 @@
-import { createSelector } from '@reduxjs/toolkit';
 import { MinervaPlugin } from '@/types/models';
+import { createSelector } from '@reduxjs/toolkit';
 import { rootSelector } from '../root/root.selectors';
 
 export const pluginsSelector = createSelector(rootSelector, state => state.plugins);
@@ -12,6 +12,10 @@ export const pluginsListDataSelector = createSelector(pluginsListSelector, plugi
   return pluginsList.data;
 });
 
+export const pluginsDrawerSelector = createSelector(pluginsSelector, plugins => {
+  return plugins.drawer;
+});
+
 export const publicPluginsListSelector = createSelector(
   pluginsListDataSelector,
   pluginsListData => {
@@ -65,3 +69,30 @@ export const isPluginLoadingSelector = createSelector(
   ({ data, pluginsId }, pluginId) =>
     pluginsId.includes(pluginId) && data[pluginId] && !Object.keys(data[pluginId]).length,
 );
+
+export const currentDrawerPluginHashSelector = createSelector(
+  pluginsDrawerSelector,
+  drawer => drawer.currentPluginHash,
+);
+
+export const selectedDrawerPluginSelector = createSelector(
+  allActivePluginsSelector,
+  currentDrawerPluginHashSelector,
+  (allActivePlugins, currentDrawerPluginHash) =>
+    allActivePlugins.find(plugin => plugin.hash === currentDrawerPluginHash),
+);
+
+export const isPluginSelectedSelector = createSelector(
+  [selectedDrawerPluginSelector, (_, pluginHash: string): string => pluginHash],
+  (selectedPlugin, pluginHash) => selectedPlugin?.hash === pluginHash,
+);
+
+export const publicPluginsListWithoutActiveSelector = createSelector(
+  publicPluginsListSelector,
+  allActivePluginsSelector,
+  (publicPlugins, allActivePlugins) => {
+    const activePluginsHashes = allActivePlugins.map(p => p.hash);
+
+    return (publicPlugins || []).filter(plugin => !activePluginsHashes.includes(plugin.hash));
+  },
+);
diff --git a/src/redux/plugins/plugins.slice.ts b/src/redux/plugins/plugins.slice.ts
index aeb408420001e991c41e1a060c280880450af4af..d5b9934636ba7857f4c3e35004e575831587ddae 100644
--- a/src/redux/plugins/plugins.slice.ts
+++ b/src/redux/plugins/plugins.slice.ts
@@ -1,8 +1,11 @@
 import { createSlice } from '@reduxjs/toolkit';
 import {
+  closePluginsDrawerReducer,
+  getAllPluginsReducer,
+  openPluginsDrawerReducer,
   registerPluginReducer,
   removePluginReducer,
-  getAllPluginsReducer,
+  setCurrentDrawerPluginHashReducer,
 } from './plugins.reducers';
 
 import { PLUGINS_INITIAL_STATE } from './plugins.constants';
@@ -12,6 +15,9 @@ const pluginsSlice = createSlice({
   initialState: PLUGINS_INITIAL_STATE,
   reducers: {
     removePlugin: removePluginReducer,
+    openPluginsDrawer: openPluginsDrawerReducer,
+    closePluginsDrawer: closePluginsDrawerReducer,
+    setCurrentDrawerPluginHash: setCurrentDrawerPluginHashReducer,
   },
   extraReducers: builder => {
     registerPluginReducer(builder);
@@ -19,5 +25,6 @@ const pluginsSlice = createSlice({
   },
 });
 
-export const { removePlugin } = pluginsSlice.actions;
+export const { removePlugin, openPluginsDrawer, closePluginsDrawer, setCurrentDrawerPluginHash } =
+  pluginsSlice.actions;
 export default pluginsSlice.reducer;
diff --git a/src/redux/plugins/plugins.thunks.ts b/src/redux/plugins/plugins.thunks.ts
index 73c7341e07cfc2f9b93515487084fe26fade667d..afe657f91d3473aa7cca56d7c2a90a1304a6d129 100644
--- a/src/redux/plugins/plugins.thunks.ts
+++ b/src/redux/plugins/plugins.thunks.ts
@@ -1,11 +1,10 @@
 /* eslint-disable no-magic-numbers */
-import axios from 'axios';
-import { createAsyncThunk } from '@reduxjs/toolkit';
-import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema';
 import { pluginSchema } from '@/models/pluginSchema';
-import type { MinervaPlugin } from '@/types/models';
 import { axiosInstance } from '@/services/api/utils/axiosInstance';
-import { z } from 'zod';
+import type { MinervaPlugin } from '@/types/models';
+import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema';
+import { createAsyncThunk } from '@reduxjs/toolkit';
+import axios from 'axios';
 import { apiPath } from '../apiPath';
 
 type RegisterPlugin = {
@@ -90,8 +89,10 @@ export const getAllPlugins = createAsyncThunk(
   async (): Promise<MinervaPlugin[]> => {
     const response = await axiosInstance.get<MinervaPlugin[]>(apiPath.getAllPlugins());
 
-    const isDataValid = validateDataUsingZodSchema(response.data, z.array(pluginSchema));
+    const isPluginDataValid = (pluginData: MinervaPlugin): boolean =>
+      validateDataUsingZodSchema(pluginData, pluginSchema);
+    const validPlugins = response.data.filter(isPluginDataValid);
 
-    return isDataValid ? response.data : [];
+    return validPlugins;
   },
 );
diff --git a/src/redux/plugins/plugins.types.ts b/src/redux/plugins/plugins.types.ts
index 2569f12845cc3394a7b8897e9133745a52cb9fa6..9a6b316add606525c4def48df1c6a5d8c1873139 100644
--- a/src/redux/plugins/plugins.types.ts
+++ b/src/redux/plugins/plugins.types.ts
@@ -14,7 +14,16 @@ export type ActivePlugins = {
   };
 };
 
+export type PluginsDrawer = {
+  isOpen: boolean;
+  currentPluginHash?: string;
+};
+
 export type PluginsState = {
   list: PluginsList;
   activePlugins: ActivePlugins;
+  drawer: PluginsDrawer;
 };
+
+export type SetCurrentDrawerPluginHashPayload = string;
+export type SetCurrentDrawerPluginHashAction = PayloadAction<SetCurrentDrawerPluginHashPayload>;
diff --git a/src/redux/root/root.fixtures.ts b/src/redux/root/root.fixtures.ts
index df213cd4546d108ee1b43163b53ff247fe4ef1f7..b27b88cc9c1c96511ed626d5568b30d04999b1d3 100644
--- a/src/redux/root/root.fixtures.ts
+++ b/src/redux/root/root.fixtures.ts
@@ -1,7 +1,6 @@
 import { BACKGROUND_INITIAL_STATE_MOCK } from '../backgrounds/background.mock';
 import { BIOENTITY_INITIAL_STATE_MOCK } from '../bioEntity/bioEntity.mock';
 import { CHEMICALS_INITIAL_STATE_MOCK } from '../chemicals/chemicals.mock';
-import { COMPARTMENT_PATHWAYS_INITIAL_STATE_MOCK } from '../compartmentPathways/compartmentPathways.mock';
 import { CONFIGURATION_INITIAL_STATE } from '../configuration/configuration.adapter';
 import { CONTEXT_MENU_INITIAL_STATE } from '../contextMenu/contextMenu.constants';
 import { COOKIE_BANNER_INITIAL_STATE_MOCK } from '../cookieBanner/cookieBanner.mock';
@@ -18,9 +17,10 @@ import { PLUGINS_INITIAL_STATE_MOCK } from '../plugins/plugins.mock';
 import { PROJECT_STATE_INITIAL_MOCK } from '../project/project.mock';
 import { REACTIONS_STATE_INITIAL_MOCK } from '../reactions/reactions.mock';
 import { SEARCH_STATE_INITIAL_MOCK } from '../search/search.mock';
-import { STATISTICS_STATE_INITIAL_MOCK } from '../statistics/statistics.mock';
 import { RootState } from '../store';
 import { USER_INITIAL_STATE_MOCK } from '../user/user.mock';
+import { STATISTICS_STATE_INITIAL_MOCK } from '../statistics/statistics.mock';
+import { COMPARTMENT_PATHWAYS_INITIAL_STATE_MOCK } from '../compartmentPathways/compartmentPathways.mock';
 import { PUBLICATIONS_INITIAL_STATE_MOCK } from '../publications/publications.mock';
 
 export const INITIAL_STORE_STATE_MOCK: RootState = {
diff --git a/src/services/pluginsManager/pluginsManager.test.ts b/src/services/pluginsManager/pluginsManager.test.ts
index f9b55d2712e3cb23ec806e3440d373fd06bcd3d3..f6ef08cecd05c2bcfc9bee92b4af7a5129d7c554 100644
--- a/src/services/pluginsManager/pluginsManager.test.ts
+++ b/src/services/pluginsManager/pluginsManager.test.ts
@@ -1,11 +1,30 @@
 /* eslint-disable no-magic-numbers */
-import { store } from '@/redux/store';
+import { ZERO } from '@/constants/common';
+import { PLUGINS_CONTENT_ELEMENT_ATTR_NAME, PLUGINS_CONTENT_ELEMENT_ID } from '@/constants/plugins';
 import { configurationFixture } from '@/models/fixtures/configurationFixture';
-import { configurationMapper } from './pluginsManager.utils';
+import { store } from '@/redux/store';
 import { PluginsManager } from './pluginsManager';
+import { configurationMapper } from './pluginsManager.utils';
 
 jest.mock('../../redux/store');
 
+const createWrapperInDocument = (): HTMLDivElement => {
+  const wrapper = document.createElement('div');
+  wrapper.id = PLUGINS_CONTENT_ELEMENT_ID;
+
+  document.body.appendChild(wrapper);
+
+  return wrapper;
+};
+
+const createPluginElement = (hash: string): void => {
+  const element = document.createElement('div');
+  element.setAttribute(PLUGINS_CONTENT_ELEMENT_ATTR_NAME, hash);
+
+  const wrapper = document.querySelector(`#${PLUGINS_CONTENT_ELEMENT_ID}`);
+  wrapper?.append(element);
+};
+
 describe('PluginsManager', () => {
   const originalWindow = { ...global.window };
 
@@ -72,4 +91,39 @@ describe('PluginsManager', () => {
 
     expect(result.element).toBeDefined();
   });
+
+  it('createAndGetPluginContent creates a content in wrapper and returns element', () => {
+    const pluginName = 'TestPlugin';
+    const pluginVersion = '1.0.0';
+    const pluginUrl = 'https://example.com/test-plugin.js';
+    const hash = '128ce10ae1b46ec4bc6d7c07278b5c9e';
+    PluginsManager.hashedPlugins = {
+      [pluginUrl]: hash,
+    };
+
+    createWrapperInDocument();
+
+    const result = PluginsManager.registerPlugin({ pluginName, pluginVersion, pluginUrl });
+
+    expect(result.element).toBeDefined();
+    expect(result.element.getAttribute(PLUGINS_CONTENT_ELEMENT_ATTR_NAME)).toBe(hash);
+
+    expect(result.element.parentNode).toBeDefined();
+    expect(result.element.parentElement?.id).toBe(PLUGINS_CONTENT_ELEMENT_ID);
+  });
+
+  it('removePluginContent removes content in wrapper and returns element', () => {
+    const hash = '128ce10ae1b46ec4bc6d7c07278b5c9e';
+
+    const wrapper = createWrapperInDocument();
+    createPluginElement(hash);
+
+    PluginsManager.removePluginContent({ hash });
+
+    expect(
+      document.querySelector(`div[${PLUGINS_CONTENT_ELEMENT_ATTR_NAME}="${hash}"]`),
+    ).not.toBeInTheDocument();
+
+    expect(wrapper?.childElementCount).toEqual(ZERO);
+  });
 });
diff --git a/src/services/pluginsManager/pluginsManager.ts b/src/services/pluginsManager/pluginsManager.ts
index a41a8ed5cad9d405bb07069425bf28f79b3112e5..66ad3b93d18d04c97a9cd9bd055ac6b356bcadd9 100644
--- a/src/services/pluginsManager/pluginsManager.ts
+++ b/src/services/pluginsManager/pluginsManager.ts
@@ -1,8 +1,9 @@
-import md5 from 'crypto-js/md5';
-import { store } from '@/redux/store';
+import { PLUGINS_CONTENT_ELEMENT_ATTR_NAME, PLUGINS_CONTENT_ELEMENT_ID } from '@/constants/plugins';
 import { registerPlugin } from '@/redux/plugins/plugins.thunks';
-import { configurationMapper } from './pluginsManager.utils';
+import { store } from '@/redux/store';
+import md5 from 'crypto-js/md5';
 import type { PluginsManagerType } from './pluginsManager.types';
+import { configurationMapper } from './pluginsManager.utils';
 
 export const PluginsManager: PluginsManagerType = {
   hashedPlugins: {},
@@ -49,13 +50,26 @@ export const PluginsManager: PluginsManagerType = {
       }),
     );
 
-    // TODO: replace when plugins drawer is implemented
-    const element = document.createElement('div');
-    const wrapper = document.querySelector('#plugins');
-    wrapper?.append(element);
+    const element = PluginsManager.createAndGetPluginContent({ hash });
 
     return {
       element,
     };
   },
+  createAndGetPluginContent({ hash }) {
+    const element = document.createElement('div');
+    element.setAttribute(PLUGINS_CONTENT_ELEMENT_ATTR_NAME, hash);
+
+    const wrapper = document.querySelector(`#${PLUGINS_CONTENT_ELEMENT_ID}`);
+    wrapper?.append(element);
+
+    return element;
+  },
+  removePluginContent({ hash }) {
+    const elements = document.querySelectorAll(
+      `div[${PLUGINS_CONTENT_ELEMENT_ATTR_NAME}="${hash}"]`,
+    );
+
+    elements.forEach(element => element.remove());
+  },
 };
diff --git a/src/services/pluginsManager/pluginsManager.types.ts b/src/services/pluginsManager/pluginsManager.types.ts
index cedb9034b59df6bb3726b1f57e1d3109814be189..76a380f182e47859ba026455457c86e7c5fd2fe0 100644
--- a/src/services/pluginsManager/pluginsManager.types.ts
+++ b/src/services/pluginsManager/pluginsManager.types.ts
@@ -1,3 +1,4 @@
+import { MinervaPlugin } from '@/types/models';
 import { Unsubscribe } from '@reduxjs/toolkit';
 import { configurationMapper } from './pluginsManager.utils';
 
@@ -18,4 +19,6 @@ export type PluginsManagerType = {
   registerPlugin({ pluginName, pluginVersion, pluginUrl }: RegisterPlugin): {
     element: HTMLDivElement;
   };
+  createAndGetPluginContent(plugin: Pick<MinervaPlugin, 'hash'>): HTMLDivElement;
+  removePluginContent(plugin: Pick<MinervaPlugin, 'hash'>): void;
 };
diff --git a/src/shared/Icon/Icon.component.tsx b/src/shared/Icon/Icon.component.tsx
index dd6d4decfbbe023e069d0ef06b80b088b2e3458d..258f7a0901139e6d82f2cf9d38b91b0489f8344b 100644
--- a/src/shared/Icon/Icon.component.tsx
+++ b/src/shared/Icon/Icon.component.tsx
@@ -1,23 +1,24 @@
-import { ChevronRightIcon } from '@/shared/Icon/Icons/ChevronRightIcon';
-import { ChevronLeftIcon } from '@/shared/Icon/Icons/ChevronLeftIcon';
 import { AdminIcon } from '@/shared/Icon/Icons/AdminIcon';
 import { ArrowIcon } from '@/shared/Icon/Icons/ArrowIcon';
 import { ChevronDownIcon } from '@/shared/Icon/Icons/ChevronDownIcon';
+import { ChevronLeftIcon } from '@/shared/Icon/Icons/ChevronLeftIcon';
+import { ChevronRightIcon } from '@/shared/Icon/Icons/ChevronRightIcon';
 import { ChevronUpIcon } from '@/shared/Icon/Icons/ChevronUpIcon';
+import { CloseIcon } from '@/shared/Icon/Icons/CloseIcon';
 import { DotsIcon } from '@/shared/Icon/Icons/DotsIcon';
 import { ExportIcon } from '@/shared/Icon/Icons/ExportIcon';
 import { InfoIcon } from '@/shared/Icon/Icons/InfoIcon';
 import { LegendIcon } from '@/shared/Icon/Icons/LegendIcon';
 import { PageIcon } from '@/shared/Icon/Icons/PageIcon';
+import { Pin } from '@/shared/Icon/Icons/Pin';
 import { PluginIcon } from '@/shared/Icon/Icons/PluginIcon';
 import { PlusIcon } from '@/shared/Icon/Icons/PlusIcon';
-import { CloseIcon } from '@/shared/Icon/Icons/CloseIcon';
-import { Pin } from '@/shared/Icon/Icons/Pin';
 
-import type { IconTypes } from '@/types/iconTypes';
+import type { IconComponentType, IconTypes } from '@/types/iconTypes';
 import { LocationIcon } from './Icons/LocationIcon';
 import { MaginfierZoomInIcon } from './Icons/MagnifierZoomIn';
 import { MaginfierZoomOutIcon } from './Icons/MagnifierZoomOut';
+import { ReloadIcon } from './Icons/ReloadIcon';
 import { ThreeDotsIcon } from './Icons/ThreeDotsIcon';
 
 export interface IconProps {
@@ -25,7 +26,7 @@ export interface IconProps {
   name: IconTypes;
 }
 
-const icons = {
+const icons: Record<IconTypes, IconComponentType> = {
   'chevron-right': ChevronRightIcon,
   'chevron-left': ChevronLeftIcon,
   'chevron-up': ChevronUpIcon,
@@ -45,6 +46,7 @@ const icons = {
   'magnifier-zoom-in': MaginfierZoomInIcon,
   'magnifier-zoom-out': MaginfierZoomOutIcon,
   'three-dots': ThreeDotsIcon,
+  reload: ReloadIcon,
 } as const;
 
 export const Icon = ({ name, className = '', ...rest }: IconProps): JSX.Element => {
diff --git a/src/shared/Icon/Icons/ChevronDownIcon.tsx b/src/shared/Icon/Icons/ChevronDownIcon.tsx
index 5b9d6d3b570653d3bcc32deb51168d34337a2926..5b0ae0ecb5470ce1ac6b669011a558ef5887ad6f 100644
--- a/src/shared/Icon/Icons/ChevronDownIcon.tsx
+++ b/src/shared/Icon/Icons/ChevronDownIcon.tsx
@@ -3,14 +3,7 @@ interface ChevronDownIconProps {
 }
 
 export const ChevronDownIcon = ({ className }: ChevronDownIconProps): JSX.Element => (
-  <svg
-    width="14"
-    height="14"
-    viewBox="0 0 14 14"
-    fill="none"
-    className={className}
-    xmlns="http://www.w3.org/2000/svg"
-  >
+  <svg viewBox="0 0 14 14" fill="none" className={className} xmlns="http://www.w3.org/2000/svg">
     <g clipPath="url(#clip0_2005_6461)">
       <path d="M6.99958 7.68437L9.88708 4.79687L10.7119 5.62171L6.99958 9.33404L3.28725 5.62171L4.11208 4.79687L6.99958 7.68437Z" />
     </g>
diff --git a/src/shared/Icon/Icons/ChevronUpIcon.tsx b/src/shared/Icon/Icons/ChevronUpIcon.tsx
index d0c049778125ffacae3d23f135e1731b60931185..20b46496e9419bd2dd5125d8b3d2afdae8ef80a8 100644
--- a/src/shared/Icon/Icons/ChevronUpIcon.tsx
+++ b/src/shared/Icon/Icons/ChevronUpIcon.tsx
@@ -3,14 +3,7 @@ interface ChevronUpIconProps {
 }
 
 export const ChevronUpIcon = ({ className }: ChevronUpIconProps): JSX.Element => (
-  <svg
-    width="14"
-    height="14"
-    viewBox="0 0 14 14"
-    fill="none"
-    className={className}
-    xmlns="http://www.w3.org/2000/svg"
-  >
+  <svg viewBox="0 0 14 14" fill="none" className={className} xmlns="http://www.w3.org/2000/svg">
     <g clipPath="url(#clip0_2005_6483)">
       <path d="M7.00042 6.31563L4.11292 9.20312L3.28809 8.37829L7.00042 4.66596L10.7128 8.37829L9.88792 9.20312L7.00042 6.31563Z" />
     </g>
diff --git a/src/shared/Icon/Icons/ReloadIcon.tsx b/src/shared/Icon/Icons/ReloadIcon.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..71e20ae396f349916c4f8bc5bbb00a98a0488009
--- /dev/null
+++ b/src/shared/Icon/Icons/ReloadIcon.tsx
@@ -0,0 +1,19 @@
+interface ReloadIconProps {
+  className?: string;
+}
+
+export const ReloadIcon = ({ className }: ReloadIconProps): JSX.Element => (
+  <svg
+    width="14"
+    height="15"
+    viewBox="0 0 14 15"
+    fill="none"
+    xmlns="http://www.w3.org/2000/svg"
+    className={className}
+  >
+    <path
+      d="M2.64253 2.45404C3.85223 1.40581 5.39985 0.829805 7.00053 0.832038C10.6825 0.832038 13.6672 3.8167 13.6672 7.4987C13.6672 8.9227 13.2205 10.2427 12.4605 11.3254L10.3339 7.4987H12.3339C12.3339 6.45312 12.0267 5.43057 11.4503 4.55821C10.8739 3.68584 10.0538 3.00214 9.09198 2.59212C8.13015 2.1821 7.069 2.06384 6.0405 2.25205C5.01199 2.44026 4.0615 2.92664 3.3072 3.6507L2.64253 2.45404ZM11.3585 12.5434C10.1488 13.5916 8.6012 14.1676 7.00053 14.1654C3.31853 14.1654 0.333862 11.1807 0.333862 7.4987C0.333862 6.0747 0.780529 4.7547 1.54053 3.67204L3.6672 7.4987H1.6672C1.66711 8.54429 1.97436 9.56684 2.55075 10.4392C3.12714 11.3116 3.94724 11.9953 4.90908 12.4053C5.87091 12.8153 6.93205 12.9336 7.96056 12.7454C8.98906 12.5571 9.93956 12.0708 10.6939 11.3467L11.3585 12.5434Z"
+      fill="#4091F4"
+    />
+  </svg>
+);
diff --git a/src/types/OLrendering.ts b/src/types/OLrendering.ts
index 6aee24d703ddc7ab5c39bf21644ad91895886891..18075b437e4f2f7e91f7de2cbe1955f8851feaf4 100644
--- a/src/types/OLrendering.ts
+++ b/src/types/OLrendering.ts
@@ -1,4 +1,4 @@
-import { Color } from './models';
+import { Color, GeneVariant } from './models';
 
 export type OverlayBioEntityRenderType = 'line' | 'rectangle';
 
@@ -19,6 +19,7 @@ export type OverlayBioEntityRender = {
   overlayId: number;
   color: Color | null;
   type: OverlayBioEntityRenderType;
+  geneVariants?: GeneVariant[] | null;
 };
 
 export interface OverlayReactionCoords {
diff --git a/src/types/iconTypes.ts b/src/types/iconTypes.ts
index 3083f71695a3744b6638705a7ec79805bd8703c9..1a7ec425177c339341635f76a994e836aacfd1c3 100644
--- a/src/types/iconTypes.ts
+++ b/src/types/iconTypes.ts
@@ -17,4 +17,7 @@ export type IconTypes =
   | 'magnifier-zoom-in'
   | 'magnifier-zoom-out'
   | 'pin'
-  | 'three-dots';
+  | 'three-dots'
+  | 'reload';
+
+export type IconComponentType = ({ className }: { className: string }) => JSX.Element;
diff --git a/src/types/models.ts b/src/types/models.ts
index 3f9efc0e75c9c1260b4572e642240f24c7b471a2..fbc40b495a27ae375e1242592391e07fa6d12f22 100644
--- a/src/types/models.ts
+++ b/src/types/models.ts
@@ -1,4 +1,3 @@
-import { z } from 'zod';
 import { bioEntityContentSchema } from '@/models/bioEntityContentSchema';
 import { bioEntityResponseSchema } from '@/models/bioEntityResponseSchema';
 import { bioEntitySchema } from '@/models/bioEntitySchema';
@@ -14,6 +13,7 @@ import { disease } from '@/models/disease';
 import { drugSchema } from '@/models/drugSchema';
 import { elementSearchResult, elementSearchResultType } from '@/models/elementSearchResult';
 import { exportElementsSchema, exportNetworkchema } from '@/models/exportSchema';
+import { geneVariant } from '@/models/geneVariant';
 import { lineSchema } from '@/models/lineSchema';
 import { loginSchema } from '@/models/loginSchema';
 import { mapBackground } from '@/models/mapBackground';
@@ -40,6 +40,7 @@ import {
 import { overviewImageView } from '@/models/overviewImageView';
 import { pluginSchema } from '@/models/pluginSchema';
 import { projectSchema } from '@/models/projectSchema';
+import { publicationsResponseSchema } from '@/models/publicationsResponseSchema';
 import { publicationSchema } from '@/models/publicationsSchema';
 import { reactionSchema } from '@/models/reaction';
 import { reactionLineSchema } from '@/models/reactionLineSchema';
@@ -47,7 +48,7 @@ import { referenceSchema } from '@/models/referenceSchema';
 import { sessionSchemaValid } from '@/models/sessionValidSchema';
 import { statisticsSchema } from '@/models/statisticsSchema';
 import { targetSchema } from '@/models/targetSchema';
-import { publicationsResponseSchema } from '@/models/publicationsResponseSchema';
+import { z } from 'zod';
 
 export type Project = z.infer<typeof projectSchema>;
 export type OverviewImageView = z.infer<typeof overviewImageView>;
@@ -94,3 +95,4 @@ 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 GeneVariant = z.infer<typeof geneVariant>;
diff --git a/src/utils/convert/addAlphaToHexString.ts b/src/utils/convert/addAlphaToHexString.ts
index ca474de5d2ef44f8dd293ddc56cb9880c3eceaeb..530d4a5d028ff39382e56cd0246da60e48c83487 100644
--- a/src/utils/convert/addAlphaToHexString.ts
+++ b/src/utils/convert/addAlphaToHexString.ts
@@ -1,12 +1,16 @@
+import { ZERO } from '@/constants/common';
 import { expandHexToFullFormatIfItsShorthanded } from './hexToRgb';
 
 const HEX_RADIX = 16;
 const EXPECTED_HEX_LENGTH = 2;
 const MAX_RGB_VALUE = 255;
 const DEFAULT_ALPHA = 1;
+const NORMALIZED_HEX_LENGTH = 6; // example: FFFFFF
 
 export const addAlphaToHexString = (hexString: string, alpha: number = DEFAULT_ALPHA): string => {
-  const fullHexString = expandHexToFullFormatIfItsShorthanded(hexString);
+  const hexStringWithoutHash = hexString.replace('#', '');
+  const hexStringNormalized = hexStringWithoutHash.slice(ZERO, NORMALIZED_HEX_LENGTH);
+  const fullHexString = expandHexToFullFormatIfItsShorthanded(hexStringNormalized);
 
   const alphaHex = Math.round(alpha * MAX_RGB_VALUE)
     .toString(HEX_RADIX)
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 0f75c8f70c01a9fc34cd4d0a7b4e4c4605fb3c36..e2c026d909241ac536fae67aa80e253c274c5280 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -37,6 +37,7 @@ const config: Config = {
       },
       boxShadow: {
         primary: '4px 8px 32px 0px rgba(0, 0, 0, 0.12)',
+        tableBorderDivide: '0 0 0 1px #e1e0e6',
       },
       dropShadow: {
         primary: '0px 4px 24px rgba(0, 0, 0, 0.08)',