Add delete routes & services for rest of data types.

This commit is contained in:
ShootingStar91
2024-09-01 15:25:39 +03:00
parent cf59d7cd4c
commit 1a3dd84e02
13 changed files with 183 additions and 39 deletions
+7 -1
View File
@@ -2,7 +2,7 @@ import { Request, Router } from 'express'
import { getAllTimeBounds, getTimeBoundDetails, getTimeBoundTimeUnits } from '../services/timeBound'
import { fixBigInt } from '../utils/common'
import { EditDataType, EditMetaData, TimeBoundDetailsType } from '../../../frontend/src/backendTypes'
import { writeTimeBound } from '../services/write/timeBound'
import { deleteTimeUnit, writeTimeBound } from '../services/write/timeBound'
import { requireOneOf } from '../middlewares/authorizer'
import { Role } from '../../../frontend/src/types'
@@ -36,4 +36,10 @@ router.put(
}
)
router.delete('/:id', requireOneOf([Role.Admin, Role.EditUnrestricted]), async (req, res) => {
const id = parseInt(req.params.id)
await deleteTimeUnit(id, req.user!)
res.status(200).send()
})
export default router
+11 -5
View File
@@ -1,11 +1,11 @@
import { Request, Router } from 'express'
import { getAllTimeUnits, getTimeUnitDetails, getTimeUnitLocalities } from '../services/timeUnit'
import { fixBigInt } from '../utils/common'
import { EditDataType, EditMetaData, TimeUnitDetailsType } from '../../../frontend/src/backendTypes'
import { getAllSequences } from '../services/sequence'
import { writeTimeUnit } from '../services/write/timeUnit'
import { requireOneOf } from '../middlewares/authorizer'
import { Role } from '../../../frontend/src/types'
import { requireOneOf } from '../middlewares/authorizer'
import { getAllSequences } from '../services/sequence'
import { getAllTimeUnits, getTimeUnitDetails, getTimeUnitLocalities } from '../services/timeUnit'
import { deleteTimeUnit, writeTimeUnit } from '../services/write/timeUnit'
import { fixBigInt } from '../utils/common'
const router = Router()
@@ -42,4 +42,10 @@ router.put(
}
)
router.delete('/:id', requireOneOf([Role.Admin, Role.EditUnrestricted]), async (req, res) => {
const id = req.params.id
await deleteTimeUnit(id, req.user!)
res.status(200).send()
})
export default router
+1 -1
View File
@@ -12,7 +12,7 @@ const getSpeciesWriteHandler = (type: ActionType) => {
table: 'com_species',
idColumn: 'species_id',
allowedColumns: getFieldsOfTables(['com_species', 'now_ls']),
type: type,
type,
})
}
+28 -8
View File
@@ -1,7 +1,19 @@
import { EditDataType, Reference, TimeBoundDetailsType } from '../../../../frontend/src/backendTypes'
import { EditDataType, Reference, TimeBoundDetailsType, User } from '../../../../frontend/src/backendTypes'
import { NOW_DB_NAME } from '../../utils/config'
import { WriteHandler } from '../writeOperations/writeHandler'
import { getFieldsOfTables } from '../../utils/db'
import { ActionType } from '../writeOperations/types'
import { getTimeBoundDetails } from '../timeBound'
const getTimeBoundWriteHandler = (type: ActionType) => {
return new WriteHandler({
dbName: NOW_DB_NAME,
table: 'now_tu_bound',
idColumn: 'bid',
allowedColumns: getFieldsOfTables(['now_tu_bound']),
type: type,
})
}
export const writeTimeBound = async (
timeBound: EditDataType<TimeBoundDetailsType>,
@@ -9,13 +21,7 @@ export const writeTimeBound = async (
references: Reference[] | undefined,
authorizer: string
) => {
const writeHandler = new WriteHandler({
dbName: NOW_DB_NAME,
table: 'now_tu_bound',
idColumn: 'bid',
allowedColumns: getFieldsOfTables(['now_tu_bound']),
type: timeBound.bid ? 'update' : 'add',
})
const writeHandler = getTimeBoundWriteHandler(timeBound.bid ? 'update' : 'add')
try {
await writeHandler.start()
@@ -31,3 +37,17 @@ export const writeTimeBound = async (
throw e
}
}
export const deleteTimeUnit = async (id: number, user: User) => {
const timeBound = await getTimeBoundDetails(id)
if (!timeBound) throw new Error('Time bound not found')
const writeHandler = getTimeBoundWriteHandler('delete')
try {
await writeHandler.start()
await writeHandler.deleteObject('now_tu_bound', timeBound, ['bid'])
await writeHandler.logUpdatesAndComplete(user.initials)
} catch (e) {
await writeHandler.end()
throw e
}
}
+29 -9
View File
@@ -1,7 +1,21 @@
import { EditDataType, Reference, TimeUnitDetailsType } from '../../../../frontend/src/backendTypes'
import { EditDataType, Reference, TimeUnitDetailsType, User } from '../../../../frontend/src/backendTypes'
import { NOW_DB_NAME } from '../../utils/config'
import { WriteHandler } from '../writeOperations/writeHandler'
import { getFieldsOfTables } from '../../utils/db'
import { ActionType } from '../writeOperations/types'
import { getTimeUnitDetails } from '../timeUnit'
const getTimeUnitWriteHandler = (type: ActionType) => {
return new WriteHandler({
dbName: NOW_DB_NAME,
table: 'now_time_unit',
idColumn: 'tu_name',
allowedColumns: getFieldsOfTables(['now_time_unit', 'now_tu_sequence']),
type,
})
}
const createTimeUnitId = (displayName: string) => displayName.toLowerCase().replace(' ', '')
export const writeTimeUnit = async (
timeUnit: EditDataType<TimeUnitDetailsType>,
@@ -9,13 +23,7 @@ export const writeTimeUnit = async (
references: Reference[] | undefined,
authorizer: string
) => {
const writeHandler = new WriteHandler({
dbName: NOW_DB_NAME,
table: 'now_time_unit',
idColumn: 'tu_name',
allowedColumns: getFieldsOfTables(['now_time_unit', 'now_tu_sequence']),
type: timeUnit.tu_name ? 'update' : 'add',
})
const writeHandler = getTimeUnitWriteHandler(timeUnit.tu_name ? 'update' : 'add')
const createdId = createTimeUnitId(timeUnit.tu_display_name!)
@@ -39,4 +47,16 @@ export const writeTimeUnit = async (
}
}
const createTimeUnitId = (displayName: string) => displayName.toLowerCase().replace(' ', '')
export const deleteTimeUnit = async (id: string, user: User) => {
const timeUnit = await getTimeUnitDetails(id)
if (!timeUnit) throw new Error('Time unit not found')
const writeHandler = getTimeUnitWriteHandler('delete')
try {
await writeHandler.start()
await writeHandler.deleteObject('now_time_unit', timeUnit, ['tu_name'])
await writeHandler.logUpdatesAndComplete(user.initials)
} catch (e) {
await writeHandler.end()
throw e
}
}
@@ -119,8 +119,6 @@ export class WriteHandler extends DatabaseHandler {
await this.createObject(table, object, idColumns)
} else if (rowState === 'removed') {
await this.deleteObject(table, object, idColumns)
} else {
throw new Error('Invalid rowState in list item object while writing')
}
}
}
@@ -33,6 +33,7 @@ export const LocalityDetails = () => {
})
const notify = useNotify()
const [deleteMutation, { isSuccess: deleteSuccess, isError: deleteError }] = useDeleteLocalityMutation()
useEffect(() => {
if (deleteSuccess) {
notify('Deleted item successfully.')
@@ -41,6 +42,7 @@ export const LocalityDetails = () => {
notify('Could not delete item. Error happened.', 'error')
}
}, [deleteSuccess, deleteError, notify, navigate])
if (isError) return <div>Error loading data</div>
if (isFetching || (!data && !isNew) || mutationLoading) return <CircularProgress />
@@ -1,5 +1,5 @@
import { useParams } from 'react-router-dom'
import { useEditSpeciesMutation, useGetSpeciesDetailsQuery } from '../../redux/speciesReducer'
import { useNavigate, useParams } from 'react-router-dom'
import { useDeleteSpeciesMutation, useEditSpeciesMutation, useGetSpeciesDetailsQuery } from '../../redux/speciesReducer'
import { CircularProgress } from '@mui/material'
import { DetailView, TabType } from '../DetailView/DetailView'
import { DietTab } from './Tabs/DietTab'
@@ -13,15 +13,34 @@ import { TeethTab } from './Tabs/TeethTab'
import { UpdateTab } from '../DetailView/common/UpdateTab'
import { EditDataType, SpeciesDetailsType } from '@/backendTypes'
import { emptySpecies } from '../DetailView/common/defaultValues'
import { useNotify } from '@/hooks/notification'
import { useEffect } from 'react'
export const SpeciesDetails = () => {
const { id } = useParams()
const isNew = id === 'new'
const { isLoading, isError, isFetching, data } = useGetSpeciesDetailsQuery(id!, { skip: isNew })
const [editSpeciesRequest] = useEditSpeciesMutation()
const notify = useNotify()
const navigate = useNavigate()
const [deleteMutation, { isSuccess: deleteSuccess, isError: deleteError }] = useDeleteSpeciesMutation()
useEffect(() => {
if (deleteSuccess) {
notify('Deleted item successfully.')
navigate('/species')
} else if (deleteError) {
notify('Could not delete item. Error happened.', 'error')
}
}, [deleteSuccess, deleteError, notify, navigate])
if (isError) return <div>Error loading data</div>
if (isLoading || isFetching || (!data && !isNew)) return <CircularProgress />
const deleteFunction = async () => {
await deleteMutation(parseInt(id!)).unwrap()
}
const onWrite = async (editData: EditDataType<SpeciesDetailsType>) => {
await editSpeciesRequest(editData)
}
@@ -76,6 +95,7 @@ export const SpeciesDetails = () => {
name: 'unknown',
error: null,
})}
deleteFunction={deleteFunction}
/>
)
}
@@ -1,12 +1,18 @@
import { useParams } from 'react-router-dom'
import { useEditTimeBoundMutation, useGetTimeBoundDetailsQuery } from '../../redux/timeBoundReducer'
import { EditDataType, TimeBoundDetailsType } from '@/backendTypes.js'
import { useNotify } from '@/hooks/notification.ts'
import { CircularProgress } from '@mui/material'
import { useEffect } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import {
useDeleteTimeBoundMutation,
useEditTimeBoundMutation,
useGetTimeBoundDetailsQuery,
} from '../../redux/timeBoundReducer'
import { emptyTimeBound } from '../DetailView/common/defaultValues.ts'
import { UpdateTab } from '../DetailView/common/UpdateTab.tsx'
import { DetailView, TabType } from '../DetailView/DetailView'
import { BoundTab } from './Tabs/BoundTab'
import { TimeUnitTab } from './Tabs/TimeUnitTab.tsx'
import { UpdateTab } from '../DetailView/common/UpdateTab.tsx'
import { EditDataType, TimeBoundDetailsType } from '@/backendTypes.js'
import { emptyTimeBound } from '../DetailView/common/defaultValues.ts'
export const TimeBoundDetails = () => {
const { id } = useParams()
@@ -15,9 +21,27 @@ export const TimeBoundDetails = () => {
skip: isNew,
})
const [editTimeBoundRequest] = useEditTimeBoundMutation()
const notify = useNotify()
const navigate = useNavigate()
const [deleteMutation, { isSuccess: deleteSuccess, isError: deleteError }] = useDeleteTimeBoundMutation()
useEffect(() => {
if (deleteSuccess) {
notify('Deleted item successfully.')
navigate('/time-bound')
} else if (deleteError) {
notify('Could not delete item. Error happened.', 'error')
}
}, [deleteSuccess, deleteError, notify, navigate])
if (isError) return <div>Error loading data</div>
if (isLoading || isFetching || (!data && !isNew)) return <CircularProgress />
const deleteFunction = async () => {
await deleteMutation(parseInt(id!)).unwrap()
}
const onWrite = async (editedTimeBound: EditDataType<TimeBoundDetailsType>) => {
await editTimeBoundRequest(editedTimeBound)
}
@@ -48,6 +72,7 @@ export const TimeBoundDetails = () => {
name: 'unknown',
error: null,
})}
deleteFunction={deleteFunction}
/>
)
}
@@ -1,21 +1,45 @@
import { useParams } from 'react-router-dom'
import { useEditTimeUnitMutation, useGetTimeUnitDetailsQuery } from '../../redux/timeUnitReducer'
import { EditDataType, TimeUnitDetailsType } from '@/backendTypes'
import { useNotify } from '@/hooks/notification'
import { CircularProgress } from '@mui/material'
import { useEffect } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import {
useDeleteTimeUnitMutation,
useEditTimeUnitMutation,
useGetTimeUnitDetailsQuery,
} from '../../redux/timeUnitReducer'
import { emptyTimeUnit } from '../DetailView/common/defaultValues'
import { UpdateTab } from '../DetailView/common/UpdateTab'
import { DetailView, TabType } from '../DetailView/DetailView'
import { LocalityTab } from './Tabs/LocalityTab'
import { TimeUnitTab } from './Tabs/TimeUnitTab'
import { UpdateTab } from '../DetailView/common/UpdateTab'
import { EditDataType, TimeUnitDetailsType } from '@/backendTypes'
import { emptyTimeUnit } from '../DetailView/common/defaultValues'
export const TimeUnitDetails = () => {
const { id } = useParams()
const isNew = id === 'new'
const { isLoading, isError, isFetching, data } = useGetTimeUnitDetailsQuery(encodeURIComponent(id!), { skip: isNew })
const [editTimeUnitRequest] = useEditTimeUnitMutation()
const notify = useNotify()
const navigate = useNavigate()
const [deleteMutation, { isSuccess: deleteSuccess, isError: deleteError }] = useDeleteTimeUnitMutation()
useEffect(() => {
if (deleteSuccess) {
notify('Deleted item successfully.')
navigate('/time-unit')
} else if (deleteError) {
notify('Could not delete item. Error happened.', 'error')
}
}, [deleteSuccess, deleteError, notify, navigate])
if (isError) return <div>Error loading data</div>
if (isLoading || isFetching || (!data && !isNew)) return <CircularProgress />
const deleteFunction = async () => {
await deleteMutation(id!).unwrap()
}
const onWrite = async (editData: EditDataType<TimeUnitDetailsType>) => {
await editTimeUnitRequest(editData)
}
@@ -43,6 +67,7 @@ export const TimeUnitDetails = () => {
data={isNew ? emptyTimeUnit : data!}
onWrite={onWrite}
validator={() => ({ name: '', error: null })}
deleteFunction={deleteFunction}
/>
)
}
+8 -1
View File
@@ -24,7 +24,14 @@ const speciesApi = api.injectEndpoints({
invalidatesTags: (result, _error, { species_id }) =>
result ? [{ type: 'species', id: species_id }, 'specieslist'] : [],
}),
deleteSpecies: builder.mutation<void, number>({
query: id => ({
url: `/species/${id}`,
method: 'DELETE',
}),
}),
}),
})
export const { useGetAllSpeciesQuery, useGetSpeciesDetailsQuery, useEditSpeciesMutation } = speciesApi
export const { useGetAllSpeciesQuery, useGetSpeciesDetailsQuery, useEditSpeciesMutation, useDeleteSpeciesMutation } =
speciesApi
+7
View File
@@ -28,6 +28,12 @@ const timeboundsApi = api.injectEndpoints({
}),
invalidatesTags: (result, _error, { bid }) => (result ? [{ type: 'timebound', id: bid }, 'timebounds'] : []),
}),
deleteTimeBound: builder.mutation<void, number>({
query: id => ({
url: `/time-bound/${id}`,
method: 'DELETE',
}),
}),
}),
})
@@ -36,4 +42,5 @@ export const {
useGetTimeBoundDetailsQuery,
useGetTimeBoundTimeUnitsQuery,
useEditTimeBoundMutation,
useDeleteTimeBoundMutation,
} = timeboundsApi
+8
View File
@@ -34,6 +34,13 @@ const timeunitsApi = api.injectEndpoints({
invalidatesTags: (result, _error, { tu_name }) =>
result ? [{ type: 'timeunit', id: tu_name }, 'timeunits'] : [],
}),
deleteTimeUnit: builder.mutation<void, string>({
query: id => ({
url: `/time-unit/${id}`,
method: 'DELETE',
}),
invalidatesTags: ['timeunits'],
}),
}),
})
@@ -43,4 +50,5 @@ export const {
useGetTimeUnitDetailsQuery,
useEditTimeUnitMutation,
useGetSequencesQuery,
useDeleteTimeUnitMutation,
} = timeunitsApi