Scale regional data catalogs
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import type { Dispatch, FormEvent, SetStateAction } from 'react'
|
||||
import { useEffect, useMemo, useState, type Dispatch, type FormEvent, type SetStateAction } from 'react'
|
||||
import type { AreaRead, DatasetCreateResponse } from '../../types'
|
||||
import { getDatasetDisplayName, getDatasetSourceDisplayName } from '../../lib/datasetDisplay'
|
||||
|
||||
const DATASET_CATALOG_PAGE_SIZE = 10
|
||||
|
||||
interface DatasetFormState {
|
||||
datasetType: string
|
||||
source: string
|
||||
@@ -123,6 +125,9 @@ export function DatasetPanel({
|
||||
onOpenDatasetInMap,
|
||||
onOpenDatasetExport,
|
||||
}: DatasetPanelProps) {
|
||||
const [historyOpen, setHistoryOpen] = useState(false)
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
const [page, setPage] = useState(1)
|
||||
const selectedDataset = datasets.find((dataset) => dataset.id === selectedDatasetId)
|
||||
const latestDatasetBySeries = new Map<string, DatasetCreateResponse>()
|
||||
datasets.forEach((dataset) => {
|
||||
@@ -140,6 +145,27 @@ export function DatasetPanel({
|
||||
const historicalDatasets = datasets.filter(
|
||||
(dataset) => dataset.temporal_series_key && latestDatasetBySeries.get(dataset.temporal_series_key)?.id !== dataset.id,
|
||||
)
|
||||
const filteredPrimaryDatasets = useMemo(() => {
|
||||
const query = searchQuery.trim().toLocaleLowerCase('nl-BE')
|
||||
if (!query) return primaryDatasets
|
||||
return primaryDatasets.filter((dataset) => {
|
||||
const searchable = [
|
||||
getDatasetDisplayName(dataset),
|
||||
getDatasetSourceDisplayName(dataset),
|
||||
dataset.source,
|
||||
dataset.source_name,
|
||||
dataset.reference_layer_name,
|
||||
String(dataset.source_metadata?.['municipality'] ?? ''),
|
||||
datasetRoleLabel(normalizeDatasetRole(dataset)),
|
||||
]
|
||||
return searchable.some((value) => String(value ?? '').toLocaleLowerCase('nl-BE').includes(query))
|
||||
})
|
||||
}, [primaryDatasets, searchQuery])
|
||||
const pageCount = Math.max(1, Math.ceil(filteredPrimaryDatasets.length / DATASET_CATALOG_PAGE_SIZE))
|
||||
const visiblePrimaryDatasets = filteredPrimaryDatasets.slice(
|
||||
(page - 1) * DATASET_CATALOG_PAGE_SIZE,
|
||||
page * DATASET_CATALOG_PAGE_SIZE,
|
||||
)
|
||||
const readyDatasets = primaryDatasets.filter((dataset) => dataset.status === 'ready').length
|
||||
const roleSummaries = [
|
||||
{
|
||||
@@ -172,6 +198,16 @@ export function DatasetPanel({
|
||||
},
|
||||
]
|
||||
|
||||
useEffect(() => {
|
||||
setPage((current) => Math.min(current, pageCount))
|
||||
}, [pageCount])
|
||||
|
||||
useEffect(() => {
|
||||
setSearchQuery('')
|
||||
setPage(1)
|
||||
setHistoryOpen(false)
|
||||
}, [selectedProjectId])
|
||||
|
||||
return (
|
||||
<section className="workspace-panel" data-testid="dataset-panel">
|
||||
<div className="panel-title-row">
|
||||
@@ -257,8 +293,42 @@ export function DatasetPanel({
|
||||
) : null}
|
||||
<div className="data-panel-list-block dataset-catalog-block">
|
||||
<p className="data-section-label">Beschikbare bronnen</p>
|
||||
<div className="catalog-browser-toolbar catalog-browser-toolbar-datasets">
|
||||
<label className="catalog-search-field">
|
||||
Zoek in beschikbare bronnen
|
||||
<input
|
||||
type="search"
|
||||
value={searchQuery}
|
||||
onChange={(event) => {
|
||||
setSearchQuery(event.target.value)
|
||||
setPage(1)
|
||||
}}
|
||||
placeholder="Naam, bron, gemeente of type"
|
||||
/>
|
||||
</label>
|
||||
<div className="catalog-pagination" aria-label="Paginering van bronnen">
|
||||
<span>{filteredPrimaryDatasets.length} van {primaryDatasets.length}</span>
|
||||
<button
|
||||
className="secondary-action"
|
||||
type="button"
|
||||
disabled={page === 1}
|
||||
onClick={() => setPage((current) => Math.max(1, current - 1))}
|
||||
>
|
||||
Vorige
|
||||
</button>
|
||||
<strong>{page} / {pageCount}</strong>
|
||||
<button
|
||||
className="secondary-action"
|
||||
type="button"
|
||||
disabled={page === pageCount}
|
||||
onClick={() => setPage((current) => Math.min(pageCount, current + 1))}
|
||||
>
|
||||
Volgende
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ul className="dataset-list">
|
||||
{primaryDatasets.map((dataset) => {
|
||||
{visiblePrimaryDatasets.map((dataset) => {
|
||||
const datasetRole = normalizeDatasetRole(dataset)
|
||||
const roleLabel = datasetRoleLabel(datasetRole)
|
||||
return (
|
||||
@@ -337,13 +407,19 @@ export function DatasetPanel({
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
{visiblePrimaryDatasets.length === 0 && datasets.length > 0 ? (
|
||||
<p className="muted">Geen bron gevonden voor deze zoekterm.</p>
|
||||
) : null}
|
||||
{historicalDatasets.length > 0 ? (
|
||||
<details className="dataset-history-disclosure">
|
||||
<details
|
||||
className="dataset-history-disclosure"
|
||||
onToggle={(event) => setHistoryOpen(event.currentTarget.open)}
|
||||
>
|
||||
<summary>
|
||||
<span>Historische meetmomenten</span>
|
||||
<strong>{historicalDatasets.length} oudere lagen</strong>
|
||||
</summary>
|
||||
<ul className="dataset-history-list">
|
||||
{historyOpen ? <ul className="dataset-history-list">
|
||||
{historicalDatasets.map((dataset) => (
|
||||
<li key={dataset.id}>
|
||||
<div>
|
||||
@@ -356,7 +432,7 @@ export function DatasetPanel({
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</ul> : null}
|
||||
</details>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user