From 7c09ccde6111a13298edce2e5dc0e0caac87464e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrian=20Or=C5=82=C3=B3w?= <adrian.orlow@fishbrain.com>
Date: Thu, 30 Nov 2023 13:28:45 +0100
Subject: [PATCH] fix: pr rfc changes

---
 .../Map/Drawer/Drawer.component.test.tsx      |  42 ++++++-
 .../ReactionDrawer.component.test.tsx         |   4 +-
 .../ReactionDrawer.component.tsx              |  33 ++----
 .../ReferenceGroup.component.test.tsx         | 111 ++++++++++++++++++
 .../ReferenceGroup.component.tsx              |  21 ++++
 .../ReactionDrawer/ReferenceGroup/index.ts    |   1 +
 .../mapSingleClick/handleAliasResults.test.ts |   4 +-
 .../handleReactionResults.test.ts             |   4 +-
 .../mapSingleClick/handleReactionResults.ts   |   4 +-
 .../handleSearchResultAction.ts               |   4 +-
 src/constants/common.ts                       |   4 +-
 src/models/mocks/referencesMock.ts            |   4 +-
 src/redux/reactions/reactions.selector.ts     |  10 ++
 .../utils/getFilteredReferences.test.ts       |   6 +-
 .../reactions}/utils/getFilteredReferences.ts |   6 +-
 .../utils/getGroupedReferences.test.ts        |   6 +-
 .../reactions}/utils/getGroupedReferences.ts  |   4 +-
 .../DrawerHeading/DrawerHeading.component.tsx |   2 +-
 .../reference.ts}                             |   8 +-
 19 files changed, 221 insertions(+), 57 deletions(-)
 create mode 100644 src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.test.tsx
 create mode 100644 src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.tsx
 create mode 100644 src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/index.ts
 rename src/{components/Map/Drawer/ReactionDrawer => redux/reactions}/utils/getFilteredReferences.test.ts (79%)
 rename src/{components/Map/Drawer/ReactionDrawer => redux/reactions}/utils/getFilteredReferences.ts (57%)
 rename src/{components/Map/Drawer/ReactionDrawer => redux/reactions}/utils/getGroupedReferences.test.ts (89%)
 rename src/{components/Map/Drawer/ReactionDrawer => redux/reactions}/utils/getGroupedReferences.ts (59%)
 rename src/{components/Map/Drawer/ReactionDrawer/ReactionDrawer.types.ts => types/reference.ts} (51%)

diff --git a/src/components/Map/Drawer/Drawer.component.test.tsx b/src/components/Map/Drawer/Drawer.component.test.tsx
index 185ccbae..a0cbbdfc 100644
--- a/src/components/Map/Drawer/Drawer.component.test.tsx
+++ b/src/components/Map/Drawer/Drawer.component.test.tsx
@@ -1,11 +1,22 @@
-import { openSearchDrawerWithSelectedTab, openSubmapsDrawer } from '@/redux/drawer/drawer.slice';
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { reactionsFixture } from '@/models/fixtures/reactionFixture';
+import {
+  openReactionDrawerById,
+  openSearchDrawerWithSelectedTab,
+  openSubmapsDrawer,
+} from '@/redux/drawer/drawer.slice';
+import { getReactionsByIds } from '@/redux/reactions/reactions.thunks';
 import { StoreType } from '@/redux/store';
-import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
-import { act, fireEvent, render, screen } from '@testing-library/react';
+import {
+  InitialStoreState,
+  getReduxWrapperWithStore,
+} from '@/utils/testing/getReduxWrapperWithStore';
+import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
+import type {} from 'redux-thunk/extend-redux';
 import { Drawer } from './Drawer.component';
 
-const renderComponent = (): { store: StoreType } => {
-  const { Wrapper, store } = getReduxWrapperWithStore();
+const renderComponent = (initialStore?: InitialStoreState): { store: StoreType } => {
+  const { Wrapper, store } = getReduxWrapperWithStore(initialStore);
   return (
     render(
       <Wrapper>
@@ -77,4 +88,25 @@ describe('Drawer - component', () => {
       expect(screen.getByTestId('submap-drawer')).toBeInTheDocument();
     });
   });
+
+  describe('reaction drawer', () => {
+    it('should open drawer and display reaction', async () => {
+      const { id } = reactionsFixture[FIRST_ARRAY_ELEMENT];
+
+      const { store } = renderComponent({
+        reactions: {
+          data: reactionsFixture,
+          loading: 'succeeded',
+          error: { message: '', name: '' },
+        },
+      });
+
+      expect(screen.queryByTestId('reaction-drawer')).not.toBeInTheDocument();
+
+      store.dispatch(getReactionsByIds([id]));
+      store.dispatch(openReactionDrawerById(id));
+
+      await waitFor(() => expect(screen.getByTestId('reaction-drawer')).toBeInTheDocument());
+    });
+  });
 });
diff --git a/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.test.tsx b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.test.tsx
index 251bc6c0..1a635a0b 100644
--- a/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.test.tsx
+++ b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.test.tsx
@@ -1,4 +1,4 @@
-import { SECOND } from '@/constants/common';
+import { SECOND_ARRAY_ELEMENT } from '@/constants/common';
 import { reactionsFixture } from '@/models/fixtures/reactionFixture';
 import { DRAWER_INITIAL_STATE } from '@/redux/drawer/drawer.constants';
 import { StoreType } from '@/redux/store';
@@ -52,7 +52,7 @@ describe('ReactionDrawer - component', () => {
   });
 
   describe('when there IS a matching reaction', () => {
-    const reaction = reactionsFixture[SECOND];
+    const reaction = reactionsFixture[SECOND_ARRAY_ELEMENT];
 
     const filteredReferences = reaction.references.filter(
       ref => ref.link !== null && ref.link !== undefined,
diff --git a/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.tsx b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.tsx
index 6bbb574f..9f6a8c4c 100644
--- a/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.tsx
+++ b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.tsx
@@ -1,26 +1,21 @@
-import { currentDrawerReactionSelector } from '@/redux/reactions/reactions.selector';
+import {
+  currentDrawerReactionGroupedReferencesSelector,
+  currentDrawerReactionSelector,
+} from '@/redux/reactions/reactions.selector';
 import { DrawerHeading } from '@/shared/DrawerHeading';
-import { Icon } from '@/shared/Icon';
-import { useMemo } from 'react';
 import { useSelector } from 'react-redux';
-import { DEFAULT_REFERENCE_SOURCE } from './ReactionDrawer.constants';
-import { getFilteredReferences } from './utils/getFilteredReferences';
-import { getGroupedReferences } from './utils/getGroupedReferences';
+import { ReferenceGroup } from './ReferenceGroup';
 
 export const ReactionDrawer = (): React.ReactNode => {
   const reaction = useSelector(currentDrawerReactionSelector);
-
-  const referencesGrouped = useMemo(() => {
-    const referencesFiltered = getFilteredReferences(reaction);
-    return getGroupedReferences(referencesFiltered);
-  }, [reaction]);
+  const referencesGrouped = useSelector(currentDrawerReactionGroupedReferencesSelector);
 
   if (!reaction) {
     return null;
   }
 
   return (
-    <div className="h-full max-h-full">
+    <div className="h-full max-h-full" data-testid="reaction-drawer">
       <DrawerHeading
         title={
           <>
@@ -34,18 +29,8 @@ export const ReactionDrawer = (): React.ReactNode => {
         </div>
         <hr className="border-b border-b-divide" />
         <h3 className="font-semibold">Annotations:</h3>
-        {referencesGrouped.map(({ source, references }) => (
-          <>
-            <h3 className="font-semibold">Source: {source || DEFAULT_REFERENCE_SOURCE}</h3>
-            {references.map(({ id, link, type }) => (
-              <a key={id} href={link} target="_blank">
-                <div className="flex justify-between">
-                  <span>{`${type} (${id})`}</span>
-                  <Icon name="arrow" className="h-6 w-6 fill-font-500" />
-                </div>
-              </a>
-            ))}
-          </>
+        {referencesGrouped.map(group => (
+          <ReferenceGroup key={group.source} group={group} />
         ))}
       </div>
     </div>
diff --git a/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.test.tsx b/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.test.tsx
new file mode 100644
index 00000000..838f1d50
--- /dev/null
+++ b/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.test.tsx
@@ -0,0 +1,111 @@
+import { StoreType } from '@/redux/store';
+import { ReferenceFiltered } from '@/types/reference';
+import {
+  InitialStoreState,
+  getReduxWrapperWithStore,
+} from '@/utils/testing/getReduxWrapperWithStore';
+import { render, screen } from '@testing-library/react';
+import { Props, ReferenceGroup } from './ReferenceGroup.component';
+
+const renderComponent = (
+  props: Props,
+  initialStoreState: InitialStoreState = {},
+): { store: StoreType } => {
+  const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState);
+
+  return (
+    render(
+      <Wrapper>
+        <ReferenceGroup {...props} />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+describe('ReactionDrawer - component', () => {
+  beforeEach(() => {
+    jest.resetAllMocks();
+    jest.clearAllMocks();
+  });
+
+  const singleReference = {
+    link: 'https://www.ncbi.nlm.nih.gov/pubmed/24448649',
+    article: {
+      title:
+        'The nutrient-responsive transcription factor TFE3 promotes autophagy, lysosomal biogenesis, and clearance of cellular debris.',
+      authors: [
+        'Martina JA',
+        ' Diab HI',
+        ' Lishu L',
+        ' Jeong-A L',
+        ' Patange S',
+        ' Raben N',
+        ' Puertollano R.',
+      ],
+      journal: 'Science signaling',
+      year: 2014,
+      link: 'https://www.ncbi.nlm.nih.gov/pubmed/24448649',
+      pubmedId: '24448649',
+      citationCount: 321,
+    },
+    type: 'PUBMED',
+    resource: '24448649',
+    id: 154973,
+    annotatorClassName: '',
+  };
+
+  const cases: [string, ReferenceFiltered[]][] = [
+    ['', [singleReference]],
+    [
+      'source1',
+      [
+        {
+          ...singleReference,
+          annotatorClassName: 'source1',
+          id: 1,
+        },
+        {
+          ...singleReference,
+          annotatorClassName: 'source1',
+          id: 2,
+        },
+      ],
+    ],
+    [
+      'source2',
+      [
+        {
+          ...singleReference,
+          annotatorClassName: 'source2',
+          id: 3,
+        },
+      ],
+    ],
+  ];
+
+  it.each(cases)('should show reference group with source=%s', (source, references) => {
+    const referencesTextHref: [string, string][] = references.map(ref => [
+      `${ref.type} (${ref.id})`,
+      ref.link as string,
+    ]);
+
+    renderComponent({
+      group: {
+        source,
+        references,
+      },
+    });
+
+    referencesTextHref.forEach(([refText, href]) => {
+      const linkReferenceSpan = screen.getByText(refText, { exact: false });
+      const linkReferenceAnchor = linkReferenceSpan.closest('a');
+
+      expect(linkReferenceSpan).toBeInTheDocument();
+      expect(linkReferenceAnchor).toBeInTheDocument();
+      expect(linkReferenceAnchor?.href).toBe(`${href}`);
+    });
+  });
+});
diff --git a/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.tsx b/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.tsx
new file mode 100644
index 00000000..aab45512
--- /dev/null
+++ b/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.tsx
@@ -0,0 +1,21 @@
+import { Icon } from '@/shared/Icon';
+import { ReferenceGroup as ReferenceGroupType } from '@/types/reference';
+import { DEFAULT_REFERENCE_SOURCE } from '../ReactionDrawer.constants';
+
+export interface Props {
+  group: ReferenceGroupType;
+}
+
+export const ReferenceGroup = ({ group: { source, references } }: Props): JSX.Element => (
+  <>
+    <h3 className="font-semibold">Source: {source || DEFAULT_REFERENCE_SOURCE}</h3>
+    {references.map(({ id, link, type }) => (
+      <a key={id} href={link} target="_blank">
+        <div className="flex justify-between">
+          <span>{`${type} (${id})`}</span>
+          <Icon name="arrow" className="h-6 w-6 fill-font-500" />
+        </div>
+      </a>
+    ))}
+  </>
+);
diff --git a/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/index.ts b/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/index.ts
new file mode 100644
index 00000000..0ac05ab8
--- /dev/null
+++ b/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/index.ts
@@ -0,0 +1 @@
+export { ReferenceGroup } from './ReferenceGroup.component';
diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts
index 701539ac..8c3eb1e6 100644
--- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts
+++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts
@@ -1,4 +1,4 @@
-import { FIRST, SIZE_OF_EMPTY_ARRAY } from '@/constants/common';
+import { FIRST_ARRAY_ELEMENT, SIZE_OF_EMPTY_ARRAY } from '@/constants/common';
 import { bioEntityResponseFixture } from '@/models/fixtures/bioEntityContentsFixture';
 import { ELEMENT_SEARCH_RESULT_MOCK_ALIAS } from '@/models/mocks/elementSearchResultMock';
 import { apiPath } from '@/redux/apiPath';
@@ -31,7 +31,7 @@ describe('handleAliasResults - util', () => {
     await waitFor(() => {
       const actions = store.getActions();
       expect(actions.length).toBeGreaterThan(SIZE_OF_EMPTY_ARRAY);
-      expect(actions[FIRST].type).toEqual('project/getMultiBioEntity/pending');
+      expect(actions[FIRST_ARRAY_ELEMENT].type).toEqual('project/getMultiBioEntity/pending');
     });
   });
 });
diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts
index 28125603..b514095b 100644
--- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts
+++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts
@@ -1,5 +1,5 @@
 /* eslint-disable no-magic-numbers */
-import { FIRST, SIZE_OF_EMPTY_ARRAY } from '@/constants/common';
+import { FIRST_ARRAY_ELEMENT, SIZE_OF_EMPTY_ARRAY } from '@/constants/common';
 import { bioEntityResponseFixture } from '@/models/fixtures/bioEntityContentsFixture';
 import { reactionsFixture } from '@/models/fixtures/reactionFixture';
 import {
@@ -47,7 +47,7 @@ describe('handleReactionResults - util', () => {
     const actions = store.getActions();
     expect(actions.length).toBeGreaterThan(SIZE_OF_EMPTY_ARRAY);
     expect(actions[2].type).toEqual('drawer/openReactionDrawerById');
-    expect(actions[2].payload).toEqual(reactionsFixture[FIRST].id);
+    expect(actions[2].payload).toEqual(reactionsFixture[FIRST_ARRAY_ELEMENT].id);
   });
 
   it('should run setBioEntityContent to empty array as third action', () => {
diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts
index f566b6c1..55c244ad 100644
--- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts
+++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts
@@ -1,4 +1,4 @@
-import { FIRST, SIZE_OF_EMPTY_ARRAY } from '@/constants/common';
+import { FIRST_ARRAY_ELEMENT, SIZE_OF_EMPTY_ARRAY } from '@/constants/common';
 import { getMultiBioEntity } from '@/redux/bioEntity/bioEntity.thunks';
 import { openReactionDrawerById } from '@/redux/drawer/drawer.slice';
 import { getReactionsByIds } from '@/redux/reactions/reactions.thunks';
@@ -16,7 +16,7 @@ export const handleReactionResults =
         return;
       }
 
-      const reaction = payload[FIRST];
+      const reaction = payload[FIRST_ARRAY_ELEMENT];
       const { products, reactants, modifiers } = reaction;
       const productsIds = products.map(p => p.aliasId);
       const reactantsIds = reactants.map(r => r.aliasId);
diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleSearchResultAction.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleSearchResultAction.ts
index e60af27c..648457ec 100644
--- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleSearchResultAction.ts
+++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleSearchResultAction.ts
@@ -1,4 +1,4 @@
-import { FIRST } from '@/constants/common';
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
 import { AppDispatch } from '@/redux/store';
 import { ElementSearchResult } from '@/types/models';
 import { handleAliasResults } from './handleAliasResults';
@@ -13,7 +13,7 @@ export const handleSearchResultAction = async ({
   searchResults,
   dispatch,
 }: HandleSearchResultActionInput): Promise<void> => {
-  const closestSearchResult = searchResults[FIRST];
+  const closestSearchResult = searchResults[FIRST_ARRAY_ELEMENT];
   const { type } = closestSearchResult;
   const action = {
     ALIAS: handleAliasResults,
diff --git a/src/constants/common.ts b/src/constants/common.ts
index 97c4d672..973c26af 100644
--- a/src/constants/common.ts
+++ b/src/constants/common.ts
@@ -1,6 +1,6 @@
 export const SIZE_OF_EMPTY_ARRAY = 0;
 export const ZERO = 0;
-export const FIRST = 0;
+export const FIRST_ARRAY_ELEMENT = 0;
 
 export const ONE = 1;
-export const SECOND = 1;
+export const SECOND_ARRAY_ELEMENT = 1;
diff --git a/src/models/mocks/referencesMock.ts b/src/models/mocks/referencesMock.ts
index f1e2a5d8..ce51b43e 100644
--- a/src/models/mocks/referencesMock.ts
+++ b/src/models/mocks/referencesMock.ts
@@ -1,4 +1,4 @@
-import { FIRST } from '@/constants/common';
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
 import { Reference } from '@/types/models';
 
 export const REFERENCES_MOCK_ALL_VALID: Reference[] = [
@@ -175,4 +175,4 @@ export const REFERENCES_MOCK_ALL_INVALID: Reference[] = [
   },
 ];
 
-export const SINGLE_VALID_REFERENCE = REFERENCES_MOCK_ALL_VALID[FIRST];
+export const SINGLE_VALID_REFERENCE = REFERENCES_MOCK_ALL_VALID[FIRST_ARRAY_ELEMENT];
diff --git a/src/redux/reactions/reactions.selector.ts b/src/redux/reactions/reactions.selector.ts
index de94e6ad..8dbc6990 100644
--- a/src/redux/reactions/reactions.selector.ts
+++ b/src/redux/reactions/reactions.selector.ts
@@ -3,6 +3,8 @@ import { createSelector } from '@reduxjs/toolkit';
 import { currentDrawerReactionIdSelector } from '../drawer/drawer.selectors';
 import { currentModelIdSelector } from '../models/models.selectors';
 import { rootSelector } from '../root/root.selectors';
+import { getReferencesWithoutEmptyLink } from './utils/getFilteredReferences';
+import { getReferencesGroupedBySource } from './utils/getGroupedReferences';
 
 export const reactionsSelector = createSelector(rootSelector, state => state.reactions);
 
@@ -25,3 +27,11 @@ export const currentDrawerReactionSelector = createSelector(
   (reactions, currentDrawerReactionId) =>
     reactions.find(({ id }) => id === currentDrawerReactionId),
 );
+
+export const currentDrawerReactionGroupedReferencesSelector = createSelector(
+  currentDrawerReactionSelector,
+  reaction => {
+    const referencesFiltered = getReferencesWithoutEmptyLink(reaction);
+    return getReferencesGroupedBySource(referencesFiltered);
+  },
+);
diff --git a/src/components/Map/Drawer/ReactionDrawer/utils/getFilteredReferences.test.ts b/src/redux/reactions/utils/getFilteredReferences.test.ts
similarity index 79%
rename from src/components/Map/Drawer/ReactionDrawer/utils/getFilteredReferences.test.ts
rename to src/redux/reactions/utils/getFilteredReferences.test.ts
index 3d887fbe..b02b2cc3 100644
--- a/src/components/Map/Drawer/ReactionDrawer/utils/getFilteredReferences.test.ts
+++ b/src/redux/reactions/utils/getFilteredReferences.test.ts
@@ -3,8 +3,8 @@ import {
   REFERENCES_MOCK_ALL_VALID,
 } from '@/models/mocks/referencesMock';
 import { Reaction } from '@/types/models';
-import { ReferenceFiltered } from '../ReactionDrawer.types';
-import { getFilteredReferences } from './getFilteredReferences';
+import { ReferenceFiltered } from '@/types/reference';
+import { getReferencesWithoutEmptyLink } from './getFilteredReferences';
 
 describe('getFilteredReferences - subUtil', () => {
   const cases: [Pick<Reaction, 'references'>, ReferenceFiltered[]][] = [
@@ -29,6 +29,6 @@ describe('getFilteredReferences - subUtil', () => {
   ];
 
   it.each(cases)('should return valid filtered references', (reaction, result) => {
-    expect(getFilteredReferences(reaction)).toStrictEqual(result);
+    expect(getReferencesWithoutEmptyLink(reaction)).toStrictEqual(result);
   });
 });
diff --git a/src/components/Map/Drawer/ReactionDrawer/utils/getFilteredReferences.ts b/src/redux/reactions/utils/getFilteredReferences.ts
similarity index 57%
rename from src/components/Map/Drawer/ReactionDrawer/utils/getFilteredReferences.ts
rename to src/redux/reactions/utils/getFilteredReferences.ts
index 10ef8b9f..987eb1a0 100644
--- a/src/components/Map/Drawer/ReactionDrawer/utils/getFilteredReferences.ts
+++ b/src/redux/reactions/utils/getFilteredReferences.ts
@@ -1,9 +1,11 @@
 import { Reaction } from '@/types/models';
-import { ReferenceFiltered } from '../ReactionDrawer.types';
+import { ReferenceFiltered } from '@/types/reference';
 
 type InputReaction = Pick<Reaction, 'references'>;
 
-export const getFilteredReferences = (reaction: InputReaction | undefined): ReferenceFiltered[] =>
+export const getReferencesWithoutEmptyLink = (
+  reaction: InputReaction | undefined,
+): ReferenceFiltered[] =>
   (reaction?.references || []).filter(
     (ref): ref is ReferenceFiltered => ref.link !== null && ref.link !== undefined,
   );
diff --git a/src/components/Map/Drawer/ReactionDrawer/utils/getGroupedReferences.test.ts b/src/redux/reactions/utils/getGroupedReferences.test.ts
similarity index 89%
rename from src/components/Map/Drawer/ReactionDrawer/utils/getGroupedReferences.test.ts
rename to src/redux/reactions/utils/getGroupedReferences.test.ts
index 465c54f8..65359741 100644
--- a/src/components/Map/Drawer/ReactionDrawer/utils/getGroupedReferences.test.ts
+++ b/src/redux/reactions/utils/getGroupedReferences.test.ts
@@ -1,5 +1,5 @@
-import { ReferenceFiltered } from '../ReactionDrawer.types';
-import { getGroupedReferences } from './getGroupedReferences';
+import { ReferenceFiltered } from '@/types/reference';
+import { getReferencesGroupedBySource } from './getGroupedReferences';
 
 describe('getGroupedReferences - util', () => {
   const singleReference = {
@@ -82,7 +82,7 @@ describe('getGroupedReferences - util', () => {
   ];
 
   it.each(cases)('should return correct grouped references', (references, referencesGrouped) =>
-    expect(getGroupedReferences(references as ReferenceFiltered[])).toMatchObject(
+    expect(getReferencesGroupedBySource(references as ReferenceFiltered[])).toMatchObject(
       referencesGrouped,
     ),
   );
diff --git a/src/components/Map/Drawer/ReactionDrawer/utils/getGroupedReferences.ts b/src/redux/reactions/utils/getGroupedReferences.ts
similarity index 59%
rename from src/components/Map/Drawer/ReactionDrawer/utils/getGroupedReferences.ts
rename to src/redux/reactions/utils/getGroupedReferences.ts
index 425d9f0c..ca09f0a9 100644
--- a/src/components/Map/Drawer/ReactionDrawer/utils/getGroupedReferences.ts
+++ b/src/redux/reactions/utils/getGroupedReferences.ts
@@ -1,7 +1,7 @@
+import { ReferenceFiltered, ReferenceGrouped } from '@/types/reference';
 import { groupBy } from '@/utils/array/groupBy';
-import { ReferenceFiltered, ReferenceGrouped } from '../ReactionDrawer.types';
 
-export const getGroupedReferences = (references: ReferenceFiltered[]): ReferenceGrouped => {
+export const getReferencesGroupedBySource = (references: ReferenceFiltered[]): ReferenceGrouped => {
   const referencesGroupedObject = groupBy(references, ref => ref.annotatorClassName);
 
   return Object.entries(referencesGroupedObject).map(([source, refs]) => ({
diff --git a/src/shared/DrawerHeading/DrawerHeading.component.tsx b/src/shared/DrawerHeading/DrawerHeading.component.tsx
index f8327fbe..17f616ad 100644
--- a/src/shared/DrawerHeading/DrawerHeading.component.tsx
+++ b/src/shared/DrawerHeading/DrawerHeading.component.tsx
@@ -4,7 +4,7 @@ import { IconButton } from '@/shared/IconButton';
 import { CLOSE_BUTTON_ROLE } from '../DrawerHeadingBackwardButton/DrawerHeadingBackwardButton.constants';
 
 interface DrawerHeadingProps {
-  title: string | JSX.Element;
+  title: string | React.ReactNode;
 }
 
 export const DrawerHeading = ({ title }: DrawerHeadingProps): JSX.Element => {
diff --git a/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.types.ts b/src/types/reference.ts
similarity index 51%
rename from src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.types.ts
rename to src/types/reference.ts
index 88a0ca30..e7201433 100644
--- a/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.types.ts
+++ b/src/types/reference.ts
@@ -1,8 +1,10 @@
-import { Reference } from '@/types/models';
+import { Reference } from './models';
 
 export type ReferenceFiltered = Omit<Reference, 'link'> & { link: string };
 
-export type ReferenceGrouped = {
+export type ReferenceGroup = {
   references: ReferenceFiltered[];
   source: string;
-}[];
+};
+
+export type ReferenceGrouped = ReferenceGroup[];
-- 
GitLab