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 (5)
Showing
with 518 additions and 2212 deletions
......@@ -65,7 +65,9 @@
"**/jest.setup.ts", // jest setup
"**/setupTests.ts"
],
"optionalDependencies": false
"optionalDependencies": false,
"peerDependencies": false,
"packageDir": "./"
}
],
"indent": ["error", 2],
......@@ -83,6 +85,12 @@
"rules": {
"@typescript-eslint/explicit-function-return-type": "error"
}
},
{
// feel free to replace with your preferred file pattern - eg. 'src/**/*Slice.ts'
"files": ["src/**/*.slice.ts", "src/**/*.reducers.ts"],
// avoid state param assignment
"rules": { "no-param-reassign": ["error", { "props": false }] }
}
],
"settings": {
......
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />
// NOTE: This file should not be edited
......
This diff is collapsed.
import { AppWrapper } from '@/components/AppWrapper';
import type { AppProps } from 'next/app';
const MyApp = ({ Component, pageProps }: AppProps): JSX.Element => (
<AppWrapper>
<Component {...pageProps} />
</AppWrapper>
);
export default MyApp;
import { useSelector } from 'react-redux';
import { selectSearchValue } from '@/redux/search/search.selectors';
import { setSearchValue } from '@/redux/search/search.slice';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { getProjectById } from '@/redux/project/project.thunks';
const ReduxPage = (): JSX.Element => {
const dispatch = useAppDispatch();
const searchValue = useSelector(selectSearchValue);
const triggerSyncUpdate = (): void => {
// eslint-disable-next-line prefer-template
const newValue = searchValue + 'test';
dispatch(setSearchValue(newValue));
dispatch(getProjectById('pd_map_winter_23'));
};
return (
<div>
{searchValue}
<button type="button" onClick={triggerSyncUpdate}>
sync update
</button>
</div>
);
};
export default ReduxPage;
import { ReactNode } from 'react';
import { Provider } from 'react-redux';
import { store } from '@/redux/store';
interface AppWrapperProps {
children: ReactNode;
}
export const AppWrapper = ({ children }: AppWrapperProps): JSX.Element => (
<Provider store={store}>{children}</Provider>
);
export { AppWrapper } from './AppWrapper.component';
......@@ -3,6 +3,6 @@ import avatarImg from '@/assets/images/user-avatar.png';
export const UserAvatar = (): JSX.Element => (
<div className="w-8 h-8 mr-7" data-testid="user-avatar">
<Image src={avatarImg} alt="user avatar" height={32} width={32} />
<Image src={avatarImg} alt="user avatar" width={32} height={32} />
</div>
);
export const BASE_API_URL = 'https://corsproxy.io/?https://pdmap.uni.lu/minerva/api';
import { z } from 'zod';
export const disease = z.object({
link: z.string(),
type: z.string(),
resource: z.string(),
id: z.number(),
annotatorClassName: z.string(),
});
import { z } from 'zod';
export const organism = z.object({
link: z.string(),
type: z.string(),
resource: z.string(),
id: z.number(),
annotatorClassName: z.string(),
});
import { z } from 'zod';
import { disease } from './disease';
import { organism } from './organism';
export const projectSchema = z.object({
version: z.string(),
disease,
organism,
idObject: z.number(),
status: z.string(),
directory: z.string(),
progress: z.number(),
notifyEmail: z.string(),
logEntries: z.boolean(),
name: z.string(),
sharedInMinervaNet: z.boolean(),
owner: z.string(),
projectId: z.string(),
creationDate: z.string(),
mapCanvasType: z.string(),
overviewImageViews: z.array(
z.object({
idObject: z.number(),
filename: z.string(),
width: z.number(),
height: z.number(),
links: z.array(
z.union([
z.object({
idObject: z.number(),
polygon: z.array(z.object({ x: z.number(), y: z.number() })),
imageLinkId: z.number(),
type: z.string(),
}),
z.object({
idObject: z.number(),
polygon: z.array(z.object({ x: z.number(), y: z.number() })),
zoomLevel: z.number(),
modelPoint: z.object({ x: z.number(), y: z.number() }),
modelLinkId: z.number(),
type: z.string(),
}),
]),
),
}),
),
});
import { useDispatch } from 'react-redux';
import { AppDispatch } from '@/redux/store';
export const useAppDispatch: () => AppDispatch = useDispatch;
import { useSelector } from 'react-redux';
import type { TypedUseSelectorHook } from 'react-redux';
import { RootState } from '@/redux/store';
// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
import { ActionReducerMapBuilder } from '@reduxjs/toolkit';
import { ProjectState } from '@/redux/project/project.types';
import { getProjectById } from '@/redux/project/project.thunks';
export const getProjectByIdReducer = (builder: ActionReducerMapBuilder<ProjectState>): void => {
builder.addCase(getProjectById.fulfilled, (state, action) => {
state.data = action.payload;
state.loading = 'succeeded';
});
};
import { createSlice } from '@reduxjs/toolkit';
import { ProjectState } from '@/redux/project/project.types';
import { getProjectByIdReducer } from './project.reducers';
const initialState: ProjectState = {
data: [],
loading: 'idle',
error: { name: '', message: '' },
};
const projectSlice = createSlice({
name: 'project',
initialState,
reducers: {},
extraReducers: builder => {
getProjectByIdReducer(builder);
},
});
export default projectSlice.reducer;
import { createAsyncThunk } from '@reduxjs/toolkit';
import { axiosInstance } from '@/services/api/utils/axiosInstance';
import { Project } from '@/types/api';
import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema';
import { projectSchema } from '@/models/project';
export const getProjectById = createAsyncThunk(
'project/getUsersByIdStatus',
async (id: string): Promise<Project | undefined> => {
const response = await axiosInstance.get<Project>(`projects/${id}`);
const isDataValid = validateDataUsingZodSchema(response.data, projectSchema);
return isDataValid ? response.data : undefined;
},
);
import { Project } from '@/types/api';
export type ProjectState = {
data: Project | undefined | [];
loading: 'idle' | 'pending' | 'succeeded' | 'failed';
error: Error;
};