Skip to content
Snippets Groups Projects
Commit 54821043 authored by mateusz-winiarczyk's avatar mateusz-winiarczyk
Browse files

feat(project): deploy and project adjustments (MIN-304)

parent 3edc9180
No related branches found
No related tags found
2 merge requests!223reset the pin numbers before search results are fetch (so the results will be...,!159feat(project): deploy and project adjustments (MIN-304)
Showing
with 166 additions and 18 deletions
NEXT_PUBLIC_BASE_API_URL = 'https://lux1.atcomp.pl/minerva/api'
NEXT_PUBLIC_BASE_NEW_API_URL = 'https://lux1.atcomp.pl/minerva/new_api/'
BASE_MAP_IMAGES_URL = 'https://lux1.atcomp.pl/'
NEXT_PUBLIC_PROJECT_ID = 'pdmap_appu_test'
ZOD_SEED = 997
......@@ -42,6 +42,13 @@ type HashPlugin = {
declare global {
interface Window {
config: {
BASE_API_URL: string;
BASE_NEW_API_URL: string;
BASE_MAP_IMAGES_URL: string;
DEFAULT_PROJECT_ID: string;
};
minerva: {
configuration?: MinervaConfiguration;
plugins: {
......
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
experimental: {
fontLoaders: [{ loader: '@next/font/google', options: { subsets: ['latin'] } }],
output: 'export',
images: {
unoptimized: true,
},
env: {
BASE_API_URL: process.env.NEXT_PUBLIC_BASE_API_URL || '',
BASE_MAP_IMAGES_URL: process.env.BASE_MAP_IMAGES_URL || '',
PROJECT_ID: process.env.NEXT_PUBLIC_PROJECT_ID || '',
ZOD_SEED: process.env.ZOD_SEED || 123,
},
};
......
import { Html, Head, Main, NextScript } from 'next/document';
import Script from 'next/script';
const Document = (): React.ReactNode => (
<Html>
<Head />
<body>
<Main />
<NextScript />
<Script src="/config.js" strategy="beforeInteractive" />
</body>
</Html>
);
export default Document;
window.config = {
BASE_API_URL: 'https://lux1.atcomp.pl/minerva/api',
BASE_NEW_API_URL: 'https://lux1.atcomp.pl/minerva/new_api/',
BASE_MAP_IMAGES_URL: 'https://lux1.atcomp.pl/',
DEFAULT_PROJECT_ID: 'pdmap_appu_test',
};
......@@ -36,3 +36,12 @@ const localStorageMock = (() => {
Object.defineProperty(global, 'localStorage', {
value: localStorageMock,
});
Object.defineProperty(window, 'config', {
value: {
BASE_API_URL: 'https://lux1.atcomp.pl/minerva/api',
BASE_NEW_API_URL: 'https://lux1.atcomp.pl/minerva/new_api/',
BASE_MAP_IMAGES_URL: 'https://lux1.atcomp.pl/',
DEFAULT_PROJECT_ID: 'pdmap_appu_test',
},
});
......@@ -45,6 +45,7 @@ describe('OverviewImagesModal - component', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......@@ -72,6 +73,7 @@ describe('OverviewImagesModal - component', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......
......@@ -18,6 +18,7 @@ describe('useOverviewImage - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......@@ -50,6 +51,7 @@ describe('useOverviewImage - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......@@ -89,6 +91,7 @@ describe('useOverviewImage - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......
......@@ -43,6 +43,7 @@ describe('useOverviewImageLinkActions - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......@@ -92,6 +93,7 @@ describe('useOverviewImageLinkActions - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......@@ -148,6 +150,7 @@ describe('useOverviewImageLinkActions - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......@@ -225,6 +228,7 @@ describe('useOverviewImageLinkActions - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......@@ -328,6 +332,7 @@ describe('useOverviewImageLinkActions - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......@@ -378,6 +383,7 @@ describe('useOverviewImageLinkActions - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
map: {
data: {
......@@ -438,6 +444,7 @@ describe('useOverviewImageLinkActions - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
map: {
data: {
......@@ -500,6 +507,7 @@ describe('useOverviewImageLinkActions - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
map: {
data: {
......
......@@ -17,6 +17,7 @@ describe('useOverviewImageLinkConfigs - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......@@ -53,6 +54,7 @@ describe('useOverviewImageLinkConfigs - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......@@ -89,6 +91,7 @@ describe('useOverviewImageLinkConfigs - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......
......@@ -18,6 +18,7 @@ describe('useOverviewImageSize - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......@@ -49,6 +50,7 @@ describe('useOverviewImageSize - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......@@ -77,6 +79,7 @@ describe('useOverviewImageSize - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......
......@@ -17,6 +17,7 @@ describe('useOverviewImageUrl - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......@@ -43,6 +44,7 @@ describe('useOverviewImageUrl - hook', () => {
},
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
......
......@@ -88,6 +88,7 @@ describe('UserOverlayForm - Component', () => {
data: projectFixture,
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
overlays: OVERLAYS_INITIAL_STATE_MOCK,
});
......@@ -111,6 +112,7 @@ describe('UserOverlayForm - Component', () => {
data: projectFixture,
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
overlays: OVERLAYS_INITIAL_STATE_MOCK,
});
......@@ -181,6 +183,7 @@ describe('UserOverlayForm - Component', () => {
data: projectFixture,
loading: 'succeeded',
error: { message: '', name: '' },
projectId: '',
},
overlays: OVERLAYS_INITIAL_STATE_MOCK,
});
......@@ -225,6 +228,7 @@ describe('UserOverlayForm - Component', () => {
data: projectFixture,
loading: 'succeeded',
error: DEFAULT_ERROR,
projectId: '',
},
overlays: OVERLAYS_INITIAL_STATE_MOCK,
});
......@@ -283,6 +287,7 @@ describe('UserOverlayForm - Component', () => {
data: projectFixture,
loading: 'succeeded',
error: DEFAULT_ERROR,
projectId: '',
},
overlays: OVERLAYS_INITIAL_STATE_MOCK,
});
......
......@@ -14,6 +14,7 @@ const MOCKED_STORE: InitialStoreState = {
data: { ...projectFixture },
loading: 'idle',
error: new Error(),
projectId: '',
},
models: {
data: [MODEL_WITH_DESCRIPTION],
......
......@@ -12,6 +12,8 @@ import {
} from '@/utils/testing/getReduxWrapperWithStore';
import { render, screen } from '@testing-library/react';
import { MockStoreEnhanced } from 'redux-mock-store';
import { PROJECT_STATE_INITIAL_MOCK } from '@/redux/project/project.mock';
import { projectFixture } from '@/models/fixtures/projectFixture';
import { MapAdditionalOptions } from './MapAdditionalOptions.component';
const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
......@@ -59,6 +61,10 @@ describe('MapAdditionalOptions - component', () => {
it('should open overview image modal on button click', () => {
const { store } = renderComponentWithActionListener({
project: {
...PROJECT_STATE_INITIAL_MOCK,
data: projectFixture,
},
map: initialMapStateFixture,
backgrounds: { ...BACKGROUND_INITIAL_STATE_MOCK, data: BACKGROUNDS_MOCK },
});
......@@ -68,8 +74,28 @@ describe('MapAdditionalOptions - component', () => {
const actions = store.getActions();
expect(actions[FIRST_ARRAY_ELEMENT]).toStrictEqual({
payload: 0,
payload: projectFixture.topOverviewImage?.idObject,
type: 'modal/openOverviewImagesModalById',
});
});
it('should disable button browse overview images if there are no overview images', () => {
const { store } = renderComponentWithActionListener({
project: {
...PROJECT_STATE_INITIAL_MOCK,
data: {
...projectFixture,
overviewImageViews: [],
},
},
map: initialMapStateFixture,
backgrounds: { ...BACKGROUND_INITIAL_STATE_MOCK, data: BACKGROUNDS_MOCK },
});
const overviewImageButton = screen.getByText('Browse overview images');
expect(overviewImageButton).toBeDisabled();
overviewImageButton.click();
const actions = store.getActions();
expect(actions).toStrictEqual([]);
});
});
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { openOverviewImagesModalById } from '@/redux/modal/modal.slice';
import { projectDefaultOverviewImageIdSelector } from '@/redux/project/project.selectors';
import {
projectDefaultOverviewImageIdSelector,
projectOverviewImagesSelector,
} from '@/redux/project/project.selectors';
import { Button } from '@/shared/Button';
import { useSelector } from 'react-redux';
import { twMerge } from 'tailwind-merge';
import { ZERO } from '@/constants/common';
import { BackgroundSelector } from './BackgroundsSelector';
// top-[calc(64px+40px+24px)] -> TOP_BAR_HEIGHT+MAP_NAVIGATION_HEIGHT+DISTANCE_FROM_MAP_NAVIGATION
......@@ -11,6 +15,8 @@ import { BackgroundSelector } from './BackgroundsSelector';
export const MapAdditionalOptions = (): JSX.Element => {
const dispatch = useAppDispatch();
const defaultOverviewImageId = useSelector(projectDefaultOverviewImageIdSelector);
const overviewImages = useSelector(projectOverviewImagesSelector);
const overviewImagesEmpty = overviewImages.length === ZERO;
const handleBrowseOverviewImagesClick = (): void => {
dispatch(openOverviewImagesModalById(defaultOverviewImageId));
......@@ -18,7 +24,11 @@ export const MapAdditionalOptions = (): JSX.Element => {
return (
<div className={twMerge('absolute right-6 top-[calc(64px+40px+24px)] z-10 flex')}>
<Button className="mr-4" onClick={handleBrowseOverviewImagesClick}>
<Button
className="mr-4"
onClick={handleBrowseOverviewImagesClick}
disabled={overviewImagesEmpty}
>
Browse overview images
</Button>
<BackgroundSelector />
......
/* eslint-disable no-magic-numbers */
export const BASE_API_URL = process.env.NEXT_PUBLIC_BASE_API_URL || '';
export const BASE_MAP_IMAGES_URL = process.env.BASE_MAP_IMAGES_URL || '';
export const BASE_NEW_API_URL = process.env.NEXT_PUBLIC_BASE_NEW_API_URL || '';
export const PROJECT_ID = process.env.NEXT_PUBLIC_PROJECT_ID || '';
import { getConfigValue, getProjectIdFromUrl } from './index.utils';
export const BASE_API_URL = getConfigValue('BASE_API_URL');
export const BASE_MAP_IMAGES_URL = getConfigValue('BASE_MAP_IMAGES_URL');
export const BASE_NEW_API_URL = getConfigValue('BASE_NEW_API_URL');
export const DEFAULT_PROJECT_ID = getConfigValue('DEFAULT_PROJECT_ID');
export const PROJECT_ID = getProjectIdFromUrl() || DEFAULT_PROJECT_ID;
export const ZOD_SEED = parseInt(process.env.ZOD_SEED || '123', 10);
export const BIO_ENTITY = 'bioEntity';
export const DRUGS_CHEMICALS = ['drugs', 'chemicals'];
import { getConfigValue, getProjectIdFromUrl } from './index.utils';
describe('getConfigValue - util', () => {
it('should return value for existing key', () => {
expect(getConfigValue('BASE_API_URL')).toBe('https://lux1.atcomp.pl/minerva/api');
});
it('should return default value for non-existing key', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(getConfigValue('nonExistingKey' as any)).toBe('');
});
});
describe('getProjectIdFromUrl - util', () => {
afterEach(() => {
jest.clearAllMocks();
});
it('should return project ID from URL if present', () => {
jest.spyOn(URLSearchParams.prototype, 'get').mockReturnValue('my_project_id');
expect(getProjectIdFromUrl()).toBe('my_project_id');
});
it('should return default project ID if not present in URL', () => {
jest.spyOn(URLSearchParams.prototype, 'get').mockReturnValue(null);
expect(getProjectIdFromUrl()).toBeNull();
});
it('should return undefined if window is undefined', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
jest.spyOn(global as any, 'window', 'get').mockImplementation(() => undefined);
expect(getProjectIdFromUrl()).toBeUndefined();
});
});
type ConfigKeys = keyof typeof window.config;
export const getConfigValue = (key: ConfigKeys): string => {
const defaultValue = '';
if (typeof window !== 'undefined' && window.config && window.config[key]) {
return window.config[key];
}
return defaultValue;
};
export const getProjectIdFromUrl = (): string | null | undefined => {
if (typeof window !== 'undefined') {
const params = new URLSearchParams(window.location.search);
return params.get('id');
}
return undefined;
};
......@@ -23,5 +23,5 @@ export const projectSchema = z.object({
creationDate: z.string(),
mapCanvasType: z.string(),
overviewImageViews: z.array(overviewImageView),
topOverviewImage: overviewImageView,
topOverviewImage: overviewImageView.nullable(),
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment