From bda7d0e7ee75b5ee729bca4f565cc598f7c04b6d Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Thu, 5 Dec 2024 11:23:24 +0100
Subject: [PATCH 01/12] notes are rendered as HTML

---
 CHANGELOG                                                | 4 +++-
 .../Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx | 6 +++++-
 .../Drawer/ReactionDrawer/ReactionDrawer.component.tsx   | 9 ++++++++-
 3 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 164d4397..a0285e6e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,8 +1,10 @@
 minerva-front (18.0.5) stable; urgency=medium
   * Bug fix: anchor overlays were disappearing after clicking on anchor and
     outside of the anchor (#319)
+  * Bug fix: bioEntity HTML notes in the left panel were not rendered as html
+    (#323)
 
- -- Piotr Gawron <piotr.gawron@uni.lu>  Wed, 27 Nov 2024 13:00:00 +0200
+ -- Piotr Gawron <piotr.gawron@uni.lu>  Thu, 05 Dec 2024 13:00:00 +0200
 
 minerva-front (18.0.4) stable; urgency=medium
   * Bug fix: link to search result from overview image caused map not to
diff --git a/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx b/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx
index 14fc5449..1e54091e 100644
--- a/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx
+++ b/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx
@@ -14,6 +14,7 @@ import { DrawerHeading } from '@/shared/DrawerHeading';
 import { ElementSearchResultType } from '@/types/models';
 import { CommentItem } from '@/components/Map/Drawer/BioEntityDrawer/Comments/CommentItem.component';
 import { ModificationResidueItem } from '@/components/Map/Drawer/BioEntityDrawer/ModificationResidueItem';
+import React from 'react';
 import { CollapsibleSection } from '../ExportDrawer/CollapsibleSection';
 import { AnnotationItem } from './AnnotationItem';
 import { AssociatedSubmap } from './AssociatedSubmap';
@@ -73,7 +74,10 @@ export const BioEntityDrawer = (): React.ReactNode => {
         {bioEntityData.notes && (
           <span>
             <hr className="border-b border-b-divide" />
-            <div className="text-sm font-normal">{bioEntityData.notes}</div>
+            <div
+              className="text-sm font-normal"
+              dangerouslySetInnerHTML={{ __html: bioEntityData.notes }}
+            />
           </span>
         )}
         {isModificationAvailable && (
diff --git a/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.tsx b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.tsx
index 1423ef7d..f772343e 100644
--- a/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.tsx
+++ b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.tsx
@@ -8,6 +8,7 @@ import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { currentDrawerReactionCommentsSelector } from '@/redux/bioEntity/bioEntity.selectors';
 import { CommentItem } from '@/components/Map/Drawer/BioEntityDrawer/Comments/CommentItem.component';
 import { ZERO } from '@/constants/common';
+import React from 'react';
 import { ReferenceGroup } from './ReferenceGroup';
 import { ConnectedBioEntitiesList } from './ConnectedBioEntitiesList';
 
@@ -37,7 +38,13 @@ export const ReactionDrawer = (): React.ReactNode => {
           Type: <b className="font-semibold">{reaction.type}</b>
         </div>
         <hr className="border-b border-b-divide" />
-        {reaction.notes && <div className="text-sm font-normal">{reaction.notes}</div>}
+        {reaction.notes && (
+          <div
+            className="text-sm font-normal"
+            dangerouslySetInnerHTML={{ __html: reaction.notes }}
+          />
+        )}
+
         <h3 className="font-semibold">Annotations:</h3>
         {referencesGrouped.map(group => (
           <ReferenceGroup key={group.source} group={group} />
-- 
GitLab


From 44c9e0010363d6d24179e1540d80f16df3c794fd Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Fri, 6 Dec 2024 10:39:08 +0100
Subject: [PATCH 02/12] Update CHANGELOG

---
 CHANGELOG | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/CHANGELOG b/CHANGELOG
index a0285e6e..37a544e7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,9 @@
+minerva-front (18.0.6) stable; urgency=medium
+
+  * No changes in frontend
+
+-- Piotr Gawron <piotr.gawron@uni.lu>  Fri, 06 Dec 2024 13:00:00 +0200
+
 minerva-front (18.0.5) stable; urgency=medium
   * Bug fix: anchor overlays were disappearing after clicking on anchor and
     outside of the anchor (#319)
-- 
GitLab


From 5faa81bfee166317bffc7b94f522de83c6fb3f14 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Wed, 11 Dec 2024 08:44:57 +0100
Subject: [PATCH 03/12] export to image should include overlays

---
 CHANGELOG                                                   | 5 +++++
 .../ExportCompound/ExportCompound.component.tsx             | 3 +++
 .../ExportCompound/utils/getGraphicsDownloadUrl.test.ts     | 6 +++++-
 .../ExportCompound/utils/getGraphicsDownloadUrl.ts          | 6 +++++-
 4 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 37a544e7..25728623 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,8 @@
+minerva-front (18.0.7) stable; urgency=medium
+  * Bug fix: export to image did not include overlays (#326)
+
+-- Piotr Gawron <piotr.gawron@uni.lu>  Wed, 11 Dec 2024 13:00:00 +0200
+
 minerva-front (18.0.6) stable; urgency=medium
 
   * No changes in frontend
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx
index f5803c10..e33a99ed 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx
@@ -5,6 +5,7 @@ import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { modelsDataSelector, modelsIdsSelector } from '@/redux/models/models.selectors';
 import { ReactNode, useCallback, useMemo, useState } from 'react';
+import { activeOverlaysIdSelector } from '@/redux/overlayBioEntity/overlayBioEntity.selector';
 import { CheckboxItem } from '../CheckboxFilter/CheckboxFilter.types';
 import { Annotations } from './Annotations';
 import { DownloadElements } from './DownloadElements/DownloadElements';
@@ -33,6 +34,7 @@ export const Export = ({ children }: ExportProps): JSX.Element => {
   const modelIds = useAppSelector(modelsIdsSelector);
   const currentModels = useAppSelector(modelsDataSelector);
   const currentBackground = useAppSelector(currentBackgroundSelector);
+  const overlays = useAppSelector(activeOverlaysIdSelector);
   const [annotations, setAnnotations] = useState<CheckboxItem[]>([]);
   const [includedCompartmentPathways, setIncludedCompartmentPathways] = useState<CheckboxItem[]>(
     [],
@@ -76,6 +78,7 @@ export const Export = ({ children }: ExportProps): JSX.Element => {
       modelId: models?.[FIRST_ARRAY_ELEMENT]?.id,
       handler: imageFormats?.[FIRST_ARRAY_ELEMENT]?.id,
       zoom: getModelExportZoom(imageSize.width, model),
+      overlayIds: overlays.map(overlayId => `${overlayId}`),
     });
 
     if (url) {
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.test.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.test.ts
index 2e6c4db9..e621890a 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.test.ts
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.test.ts
@@ -3,10 +3,11 @@ import { GetGraphicsDownloadUrlProps, getGraphicsDownloadUrl } from './getGraphi
 
 describe('getGraphicsDownloadUrl - util', () => {
   const cases: [GetGraphicsDownloadUrlProps, string | undefined][] = [
-    [{}, undefined],
+    [{ overlayIds: [] }, undefined],
     [
       {
         backgroundId: 50,
+        overlayIds: [],
       },
       undefined,
     ],
@@ -14,6 +15,7 @@ describe('getGraphicsDownloadUrl - util', () => {
       {
         backgroundId: 50,
         modelId: '30',
+        overlayIds: [],
       },
       undefined,
     ],
@@ -22,6 +24,7 @@ describe('getGraphicsDownloadUrl - util', () => {
         backgroundId: 50,
         modelId: '30',
         handler: 'any.handler.image',
+        overlayIds: [],
       },
       undefined,
     ],
@@ -31,6 +34,7 @@ describe('getGraphicsDownloadUrl - util', () => {
         modelId: '30',
         handler: 'any.handler.image',
         zoom: 7,
+        overlayIds: [],
       },
       `${BASE_API_URL}/projects/${PROJECT_ID}/models/30:downloadImage?backgroundOverlayId=50&handlerClass=any.handler.image&zoomLevel=7`,
     ],
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.ts
index c4020e98..169265ea 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.ts
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.ts
@@ -5,6 +5,7 @@ export interface GetGraphicsDownloadUrlProps {
   modelId?: string;
   handler?: string;
   zoom?: number;
+  overlayIds: string[];
 }
 
 export const getGraphicsDownloadUrl = ({
@@ -12,6 +13,7 @@ export const getGraphicsDownloadUrl = ({
   modelId,
   handler,
   zoom,
+  overlayIds,
 }: GetGraphicsDownloadUrlProps): string | undefined => {
   const isAllElementsTruthy = [backgroundId, modelId, handler, zoom].reduce(
     (a, b) => Boolean(a) && Boolean(b),
@@ -22,5 +24,7 @@ export const getGraphicsDownloadUrl = ({
     return undefined;
   }
 
-  return `${BASE_API_URL}/projects/${PROJECT_ID}/models/${modelId}:downloadImage?backgroundOverlayId=${backgroundId}&handlerClass=${handler}&zoomLevel=${zoom}`;
+  const overlays = overlayIds.join(',');
+
+  return `${BASE_API_URL}/projects/${PROJECT_ID}/models/${modelId}:downloadImage?backgroundOverlayId=${backgroundId}&handlerClass=${handler}&zoomLevel=${zoom}&overlayIds=${overlays}`;
 };
-- 
GitLab


From 972c905e555e46bb097a0ed58e39985c777723b3 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Wed, 11 Dec 2024 08:59:33 +0100
Subject: [PATCH 04/12] fix tests

---
 .../ExportCompound/utils/getGraphicsDownloadUrl.test.ts       | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.test.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.test.ts
index e621890a..a4e4c59d 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.test.ts
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.test.ts
@@ -34,9 +34,9 @@ describe('getGraphicsDownloadUrl - util', () => {
         modelId: '30',
         handler: 'any.handler.image',
         zoom: 7,
-        overlayIds: [],
+        overlayIds: ['107'],
       },
-      `${BASE_API_URL}/projects/${PROJECT_ID}/models/30:downloadImage?backgroundOverlayId=50&handlerClass=any.handler.image&zoomLevel=7`,
+      `${BASE_API_URL}/projects/${PROJECT_ID}/models/30:downloadImage?backgroundOverlayId=50&handlerClass=any.handler.image&zoomLevel=7&overlayIds=107`,
     ],
   ];
 
-- 
GitLab


From eb710e2815ce2301509cf5e0feff78a3cd548eb5 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Wed, 11 Dec 2024 10:20:53 +0100
Subject: [PATCH 05/12] bump tailwind dependency

---
 package-lock.json | 22 +++++++++++-----------
 package.json      |  2 +-
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 095755a0..95f24b71 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -39,7 +39,7 @@
         "react-redux": "8.1.3",
         "sonner": "1.4.3",
         "tailwind-merge": "1.14.0",
-        "tailwindcss": "3.3.3",
+        "tailwindcss": "3.4.13",
         "ts-deepmerge": "6.2.0",
         "use-debounce": "9.0.4",
         "uuid": "9.0.1",
@@ -13020,19 +13020,19 @@
       }
     },
     "node_modules/tailwindcss": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz",
-      "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==",
+      "version": "3.4.13",
+      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz",
+      "integrity": "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==",
       "dependencies": {
         "@alloc/quick-lru": "^5.2.0",
         "arg": "^5.0.2",
         "chokidar": "^3.5.3",
         "didyoumean": "^1.2.2",
         "dlv": "^1.1.3",
-        "fast-glob": "^3.2.12",
+        "fast-glob": "^3.3.0",
         "glob-parent": "^6.0.2",
         "is-glob": "^4.0.3",
-        "jiti": "^1.18.2",
+        "jiti": "^1.21.0",
         "lilconfig": "^2.1.0",
         "micromatch": "^4.0.5",
         "normalize-path": "^3.0.0",
@@ -23497,19 +23497,19 @@
       "integrity": "sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ=="
     },
     "tailwindcss": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz",
-      "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==",
+      "version": "3.4.13",
+      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz",
+      "integrity": "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==",
       "requires": {
         "@alloc/quick-lru": "^5.2.0",
         "arg": "^5.0.2",
         "chokidar": "^3.5.3",
         "didyoumean": "^1.2.2",
         "dlv": "^1.1.3",
-        "fast-glob": "^3.2.12",
+        "fast-glob": "^3.3.0",
         "glob-parent": "^6.0.2",
         "is-glob": "^4.0.3",
-        "jiti": "^1.18.2",
+        "jiti": "^1.21.0",
         "lilconfig": "^2.1.0",
         "micromatch": "^4.0.5",
         "normalize-path": "^3.0.0",
diff --git a/package.json b/package.json
index 01cbb2f8..9255d88b 100644
--- a/package.json
+++ b/package.json
@@ -53,7 +53,7 @@
     "react-redux": "8.1.3",
     "sonner": "1.4.3",
     "tailwind-merge": "1.14.0",
-    "tailwindcss": "3.3.3",
+    "tailwindcss": "3.4.13",
     "ts-deepmerge": "6.2.0",
     "use-debounce": "9.0.4",
     "uuid": "9.0.1",
-- 
GitLab


From 138c591cf8450db7e93d60d7a7e0076f3dc8083e Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Wed, 11 Dec 2024 10:22:34 +0100
Subject: [PATCH 06/12] configurable logos were not loaded

---
 CHANGELOG                                     |  1 +
 src/components/Map/Map.component.tsx          |  4 +-
 .../MapAdditionalLogos.component.tsx          | 51 +++++++++++++++++++
 .../Map/MapAdditionalLogos/index.ts           |  1 +
 .../configuration/configuration.constants.ts  |  6 +++
 .../configuration/configuration.selectors.ts  | 32 ++++++++++++
 6 files changed, 94 insertions(+), 1 deletion(-)
 create mode 100644 src/components/Map/MapAdditionalLogos/MapAdditionalLogos.component.tsx
 create mode 100644 src/components/Map/MapAdditionalLogos/index.ts

diff --git a/CHANGELOG b/CHANGELOG
index 25728623..52071d51 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
 minerva-front (18.0.7) stable; urgency=medium
   * Bug fix: export to image did not include overlays (#326)
+  * Bug fix: missing logos added (#329)
 
 -- Piotr Gawron <piotr.gawron@uni.lu>  Wed, 11 Dec 2024 13:00:00 +0200
 
diff --git a/src/components/Map/Map.component.tsx b/src/components/Map/Map.component.tsx
index 72d18ebf..033ebd2f 100644
--- a/src/components/Map/Map.component.tsx
+++ b/src/components/Map/Map.component.tsx
@@ -1,8 +1,9 @@
 import { Drawer } from '@/components/Map/Drawer';
 import { Legend } from '@/components/Map/Legend';
+import { MapAdditionalLogos } from '@/components/Map/MapAdditionalLogos';
+import { MapViewer } from '@/components/Map/MapViewer';
 import { MapAdditionalActions } from './MapAdditionalActions';
 import { MapAdditionalOptions } from './MapAdditionalOptions';
-import { MapViewer } from './MapViewer/MapViewer.component';
 import { PluginsDrawer } from './PluginsDrawer';
 
 export const Map = (): JSX.Element => (
@@ -16,5 +17,6 @@ export const Map = (): JSX.Element => (
     <MapViewer />
     <Legend />
     <MapAdditionalActions />
+    <MapAdditionalLogos />
   </div>
 );
diff --git a/src/components/Map/MapAdditionalLogos/MapAdditionalLogos.component.tsx b/src/components/Map/MapAdditionalLogos/MapAdditionalLogos.component.tsx
new file mode 100644
index 00000000..51b29d2d
--- /dev/null
+++ b/src/components/Map/MapAdditionalLogos/MapAdditionalLogos.component.tsx
@@ -0,0 +1,51 @@
+/* eslint-disable @next/next/no-img-element */
+import { twMerge } from 'tailwind-merge';
+import {
+  leftLogoImgValSelector,
+  leftLogoLinkValSelector,
+  leftLogoTextValSelector,
+  rightLogoImgValSelector,
+  rightLogoLinkValSelector,
+  rightLogoTextValSelector,
+} from '@/redux/configuration/configuration.selectors';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { LinkButton } from '@/shared/LinkButton';
+
+export const MapAdditionalLogos = (): JSX.Element => {
+  const leftLink = useAppSelector(leftLogoLinkValSelector);
+  const leftText = useAppSelector(leftLogoTextValSelector);
+  const leftImage = useAppSelector(leftLogoImgValSelector);
+
+  const rightLink = useAppSelector(rightLogoLinkValSelector);
+  const rightText = useAppSelector(rightLogoTextValSelector);
+  const rightImage = useAppSelector(rightLogoImgValSelector);
+
+  return (
+    <div className={twMerge('absolute bottom-6 left-[102px] grid grid-cols-2 gap-4')}>
+      {leftLink && (
+        <LinkButton
+          type="button"
+          className="flex h-auto max-h-20 w-auto max-w-20 cursor-pointer items-center justify-center border-0 bg-gray-200 bg-opacity-20 hover:bg-gray-300 hover:bg-opacity-30"
+          data-testid="location-button"
+          title={leftText}
+          href={leftLink}
+          target="_blank"
+        >
+          <img alt={leftText} src={leftImage} />
+        </LinkButton>
+      )}
+      {rightLink && (
+        <LinkButton
+          type="button"
+          className="flex h-auto max-h-20 w-auto max-w-20 cursor-pointer items-center justify-center border-0 bg-gray-200 bg-opacity-20 hover:bg-gray-300 hover:bg-opacity-30"
+          data-testid="location-button"
+          title={rightText}
+          href={rightLink}
+          target="_blank"
+        >
+          <img alt={rightText} src={rightImage} />
+        </LinkButton>
+      )}
+    </div>
+  );
+};
diff --git a/src/components/Map/MapAdditionalLogos/index.ts b/src/components/Map/MapAdditionalLogos/index.ts
new file mode 100644
index 00000000..6ea9ee31
--- /dev/null
+++ b/src/components/Map/MapAdditionalLogos/index.ts
@@ -0,0 +1 @@
+export { MapAdditionalLogos } from './MapAdditionalLogos.component';
diff --git a/src/redux/configuration/configuration.constants.ts b/src/redux/configuration/configuration.constants.ts
index 032c5e0b..25ff1216 100644
--- a/src/redux/configuration/configuration.constants.ts
+++ b/src/redux/configuration/configuration.constants.ts
@@ -7,6 +7,12 @@ export const SEARCH_DISTANCE_NAME_ID = 'SEARCH_DISTANCE';
 export const REQUEST_ACCOUNT_EMAIL = 'REQUEST_ACCOUNT_EMAIL';
 export const TERMS_OF_SERVICE_ID = 'TERMS_OF_USE';
 export const COOKIE_POLICY_URL = 'COOKIE_POLICY_URL';
+export const LEFT_LOGO_IMG = 'LEFT_LOGO_IMG';
+export const LEFT_LOGO_LINK = 'LEFT_LOGO_LINK';
+export const LEFT_LOGO_TEXT = 'LEFT_LOGO_TEXT';
+export const RIGHT_LOGO_IMG = 'RIGHT_LOGO_IMG';
+export const RIGHT_LOGO_LINK = 'RIGHT_LOGO_LINK';
+export const RIGHT_LOGO_TEXT = 'RIGHT_LOGO_TEXT';
 
 export const LEGEND_FILE_NAMES_IDS = [
   'LEGEND_FILE_1',
diff --git a/src/redux/configuration/configuration.selectors.ts b/src/redux/configuration/configuration.selectors.ts
index 01a9eb4c..8677cadb 100644
--- a/src/redux/configuration/configuration.selectors.ts
+++ b/src/redux/configuration/configuration.selectors.ts
@@ -20,6 +20,12 @@ import {
   REQUEST_ACCOUNT_EMAIL,
   TERMS_OF_SERVICE_ID,
   COOKIE_POLICY_URL,
+  LEFT_LOGO_IMG,
+  LEFT_LOGO_LINK,
+  LEFT_LOGO_TEXT,
+  RIGHT_LOGO_IMG,
+  RIGHT_LOGO_LINK,
+  RIGHT_LOGO_TEXT,
 } from './configuration.constants';
 
 import { ConfigurationHandlersIds, ConfigurationImageHandlersIds } from './configuration.types';
@@ -151,3 +157,29 @@ export const loadingConfigurationMainSelector = createSelector(
   configurationSelector,
   state => state?.main?.loading,
 );
+
+export const leftLogoImgValSelector = createSelector(
+  configurationOptionsSelector,
+  state => configurationAdapterSelectors.selectById(state, LEFT_LOGO_IMG)?.value,
+);
+export const leftLogoLinkValSelector = createSelector(
+  configurationOptionsSelector,
+  state => configurationAdapterSelectors.selectById(state, LEFT_LOGO_LINK)?.value,
+);
+export const leftLogoTextValSelector = createSelector(
+  configurationOptionsSelector,
+  state => configurationAdapterSelectors.selectById(state, LEFT_LOGO_TEXT)?.value,
+);
+
+export const rightLogoImgValSelector = createSelector(
+  configurationOptionsSelector,
+  state => configurationAdapterSelectors.selectById(state, RIGHT_LOGO_IMG)?.value,
+);
+export const rightLogoLinkValSelector = createSelector(
+  configurationOptionsSelector,
+  state => configurationAdapterSelectors.selectById(state, RIGHT_LOGO_LINK)?.value,
+);
+export const rightLogoTextValSelector = createSelector(
+  configurationOptionsSelector,
+  state => configurationAdapterSelectors.selectById(state, RIGHT_LOGO_TEXT)?.value,
+);
-- 
GitLab


From 38f51e0f83c6b6faf765ab3b693250b451f1b430 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Wed, 11 Dec 2024 12:11:05 +0100
Subject: [PATCH 07/12] provide info about entries when returning list of
 visible data overlays

---
 CHANGELOG                                     |  2 +
 .../map/overlays/getVisibleDataOverlays.ts    | 40 ++++++++++++++++-
 .../map/overlays/types/DataOverlay.ts         | 44 +++++++++++++++++++
 .../map/overlays/types/DataOverlayEntry.ts    | 27 ++++++++++++
 4 files changed, 112 insertions(+), 1 deletion(-)
 create mode 100644 src/services/pluginsManager/map/overlays/types/DataOverlay.ts
 create mode 100644 src/services/pluginsManager/map/overlays/types/DataOverlayEntry.ts

diff --git a/CHANGELOG b/CHANGELOG
index 52071d51..a58b1598 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
 minerva-front (18.0.7) stable; urgency=medium
   * Bug fix: export to image did not include overlays (#326)
   * Bug fix: missing logos added (#329)
+  * Bug fix: plugin API did not provide overlay entries when returning list of
+    visible overlays (#332)
 
 -- Piotr Gawron <piotr.gawron@uni.lu>  Wed, 11 Dec 2024 13:00:00 +0200
 
diff --git a/src/services/pluginsManager/map/overlays/getVisibleDataOverlays.ts b/src/services/pluginsManager/map/overlays/getVisibleDataOverlays.ts
index 6224d3ff..5f570436 100644
--- a/src/services/pluginsManager/map/overlays/getVisibleDataOverlays.ts
+++ b/src/services/pluginsManager/map/overlays/getVisibleDataOverlays.ts
@@ -1,9 +1,47 @@
-import { activeOverlaysSelector } from '@/redux/overlayBioEntity/overlayBioEntity.selector';
+import {
+  activeOverlaysSelector,
+  overlayBioEntityDataSelector,
+} from '@/redux/overlayBioEntity/overlayBioEntity.selector';
 import { store } from '@/redux/store';
 import { MapOverlay } from '@/types/models';
+import { DataOverlay } from '@/services/pluginsManager/map/overlays/types/DataOverlay';
+import { modelsDataSelector } from '@/redux/models/models.selectors';
+import { DataOverlayEntry } from '@/services/pluginsManager/map/overlays/types/DataOverlayEntry';
 
 export const getVisibleDataOverlays = (): MapOverlay[] => {
   const activeOverlays = activeOverlaysSelector(store.getState());
+  const overlayData = overlayBioEntityDataSelector(store.getState());
+
+  const models = modelsDataSelector(store.getState());
+
+  const dataOverlays = activeOverlays.map(mapOverlay => new DataOverlay(mapOverlay));
+
+  dataOverlays.forEach(dataOverlay => {
+    const mapOverlayData = overlayData[dataOverlay.id];
+    if (mapOverlayData) {
+      models.forEach(model => {
+        const entries = mapOverlayData[model.idObject];
+        if (entries) {
+          entries.forEach(dataEntry => {
+            if (dataEntry.type === 'submap-link') {
+              dataOverlay.addEntry(
+                new DataOverlayEntry(
+                  Number(dataEntry.id),
+                  'ALIAS',
+                  dataEntry.modelId,
+                  dataEntry.color,
+                  dataEntry.value,
+                ),
+              );
+            } else {
+              // eslint-disable-next-line no-console
+              console.log(`${dataEntry.type} not supported`);
+            }
+          });
+        }
+      });
+    }
+  });
 
   return activeOverlays;
 };
diff --git a/src/services/pluginsManager/map/overlays/types/DataOverlay.ts b/src/services/pluginsManager/map/overlays/types/DataOverlay.ts
new file mode 100644
index 00000000..e79d88ba
--- /dev/null
+++ b/src/services/pluginsManager/map/overlays/types/DataOverlay.ts
@@ -0,0 +1,44 @@
+import { MapOverlay } from '@/types/models';
+import { DataOverlayEntry } from '@/services/pluginsManager/map/overlays/types/DataOverlayEntry';
+
+export class DataOverlay {
+  id: number;
+
+  idObject: number;
+
+  name: string;
+
+  order: number;
+
+  creator: string;
+
+  description: string;
+
+  genomeType: string | null;
+
+  genomeVersion: string | null;
+
+  publicOverlay: boolean;
+
+  type: string;
+
+  entries: DataOverlayEntry[];
+
+  constructor(mapOverlay: MapOverlay) {
+    this.id = mapOverlay.idObject;
+    this.idObject = mapOverlay.idObject;
+    this.name = mapOverlay.name;
+    this.order = mapOverlay.order;
+    this.creator = mapOverlay.creator;
+    this.description = mapOverlay.description;
+    this.genomeType = mapOverlay.genomeType;
+    this.genomeVersion = mapOverlay.genomeVersion;
+    this.publicOverlay = mapOverlay.publicOverlay;
+    this.type = mapOverlay.type;
+    this.entries = [];
+  }
+
+  public addEntry(entry: DataOverlayEntry): void {
+    this.entries.push(entry);
+  }
+}
diff --git a/src/services/pluginsManager/map/overlays/types/DataOverlayEntry.ts b/src/services/pluginsManager/map/overlays/types/DataOverlayEntry.ts
new file mode 100644
index 00000000..2627887c
--- /dev/null
+++ b/src/services/pluginsManager/map/overlays/types/DataOverlayEntry.ts
@@ -0,0 +1,27 @@
+import { Color } from '@/types/models';
+
+export class DataOverlayEntry {
+  bioEntityId: number;
+
+  bioEntityType: string;
+
+  bioEntityModelId: number;
+
+  color: Color | null;
+
+  value: number | null;
+
+  constructor(
+    bioEntityId: number,
+    bioEntityType: string,
+    bioEntityModelId: number,
+    color: Color | null,
+    value: number | null,
+  ) {
+    this.bioEntityId = bioEntityId;
+    this.color = color;
+    this.value = value;
+    this.bioEntityType = bioEntityType;
+    this.bioEntityModelId = bioEntityModelId;
+  }
+}
-- 
GitLab


From 671676199d1103df8c61c819689ba082907f5b93 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Wed, 11 Dec 2024 12:58:29 +0100
Subject: [PATCH 08/12] provide data overlay entries for plugins in new
 interface

---
 .../map/overlays/getVisibleDataOverlays.test.ts              | 5 ++++-
 .../pluginsManager/map/overlays/getVisibleDataOverlays.ts    | 5 ++---
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/services/pluginsManager/map/overlays/getVisibleDataOverlays.test.ts b/src/services/pluginsManager/map/overlays/getVisibleDataOverlays.test.ts
index 036a668b..c0f486b9 100644
--- a/src/services/pluginsManager/map/overlays/getVisibleDataOverlays.test.ts
+++ b/src/services/pluginsManager/map/overlays/getVisibleDataOverlays.test.ts
@@ -3,6 +3,7 @@ import { overlaysFixture } from '@/models/fixtures/overlaysFixture';
 import { OVERLAYS_INITIAL_STATE_MOCK } from '@/redux/overlays/overlays.mock';
 import { RootState, store } from '@/redux/store';
 import { OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK } from '@/redux/overlayBioEntity/overlayBioEntity.mock';
+import { DataOverlay } from '@/services/pluginsManager/map/overlays/types/DataOverlay';
 import { getVisibleDataOverlays } from './getVisibleDataOverlays';
 
 const ACTIVE_OVERLAYS_IDS = overlaysFixture.map(overlay => overlay.idObject);
@@ -34,7 +35,9 @@ describe('getVisibleDataOverlays', () => {
         }) as RootState,
     );
 
-    expect(getVisibleDataOverlays()).toEqual(overlaysFixture);
+    expect(getVisibleDataOverlays()).toEqual(
+      overlaysFixture.map(overlay => new DataOverlay(overlay)),
+    );
   });
 
   it('should return empty array if no active overlays', () => {
diff --git a/src/services/pluginsManager/map/overlays/getVisibleDataOverlays.ts b/src/services/pluginsManager/map/overlays/getVisibleDataOverlays.ts
index 5f570436..14a69d51 100644
--- a/src/services/pluginsManager/map/overlays/getVisibleDataOverlays.ts
+++ b/src/services/pluginsManager/map/overlays/getVisibleDataOverlays.ts
@@ -3,12 +3,11 @@ import {
   overlayBioEntityDataSelector,
 } from '@/redux/overlayBioEntity/overlayBioEntity.selector';
 import { store } from '@/redux/store';
-import { MapOverlay } from '@/types/models';
 import { DataOverlay } from '@/services/pluginsManager/map/overlays/types/DataOverlay';
 import { modelsDataSelector } from '@/redux/models/models.selectors';
 import { DataOverlayEntry } from '@/services/pluginsManager/map/overlays/types/DataOverlayEntry';
 
-export const getVisibleDataOverlays = (): MapOverlay[] => {
+export const getVisibleDataOverlays = (): DataOverlay[] => {
   const activeOverlays = activeOverlaysSelector(store.getState());
   const overlayData = overlayBioEntityDataSelector(store.getState());
 
@@ -43,5 +42,5 @@ export const getVisibleDataOverlays = (): MapOverlay[] => {
     }
   });
 
-  return activeOverlays;
+  return dataOverlays;
 };
-- 
GitLab


From a4ba3e5e819d5189e1e90b9836a87c776471d638 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Thu, 12 Dec 2024 12:01:10 +0100
Subject: [PATCH 09/12] current view is changing properly image size

---
 .../CurrentView/CurrentView.component.tsx     | 24 ++++++++++
 .../CurrentView/CurrentView.constants.ts      |  5 ++
 .../CurrentView/CurrentView.types.ts          |  3 ++
 .../ExportCompound/CurrentView/index.ts       |  1 +
 .../ExportCompound.component.tsx              |  8 ++++
 .../ExportCompound/ExportCompound.constant.ts |  3 ++
 .../ExportCompound/ExportCompound.types.ts    |  3 ++
 .../ImageSize/utils/useImageSize.ts           | 33 +++++++++----
 .../ImageSize/utils/useScreenAspectRatios.ts  | 48 +++++++++++++++++++
 .../Graphics/Graphics.component.tsx           |  1 +
 10 files changed, 119 insertions(+), 10 deletions(-)
 create mode 100644 src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.component.tsx
 create mode 100644 src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.constants.ts
 create mode 100644 src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.types.ts
 create mode 100644 src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/index.ts
 create mode 100644 src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useScreenAspectRatios.ts

diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.component.tsx
new file mode 100644
index 00000000..cad075a0
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.component.tsx
@@ -0,0 +1,24 @@
+import { useContext } from 'react';
+import { ExportContext } from '@/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.context';
+
+export const CurrentView = (): React.ReactNode => {
+  const { setCurrentView, data } = useContext(ExportContext);
+
+  return (
+    <div className="flex flex-col gap-4 border-b">
+      <label className="flex h-9 items-center gap-4">
+        <span>Current view:&nbsp;</span>
+        <input
+          className="rounded-[64px] border border-transparent bg-cultured px-4 py-2.5 text-xs font-medium text-font-400 outline-none  hover:border-greyscale-600 focus:border-greyscale-600"
+          name="width"
+          checked={data.currentView.value}
+          type="checkbox"
+          aria-label="export graphics width input"
+          onChange={(e): void => {
+            setCurrentView({ value: e.target.checked });
+          }}
+        />
+      </label>
+    </div>
+  );
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.constants.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.constants.ts
new file mode 100644
index 00000000..f512b6d7
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.constants.ts
@@ -0,0 +1,5 @@
+import { CurrentView } from './CurrentView.types';
+
+export const DEFAULT_CURRENT_VIEW: CurrentView = {
+  value: false,
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.types.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.types.ts
new file mode 100644
index 00000000..dc5bc917
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.types.ts
@@ -0,0 +1,3 @@
+export interface CurrentView {
+  value: boolean;
+}
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/index.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/index.ts
new file mode 100644
index 00000000..883104d6
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/index.ts
@@ -0,0 +1 @@
+export { CurrentView } from './CurrentView.component';
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx
index e33a99ed..1b7d192b 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx
@@ -6,6 +6,8 @@ import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { modelsDataSelector, modelsIdsSelector } from '@/redux/models/models.selectors';
 import { ReactNode, useCallback, useMemo, useState } from 'react';
 import { activeOverlaysIdSelector } from '@/redux/overlayBioEntity/overlayBioEntity.selector';
+import { CurrentView } from '@/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView';
+import { DEFAULT_CURRENT_VIEW } from '@/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.constants';
 import { CheckboxItem } from '../CheckboxFilter/CheckboxFilter.types';
 import { Annotations } from './Annotations';
 import { DownloadElements } from './DownloadElements/DownloadElements';
@@ -18,6 +20,7 @@ import { ImageFormat } from './ImageFormat';
 import { ImageSize } from './ImageSize';
 import { DEFAULT_IMAGE_SIZE } from './ImageSize/ImageSize.constants';
 import { ImageSize as ImageSizeType } from './ImageSize/ImageSize.types';
+import { CurrentView as CurrentViewType } from './CurrentView/CurrentView.types';
 import { IncludedCompartmentPathways } from './IncludedCompartmentPathways ';
 import { Submap } from './Submap';
 import { getDownloadElementsBodyRequest } from './utils/getDownloadElementsBodyRequest';
@@ -45,6 +48,7 @@ export const Export = ({ children }: ExportProps): JSX.Element => {
   const [models, setModels] = useState<CheckboxItem[]>([]);
   const [imageSize, setImageSize] = useState<ImageSizeType>(DEFAULT_IMAGE_SIZE);
   const [imageFormats, setImageFormats] = useState<CheckboxItem[]>([]);
+  const [currentView, setCurrentView] = useState<CurrentViewType>(DEFAULT_CURRENT_VIEW);
 
   const handleDownloadElements = useCallback(async () => {
     const body = getDownloadElementsBodyRequest({
@@ -94,6 +98,7 @@ export const Export = ({ children }: ExportProps): JSX.Element => {
       models,
       imageSize,
       imageFormats,
+      currentView,
     }),
     [
       annotations,
@@ -102,6 +107,7 @@ export const Export = ({ children }: ExportProps): JSX.Element => {
       models,
       imageSize,
       imageFormats,
+      currentView,
     ],
   );
 
@@ -113,6 +119,7 @@ export const Export = ({ children }: ExportProps): JSX.Element => {
       setModels,
       setImageSize,
       setImageFormats,
+      setCurrentView,
       handleDownloadElements,
       handleDownloadNetwork,
       handleDownloadGraphics,
@@ -133,3 +140,4 @@ Export.ImageSize = ImageSize;
 Export.ImageFormat = ImageFormat;
 Export.DownloadNetwork = DownloadNetwork;
 Export.DownloadGraphics = DownloadGraphics;
+Export.CurrentView = CurrentView;
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.constant.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.constant.ts
index 5a7e4f08..5381e784 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.constant.ts
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.constant.ts
@@ -1,3 +1,4 @@
+import { DEFAULT_CURRENT_VIEW } from '@/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.constants';
 import { ExportContextType } from './ExportCompound.types';
 import { DEFAULT_IMAGE_SIZE } from './ImageSize/ImageSize.constants';
 
@@ -54,6 +55,7 @@ export const EXPORT_CONTEXT_DEFAULT_VALUE: ExportContextType = {
   setModels: () => {},
   setImageSize: () => {},
   setImageFormats: () => {},
+  setCurrentView: () => {},
   handleDownloadElements: () => Promise.resolve(),
   handleDownloadNetwork: () => Promise.resolve(),
   handleDownloadGraphics: () => {},
@@ -64,5 +66,6 @@ export const EXPORT_CONTEXT_DEFAULT_VALUE: ExportContextType = {
     models: [],
     imageFormats: [],
     imageSize: DEFAULT_IMAGE_SIZE,
+    currentView: DEFAULT_CURRENT_VIEW,
   },
 };
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.types.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.types.ts
index 02c87101..b57cc6e0 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.types.ts
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.types.ts
@@ -1,3 +1,4 @@
+import { CurrentView } from '@/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.types';
 import { CheckboxItem } from '../CheckboxFilter/CheckboxFilter.types';
 import { ImageSize } from './ImageSize/ImageSize.types';
 
@@ -6,6 +7,7 @@ export type ExportContextType = {
   setIncludedCompartmentPathways: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
   setExcludedCompartmentPathways: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
   setModels: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
+  setCurrentView: React.Dispatch<React.SetStateAction<CurrentView>>;
   setImageSize: React.Dispatch<React.SetStateAction<ImageSize>>;
   setImageFormats: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
   handleDownloadElements: () => Promise<void>;
@@ -16,6 +18,7 @@ export type ExportContextType = {
     includedCompartmentPathways: CheckboxItem[];
     excludedCompartmentPathways: CheckboxItem[];
     models: CheckboxItem[];
+    currentView: CurrentView;
     imageSize: ImageSize;
     imageFormats: CheckboxItem[];
   };
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useImageSize.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useImageSize.ts
index f36afdd3..d4869197 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useImageSize.ts
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useImageSize.ts
@@ -1,9 +1,13 @@
 import { MapModel } from '@/types/models';
 import { numberToSafeInt } from '@/utils/number/numberToInt';
 import { useCallback, useContext, useEffect } from 'react';
+import {
+  getScreenAspectRatios,
+  getScreenDimension,
+} from '@/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useScreenAspectRatios';
 import { ExportContext } from '../../ExportCompound.context';
 import { DEFAULT_IMAGE_HEIGHT, DEFAULT_IMAGE_WIDTH } from '../ImageSize.constants';
-import { ImageSize } from '../ImageSize.types';
+import { ImageSize, ModelAspectRatios } from '../ImageSize.types';
 import { useExportGraphicsSelectedModel } from './useExportGraphicsSelectedModel';
 import { getModelAspectRatios } from './useModelAspectRatios';
 
@@ -16,9 +20,15 @@ interface UseImageSizeResults {
 
 export const useImageSize = (): UseImageSizeResults => {
   const selectedModel = useExportGraphicsSelectedModel();
-  const aspectRatios = getModelAspectRatios(selectedModel);
-  const { data, setImageSize } = useContext(ExportContext);
-  const { imageSize } = data;
+  const { data, setImageSize, setCurrentView } = useContext(ExportContext);
+  const { imageSize, currentView } = data;
+  let aspectRatios: ModelAspectRatios;
+  if (currentView.value) {
+    aspectRatios = getScreenAspectRatios();
+  } else {
+    aspectRatios = getModelAspectRatios(selectedModel);
+  }
+
   const maxWidth = selectedModel?.width || DEFAULT_IMAGE_WIDTH;
   const maxHeight = selectedModel?.height || DEFAULT_IMAGE_HEIGHT;
 
@@ -27,8 +37,8 @@ export const useImageSize = (): UseImageSizeResults => {
       const newWidth = newImageSize.width;
       const newHeight = newImageSize.height;
 
-      const widthMinMax = Math.min(maxWidth, newWidth);
-      const heightMinMax = Math.min(maxHeight, newHeight);
+      const widthMinMax = currentView.value ? newWidth : Math.min(maxWidth, newWidth);
+      const heightMinMax = currentView.value ? newHeight : Math.min(maxHeight, newHeight);
 
       const widthInt = numberToSafeInt(widthMinMax);
       const heightInt = numberToSafeInt(heightMinMax);
@@ -43,14 +53,17 @@ export const useImageSize = (): UseImageSizeResults => {
 
   const setDefaultModelImageSize = useCallback(
     (model: MapModel): void => {
+      const screenDimension = getScreenDimension();
+      const width = currentView.value ? screenDimension.width : model.width;
+      const height = currentView.value ? screenDimension.height : model.height;
       const newImageSize = getNormalizedImageSize({
-        width: model.width,
-        height: model.height,
+        width,
+        height,
       });
 
       setImageSize(newImageSize);
     },
-    [getNormalizedImageSize, setImageSize],
+    [getNormalizedImageSize, setImageSize, setCurrentView, currentView],
   );
 
   const handleChangeWidth = (width: number): void => {
@@ -77,7 +90,7 @@ export const useImageSize = (): UseImageSizeResults => {
     }
 
     setDefaultModelImageSize(selectedModel);
-  }, [setDefaultModelImageSize, selectedModel]);
+  }, [setDefaultModelImageSize, selectedModel, setCurrentView, currentView]);
 
   return {
     handleChangeWidth,
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useScreenAspectRatios.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useScreenAspectRatios.ts
new file mode 100644
index 00000000..e586afcb
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useScreenAspectRatios.ts
@@ -0,0 +1,48 @@
+import { getBounds } from '@/services/pluginsManager/map/data/getBounds';
+import { ZERO } from '@/constants/common';
+import { DEFAULT_IMAGE_SIZE, DEFAULT_MODEL_ASPECT_RATIOS } from '../ImageSize.constants';
+import { ImageSize, ModelAspectRatios } from '../ImageSize.types';
+
+export const getScreenAspectRatios = (): ModelAspectRatios => {
+  const bounds = getBounds();
+  if (!bounds) {
+    return DEFAULT_MODEL_ASPECT_RATIOS;
+  }
+  let { x1, y1 } = bounds;
+  const { x2, y2 } = bounds;
+  if (x1 > x2) {
+    x1 = ZERO;
+  }
+  if (y1 > y2) {
+    y1 = ZERO;
+  }
+  const width = x2 - x1;
+  const height = y2 - y1;
+
+  return {
+    vertical: height / width,
+    horizontal: width / height,
+  };
+};
+
+export const getScreenDimension = (): ImageSize => {
+  const bounds = getBounds();
+  if (!bounds) {
+    return DEFAULT_IMAGE_SIZE;
+  }
+  let { x1, y1 } = bounds;
+  const { x2, y2 } = bounds;
+  if (x1 > x2) {
+    x1 = ZERO;
+  }
+  if (y1 > y2) {
+    y1 = ZERO;
+  }
+  const width = x2 - x1;
+  const height = y2 - y1;
+
+  return {
+    width,
+    height,
+  };
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/Graphics/Graphics.component.tsx b/src/components/Map/Drawer/ExportDrawer/Graphics/Graphics.component.tsx
index 547c2c14..aafe37a2 100644
--- a/src/components/Map/Drawer/ExportDrawer/Graphics/Graphics.component.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/Graphics/Graphics.component.tsx
@@ -4,6 +4,7 @@ export const Graphics = (): React.ReactNode => {
   return (
     <div data-testid="graphics-tab">
       <Export>
+        <Export.CurrentView />
         <Export.Submap />
         <Export.ImageSize />
         <Export.ImageFormat />
-- 
GitLab


From ded1605d652fe5a31ef8808d340a70921b1c7d7c Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Thu, 12 Dec 2024 12:23:51 +0100
Subject: [PATCH 10/12] download image considering bounds when current view is
 selected

---
 .../ExportCompound.component.tsx              |  1 +
 .../ImageSize/utils/useScreenAspectRatios.ts  | 19 ++-----------------
 .../utils/getGraphicsDownloadUrl.ts           | 14 +++++++++++++-
 .../pluginsManager/map/data/getBounds.ts      |  5 +++--
 4 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx
index 1b7d192b..1c7da289 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx
@@ -83,6 +83,7 @@ export const Export = ({ children }: ExportProps): JSX.Element => {
       handler: imageFormats?.[FIRST_ARRAY_ELEMENT]?.id,
       zoom: getModelExportZoom(imageSize.width, model),
       overlayIds: overlays.map(overlayId => `${overlayId}`),
+      currentView: currentView.value,
     });
 
     if (url) {
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useScreenAspectRatios.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useScreenAspectRatios.ts
index e586afcb..ee1bec83 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useScreenAspectRatios.ts
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useScreenAspectRatios.ts
@@ -1,5 +1,4 @@
 import { getBounds } from '@/services/pluginsManager/map/data/getBounds';
-import { ZERO } from '@/constants/common';
 import { DEFAULT_IMAGE_SIZE, DEFAULT_MODEL_ASPECT_RATIOS } from '../ImageSize.constants';
 import { ImageSize, ModelAspectRatios } from '../ImageSize.types';
 
@@ -8,14 +7,7 @@ export const getScreenAspectRatios = (): ModelAspectRatios => {
   if (!bounds) {
     return DEFAULT_MODEL_ASPECT_RATIOS;
   }
-  let { x1, y1 } = bounds;
-  const { x2, y2 } = bounds;
-  if (x1 > x2) {
-    x1 = ZERO;
-  }
-  if (y1 > y2) {
-    y1 = ZERO;
-  }
+  const { x1, x2, y1, y2 } = bounds;
   const width = x2 - x1;
   const height = y2 - y1;
 
@@ -30,14 +22,7 @@ export const getScreenDimension = (): ImageSize => {
   if (!bounds) {
     return DEFAULT_IMAGE_SIZE;
   }
-  let { x1, y1 } = bounds;
-  const { x2, y2 } = bounds;
-  if (x1 > x2) {
-    x1 = ZERO;
-  }
-  if (y1 > y2) {
-    y1 = ZERO;
-  }
+  const { x1, x2, y1, y2 } = bounds;
   const width = x2 - x1;
   const height = y2 - y1;
 
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.ts
index 169265ea..28448995 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.ts
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.ts
@@ -1,4 +1,5 @@
 import { BASE_API_URL, PROJECT_ID } from '@/constants';
+import { getBounds } from '@/services/pluginsManager/map/data/getBounds';
 
 export interface GetGraphicsDownloadUrlProps {
   backgroundId?: number;
@@ -6,6 +7,7 @@ export interface GetGraphicsDownloadUrlProps {
   handler?: string;
   zoom?: number;
   overlayIds: string[];
+  currentView?: boolean;
 }
 
 export const getGraphicsDownloadUrl = ({
@@ -14,6 +16,7 @@ export const getGraphicsDownloadUrl = ({
   handler,
   zoom,
   overlayIds,
+  currentView,
 }: GetGraphicsDownloadUrlProps): string | undefined => {
   const isAllElementsTruthy = [backgroundId, modelId, handler, zoom].reduce(
     (a, b) => Boolean(a) && Boolean(b),
@@ -26,5 +29,14 @@ export const getGraphicsDownloadUrl = ({
 
   const overlays = overlayIds.join(',');
 
-  return `${BASE_API_URL}/projects/${PROJECT_ID}/models/${modelId}:downloadImage?backgroundOverlayId=${backgroundId}&handlerClass=${handler}&zoomLevel=${zoom}&overlayIds=${overlays}`;
+  let polygonSuffix = '';
+  if (currentView) {
+    const bounds = getBounds();
+    if (bounds) {
+      const { x1, y1, x2, y2 } = bounds;
+      polygonSuffix = `&polygonString=${x1},${y1};${x1},${y2};${x2},${y2};${x2},${y1}`;
+    }
+  }
+
+  return `${BASE_API_URL}/projects/${PROJECT_ID}/models/${modelId}:downloadImage?backgroundOverlayId=${backgroundId}&handlerClass=${handler}&zoomLevel=${zoom}&overlayIds=${overlays}${polygonSuffix}`;
 };
diff --git a/src/services/pluginsManager/map/data/getBounds.ts b/src/services/pluginsManager/map/data/getBounds.ts
index 626e13f7..a905228e 100644
--- a/src/services/pluginsManager/map/data/getBounds.ts
+++ b/src/services/pluginsManager/map/data/getBounds.ts
@@ -2,6 +2,7 @@ import { mapDataSizeSelector } from '@/redux/map/map.selectors';
 import { store } from '@/redux/store';
 import { latLngToPoint } from '@/utils/map/latLngToPoint';
 import { toLonLat } from 'ol/proj';
+import { ZERO } from '@/constants/common';
 import { MapManager } from '../mapManager';
 
 type GetBoundsReturnType =
@@ -29,8 +30,8 @@ export const getBounds = (): GetBoundsReturnType => {
   const { x: x2, y: y2 } = latLngToPoint([latY2, lngX2], mapSize, { rounded: true });
 
   return {
-    x1,
-    y1,
+    x1: x1 > x2 ? ZERO : x1, // handle lat,lng overflow
+    y1: y1 > y2 ? ZERO : y1, // handle lat,lng overflow
     x2,
     y2,
   };
-- 
GitLab


From a976ff3d96dc03e4d8ac23acfd9194532a386d17 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Thu, 12 Dec 2024 12:49:05 +0100
Subject: [PATCH 11/12] when selecting current view set proper model in the
 list

---
 .../CurrentView/CurrentView.component.tsx         | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.component.tsx
index cad075a0..cb7e611d 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.component.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/CurrentView/CurrentView.component.tsx
@@ -1,8 +1,13 @@
 import { useContext } from 'react';
 import { ExportContext } from '@/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.context';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { currentModelIdSelector, currentModelNameSelector } from '@/redux/models/models.selectors';
 
 export const CurrentView = (): React.ReactNode => {
-  const { setCurrentView, data } = useContext(ExportContext);
+  const { setCurrentView, data, setModels } = useContext(ExportContext);
+
+  const currentMapModelId = useAppSelector(currentModelIdSelector);
+  const currentMapModelName = useAppSelector(currentModelNameSelector);
 
   return (
     <div className="flex flex-col gap-4 border-b">
@@ -16,6 +21,14 @@ export const CurrentView = (): React.ReactNode => {
           aria-label="export graphics width input"
           onChange={(e): void => {
             setCurrentView({ value: e.target.checked });
+            if (e.target.checked) {
+              setModels([
+                {
+                  id: `${currentMapModelId}`,
+                  label: currentMapModelName,
+                },
+              ]);
+            }
           }}
         />
       </label>
-- 
GitLab


From 8fbfcf0ea1d9e783b391b1cd607162ad946f522e Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Thu, 12 Dec 2024 13:13:38 +0100
Subject: [PATCH 12/12] rename Submap to Dialog

---
 CHANGELOG                                                 | 1 +
 .../ExportCompound/Submap/Submap.component.test.tsx       | 8 ++++----
 .../ExportCompound/Submap/Submap.component.tsx            | 2 +-
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 0992fd8c..ead072d8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,7 @@ minerva-front (19.0.0~alpha.0) stable; urgency=medium
   * Feature: allow plugin to access info about opened panel (#309)
   * Feature: allow plugin to hide opened panel (#309)
   * Feature: allow plugin to open left panel (#309)
+  * Feature: allow to export current view for graphics export (#327)
 
  -- Piotr Gawron <piotr.gawron@uni.lu>  Fri, 18 Oct 2024 13:00:00 +0200
 
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.test.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.test.tsx
index 6ee9cb42..f3b874e3 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.test.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.test.tsx
@@ -45,7 +45,7 @@ describe('Submap - component', () => {
       navigationButton.click();
     });
 
-    expect(screen.getByText('Submap')).toBeInTheDocument();
+    expect(screen.getByText('Diagram')).toBeInTheDocument();
 
     await waitFor(() => {
       expect(screen.getByTestId('checkbox-filter')).toBeInTheDocument();
@@ -64,7 +64,7 @@ describe('Submap - component', () => {
         },
       },
     });
-    expect(screen.getByText('Submap')).toBeInTheDocument();
+    expect(screen.getByText('Diagram')).toBeInTheDocument();
     const navigationButton = screen.getByTestId('accordion-item-button');
     act(() => {
       navigationButton.click();
@@ -83,7 +83,7 @@ describe('Submap - component', () => {
         },
       },
     });
-    expect(screen.getByText('Submap')).toBeInTheDocument();
+    expect(screen.getByText('Diagram')).toBeInTheDocument();
     const navigationButton = screen.getByTestId('accordion-item-button');
     act(() => {
       navigationButton.click();
@@ -103,7 +103,7 @@ describe('Submap - component', () => {
         },
       },
     });
-    expect(screen.getByText('Submap')).toBeInTheDocument();
+    expect(screen.getByText('Diagram')).toBeInTheDocument();
     const navigationButton = screen.getByTestId('accordion-item-button');
     act(() => {
       navigationButton.click();
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.tsx
index 422c4b73..21e1048d 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.tsx
@@ -30,7 +30,7 @@ export const Submap = (): React.ReactNode => {
   }
 
   return (
-    <CollapsibleSection title="Submap" dangerouslySetExpanded>
+    <CollapsibleSection title="Diagram" dangerouslySetExpanded>
       {isPending && <p>Loading...</p>}
       {!isPending && mappedElementAnnotations && mappedElementAnnotations.length > ZERO && (
         <CheckboxFilter
-- 
GitLab