Added Regions with Coordinators and Countries

This commit is contained in:
Kari Lintulaakso
2024-05-28 14:11:30 +03:00
parent a93f775c4d
commit ec99e7d299
11 changed files with 200 additions and 0 deletions
+2
View File
@@ -4,6 +4,7 @@ import 'express-async-errors'
import userRouter from './routes/user'
import localityRouter from './routes/locality'
import referenceRouter from './routes/reference'
import regionRouter from './routes/region'
import speciesRouter from './routes/species'
import timeUnitRouter from './routes/timeUnit'
import museumRouter from './routes/museum'
@@ -30,6 +31,7 @@ if (BACKEND_MODE !== 'dev') app.use(requireLogin)
app.use('/locality', localityRouter)
app.use('/reference', referenceRouter)
app.use('/region', regionRouter)
app.use('/species', speciesRouter)
app.use('/time-unit', timeUnitRouter)
app.use('/museum', museumRouter)
+17
View File
@@ -0,0 +1,17 @@
import { Router } from 'express'
import { getAllRegions, getRegionDetails } from '../services/region'
const router = Router()
router.get('/all', async (_req, res) => {
const regions = await getAllRegions()
return res.status(200).send(regions)
})
router.get('/:id', async (req, res) => {
const id = parseInt(req.params.id)
const region = await getRegionDetails(id)
res.status(200).send(region)
})
export default router
+23
View File
@@ -0,0 +1,23 @@
import { prisma } from '../utils/db'
export const getAllRegions = async () => {
const result = await prisma.now_reg_coord.findMany({})
return result
}
export const getRegionDetails = async (id: number) => {
// TODO: Check if user has access
const result = await prisma.now_reg_coord.findUnique({
where: { reg_coord_id: id },
include: {
now_reg_coord_country: {},
now_reg_coord_people: {
include: {
com_people: true,
},
},
},
})
return result
}
+5
View File
@@ -21,3 +21,8 @@ export const createTestUser = async () => {
}
}
}
export const getAllUsers = async () => {
const result = await prisma.com_users.findMany({})
return result
}
+4
View File
@@ -4,6 +4,8 @@ import { NavBar } from './components/NavBar'
import { BrowserRouter, Route, Routes } from 'react-router-dom'
import { LocalityTable } from './components/Locality/LocalityTable'
import { ReferenceTable } from './components/Reference/ReferenceTable'
import { RegionTable } from './components/Region/RegionTable'
import { RegionDetails } from './components/Region/RegionDetails'
import { SpeciesTable } from './components/Species/SpeciesTable'
import { TimeUnitTable } from './components/TimeUnit/TimeUnitTable'
import { Login } from './components/Login'
@@ -25,6 +27,8 @@ const App = () => {
<Route element={<LocalityDetails />} path="/locality/:id" />
<Route element={<LocalityTable />} path="/locality/" />
<Route element={<ReferenceTable />} path="/reference/" />
<Route element={<RegionTable />} path="/region/" />
<Route element={<RegionDetails />} path="/region/:id" />
<Route element={<SpeciesDetails />} path="/species/:id" />
<Route element={<SpeciesTable />} path="/species/" />
<Route element={<TimeUnitTable />} path="/time-unit/" />
+4
View File
@@ -14,6 +14,9 @@ export type LocalityUpdate = Prisma.now_lau & { now_lr: Prisma.now_lr }
export type SpeciesUpdate = Prisma.now_sau & { now_lr: Prisma.now_sr }
export type Museum = Prisma.com_mlist
export type Project = Prisma.now_proj
export type Region = Prisma.now_reg_coord
export type RegionCoordinator = Prisma.now_reg_coord_people
export type RegionCountry = Prisma.now_reg_coord_country
export type SedimentaryStructure = Prisma.now_ss
export type LocalitySynonym = Prisma.now_syn_loc
export type SpeciesSynonym = Prisma.com_taxa_synonym
@@ -70,6 +73,7 @@ export type Reference = {
}
export type ReferenceDetails = Prisma.ref_ref
export type RegionDetails = Prisma.now_reg_coord & { now_reg_coord_people: Array<Editable<RegionCoordinator>> }
export type TimeUnit = {
low_bound: number
+2
View File
@@ -16,6 +16,8 @@ export const NavBar = () => {
{ title: 'Species', url: '/species' },
{ title: 'Reference', url: '/reference' },
{ title: 'Time unit', url: '/time-unit' },
{ title: 'Region', url: '/region' },
{ title: 'Admin', url: '/admin' },
]
if (user.username === null) pages.push({ title: 'Login', url: '/login' })
@@ -0,0 +1,22 @@
import { useParams } from 'react-router-dom'
import { useGetRegionDetailsQuery } from '../../redux/regionReducer'
import { CircularProgress } from '@mui/material'
import { DetailView, TabType } from '../DetailView/DetailView'
import { CoordinatorTab } from './Tabs/CoordinatorTab'
export const RegionDetails = () => {
const { id } = useParams()
const { isLoading, isError, data } = useGetRegionDetailsQuery(id!)
if (isError) return <div>Error loading data</div>
if (isLoading || !data) return <CircularProgress />
const tabs: TabType[] = [
{
title: 'Regional',
content: <CoordinatorTab />,
},
]
return <DetailView tabs={tabs} data={data} onWrite={() => {}} validator={() => null} />
}
@@ -0,0 +1,48 @@
import { useMemo, ReactNode } from 'react'
import { type MRT_ColumnDef } from 'material-react-table'
import { useGetAllRegionsQuery } from '../../redux/regionReducer'
import { Region } from '@/backendTypes'
import { TableView } from '../TableView/TableView'
import { Box, Tooltip } from '@mui/material'
const Cell = ({ renderedCellValue }: { renderedCellValue: ReactNode }) => (
<Tooltip title={renderedCellValue}>
<Box sx={{ maxWidth: '260px', WebkitMaskImage: 'linear-gradient(to right, #000 90%, transparent)' }}>
{renderedCellValue}
</Box>
</Tooltip>
)
export const RegionTable = ({ selectorFn }: { selectorFn?: (id: Region) => void }) => {
const regionQuery = useGetAllRegionsQuery()
const columns = useMemo<MRT_ColumnDef<Region>[]>(
() => [
{
id: 'id',
accessorKey: 'reg_coord_id',
header: 'Region Id',
size: 20,
},
{
accessorKey: 'region',
header: 'Region',
maxSize: 60,
},
],
[]
)
const checkRowRestriction = () => {
return false
}
return (
<TableView<Region>
selectorFn={selectorFn}
checkRowRestriction={checkRowRestriction}
idFieldName="reg_coord_id"
columns={columns}
data={regionQuery.data}
url="region"
/>
)
}
@@ -0,0 +1,54 @@
import { Editable, RegionDetails, RegionCoordinator, RegionCountry } from '@/backendTypes'
import { useDetailContext } from '@/components/DetailView/hooks'
import { Grouped } from '@/components/DetailView/common/tabLayoutHelpers'
import { MRT_ColumnDef } from 'material-react-table'
import { EditableTable } from '@/components/DetailView/common/EditableTable'
export const CoordinatorTab = () => {
const { editData, mode } = useDetailContext<RegionDetails>()
const coordinator: MRT_ColumnDef<RegionCoordinator>[] = [
{
accessorKey: 'com_people.surname',
header: 'Surname',
},
{
accessorKey: 'com_people.first_name',
header: 'First name',
},
{
accessorKey: 'com_people.organization',
header: 'Organization',
},
]
const country: MRT_ColumnDef<RegionCountry>[] = [
{
accessorKey: 'country',
header: 'Country',
},
]
// TODO: Selecting existing User or Country
return (
<>
<Grouped title="Regional Coordinators">
{mode === 'edit'}
<EditableTable<Editable<RegionCoordinator>, RegionDetails>
columns={coordinator}
data={editData.now_reg_coord_people}
editable
field="now_reg_coord_people"
/>
</Grouped>
<Grouped title="Countries">
{mode === 'edit'}
<EditableTable<Editable<RegionCountry>, RegionDetails>
columns={country}
data={editData.now_reg_coord_country}
editable
field="now_reg_coord_country"
/>
</Grouped>
</>
)
}
+19
View File
@@ -0,0 +1,19 @@
import { api } from './api'
import { Region, RegionDetails } from '@/backendTypes'
const regionsApi = api.injectEndpoints({
endpoints: builder => ({
getAllRegions: builder.query<Region[], void>({
query: () => ({
url: `/region/all`,
}),
}),
getRegionDetails: builder.query<RegionDetails, string>({
query: id => ({
url: `/region/${id}`,
}),
}),
}),
})
export const { useGetAllRegionsQuery, useGetRegionDetailsQuery } = regionsApi