mirror of
https://github.com/nowcommunity/nowdatabase.git
synced 2026-10-12 19:13:52 +03:00
Add title (name of item) to each detail view, rename detailtypes
This commit is contained in:
+19
-2
@@ -10,6 +10,7 @@ import { SpeciesDetails } from './components/Species/SpeciesDetails'
|
||||
import { Page } from './components/Page'
|
||||
import { LocalityTable } from './components/Locality/LocalityTable'
|
||||
import { LocalityDetails } from './components/Locality/LocalityDetails'
|
||||
import { LocalityDetailsType, ReferenceDetailsType, SpeciesDetailsType, TimeUnitDetailsType } from './backendTypes'
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
@@ -30,6 +31,7 @@ const App = () => {
|
||||
detailView={<LocalityDetails />}
|
||||
viewName="locality"
|
||||
idFieldName="lid"
|
||||
createTitle={(loc: LocalityDetailsType) => `${loc.loc_name}`}
|
||||
/>
|
||||
}
|
||||
path="/locality/:id?"
|
||||
@@ -41,18 +43,33 @@ const App = () => {
|
||||
detailView={<SpeciesDetails />}
|
||||
viewName="species"
|
||||
idFieldName="species_id"
|
||||
createTitle={(species: SpeciesDetailsType) => `${species.species_name}`}
|
||||
/>
|
||||
}
|
||||
path="/species/:id?"
|
||||
/>
|
||||
<Route
|
||||
element={
|
||||
<Page tableView={<ReferenceTable />} detailView={null} viewName="reference" idFieldName="lid" />
|
||||
<Page
|
||||
tableView={<ReferenceTable />}
|
||||
detailView={null}
|
||||
viewName="reference"
|
||||
idFieldName="rid"
|
||||
createTitle={(ref: ReferenceDetailsType) => `${ref.issue}: ${ref.title_primary}`}
|
||||
/>
|
||||
}
|
||||
path="/reference/:id?"
|
||||
/>
|
||||
<Route
|
||||
element={<Page tableView={<TimeUnitTable />} detailView={null} viewName="time-unit" idFieldName="" />}
|
||||
element={
|
||||
<Page
|
||||
tableView={<TimeUnitTable />}
|
||||
detailView={null}
|
||||
viewName="time-unit"
|
||||
idFieldName="tu_name"
|
||||
createTitle={(tu: TimeUnitDetailsType) => `${tu.tu_display_name}`}
|
||||
/>
|
||||
}
|
||||
path="/time-unit/:id?"
|
||||
/>
|
||||
<Route element={<FrontPage />} path="/" />
|
||||
|
||||
Vendored
+4
-4
@@ -17,7 +17,7 @@ export type Project = Prisma.now_proj
|
||||
export type SedimentaryStructure = Prisma.now_ss
|
||||
export type LocalitySynonym = Prisma.now_syn_loc
|
||||
export type SpeciesSynonym = Prisma.com_taxa_synonym
|
||||
export type LocalityDetails = Omit<Prisma.now_loc, 'now_mus'> & { museums: Array<Editable<Museum>> } & {
|
||||
export type LocalityDetailsType = Omit<Prisma.now_loc, 'now_mus'> & { museums: Array<Editable<Museum>> } & {
|
||||
now_ls: Array<Editable<LocalitySpecies>>
|
||||
} & { now_plr: Array<Editable<LocalityProject>> } & { now_syn_loc: Array<Editable<LocalitySynonym>> } & {
|
||||
now_ss: Editable<SedimentaryStructure>[]
|
||||
@@ -34,7 +34,7 @@ export type Locality = {
|
||||
loc_status: boolean | null
|
||||
}
|
||||
|
||||
export type SpeciesDetails = Prisma.com_species & { now_ls: Array<Editable<SpeciesLocality>> } & {
|
||||
export type SpeciesDetailsType = Prisma.com_species & { now_ls: Array<Editable<SpeciesLocality>> } & {
|
||||
com_taxa_synonym: Array<Editable<SpeciesSynonym>>
|
||||
} & { now_sau: Array<Editable<SpeciesUpdate>> }
|
||||
|
||||
@@ -69,7 +69,7 @@ export type Reference = {
|
||||
title_secondary: string
|
||||
}
|
||||
|
||||
export type ReferenceDetails = Prisma.ref_ref
|
||||
export type ReferenceDetailsType = Prisma.ref_ref
|
||||
|
||||
export type TimeUnit = {
|
||||
low_bound: number
|
||||
@@ -89,4 +89,4 @@ export type TimeUnit = {
|
||||
rank: string
|
||||
}
|
||||
|
||||
export type TimeUnitDetails = Prisma.now_time_unit
|
||||
export type TimeUnitDetailsType = Prisma.now_time_unit
|
||||
|
||||
@@ -3,18 +3,23 @@ import ArrowBackIcon from '@mui/icons-material/ArrowBack'
|
||||
import ArrowForwardIcon from '@mui/icons-material/ArrowForward'
|
||||
import { useDetailContext } from './Context/DetailContext'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useContext } from 'react'
|
||||
import { PageContext } from '../Page'
|
||||
import { usePageContext } from '../Page'
|
||||
|
||||
export const DetailBrowser = <T,>() => {
|
||||
const { data } = useDetailContext<T>()
|
||||
export const DetailBrowser = <T extends object>() => {
|
||||
const { data, mode } = useDetailContext<T>()
|
||||
const navigate = useNavigate()
|
||||
const { idList, idFieldName, viewName } = useContext(PageContext)
|
||||
const { idList, idFieldName, viewName, createTitle } = usePageContext<T>()
|
||||
const idListExists = idList?.length > 0
|
||||
const currentIndex = idList.indexOf((data as { [key: string]: string })[idFieldName as string])
|
||||
const currentIndex = idList.indexOf((data as { [key: string]: string })[idFieldName])
|
||||
const nextIndex = currentIndex + 1
|
||||
const previousIndex = currentIndex - 1
|
||||
|
||||
const getText = () => {
|
||||
if (mode.read) {
|
||||
return `Viewing ${viewName}: ${createTitle(data)}`
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@@ -27,7 +32,7 @@ export const DetailBrowser = <T,>() => {
|
||||
gap: '1em',
|
||||
}}
|
||||
>
|
||||
<div> Viewing details of a {viewName}</div>
|
||||
<div>{getText()}</div>
|
||||
{idListExists && (
|
||||
<div>
|
||||
{previousIndex >= 0 && (
|
||||
|
||||
@@ -84,7 +84,7 @@ export const DetailView = <T extends object>({
|
||||
elevation: 5,
|
||||
}
|
||||
|
||||
const refSelectionView = (
|
||||
const stagingView = (
|
||||
<Paper {...paperProps}>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', rowGap: '1em' }}>
|
||||
<StagingView />
|
||||
@@ -132,7 +132,7 @@ export const DetailView = <T extends object>({
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
{mode.staging ? refSelectionView : tabView}
|
||||
{mode.staging ? stagingView : tabView}
|
||||
</DetailContextProvider>
|
||||
</Stack>
|
||||
)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { LocalityDetails } from '@/backendTypes'
|
||||
import { LocalityDetailsType } from '@/backendTypes'
|
||||
import { ArrayFrame } from './common/tabLayoutHelpers'
|
||||
import { useDetailContext } from './Context/DetailContext'
|
||||
|
||||
export const StagingView = () => {
|
||||
const { bigTextField } = useDetailContext<LocalityDetails>()
|
||||
const { bigTextField } = useDetailContext<LocalityDetailsType>()
|
||||
|
||||
const array = [
|
||||
['Date', new Date().toLocaleDateString('en-CA')],
|
||||
|
||||
@@ -2,8 +2,7 @@ import { useNavigate } from 'react-router-dom'
|
||||
import { Button } from '@mui/material'
|
||||
import ArrowBackIcon from '@mui/icons-material/ArrowBack'
|
||||
import SaveIcon from '@mui/icons-material/Save'
|
||||
import { useContext } from 'react'
|
||||
import { PageContext } from '../Page'
|
||||
import { usePageContext } from '../Page'
|
||||
import { useDetailContext } from './Context/DetailContext'
|
||||
|
||||
export const WriteButton = <T,>({ onWrite, text }: { onWrite: (editData: T) => void; text?: string }) => {
|
||||
@@ -29,7 +28,7 @@ export const WriteButton = <T,>({ onWrite, text }: { onWrite: (editData: T) => v
|
||||
|
||||
export const ReturnButton = () => {
|
||||
const navigate = useNavigate()
|
||||
const { tableUrl } = useContext(PageContext)
|
||||
const { tableUrl } = usePageContext()
|
||||
const { mode, setMode } = useDetailContext()
|
||||
if (mode.staging) {
|
||||
return (
|
||||
|
||||
@@ -12,7 +12,7 @@ import { ProjectTab } from './Tabs/ProjectTab'
|
||||
import { SpeciesTab } from './Tabs/SpeciesTab'
|
||||
import { TaphonomyTab } from './Tabs/TaphonomyTab'
|
||||
import { UpdateTab } from './Tabs/UpdateTab'
|
||||
import { LocalityDetails as LocalityDetailsType } from '@/backendTypes'
|
||||
import { LocalityDetailsType } from '@/backendTypes'
|
||||
import { validateLocality } from '@/validators/locality'
|
||||
|
||||
export const LocalityDetails = () => {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { LocalityDetails } from '@/backendTypes'
|
||||
import { LocalityDetailsType } from '@/backendTypes'
|
||||
import { ArrayFrame, HalfFrames } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
|
||||
export const AgeTab = () => {
|
||||
const { textField, radioSelection, dropdown, bigTextField } = useDetailContext<LocalityDetails>()
|
||||
const { textField, radioSelection, dropdown, bigTextField } = useDetailContext<LocalityDetailsType>()
|
||||
|
||||
const fracOptions = [
|
||||
{ value: '', display: 'None' },
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { LocalityDetails } from '@/backendTypes'
|
||||
import { LocalityDetailsType } from '@/backendTypes'
|
||||
import { ArrayFrame, HalfFrames } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
|
||||
export const ClimateTab = () => {
|
||||
const { textField, dropdown, bigTextField } = useDetailContext<LocalityDetails>()
|
||||
const { textField, dropdown, bigTextField } = useDetailContext<LocalityDetailsType>()
|
||||
|
||||
const climateTypeOptions = [
|
||||
'',
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { LocalityDetails } from '@/backendTypes'
|
||||
import { LocalityDetailsType } from '@/backendTypes'
|
||||
import { ArrayFrame } from '../../DetailView/common/tabLayoutHelpers'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
|
||||
export const EcometricsTab = () => {
|
||||
const { textField } = useDetailContext<LocalityDetails>()
|
||||
const { textField } = useDetailContext<LocalityDetailsType>()
|
||||
|
||||
const ecometrics = [
|
||||
['Estimate of annual precipitation (mm)', textField('estimate_precip')],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Editable, LocalityDetails, SedimentaryStructure, SedimentaryStructureValues } from '@/backendTypes'
|
||||
import { Editable, LocalityDetailsType, SedimentaryStructure, SedimentaryStructureValues } from '@/backendTypes'
|
||||
import { EditableTable } from '@/components/DetailView/common/EditableTable'
|
||||
import { SelectingTable } from '@/components/DetailView/common/SelectingTable'
|
||||
import { ArrayFrame, HalfFrames, Grouped } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
@@ -7,7 +7,7 @@ import { useGetAllSedimentaryStructuresQuery } from '@/redux/sedimentaryStructur
|
||||
import { MRT_ColumnDef } from 'material-react-table'
|
||||
|
||||
export const LithologyTab = () => {
|
||||
const { textField, dropdown, setEditData, bigTextField } = useDetailContext<LocalityDetails>()
|
||||
const { textField, dropdown, setEditData, bigTextField } = useDetailContext<LocalityDetailsType>()
|
||||
const { data: sedimentaryStructuresData } = useGetAllSedimentaryStructuresQuery()
|
||||
|
||||
const rockTypeOptions = [
|
||||
@@ -159,7 +159,7 @@ export const LithologyTab = () => {
|
||||
['Comments', bigTextField('depo_comm')],
|
||||
]
|
||||
|
||||
const { editData, mode } = useDetailContext<LocalityDetails>()
|
||||
const { editData, mode } = useDetailContext<LocalityDetailsType>()
|
||||
|
||||
const columns: MRT_ColumnDef<SedimentaryStructure>[] = [
|
||||
{
|
||||
@@ -185,7 +185,7 @@ export const LithologyTab = () => {
|
||||
<Grouped title="Sedimentary Structure & Taphonomic Detail">
|
||||
{!mode.read && (
|
||||
<>
|
||||
<SelectingTable<SedimentaryStructureValues, LocalityDetails>
|
||||
<SelectingTable<SedimentaryStructureValues, LocalityDetailsType>
|
||||
buttonText="Add existing sedimentary structure"
|
||||
columns={selectingTableColumns}
|
||||
data={sedimentaryStructuresData}
|
||||
@@ -201,7 +201,11 @@ export const LithologyTab = () => {
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<EditableTable<Editable<SedimentaryStructure>, LocalityDetails> columns={columns} editable field="now_ss" />
|
||||
<EditableTable<Editable<SedimentaryStructure>, LocalityDetailsType>
|
||||
columns={columns}
|
||||
editable
|
||||
field="now_ss"
|
||||
/>
|
||||
</Grouped>
|
||||
<ArrayFrame half array={depositionalContext} title="Depositional Context" />
|
||||
</HalfFrames>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Editable, LocalityDetails, LocalitySynonym } from '@/backendTypes'
|
||||
import { Editable, LocalityDetailsType, LocalitySynonym } from '@/backendTypes'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
import { Grouped, ArrayFrame, HalfFrames } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { Box, TextField } from '@mui/material'
|
||||
@@ -8,7 +8,7 @@ import { EditableTable } from '@/components/DetailView/common/EditableTable'
|
||||
import { EditingModal } from '@/components/DetailView/common/EditingModal'
|
||||
|
||||
export const LocalityTab = () => {
|
||||
const { data, textField, radioSelection, dropdown, mode, bigTextField } = useDetailContext<LocalityDetails>()
|
||||
const { data, textField, radioSelection, dropdown, mode, bigTextField } = useDetailContext<LocalityDetailsType>()
|
||||
|
||||
const approximateCoordinatesOptions = ['', { display: 'No', value: '0' }, { display: 'Yes', value: '1' }]
|
||||
const generalLocalityOptions = ['', { display: 'No', value: 'n' }, { display: 'Yes', value: 'y' }]
|
||||
@@ -94,7 +94,7 @@ export const LocalityTab = () => {
|
||||
|
||||
<Grouped title="Synonyms">
|
||||
{!mode.read && editingModal}
|
||||
<EditableTable<Editable<LocalitySynonym>, LocalityDetails> columns={columns} editable field="now_syn_loc" />
|
||||
<EditableTable<Editable<LocalitySynonym>, LocalityDetailsType> columns={columns} editable field="now_syn_loc" />
|
||||
</Grouped>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Editable, LocalityDetails, Museum } from '@/backendTypes'
|
||||
import { Editable, LocalityDetailsType, Museum } from '@/backendTypes'
|
||||
import { EditableTable } from '@/components/DetailView/common/EditableTable'
|
||||
import { EditingForm } from '@/components/DetailView/common/EditingForm'
|
||||
import { Grouped } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
@@ -9,7 +9,7 @@ import { Box, CircularProgress } from '@mui/material'
|
||||
import { MRT_ColumnDef } from 'material-react-table'
|
||||
|
||||
export const MuseumTab = () => {
|
||||
const { mode } = useDetailContext<LocalityDetails>()
|
||||
const { mode } = useDetailContext<LocalityDetailsType>()
|
||||
const { data: museumData, isError } = useGetAllMuseumsQuery()
|
||||
|
||||
if (isError) return 'Error loading museums.'
|
||||
@@ -48,12 +48,12 @@ export const MuseumTab = () => {
|
||||
<Grouped title="Museums">
|
||||
{!mode.read && (
|
||||
<Box display="flex" gap={1}>
|
||||
<EditingForm<Museum, LocalityDetails>
|
||||
<EditingForm<Museum, LocalityDetailsType>
|
||||
buttonText="Add new museum"
|
||||
formFields={formFields}
|
||||
arrayFieldName="museums"
|
||||
/>
|
||||
<SelectingTable<Museum, LocalityDetails>
|
||||
<SelectingTable<Museum, LocalityDetailsType>
|
||||
buttonText="Add existing museum"
|
||||
data={museumData}
|
||||
columns={columns}
|
||||
@@ -62,7 +62,7 @@ export const MuseumTab = () => {
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
<EditableTable<Editable<Museum>, LocalityDetails> columns={columns} editable field="museums" />
|
||||
<EditableTable<Editable<Museum>, LocalityDetailsType> columns={columns} editable field="museums" />
|
||||
</Grouped>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Editable, LocalityDetails, LocalityProject } from '@/backendTypes'
|
||||
import { Editable, LocalityDetailsType, LocalityProject } from '@/backendTypes'
|
||||
import { EditableTable } from '@/components/DetailView/common/EditableTable'
|
||||
import { Grouped } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { EditingModal } from '@/components/DetailView/common/EditingModal'
|
||||
@@ -8,7 +8,7 @@ import { MRT_ColumnDef } from 'material-react-table'
|
||||
import { useForm } from 'react-hook-form'
|
||||
|
||||
export const ProjectTab = () => {
|
||||
const { mode } = useDetailContext<LocalityDetails>()
|
||||
const { mode } = useDetailContext<LocalityDetailsType>()
|
||||
const {
|
||||
register,
|
||||
formState: { errors },
|
||||
@@ -58,7 +58,7 @@ export const ProjectTab = () => {
|
||||
return (
|
||||
<Grouped title="Projects">
|
||||
{!mode.read && editingModal}
|
||||
<EditableTable<Editable<LocalityProject>, LocalityDetails> columns={columns} editable field="now_plr" />
|
||||
<EditableTable<Editable<LocalityProject>, LocalityDetailsType> columns={columns} editable field="now_plr" />
|
||||
</Grouped>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Editable, LocalityDetails, LocalitySpecies } from '@/backendTypes'
|
||||
import { Editable, LocalityDetailsType, LocalitySpecies } from '@/backendTypes'
|
||||
import { EditableTable } from '@/components/DetailView/common/EditableTable'
|
||||
import { EditingModal } from '@/components/DetailView/common/EditingModal'
|
||||
import { Grouped } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
@@ -8,7 +8,7 @@ import { MRT_ColumnDef } from 'material-react-table'
|
||||
import { useForm } from 'react-hook-form'
|
||||
|
||||
export const SpeciesTab = () => {
|
||||
const { mode } = useDetailContext<LocalityDetails>()
|
||||
const { mode } = useDetailContext<LocalityDetailsType>()
|
||||
const {
|
||||
register,
|
||||
formState: { errors },
|
||||
@@ -79,7 +79,7 @@ export const SpeciesTab = () => {
|
||||
return (
|
||||
<Grouped title="Species">
|
||||
{!mode.read && editingModal}
|
||||
<EditableTable<Editable<LocalitySpecies>, LocalityDetails> columns={columns} editable field="now_ls" />
|
||||
<EditableTable<Editable<LocalitySpecies>, LocalityDetailsType> columns={columns} editable field="now_ls" />
|
||||
</Grouped>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Editable, LocalityDetails, CollectingMethod } from '@/backendTypes'
|
||||
import { Editable, LocalityDetailsType, CollectingMethod } from '@/backendTypes'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
import { Grouped, ArrayFrame, HalfFrames } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { Box, TextField } from '@mui/material'
|
||||
@@ -8,8 +8,8 @@ import { EditableTable } from '@/components/DetailView/common/EditableTable'
|
||||
import { EditingModal } from '@/components/DetailView/common/EditingModal'
|
||||
|
||||
export const TaphonomyTab = () => {
|
||||
const { textField, dropdown } = useDetailContext<LocalityDetails>()
|
||||
const { mode } = useDetailContext<LocalityDetails>()
|
||||
const { textField, dropdown } = useDetailContext<LocalityDetailsType>()
|
||||
const { mode } = useDetailContext<LocalityDetailsType>()
|
||||
|
||||
const assemblageFormationOptions = [
|
||||
'',
|
||||
@@ -158,7 +158,7 @@ export const TaphonomyTab = () => {
|
||||
<HalfFrames>
|
||||
<Grouped title="Collecting Methods">
|
||||
{!mode.read && editingModal}
|
||||
<EditableTable<Editable<CollectingMethod>, LocalityDetails>
|
||||
<EditableTable<Editable<CollectingMethod>, LocalityDetailsType>
|
||||
columns={columns}
|
||||
editable
|
||||
field="now_coll_meth"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Editable, LocalityDetails, LocalityUpdate } from '@/backendTypes'
|
||||
import { Editable, LocalityDetailsType, LocalityUpdate } from '@/backendTypes'
|
||||
import { EditableTable } from '@/components/DetailView/common/EditableTable'
|
||||
import { Grouped } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { Box } from '@mui/material'
|
||||
@@ -33,7 +33,7 @@ export const UpdateTab = () => {
|
||||
|
||||
return (
|
||||
<Grouped title="Updates">
|
||||
<EditableTable<Editable<LocalityUpdate>, LocalityDetails> columns={columns} editable field="now_lau" />
|
||||
<EditableTable<Editable<LocalityUpdate>, LocalityDetailsType> columns={columns} editable field="now_lau" />
|
||||
</Grouped>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,32 +1,29 @@
|
||||
/* eslint-disable react-refresh/only-export-components */
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { ReactNode, createContext, useState } from 'react'
|
||||
import { ReactNode, createContext, useContext, useState, Context } from 'react'
|
||||
|
||||
export type PageContextType<T> = {
|
||||
idList: string[]
|
||||
setIdList: (ids: string[]) => void
|
||||
idFieldName: keyof T
|
||||
idFieldName: string
|
||||
viewName: string
|
||||
tableUrl: string
|
||||
setTableUrl: (newUrl: string) => void
|
||||
createTitle: (data: T) => string
|
||||
}
|
||||
|
||||
export const PageContext = createContext<PageContextType<{ [key: string | number | symbol]: unknown }>>({
|
||||
idFieldName: null!,
|
||||
idList: [],
|
||||
setIdList: () => {},
|
||||
viewName: null!,
|
||||
tableUrl: '',
|
||||
setTableUrl: () => {},
|
||||
})
|
||||
export const PageContext = createContext<PageContextType<unknown>>(null!)
|
||||
|
||||
export const PageContextProvider = <T extends object>({
|
||||
children,
|
||||
idFieldName,
|
||||
viewName,
|
||||
createTitle,
|
||||
}: {
|
||||
children: ReactNode | ReactNode[]
|
||||
idFieldName: keyof T
|
||||
idFieldName: string
|
||||
viewName: string
|
||||
createTitle: (data: T) => string
|
||||
}) => {
|
||||
const [idList, setIdList] = useState<string[]>([])
|
||||
const [tableUrl, setTableUrl] = useState<string>(`/${viewName}`)
|
||||
@@ -40,6 +37,7 @@ export const PageContextProvider = <T extends object>({
|
||||
viewName,
|
||||
tableUrl,
|
||||
setTableUrl: (newUrl: string) => setTableUrl(newUrl),
|
||||
createTitle: (data: unknown) => createTitle(data as T),
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
@@ -47,20 +45,28 @@ export const PageContextProvider = <T extends object>({
|
||||
)
|
||||
}
|
||||
|
||||
export const Page = <T extends object>({
|
||||
export const usePageContext = <T extends object>() => {
|
||||
const pageContext = useContext<PageContextType<T>>(PageContext as unknown as Context<PageContextType<T>>)
|
||||
if (!pageContext) throw new Error('detailContext lacking provider')
|
||||
return pageContext
|
||||
}
|
||||
|
||||
export const Page = <T extends Record<string, unknown>>({
|
||||
tableView,
|
||||
detailView,
|
||||
idFieldName,
|
||||
viewName,
|
||||
createTitle,
|
||||
}: {
|
||||
tableView: ReactNode
|
||||
detailView: ReactNode
|
||||
idFieldName: keyof T
|
||||
viewName: string
|
||||
createTitle: (data: T) => string
|
||||
}) => {
|
||||
const { id } = useParams()
|
||||
return (
|
||||
<PageContextProvider<T> idFieldName={idFieldName} viewName={viewName}>
|
||||
<PageContextProvider<T> idFieldName={idFieldName as string} viewName={viewName} createTitle={createTitle}>
|
||||
{id ? detailView : tableView}
|
||||
</PageContextProvider>
|
||||
)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { SpeciesDetails } from '@/backendTypes'
|
||||
import { SpeciesDetailsType } from '@/backendTypes'
|
||||
import { ArrayFrame } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
|
||||
export const DietTab = () => {
|
||||
const { dropdown } = useDetailContext<SpeciesDetails>()
|
||||
const { dropdown } = useDetailContext<SpeciesDetailsType>()
|
||||
|
||||
const diet1Options = ['', 'animal', 'omnivore', 'plant']
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Editable, SpeciesDetails, SpeciesLocality } from '@/backendTypes'
|
||||
import { Editable, SpeciesDetailsType, SpeciesLocality } from '@/backendTypes'
|
||||
import { EditableTable } from '@/components/DetailView/common/EditableTable'
|
||||
import { EditingModal } from '@/components/DetailView/common/EditingModal'
|
||||
import { Grouped } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
@@ -8,7 +8,7 @@ import { MRT_ColumnDef } from 'material-react-table'
|
||||
import { useForm } from 'react-hook-form'
|
||||
|
||||
export const LocalitySpeciesTab = () => {
|
||||
const { mode } = useDetailContext<SpeciesDetails>()
|
||||
const { mode } = useDetailContext<SpeciesDetailsType>()
|
||||
const {
|
||||
register,
|
||||
formState: { errors },
|
||||
@@ -153,7 +153,7 @@ export const LocalitySpeciesTab = () => {
|
||||
return (
|
||||
<Grouped title="Locality-Species Information">
|
||||
{!mode.read && editingModal}
|
||||
<EditableTable<Editable<SpeciesLocality>, SpeciesDetails> columns={columns} editable field="now_ls" />
|
||||
<EditableTable<Editable<SpeciesLocality>, SpeciesDetailsType> columns={columns} editable field="now_ls" />
|
||||
</Grouped>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Editable, Locality, SpeciesDetails } from '@/backendTypes'
|
||||
import { Editable, Locality, SpeciesDetailsType } from '@/backendTypes'
|
||||
import { Grouped } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { EditableTable } from '@/components/DetailView/common/EditableTable'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
@@ -7,7 +7,7 @@ import { Box, CircularProgress } from '@mui/material'
|
||||
import { SelectingTable } from '@/components/DetailView/common/SelectingTable'
|
||||
|
||||
export const LocalityTab = () => {
|
||||
const { data, editData, mode } = useDetailContext<SpeciesDetails>()
|
||||
const { data, editData, mode } = useDetailContext<SpeciesDetailsType>()
|
||||
const { data: localitiesData, isError } = useGetAllLocalitiesQuery()
|
||||
|
||||
if (isError) return 'Error loading Localities.'
|
||||
@@ -49,7 +49,7 @@ export const LocalityTab = () => {
|
||||
// const editingModal = <EditingForm buttonText="Add new locality" formFields={formFields} arrayFieldName="now_ls" />
|
||||
|
||||
const selectingTable = (
|
||||
<SelectingTable<Editable<Locality>, SpeciesDetails>
|
||||
<SelectingTable<Editable<Locality>, SpeciesDetailsType>
|
||||
buttonText="Add existing locality"
|
||||
columns={columns}
|
||||
data={localitiesData}
|
||||
@@ -65,7 +65,7 @@ export const LocalityTab = () => {
|
||||
{selectingTable}
|
||||
</Box>
|
||||
)}
|
||||
<EditableTable<Editable<Locality>, SpeciesDetails>
|
||||
<EditableTable<Editable<Locality>, SpeciesDetailsType>
|
||||
columns={columns}
|
||||
editTableData={editData.now_ls.map(item =>
|
||||
!item.now_loc ? (item as unknown as Editable<Locality>) : item.now_loc
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { SpeciesDetails } from '@/backendTypes'
|
||||
import { SpeciesDetailsType } from '@/backendTypes'
|
||||
import { ArrayFrame, HalfFrames } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
|
||||
export const LocomotionTab = () => {
|
||||
const { dropdown } = useDetailContext<SpeciesDetails>()
|
||||
const { dropdown } = useDetailContext<SpeciesDetailsType>()
|
||||
|
||||
const feedingHabitat1Options = ['', 'ae', 'aq', 'sa', 'te']
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { SpeciesDetails } from '@/backendTypes'
|
||||
import { SpeciesDetailsType } from '@/backendTypes'
|
||||
import { ArrayFrame, HalfFrames } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { useDetailContext } from '@components/DetailView/Context/DetailContext'
|
||||
|
||||
export const SizeTab = () => {
|
||||
const { dropdown, textField } = useDetailContext<SpeciesDetails>()
|
||||
const { dropdown, textField } = useDetailContext<SpeciesDetailsType>()
|
||||
|
||||
const snoutVentLengthOptions = ['', '<10cm', '10cm-1m', '1m-2m', '2m-5m', '>5m']
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Editable, SpeciesDetails, SpeciesSynonym } from '@/backendTypes'
|
||||
import { Editable, SpeciesDetailsType, SpeciesSynonym } from '@/backendTypes'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
import { Grouped } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { Box, TextField } from '@mui/material'
|
||||
@@ -8,7 +8,7 @@ import { EditableTable } from '@/components/DetailView/common/EditableTable'
|
||||
import { EditingModal } from '@/components/DetailView/common/EditingModal'
|
||||
|
||||
export const SynonymTab = () => {
|
||||
const { mode } = useDetailContext<SpeciesDetails>()
|
||||
const { mode } = useDetailContext<SpeciesDetailsType>()
|
||||
const {
|
||||
register,
|
||||
formState: { errors },
|
||||
@@ -49,7 +49,11 @@ export const SynonymTab = () => {
|
||||
<>
|
||||
<Grouped title="Synonyms">
|
||||
{!mode.read && editingModal}
|
||||
<EditableTable<Editable<SpeciesSynonym>, SpeciesDetails> columns={columns} editable field="com_taxa_synonym" />
|
||||
<EditableTable<Editable<SpeciesSynonym>, SpeciesDetailsType>
|
||||
columns={columns}
|
||||
editable
|
||||
field="com_taxa_synonym"
|
||||
/>
|
||||
</Grouped>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { SpeciesDetails } from '@/backendTypes'
|
||||
import { SpeciesDetailsType } from '@/backendTypes'
|
||||
import { ArrayFrame, HalfFrames } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
|
||||
export const TaxonomyTab = () => {
|
||||
const { textField, dropdown, bigTextField } = useDetailContext<SpeciesDetails>()
|
||||
const { textField, dropdown, bigTextField } = useDetailContext<SpeciesDetailsType>()
|
||||
|
||||
const taxonStatusOptions = [
|
||||
'',
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { SpeciesDetails } from '@/backendTypes'
|
||||
import { SpeciesDetailsType } from '@/backendTypes'
|
||||
import { ArrayFrame, HalfFrames } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
|
||||
|
||||
export const TeethTab = () => {
|
||||
const { dropdown, textField } = useDetailContext<SpeciesDetails>()
|
||||
const { dropdown, textField } = useDetailContext<SpeciesDetailsType>()
|
||||
|
||||
const toothShapeMulticuspidOptions = [
|
||||
{ value: '', display: 'None' },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Editable, SpeciesDetails, SpeciesUpdate } from '@/backendTypes'
|
||||
import { Editable, SpeciesDetailsType, SpeciesUpdate } from '@/backendTypes'
|
||||
import { EditableTable } from '@/components/DetailView/common/EditableTable'
|
||||
import { Grouped } from '@/components/DetailView/common/tabLayoutHelpers'
|
||||
import { Box } from '@mui/material'
|
||||
@@ -33,7 +33,7 @@ export const UpdateTab = () => {
|
||||
|
||||
return (
|
||||
<Grouped title="Updates">
|
||||
<EditableTable<Editable<SpeciesUpdate>, SpeciesDetails> columns={columns} editable field="now_sau" />
|
||||
<EditableTable<Editable<SpeciesUpdate>, SpeciesDetailsType> columns={columns} editable field="now_sau" />
|
||||
</Grouped>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useContext, useEffect, useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import {
|
||||
type MRT_ColumnFiltersState,
|
||||
type MRT_ColumnDef,
|
||||
@@ -12,7 +12,7 @@ import { CircularProgress } from '@mui/material'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { renderCustomToolbar, renderCustomToolbarModalVersion } from './helpers'
|
||||
import { ActionComponent } from './ActionComponent'
|
||||
import { PageContext } from '../Page'
|
||||
import { usePageContext } from '../Page'
|
||||
|
||||
type TableStateInUrl = 'sorting' | 'columnfilters' | 'pagination'
|
||||
|
||||
@@ -45,7 +45,7 @@ export const TableView = <T extends MRT_RowData>({
|
||||
const [columnFilters, setColumnFilters] = useState<MRT_ColumnFiltersState>([])
|
||||
const [sorting, setSorting] = useState<MRT_SortingState>([])
|
||||
const [pagination, setPagination] = useState<MRT_PaginationState>(defaultPagination)
|
||||
const { setIdList, setTableUrl } = useContext(PageContext)
|
||||
const { setIdList, setTableUrl } = usePageContext<T>()
|
||||
const loadStateFromUrl = (state: TableStateInUrl, defaultState: [] | MRT_PaginationState) => {
|
||||
const searchParams = new URLSearchParams(location.search)
|
||||
const stateFromUrl = searchParams.get(state)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { api } from './api'
|
||||
import { Locality, LocalityDetails } from '@/backendTypes'
|
||||
import { Locality, LocalityDetailsType } from '@/backendTypes'
|
||||
|
||||
const localitiesApi = api.injectEndpoints({
|
||||
endpoints: builder => ({
|
||||
@@ -8,13 +8,13 @@ const localitiesApi = api.injectEndpoints({
|
||||
url: `/locality/all`,
|
||||
}),
|
||||
}),
|
||||
getLocalityDetails: builder.query<LocalityDetails, string>({
|
||||
getLocalityDetails: builder.query<LocalityDetailsType, string>({
|
||||
query: id => ({
|
||||
url: `/locality/${id}`,
|
||||
}),
|
||||
providesTags: result => (result ? [{ type: 'locality', id: result.lid }] : []),
|
||||
}),
|
||||
editLocality: builder.mutation<LocalityDetails, LocalityDetails>({
|
||||
editLocality: builder.mutation<LocalityDetailsType, LocalityDetailsType>({
|
||||
query: locality => ({
|
||||
url: `/locality/`,
|
||||
method: 'PUT',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { api } from './api'
|
||||
import { Reference, ReferenceDetails } from '@/backendTypes'
|
||||
import { Reference, ReferenceDetailsType } from '@/backendTypes'
|
||||
|
||||
const referencesApi = api.injectEndpoints({
|
||||
endpoints: builder => ({
|
||||
@@ -8,7 +8,7 @@ const referencesApi = api.injectEndpoints({
|
||||
url: `/reference/all`,
|
||||
}),
|
||||
}),
|
||||
getReferenceDetails: builder.query<ReferenceDetails, string>({
|
||||
getReferenceDetails: builder.query<ReferenceDetailsType, string>({
|
||||
query: id => ({
|
||||
url: `/reference/${id}`,
|
||||
}),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { api } from './api'
|
||||
import { Species, SpeciesDetails } from '@/backendTypes'
|
||||
import { Species, SpeciesDetailsType } from '@/backendTypes'
|
||||
|
||||
const speciesApi = api.injectEndpoints({
|
||||
endpoints: builder => ({
|
||||
@@ -8,7 +8,7 @@ const speciesApi = api.injectEndpoints({
|
||||
url: `/species/all`,
|
||||
}),
|
||||
}),
|
||||
getSpeciesDetails: builder.query<SpeciesDetails, string>({
|
||||
getSpeciesDetails: builder.query<SpeciesDetailsType, string>({
|
||||
query: id => ({
|
||||
url: `/species/${id}`,
|
||||
}),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { api } from './api'
|
||||
import { TimeUnit, TimeUnitDetails } from '@/backendTypes'
|
||||
import { TimeUnit, TimeUnitDetailsType } from '@/backendTypes'
|
||||
|
||||
const timeunitsApi = api.injectEndpoints({
|
||||
endpoints: builder => ({
|
||||
@@ -8,7 +8,7 @@ const timeunitsApi = api.injectEndpoints({
|
||||
url: `/time-unit/all`,
|
||||
}),
|
||||
}),
|
||||
getTimeUnitDetails: builder.query<TimeUnitDetails, string>({
|
||||
getTimeUnitDetails: builder.query<TimeUnitDetailsType, string>({
|
||||
query: id => ({
|
||||
url: `/time-unit/${id}`,
|
||||
}),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { LocalityDetails } from '../backendTypes'
|
||||
import { LocalityDetailsType } from '../backendTypes'
|
||||
import { Validators, validator } from './validator'
|
||||
|
||||
export const validateLocality = (editData: LocalityDetails, fieldName: keyof LocalityDetails) => {
|
||||
const validators: Validators<Partial<LocalityDetails>> = {
|
||||
export const validateLocality = (editData: LocalityDetailsType, fieldName: keyof LocalityDetailsType) => {
|
||||
const validators: Validators<Partial<LocalityDetailsType>> = {
|
||||
bfa_max_abs: {
|
||||
name: 'Basis for age (absolute)',
|
||||
asNumber: (num: number) => {
|
||||
|
||||
Reference in New Issue
Block a user