add refresh button to Locality -> Occurrence tab

This commit is contained in:
juhanikat
2026-09-07 16:21:37 +03:00
parent c0eb7adf78
commit 7d8e345bc4
3 changed files with 39 additions and 20 deletions
+7
View File
@@ -42,6 +42,13 @@ router.post('/export/dwc-archive', requireOneOf([Role.Admin]), async (req, res)
return sendDwcArchive(ids, res)
})
router.get('/:id/occurrences', async (req, res) => {
const id = parseInt(req.params.id)
const locality = await getLocalityDetails(id, req.user)
if (!locality) return res.status(404).send()
return res.status(200).send(fixBigInt(locality.now_ls))
})
router.get('/:id', async (req, res) => {
const id = parseInt(req.params.id)
const locality = await getLocalityDetails(id, req.user)
@@ -1,4 +1,4 @@
import { Editable, LocalityDetailsType, LocalitySpecies } from '@/shared/types'
import { Editable, LocalityDetailsType, LocalitySpecies, RowState } from '@/shared/types'
import { EditableTable } from '@/components/DetailView/common/EditableTable'
import { EditingModal } from '@/components/DetailView/common/EditingModal'
import { Grouped } from '@/components/DetailView/common/tabLayoutHelpers'
@@ -17,6 +17,7 @@ import {
getUniqueLocalityOccurrenceMapExportLocalities,
} from '@/components/Species/localitySpeciesMapExport'
import { EntryUpdateHistory } from '@/components/DetailView/common/FieldUpdateHistory'
import { useLazyGetLocalityOccurrencesQuery } from '@/redux/localityReducer'
const hasMesowearScoreInputs = (row: LocalitySpecies) => {
return (
@@ -30,12 +31,13 @@ const hasMesowearScoreInputs = (row: LocalitySpecies) => {
}
export const OccurrencesTab = () => {
const { mode, data, editData } = useDetailContext<LocalityDetailsType>()
const { mode, data, editData, setEditData } = useDetailContext<LocalityDetailsType>()
const location = useLocation()
const {
register,
formState: { errors },
} = useForm()
const [refreshOccurrences, { isFetching }] = useLazyGetLocalityOccurrencesQuery()
const sortedOccurrenceRows = useMemo(() => {
const sourceRows = (mode.read ? data.now_ls : editData.now_ls) as unknown as Editable<LocalitySpecies>[]
@@ -215,12 +217,6 @@ export const OccurrencesTab = () => {
},
]
// eslint-disable-next-line @typescript-eslint/require-await
const onSave = async () => {
// TODO: Saving logic here (add Occurrence to editData)
return Object.keys(errors).length === 0
}
const getExportLocalities = <T extends MRT_RowData>(table: MRT_TableInstance<T>) => {
const rows = table.getPrePaginationRowModel().rows.map(row => row.original as unknown as LocalitySpecies)
return getUniqueLocalityOccurrenceMapExportLocalities(data, rows)
@@ -234,20 +230,32 @@ export const OccurrencesTab = () => {
await exportOccurrenceMapSvg(table, 'locality-occurrences-map', getExportLocalities)
}
const editingModal = (
<EditingModal buttonText={occurrenceLabels.addNewButton} onSave={onSave}>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '1em' }}>
<TextField {...register('com_species.order_name', { required: true })} label="Order" />
<TextField {...register('com_species.family_name', { required: true })} label="Family" />
<TextField {...register('com_species.genus_name', { required: true })} label="Genus" />
<TextField {...register('com_species.species_name', { required: true })} label="Species" />
<TextField {...register('com_species.unique_identifier', { required: true })} label="Unique Identifier" />
</Box>
</EditingModal>
)
const handleRefresh = async () => {
const result = await refreshOccurrences(String(editData.lid)).unwrap()
const filteredResult = result.filter(row => {
const localRow = editData.now_ls.find(ls => ls.species_id == row.species_id)
return localRow?.rowState !== 'removed'
})
const refreshedRows = filteredResult.map(row => ({
...row,
rowState: 'clean' as RowState,
}))
const removedRows = editData.now_ls.filter(row => row.rowState! === 'removed')
setEditData({
...editData,
now_ls: [...refreshedRows, ...removedRows],
})
}
return (
<Grouped title={occurrenceLabels.informationSectionTitle}>
<Button onClick={() => void handleRefresh()} disabled={isFetching}>
Refresh Occurrences
</Button>
{!mode.read && (
<Button
disabled={mode.new}
+5 -1
View File
@@ -1,6 +1,6 @@
import { api } from './api'
import { addLocality } from '@/redux/userReducer'
import { EditDataType, EditMetaData, Locality, LocalityDetailsType } from '@/shared/types'
import { EditDataType, EditMetaData, Locality, LocalityDetailsType, LocalitySpeciesDetailsType } from '@/shared/types'
const sanitizeLocalityProjects = (locality?: EditDataType<LocalityDetailsType>) => {
if (!locality || !locality.now_plr) return [] as LocalityDetailsType['now_plr']
@@ -23,6 +23,9 @@ const localitiesApi = api.injectEndpoints({
}),
providesTags: result => (result ? [{ type: 'locality', id: result.lid }] : []),
}),
getLocalityOccurrences: builder.query<LocalitySpeciesDetailsType[], string>({
query: lid => `/locality/${lid}/occurrences`,
}),
editLocality: builder.mutation<{ id: number }, EditDataType<LocalityDetailsType> & EditMetaData>({
query: locality => ({
url: `/locality`,
@@ -68,6 +71,7 @@ const localitiesApi = api.injectEndpoints({
export const {
useGetAllLocalitiesQuery,
useGetLocalityDetailsQuery,
useLazyGetLocalityOccurrencesQuery,
useEditLocalityMutation,
useDeleteLocalityMutation,
} = localitiesApi