new time bounds can now be created in time unit edit view

This commit is contained in:
juhanikat
2025-08-03 13:23:43 +03:00
parent 121e291652
commit 12cfb54426
3 changed files with 97 additions and 8 deletions
+56 -5
View File
@@ -1,5 +1,11 @@
import { Request, Router } from 'express'
import { EditDataType, EditMetaData, TimeUnitDetailsType, Role } from '../../../frontend/src/shared/types'
import {
EditDataType,
EditMetaData,
TimeUnitDetailsType,
Role,
TimeBoundDetailsType,
} from '../../../frontend/src/shared/types'
import { requireOneOf } from '../middlewares/authorizer'
import { getAllSequences } from '../services/sequence'
import {
@@ -8,9 +14,10 @@ import {
getTimeUnitLocalities,
validateEntireTimeUnit,
} from '../services/timeUnit'
import { getTimeBoundDetails } from '../services/timeBound'
import { getTimeBoundDetails, validateEntireTimeBound } from '../services/timeBound'
import { deleteTimeUnit, writeTimeUnit } from '../services/write/timeUnit'
import { fixBigInt } from '../utils/common'
import { writeTimeBound } from '../services/write/timeBound'
const router = Router()
@@ -45,22 +52,66 @@ router.put(
let validationUpBound = undefined
let validationLowBound = undefined
if (editedTimeUnit.up_bnd) {
let newUpBoundId = undefined
let newLowBoundId = undefined
// new up bound has been created in time unit edit view
if (!editedTimeUnit.up_bnd && editedTimeUnit.up_bound) {
const newUpBound = {
...editedTimeUnit.up_bound,
now_bau: [],
references: references,
} as EditDataType<TimeBoundDetailsType> & EditMetaData
const newUpBoundValidationErrors = await validateEntireTimeBound(newUpBound)
if (newUpBoundValidationErrors.length > 0) {
return res.status(403).send(newUpBoundValidationErrors)
}
const { result } = await writeTimeBound(newUpBound, undefined, references, req.user!.initials)
newUpBoundId = result
validationUpBound = (await getTimeBoundDetails(newUpBoundId)) ?? undefined
} else if (editedTimeUnit.up_bnd) {
validationUpBound = (await getTimeBoundDetails(editedTimeUnit.up_bnd)) ?? undefined
}
if (editedTimeUnit.low_bnd) {
// new low bound has been created in time unit edit view
if (!editedTimeUnit.low_bnd && editedTimeUnit.low_bound) {
const newLowBound = { ...editedTimeUnit.low_bound, now_bau: [], references: references }
const newLowBoundValidationErrors = await validateEntireTimeBound(newLowBound)
if (newLowBoundValidationErrors.length > 0) {
return res.status(403).send(newLowBoundValidationErrors)
}
const { result } = await writeTimeBound(newLowBound, undefined, references, req.user!.initials)
newLowBoundId = result
validationLowBound = (await getTimeBoundDetails(newLowBoundId)) ?? undefined
} else if (editedTimeUnit.low_bnd) {
validationLowBound = (await getTimeBoundDetails(editedTimeUnit.low_bnd)) ?? undefined
}
const validationErrors = await validateEntireTimeUnit({
...editedTimeUnit,
up_bnd: newUpBoundId ?? editedTimeUnit.up_bnd,
up_bound: validationUpBound,
low_bnd: newLowBoundId ?? editedTimeUnit.low_bnd,
low_bound: validationLowBound,
references: references,
})
if (validationErrors.length > 0) {
return res.status(403).send(validationErrors)
}
const { tu_name, errorObject } = await writeTimeUnit(editedTimeUnit, comment, references, req.user!.initials)
const { tu_name, errorObject } = await writeTimeUnit(
{
...editedTimeUnit,
up_bnd: newUpBoundId ?? editedTimeUnit.up_bnd,
low_bnd: newLowBoundId ?? editedTimeUnit.low_bnd,
},
comment,
references,
req.user!.initials
)
if (errorObject) {
return res.status(403).send(errorObject)
}
@@ -1,13 +1,15 @@
import { SequenceDetailsType, TimeUnitDetailsType } from '@/shared/types'
import { SequenceDetailsType, TimeBound, TimeUnitDetailsType } from '@/shared/types'
import { FieldWithTableSelection, TimeBoundSelection } from '@/components/DetailView/common/editingComponents'
import { emptyOption } from '@/components/DetailView/common/misc'
import { ArrayFrame, Grouped } from '@/components/DetailView/common/tabLayoutHelpers'
import { useDetailContext } from '@/components/DetailView/Context/DetailContext'
import { SequenceTable } from '@/components/Sequence/SequenceTable'
import { Box } from '@mui/material'
import { EditingForm } from '@/components/DetailView/common/EditingForm'
export const TimeUnitTab = () => {
const { textField, dropdown, data, editData, fieldsWithErrors, mode } = useDetailContext<TimeUnitDetailsType>()
const { textField, dropdown, data, editData, setEditData, fieldsWithErrors, mode } =
useDetailContext<TimeUnitDetailsType>()
const rankOptions = [
'Age',
@@ -66,6 +68,12 @@ export const TimeUnitTab = () => {
['Comment', low_bcomment],
]
const formFields: { name: string; label: string; required?: boolean }[] = [
{ name: 'b_name', label: 'Name', required: true },
{ name: 'age', label: 'Age (Ma)', required: true },
{ name: 'b_comment', label: 'Comment', required: false },
]
return (
<>
<ArrayFrame array={timeUnit} title="Time Unit" />
@@ -73,6 +81,21 @@ export const TimeUnitTab = () => {
<Grouped title="Upper Bound" error={'up_bnd' in fieldsWithErrors}>
{!mode.read && (
<Box display="flex" gap={1} marginBottom={'15px'}>
<EditingForm<TimeBound, TimeUnitDetailsType>
buttonText="Add new time bound"
formFields={formFields}
editAction={(newUpTimeBound: TimeBound) => {
setEditData({
...editData,
up_bnd: undefined,
up_bound: {
b_name: newUpTimeBound.b_name,
age: Number(newUpTimeBound.age),
b_comment: newUpTimeBound.b_comment,
},
})
}}
/>
<TimeBoundSelection key="up_bnd" targetField="up_bnd" />
</Box>
)}
@@ -81,6 +104,21 @@ export const TimeUnitTab = () => {
<Grouped title="Lower Bound" error={'low_bnd' in fieldsWithErrors}>
{!mode.read && (
<Box display="flex" gap={1} marginBottom={'15px'}>
<EditingForm<TimeBound, TimeUnitDetailsType>
buttonText="Add new time bound"
formFields={formFields}
editAction={(newLowTimeBound: TimeBound) => {
setEditData({
...editData,
low_bnd: undefined,
low_bound: {
b_name: newLowTimeBound.b_name,
age: Number(newLowTimeBound.age),
b_comment: newLowTimeBound.b_comment,
},
})
}}
/>
<TimeBoundSelection key="low_bnd" targetField="low_bnd" />
</Box>
)}
+1 -1
View File
@@ -32,7 +32,7 @@ const timeunitsApi = api.injectEndpoints({
body: { timeUnit },
}),
invalidatesTags: (result, _error, { tu_name }) =>
result ? [{ type: 'timeunit', id: tu_name }, 'timeunits'] : [],
result ? [{ type: 'timeunit', id: tu_name }, 'timeunits', 'timebounds'] : [],
}),
deleteTimeUnit: builder.mutation<void, string>({
query: id => ({