Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • minerva/frontend
1 result
Show changes
Commits on Source (24)
Showing
with 195 additions and 128 deletions
......@@ -40,6 +40,7 @@
"react-dropzone": "14.2.3",
"react-redux": "8.1.3",
"react-select": "5.9.0",
"react-use-websocket": "4.11.1",
"sonner": "1.4.3",
"tailwind-merge": "1.14.0",
"tailwindcss": "3.4.13",
......@@ -12275,6 +12276,11 @@
"react-dom": ">=16.6.0"
}
},
"node_modules/react-use-websocket": {
"version": "4.11.1",
"resolved": "https://registry.npmjs.org/react-use-websocket/-/react-use-websocket-4.11.1.tgz",
"integrity": "sha512-39e8mK2a2A1h8uY3ePF45b2q0vwMOmaEy7J5qEhQg4n7vYa5oDLmqutG36kZQgAQ/3KCZS0brlGRbbZJ0+zfKQ=="
},
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
......@@ -14457,9 +14463,9 @@
"dev": true
},
"node_modules/ws": {
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
"integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"dev": true,
"engines": {
"node": ">=10.0.0"
......@@ -23504,6 +23510,11 @@
"prop-types": "^15.6.2"
}
},
"react-use-websocket": {
"version": "4.11.1",
"resolved": "https://registry.npmjs.org/react-use-websocket/-/react-use-websocket-4.11.1.tgz",
"integrity": "sha512-39e8mK2a2A1h8uY3ePF45b2q0vwMOmaEy7J5qEhQg4n7vYa5oDLmqutG36kZQgAQ/3KCZS0brlGRbbZJ0+zfKQ=="
},
"read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
......@@ -25133,9 +25144,9 @@
}
},
"ws": {
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
"integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"dev": true,
"requires": {}
},
......
......@@ -4,6 +4,7 @@ import { ReactNode } from 'react';
import { Provider } from 'react-redux';
import { Toaster } from 'sonner';
import { Modal } from '@/components/FunctionalArea/Modal';
import { WebSocketEntityUpdatesProvider } from '@/utils/websocket-entity-updates/webSocketEntityUpdatesProvider';
interface AppWrapperProps {
children: ReactNode;
......@@ -13,17 +14,19 @@ export const AppWrapper = ({ children }: AppWrapperProps): JSX.Element => {
return (
<MapInstanceProvider>
<Provider store={store}>
<>
<Modal />
<Toaster
position="top-center"
visibleToasts={1}
style={{
width: '700px',
}}
/>
{children}
</>
<WebSocketEntityUpdatesProvider>
<>
<Modal />
<Toaster
position="top-center"
visibleToasts={1}
style={{
width: '700px',
}}
/>
{children}
</>
</WebSocketEntityUpdatesProvider>
</Provider>
</MapInstanceProvider>
);
......
......@@ -8,6 +8,8 @@ import { act, render, screen } from '@testing-library/react';
import { CONTEXT_MENU_INITIAL_STATE } from '@/redux/contextMenu/contextMenu.constants';
import { bioEntityContentFixture } from '@/models/fixtures/bioEntityContentsFixture';
import { PluginsContextMenu } from '@/services/pluginsManager/pluginContextMenu/pluginsContextMenu';
import { modelElementFixture } from '@/models/fixtures/modelElementFixture';
import { DEFAULT_ERROR } from '@/constants/errors';
import { ContextMenu } from './ContextMenu.component';
const renderComponent = (initialStore?: InitialStoreState): { store: StoreType } => {
......@@ -97,31 +99,40 @@ describe('ContextMenu - Component', () => {
it('should display uniprot id as option if it is provided', () => {
renderComponent({
bioEntity: {
data: [
{
searchQueryElement: bioEntityContentFixture.bioEntity.id.toString(),
modelElements: {
data: {
0: {
data: [modelElementFixture],
loading: 'succeeded',
error: { name: '', message: '' },
data: [
{
...bioEntityContentFixture,
bioEntity: {
...bioEntityContentFixture.bioEntity,
fullName: 'BioEntity Full Name',
references: [
{
...bioEntityContentFixture.bioEntity.references[0],
type: 'UNIPROT',
},
],
},
},
],
error: { message: '', name: '' },
},
],
loading: 'succeeded',
error: { message: '', name: '' },
},
search: {
data: [
{
searchQueryElement: modelElementFixture.id.toString(),
loading: 'succeeded',
error: DEFAULT_ERROR,
data: [
{
modelElement: {
...modelElementFixture,
fullName: 'BioEntity Full Name',
references: [
{
...bioEntityContentFixture.bioEntity.references[0],
type: 'UNIPROT',
},
],
},
perfect: true,
},
],
},
],
loading: 'pending',
error: DEFAULT_ERROR,
},
},
contextMenu: {
...CONTEXT_MENU_INITIAL_STATE,
......@@ -144,31 +155,40 @@ describe('ContextMenu - Component', () => {
it('should open molart modal when clicking on uniprot', async () => {
const { store } = renderComponent({
bioEntity: {
data: [
{
searchQueryElement: bioEntityContentFixture.bioEntity.id.toString(),
modelElements: {
data: {
0: {
data: [modelElementFixture],
loading: 'succeeded',
error: { name: '', message: '' },
data: [
{
...bioEntityContentFixture,
bioEntity: {
...bioEntityContentFixture.bioEntity,
fullName: 'BioEntity Full Name',
references: [
{
...bioEntityContentFixture.bioEntity.references[0],
type: 'UNIPROT',
},
],
},
},
],
error: { message: '', name: '' },
},
],
loading: 'succeeded',
error: { message: '', name: '' },
},
search: {
data: [
{
searchQueryElement: modelElementFixture.id.toString(),
loading: 'succeeded',
error: DEFAULT_ERROR,
data: [
{
modelElement: {
...modelElementFixture,
fullName: 'BioEntity Full Name',
references: [
{
...bioEntityContentFixture.bioEntity.references[0],
type: 'UNIPROT',
},
],
},
perfect: true,
},
],
},
],
loading: 'pending',
error: DEFAULT_ERROR,
},
},
contextMenu: {
...CONTEXT_MENU_INITIAL_STATE,
......
import { searchedBioEntityElementUniProtIdSelector } from '@/redux/bioEntity/bioEntity.selectors';
import { contextMenuSelector } from '@/redux/contextMenu/contextMenu.selector';
import { closeContextMenu } from '@/redux/contextMenu/contextMenu.slice';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
......@@ -9,12 +8,13 @@ import { twMerge } from 'tailwind-merge';
import { FIRST_ARRAY_ELEMENT, SECOND_ARRAY_ELEMENT, ZERO } from '@/constants/common';
import { PluginsContextMenu } from '@/services/pluginsManager/pluginContextMenu/pluginsContextMenu';
import { BioEntity, NewReaction } from '@/types/models';
import { ModelElement, NewReaction } from '@/types/models';
import { ClickCoordinates } from '@/services/pluginsManager/pluginContextMenu/pluginsContextMenu.types';
import { currentModelSelector } from '@/redux/models/models.selectors';
import { mapDataLastPositionSelector } from '@/redux/map/map.selectors';
import { DEFAULT_ZOOM } from '@/constants/map';
import { OutsideClickWrapper } from '@/shared/OutsideClickWrapper';
import { searchedModelElementUniProtIdSelector } from '@/redux/modelElements/modelElements.selector';
export const ContextMenu = (): React.ReactNode => {
const pluginContextMenu = PluginsContextMenu.menuItems;
......@@ -22,7 +22,7 @@ export const ContextMenu = (): React.ReactNode => {
const lastPosition = useAppSelector(mapDataLastPositionSelector);
const dispatch = useAppDispatch();
const { isOpen, coordinates } = useAppSelector(contextMenuSelector);
const unitProtId = useAppSelector(searchedBioEntityElementUniProtIdSelector);
const unitProtId = useAppSelector(searchedModelElementUniProtIdSelector);
const isUnitProtIdAvailable = (): boolean => unitProtId !== undefined;
......@@ -49,7 +49,10 @@ export const ContextMenu = (): React.ReactNode => {
const modelId = model ? model.id : ZERO;
const handleCallback = (
callback: (coordinates: ClickCoordinates, element: BioEntity | NewReaction | undefined) => void,
callback: (
coordinates: ClickCoordinates,
element: ModelElement | NewReaction | undefined,
) => void,
) => {
return () => {
closeContextMenuFunction();
......
......@@ -94,6 +94,7 @@ describe('EditOverlayModal - component', () => {
login: 'test',
role: 'user',
userData: null,
token: null,
},
modal: {
isOpen: true,
......@@ -132,6 +133,7 @@ describe('EditOverlayModal - component', () => {
login: 'test',
role: 'user',
userData: null,
token: null,
},
modal: {
isOpen: true,
......@@ -171,6 +173,7 @@ describe('EditOverlayModal - component', () => {
login: 'test',
role: 'user',
userData: null,
token: null,
},
modal: {
isOpen: true,
......@@ -218,6 +221,7 @@ describe('EditOverlayModal - component', () => {
login: 'test',
role: 'user',
userData: null,
token: null,
},
modal: {
isOpen: true,
......
......@@ -15,6 +15,7 @@ describe('useEditOverlay', () => {
login: 'test',
role: 'user',
userData: null,
token: null,
},
modal: {
isOpen: true,
......@@ -54,6 +55,7 @@ describe('useEditOverlay', () => {
login: 'test',
role: 'user',
userData: null,
token: null,
},
modal: {
isOpen: true,
......@@ -96,6 +98,7 @@ describe('useEditOverlay', () => {
login: null,
role: 'user',
userData: null,
token: null,
},
modal: {
isOpen: true,
......@@ -134,6 +137,7 @@ describe('useEditOverlay', () => {
login: 'test',
role: 'user',
userData: null,
token: null,
},
modal: {
isOpen: true,
......@@ -173,6 +177,7 @@ describe('useEditOverlay', () => {
login: null,
role: 'user',
userData: null,
token: null,
},
modal: {
isOpen: true,
......
......@@ -43,7 +43,7 @@ const renderComponent = (
...LAYERS_STATE_INITIAL_LAYER_MOCK,
data: {
...LAYER_STATE_DEFAULT_DATA,
activeLayer: 1,
activeLayers: [1],
},
},
},
......@@ -136,6 +136,7 @@ describe('LayerImageObjectEditFactoryModal - component', () => {
y: 1,
width: 1,
height: 1,
layer: 1,
glyph: 1,
z: 1,
};
......
......@@ -5,7 +5,6 @@ import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { mapEditToolsLayerImageObjectSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
import { LayerImageObjectForm } from '@/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectForm.component';
import { currentModelIdSelector } from '@/redux/models/models.selectors';
import { layersActiveLayerSelector } from '@/redux/layers/layers.selectors';
import { addGlyph } from '@/redux/glyphs/glyphs.thunks';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { updateLayerImageObject } from '@/redux/layers/layers.thunks';
......@@ -22,7 +21,6 @@ export const LayerImageObjectEditFactoryModal: React.FC = () => {
const { mapInstance } = useMapInstance();
const currentModelId = useAppSelector(currentModelIdSelector);
const activeLayer = useAppSelector(layersActiveLayerSelector);
const dispatch = useAppDispatch();
const [selectedGlyph, setSelectedGlyph] = useState<number | null>(
......@@ -32,7 +30,7 @@ export const LayerImageObjectEditFactoryModal: React.FC = () => {
const [isSending, setIsSending] = useState<boolean>(false);
const handleSubmit = async (): Promise<void> => {
if (!layerImageObject || !activeLayer) {
if (!layerImageObject) {
return;
}
setIsSending(true);
......@@ -49,15 +47,17 @@ export const LayerImageObjectEditFactoryModal: React.FC = () => {
const layerImage = await dispatch(
updateLayerImageObject({
modelId: currentModelId,
layerId: activeLayer,
layerId: layerImageObject.layer,
...layerImageObject,
glyph: glyphId,
}),
).unwrap();
if (layerImage) {
dispatch(layerUpdateImage({ modelId: currentModelId, layerId: activeLayer, layerImage }));
dispatch(
layerUpdateImage({ modelId: currentModelId, layerId: layerImage.layer, layerImage }),
);
dispatch(mapEditToolsSetLayerObject(layerImage));
updateGlyph(mapInstance, activeLayer, layerImage);
updateGlyph(mapInstance, layerImage.layer, layerImage);
}
showToast({
type: 'success',
......
......@@ -36,7 +36,8 @@ const renderComponent = (): { store: StoreType } => {
...LAYERS_STATE_INITIAL_LAYER_MOCK,
data: {
...LAYER_STATE_DEFAULT_DATA,
activeLayer: 1,
activeLayers: [1],
drawLayer: 1,
},
},
},
......
......@@ -4,7 +4,7 @@ import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { layerImageObjectFactoryStateSelector } from '@/redux/modal/modal.selector';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { currentModelIdSelector } from '@/redux/models/models.selectors';
import { highestZIndexSelector, layersActiveLayerSelector } from '@/redux/layers/layers.selectors';
import { highestZIndexSelector, layersDrawLayerSelector } from '@/redux/layers/layers.selectors';
import { addLayerImageObject } from '@/redux/layers/layers.thunks';
import { addGlyph } from '@/redux/glyphs/glyphs.thunks';
import { SerializedError } from '@reduxjs/toolkit';
......@@ -15,10 +15,11 @@ import { useMapInstance } from '@/utils/context/mapInstanceContext';
import { layerAddImage } from '@/redux/layers/layers.slice';
import { LayerImageObjectForm } from '@/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectForm.component';
import drawElementOnLayer from '@/components/Map/MapViewer/utils/shapes/layer/utils/drawElementOnLayer';
import { mapEditToolsSetActiveAction } from '@/redux/mapEditTools/mapEditTools.slice';
export const LayerImageObjectFactoryModal: React.FC = () => {
const currentModelId = useAppSelector(currentModelIdSelector);
const activeLayer = useAppSelector(layersActiveLayerSelector);
const drawLayer = useAppSelector(layersDrawLayerSelector);
const layerImageObjectFactoryState = useAppSelector(layerImageObjectFactoryStateSelector);
const dispatch = useAppDispatch();
const highestZIndex = useAppSelector(highestZIndexSelector);
......@@ -29,7 +30,7 @@ export const LayerImageObjectFactoryModal: React.FC = () => {
const [isSending, setIsSending] = useState<boolean>(false);
const handleSubmit = async (): Promise<void> => {
if (!layerImageObjectFactoryState || !activeLayer) {
if (!layerImageObjectFactoryState || !drawLayer) {
return;
}
setIsSending(true);
......@@ -45,7 +46,7 @@ export const LayerImageObjectFactoryModal: React.FC = () => {
const imageData = await dispatch(
addLayerImageObject({
modelId: currentModelId,
layerId: activeLayer,
layerId: drawLayer,
x: layerImageObjectFactoryState.x,
y: layerImageObjectFactoryState.y,
z: highestZIndex + 1,
......@@ -62,11 +63,11 @@ export const LayerImageObjectFactoryModal: React.FC = () => {
return;
}
dispatch(
layerAddImage({ modelId: currentModelId, layerId: activeLayer, layerImage: imageData }),
layerAddImage({ modelId: currentModelId, layerId: drawLayer, layerImage: imageData }),
);
drawElementOnLayer({
mapInstance,
activeLayer,
activeLayer: drawLayer,
object: imageData,
drawFunctionKey: 'drawImage',
});
......@@ -75,6 +76,7 @@ export const LayerImageObjectFactoryModal: React.FC = () => {
message: 'A new image has been successfully added',
});
dispatch(closeModal());
dispatch(mapEditToolsSetActiveAction(null));
} catch (error) {
const typedError = error as SerializedError;
showToast({
......
......@@ -41,7 +41,8 @@ const renderComponent = (): { store: StoreType } => {
...LAYERS_STATE_INITIAL_LAYER_MOCK,
data: {
...LAYER_STATE_DEFAULT_DATA,
activeLayer: 1,
activeLayers: [1],
drawLayer: 1,
},
},
},
......
......@@ -13,7 +13,7 @@ import { LayerTextFactoryForm } from '@/components/FunctionalArea/Modal/LayerTex
import { Color } from '@/types/models';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { layerTextFactoryStateSelector } from '@/redux/modal/modal.selector';
import { highestZIndexSelector, layersActiveLayerSelector } from '@/redux/layers/layers.selectors';
import { highestZIndexSelector, layersDrawLayerSelector } from '@/redux/layers/layers.selectors';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { currentModelIdSelector } from '@/redux/models/models.selectors';
import { showToast } from '@/utils/showToast';
......@@ -23,10 +23,11 @@ import { addLayerText } from '@/redux/layers/layers.thunks';
import { layerAddText } from '@/redux/layers/layers.slice';
import drawElementOnLayer from '@/components/Map/MapViewer/utils/shapes/layer/utils/drawElementOnLayer';
import { useMapInstance } from '@/utils/context/mapInstanceContext';
import { BLACK_COLOR, WHITE_COLOR } from '@/components/Map/MapViewer/MapViewer.constants';
import { BLACK_COLOR } from '@/components/Map/MapViewer/MapViewer.constants';
import { mapEditToolsSetActiveAction } from '@/redux/mapEditTools/mapEditTools.slice';
export const LayerTextFactoryModal: React.FC = () => {
const activeLayer = useAppSelector(layersActiveLayerSelector);
const drawLayer = useAppSelector(layersDrawLayerSelector);
const currentModelId = useAppSelector(currentModelIdSelector);
const layerTextFactoryState = useAppSelector(layerTextFactoryStateSelector);
const dispatch = useAppDispatch();
......@@ -40,18 +41,18 @@ export const LayerTextFactoryModal: React.FC = () => {
horizontalAlign: DEFAULT_HORIZONTAL_ALIGNMENT,
verticalAlign: DEFAULT_VERTICAL_ALIGNMENT,
color: BLACK_COLOR,
borderColor: { ...WHITE_COLOR, alpha: 0 },
borderColor: BLACK_COLOR,
});
const handleSubmit = async (): Promise<void> => {
if (!layerTextFactoryState || !activeLayer) {
if (!layerTextFactoryState || !drawLayer) {
return;
}
try {
const textData = await dispatch(
addLayerText({
modelId: currentModelId,
layerId: activeLayer,
layerId: drawLayer,
boundingBox: layerTextFactoryState,
textData: data,
z: highestZIndex + 1,
......@@ -64,12 +65,10 @@ export const LayerTextFactoryModal: React.FC = () => {
});
return;
}
dispatch(
layerAddText({ modelId: currentModelId, layerId: activeLayer, layerText: textData }),
);
dispatch(layerAddText({ modelId: currentModelId, layerId: drawLayer, layerText: textData }));
drawElementOnLayer({
mapInstance,
activeLayer,
activeLayer: drawLayer,
object: textData,
drawFunctionKey: 'drawText',
});
......@@ -78,6 +77,7 @@ export const LayerTextFactoryModal: React.FC = () => {
message: 'A new text has been successfully added',
});
dispatch(closeModal());
dispatch(mapEditToolsSetActiveAction(null));
} catch (error) {
const typedError = error as SerializedError;
showToast({
......@@ -87,10 +87,6 @@ export const LayerTextFactoryModal: React.FC = () => {
} finally {
setIsSending(false);
}
setIsSending(true);
setTimeout(() => {
setIsSending(false);
}, 5000);
};
const changeValues = (value: string | number | Color, key: string): void => {
......
......@@ -58,11 +58,15 @@ export const LayerTextForm = ({ data, onChange }: LayerTextFormProps): React.JSX
</div>
<div>
<span>Color:</span>
<ColorTilePicker colorChange={color => onChange(hexToRgbIntAlpha(color), 'color')} />
<ColorTilePicker
initialColor={data.color}
colorChange={color => onChange(hexToRgbIntAlpha(color), 'color')}
/>
</div>
<div>
<span>Border color:</span>
<ColorTilePicker
initialColor={data.borderColor}
colorChange={color => onChange(hexToRgbIntAlpha(color), 'borderColor')}
/>
</div>
......
......@@ -18,6 +18,8 @@ jest.mock('./utils/useOverviewImageSize', () => ({
})),
}));
const PROJECT_DIRECTORY = 'directory';
const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState);
......@@ -42,6 +44,7 @@ describe('OverviewImagesModal - component', () => {
...projectFixture,
overviewImageViews: [],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
directory: PROJECT_DIRECTORY,
},
loading: 'succeeded',
error: { message: '', name: '' },
......@@ -70,6 +73,7 @@ describe('OverviewImagesModal - component', () => {
...projectFixture,
overviewImageViews: [PROJECT_OVERVIEW_IMAGE_MOCK],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
directory: PROJECT_DIRECTORY,
},
loading: 'succeeded',
error: { message: '', name: '' },
......@@ -91,7 +95,7 @@ describe('OverviewImagesModal - component', () => {
it('should render image with valid src', () => {
const imageElement = screen.getByAltText('overview');
const result = `${BASE_MAP_IMAGES_URL}/map_images/${PROJECT_OVERVIEW_IMAGE_MOCK.filename}`;
const result = `${BASE_MAP_IMAGES_URL}/map_images/${PROJECT_DIRECTORY}/${PROJECT_OVERVIEW_IMAGE_MOCK.filename}`;
expect(imageElement.getAttribute('src')).toBe(result);
});
......
......@@ -7,6 +7,8 @@ import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithSto
import { renderHook } from '@testing-library/react';
import { useOverviewImage } from './useOverviewImage';
const PROJECT_DIRECTORY = 'directory';
describe('useOverviewImage - hook', () => {
describe('when image data is invalid', () => {
const { Wrapper } = getReduxWrapperWithStore({
......@@ -15,6 +17,7 @@ describe('useOverviewImage - hook', () => {
...projectFixture,
overviewImageViews: [],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
directory: PROJECT_DIRECTORY,
},
loading: 'succeeded',
error: { message: '', name: '' },
......@@ -48,6 +51,7 @@ describe('useOverviewImage - hook', () => {
...projectFixture,
overviewImageViews: [PROJECT_OVERVIEW_IMAGE_MOCK],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
directory: PROJECT_DIRECTORY,
},
loading: 'succeeded',
error: { message: '', name: '' },
......@@ -66,7 +70,7 @@ describe('useOverviewImage - hook', () => {
});
it('should return default size of image and valid imageUrl', () => {
const imageUrl = `${BASE_MAP_IMAGES_URL}/map_images/${PROJECT_OVERVIEW_IMAGE_MOCK.filename}`;
const imageUrl = `${BASE_MAP_IMAGES_URL}/map_images/${PROJECT_DIRECTORY}/${PROJECT_OVERVIEW_IMAGE_MOCK.filename}`;
expect(result.current).toMatchObject({
imageUrl,
......@@ -88,6 +92,7 @@ describe('useOverviewImage - hook', () => {
},
],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
directory: PROJECT_DIRECTORY,
},
loading: 'succeeded',
error: { message: '', name: '' },
......@@ -109,7 +114,7 @@ describe('useOverviewImage - hook', () => {
);
it('should return size of image and valid imageUrl', () => {
const imageUrl = `${BASE_MAP_IMAGES_URL}/map_images/${PROJECT_OVERVIEW_IMAGE_MOCK.filename}`;
const imageUrl = `${BASE_MAP_IMAGES_URL}/map_images/${PROJECT_DIRECTORY}/${PROJECT_OVERVIEW_IMAGE_MOCK.filename}`;
expect(result.current).toMatchObject({
imageUrl,
......
......@@ -6,6 +6,8 @@ import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithSto
import { renderHook } from '@testing-library/react';
import { useOverviewImageUrl } from './useOverviewImageUrl';
const PROJECT_DIRECTORY = 'directory';
describe('useOverviewImageUrl - hook', () => {
describe('when currentImage data is valid', () => {
const { Wrapper } = getReduxWrapperWithStore({
......@@ -14,6 +16,7 @@ describe('useOverviewImageUrl - hook', () => {
...projectFixture,
overviewImageViews: [],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
directory: PROJECT_DIRECTORY,
},
loading: 'succeeded',
error: { message: '', name: '' },
......@@ -41,6 +44,7 @@ describe('useOverviewImageUrl - hook', () => {
...projectFixture,
overviewImageViews: [PROJECT_OVERVIEW_IMAGE_MOCK],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
directory: PROJECT_DIRECTORY,
},
loading: 'succeeded',
error: { message: '', name: '' },
......@@ -58,7 +62,7 @@ describe('useOverviewImageUrl - hook', () => {
const { result } = renderHook(() => useOverviewImageUrl(), { wrapper: Wrapper });
expect(result.current).toBe(
`${BASE_MAP_IMAGES_URL}/map_images/${PROJECT_OVERVIEW_IMAGE_MOCK.filename}`,
`${BASE_MAP_IMAGES_URL}/map_images/${PROJECT_DIRECTORY}/${PROJECT_OVERVIEW_IMAGE_MOCK.filename}`,
);
});
});
......
import { BASE_MAP_IMAGES_URL } from '@/constants';
import { currentOverviewImageSelector } from '@/redux/project/project.selectors';
import {
currentOverviewImageSelector,
projectDirectorySelector,
} from '@/redux/project/project.selectors';
import { useSelector } from 'react-redux';
export const useOverviewImageUrl = (): string => {
const currentImage = useSelector(currentOverviewImageSelector);
if (!currentImage) {
const directory = useSelector(projectDirectorySelector);
if (!currentImage || !directory) {
return '';
}
return `${BASE_MAP_IMAGES_URL}/map_images/${currentImage.filename}`;
return `${BASE_MAP_IMAGES_URL}/map_images/${directory}/${currentImage.filename}`;
};
......@@ -5,7 +5,7 @@ import { apiPath } from '@/redux/apiPath';
import { DEFAULT_POSITION } from '@/redux/map/map.constants';
import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
import { AppDispatch, RootState } from '@/redux/store';
import { BioEntity, MapModel } from '@/types/models';
import { MapModel, PublicationElement } from '@/types/models';
import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse';
import {
InitialStoreState,
......@@ -14,12 +14,12 @@ import {
import { render, screen, waitFor } from '@testing-library/react';
import { HttpStatusCode } from 'axios';
import { MockStoreEnhanced } from 'redux-mock-store';
import { isReactionBioEntity } from '@/redux/reactions/isReactionBioentity';
import { isReactionElement } from '@/redux/reactions/isReactionElement';
import { ElementLink } from './ElementLink.component';
const mockedAxiosNewClient = mockNetworkNewAPIResponse();
const TARGET_ELEMENT: BioEntity = {
const TARGET_ELEMENT: PublicationElement = {
...bioEntityResponseFixture.content[FIRST_ARRAY_ELEMENT].bioEntity,
id: 123,
model: 52,
......@@ -36,20 +36,20 @@ const OTHER_MODEL: MapModel = {
};
interface Props {
target: BioEntity;
target: PublicationElement;
}
const getElementText = (bioEntity: BioEntity): string => {
const isReaction = isReactionBioEntity(bioEntity);
const getElementText = (element: PublicationElement): string => {
const isReaction = isReactionElement(element);
const prefix = isReaction ? 'Reaction: ' : 'Element: ';
return prefix + bioEntity.elementId;
return prefix + element.elementId;
};
const getSearchQuery = (bioEntity: BioEntity): string => {
const isReaction = isReactionBioEntity(bioEntity);
const getSearchQuery = (element: PublicationElement): string => {
const isReaction = isReactionElement(element);
return (isReaction ? 'reaction:' : 'element:') + bioEntity.id;
return (isReaction ? 'reaction:' : 'element:') + element.id;
};
const renderComponent = (
......@@ -86,10 +86,10 @@ describe('ElementLink - component', () => {
});
it('should should show element id', async () => {
const bioEntity = TARGET_ELEMENT;
const element = TARGET_ELEMENT;
await waitFor(() => {
expect(screen.getByText(getElementText(bioEntity))).toBeInTheDocument();
expect(screen.getByText(getElementText(element))).toBeInTheDocument();
});
});
});
......@@ -116,10 +116,10 @@ describe('ElementLink - component', () => {
},
);
const bioEntity = TARGET_ELEMENT;
const element = TARGET_ELEMENT;
await waitFor(() => {
const link = screen.getByText(getElementText(bioEntity));
const link = screen.getByText(getElementText(element));
link.click();
const actions = store.getActions();
......@@ -148,7 +148,7 @@ describe('ElementLink - component', () => {
expect(actions).toEqual(
expect.arrayContaining([
expect.objectContaining({
payload: getSearchQuery(bioEntity),
payload: getSearchQuery(element),
type: 'drawer/openSearchDrawerWithSelectedTab',
}),
]),
......@@ -206,10 +206,10 @@ describe('ElementLink - component', () => {
},
);
const bioEntity = TARGET_ELEMENT;
const element = TARGET_ELEMENT;
await waitFor(() => {
const link = screen.getByText(getElementText(bioEntity));
const link = screen.getByText(getElementText(element));
link.click();
const actions = store.getActions();
......@@ -238,7 +238,7 @@ describe('ElementLink - component', () => {
expect(actions).toEqual(
expect.arrayContaining([
expect.objectContaining({
payload: getSearchQuery(bioEntity),
payload: getSearchQuery(element),
type: 'drawer/openSearchDrawerWithSelectedTab',
}),
]),
......
......@@ -13,11 +13,11 @@ import { closeModal } from '@/redux/modal/modal.slice';
import { modelsNameMapSelector } from '@/redux/models/models.selectors';
import { getSearchData } from '@/redux/search/search.thunks';
import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus';
import { BioEntity } from '@/types/models';
import { isReactionBioEntity } from '@/redux/reactions/isReactionBioentity';
import { PublicationElement } from '@/types/models';
import { isReactionElement } from '@/redux/reactions/isReactionElement';
interface Props {
target: BioEntity;
target: PublicationElement;
}
export const ElementLink = ({ target }: Props): JSX.Element => {
......@@ -26,7 +26,7 @@ export const ElementLink = ({ target }: Props): JSX.Element => {
const currentModelId = useAppSelector(mapModelIdSelector);
const mapsNames = useAppSelector(modelsNameMapSelector);
const isReaction = isReactionBioEntity(target);
const isReaction = isReactionElement(target);
const isMapAlreadyOpened = (modelId: number): boolean =>
openedMaps.some(map => map.modelId === modelId);
......