Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0112572
support review dataset type #821
pdurbin Sep 30, 2025
62c0990
Merge branch 'develop' into 821-datasetTypes #821
pdurbin Oct 2, 2025
e41580f
fix tests in JSDatasetMapper.spec.ts #821
pdurbin Oct 2, 2025
6b30968
exercise dropdown under "Edit Dataset" button #821
pdurbin Oct 3, 2025
1042ec0
switch from URLSearchParams to useSearchParams and tweak test #821
pdurbin Oct 6, 2025
7d6fd67
replace URLSearchParams with useSearchParams #821
pdurbin Oct 6, 2025
ecf5ac9
retrieve dataset types from API instead of hard coding #821
pdurbin Oct 8, 2025
574f01e
we need "hasValidTermsOfAccess: true" for the test to pass
pdurbin Oct 8, 2025
96058e8
Merge branch 'develop' into 797-dataset-type-selection-step
g-saracca Oct 17, 2025
3a6f23c
feat(designSystem): showPlaceholderOptionInMenu prop
g-saracca Oct 17, 2025
7e787f2
feat: initial type select
g-saracca Oct 17, 2025
b5b461c
feat: add another option for selecting the dataset type
g-saracca Oct 17, 2025
080b985
chore: install pr js-dv version
g-saracca Oct 20, 2025
af57f6d
refactor: remove datasetRepository references from various components…
g-saracca Oct 20, 2025
7a83852
refactor: remove more unused props
g-saracca Oct 20, 2025
2c1b7cf
feat: use dataset type when getting metadata blocks info and submitti…
g-saracca Oct 20, 2025
3f2c58b
feat: update stories
g-saracca Oct 20, 2025
aeaedec
Merge branch 'develop' into 797-dataset-type-selection-step
g-saracca Oct 20, 2025
ebbc7c0
chore: use alpha js-dv version
g-saracca Oct 20, 2025
debfad4
revert change in test
g-saracca Oct 20, 2025
0bba689
feat: add get dataset type by name or id to repository
g-saracca Oct 20, 2025
a883621
feat: add new use case to mock repos
g-saracca Oct 20, 2025
2bbe1ce
refactor: use datasetTypeName instead of datasetType for now
g-saracca Oct 20, 2025
3173542
feat: add readonly dataset type field
g-saracca Oct 20, 2025
9edc05d
test: increase waiting time
g-saracca Oct 21, 2025
259a55e
revert change in select advanced since is not needed
g-saracca Oct 21, 2025
4cc0129
test: add unit cases
g-saracca Oct 21, 2025
066350e
refactor: remove getDatasetTypeByNameOrId method from DatasetReposito…
g-saracca Oct 21, 2025
d7fed1d
fix: update dataset type descriptions
g-saracca Oct 21, 2025
44aaa4f
test: add validation for closing dataset type select dropdown on outs…
g-saracca Oct 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@dnd-kit/sortable": "8.0.0",
"@dnd-kit/utilities": "3.2.2",
"@faker-js/faker": "7.6.0",
"@iqss/dataverse-client-javascript": "2.0.0-alpha.77",
"@iqss/dataverse-client-javascript": "2.0.0-alpha.78",
"@iqss/dataverse-design-system": "*",
"@istanbuljs/nyc-config-typescript": "1.0.2",
"@tanstack/react-table": "8.9.2",
Expand Down
7 changes: 7 additions & 0 deletions public/locales/en/createDataset.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,12 @@
"label": "Dataset Template",
"description": "The dataset template which prepopulates info into the form automatically.",
"helpText": "Changing the template will clear any fields you may have entered data into."
},
"datasetType": {
"label": "Dataset Type",
"description": "The type of dataset you are creating.",
"helpText": "Changing the dataset type will clear any fields you may have entered data into.",
"placeholder": "Select a dataset type",
"toggleMenu": "Toggle dataset types options menu"
}
}
5 changes: 4 additions & 1 deletion public/locales/en/editDatasetMetadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@
"label": "Host Collection",
"description": "The collection which contains this data."
},
"metadata": "Metadata"
"metadata": "Metadata",
"datasetType": {
"label": "Dataset Type"
}
}
56 changes: 56 additions & 0 deletions src/dataset/domain/hooks/useGetAvailableDatasetTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { useCallback, useEffect, useState } from 'react'
import { ReadError } from '@iqss/dataverse-client-javascript'
import { JSDataverseReadErrorHandler } from '@/shared/helpers/JSDataverseReadErrorHandler'
import { DatasetRepository } from '../repositories/DatasetRepository'
import { getAvailableDatasetTypes } from '../useCases/getAvailableDatasetTypes'
import { DatasetType } from '../models/DatasetType'

interface useGetAvailableDatasetTypesProps {
datasetRepository: DatasetRepository
autoFetch?: boolean
}

export const useGetAvailableDatasetTypes = ({
datasetRepository,
autoFetch = true
}: useGetAvailableDatasetTypesProps) => {
const [datasetTypes, setDatasetTypes] = useState<DatasetType[]>([])
const [isLoadingDatasetTypes, setIsLoadingDatasetTypes] = useState<boolean>(autoFetch)
const [errorGetDatasetTypes, setErrorGetDatasetTypes] = useState<string | null>(null)

const fetchDatasetTypes = useCallback(async () => {
setIsLoadingDatasetTypes(true)
setErrorGetDatasetTypes(null)

try {
const response: DatasetType[] = await getAvailableDatasetTypes(datasetRepository)

setDatasetTypes(response)
} catch (err) {
if (err instanceof ReadError) {
const error = new JSDataverseReadErrorHandler(err)
const formattedError =
error.getReasonWithoutStatusCode() ?? /* istanbul ignore next */ error.getErrorMessage()

setErrorGetDatasetTypes(formattedError)
} else {
setErrorGetDatasetTypes('Something went wrong getting the dataset types. Try again later.')
}
} finally {
setIsLoadingDatasetTypes(false)
}
}, [datasetRepository])

useEffect(() => {
if (autoFetch) {
void fetchDatasetTypes()
}
}, [autoFetch, fetchDatasetTypes])

return {
datasetTypes,
isLoadingDatasetTypes,
errorGetDatasetTypes,
fetchDatasetTypes
}
}
9 changes: 6 additions & 3 deletions src/dataset/domain/models/Dataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,8 @@ export class Dataset {
public readonly nextMajorVersion?: string,
public readonly nextMinorVersion?: string,
public readonly requiresMajorVersionUpdate?: boolean,
public readonly fileStore?: string
public readonly fileStore?: string,
public readonly datasetType?: string
) {}

public checkIsLockedFromPublishing(userPersistentId: string): boolean {
Expand Down Expand Up @@ -533,7 +534,8 @@ export class Dataset {
public readonly nextMajorVersionNumber?: string,
public readonly nextMinorVersionNumber?: string,
public readonly requiresMajorVersionUpdate?: boolean,
public readonly fileStore?: string
public readonly fileStore?: string,
public readonly datasetType?: string
) {
this.withAlerts()
}
Expand Down Expand Up @@ -605,7 +607,8 @@ export class Dataset {
this.nextMajorVersionNumber,
this.nextMinorVersionNumber,
this.requiresMajorVersionUpdate,
this.fileStore
this.fileStore,
this.datasetType
)
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/dataset/domain/models/DatasetType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface DatasetType {
id: number
name: string
linkedMetadataBlocks?: string[]
availableLicenses?: string[]
}
8 changes: 7 additions & 1 deletion src/dataset/domain/repositories/DatasetRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { DatasetDownloadCount } from '../models/DatasetDownloadCount'
import { FormattedCitation, CitationFormat } from '../models/DatasetCitation'
import { DatasetTemplate } from '../models/DatasetTemplate'
import { CollectionSummary } from '@/collection/domain/models/CollectionSummary'
import { DatasetType } from '../models/DatasetType'

export interface DatasetRepository {
getByPersistentId: (
Expand All @@ -27,7 +28,11 @@ export interface DatasetRepository {
includeDeaccessioned: boolean
) => Promise<DatasetVersionDiff>

create: (dataset: DatasetDTO, collectionId: string) => Promise<{ persistentId: string }>
create: (
dataset: DatasetDTO,
collectionId: string,
datasetType?: string
) => Promise<{ persistentId: string }>
updateMetadata: (
datasetId: string | number,
datasetDTO: DatasetDTO,
Expand Down Expand Up @@ -60,4 +65,5 @@ export interface DatasetRepository {
link(datasetId: string | number, collectionIdOrAlias: string | number): Promise<void>
unlink(datasetId: string | number, collectionIdOrAlias: string | number): Promise<void>
getDatasetLinkedCollections: (datasetId: string | number) => Promise<CollectionSummary[]>
getAvailableDatasetTypes: () => Promise<DatasetType[]>
}
5 changes: 3 additions & 2 deletions src/dataset/domain/useCases/createDataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { DatasetDTO } from './DTOs/DatasetDTO'
export function createDataset(
datasetRepository: DatasetRepository,
dataset: DatasetDTO,
collectionId: string
collectionId: string,
datasetType?: string
): Promise<{ persistentId: string }> {
return datasetRepository.create(dataset, collectionId).catch((error: Error) => {
return datasetRepository.create(dataset, collectionId, datasetType).catch((error: Error) => {
throw new Error(error.message)
})
}
8 changes: 8 additions & 0 deletions src/dataset/domain/useCases/getAvailableDatasetTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { DatasetRepository } from '../repositories/DatasetRepository'
import { DatasetType } from '@iqss/dataverse-client-javascript'

export function getAvailableDatasetTypes(
datasetRepository: DatasetRepository
): Promise<DatasetType[]> {
return datasetRepository.getAvailableDatasetTypes()
}
6 changes: 4 additions & 2 deletions src/dataset/infrastructure/mappers/JSDatasetMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ export class JSDatasetMapper {
latestPublishedVersionMajorNumber?: number,
latestPublishedVersionMinorNumber?: number,
datasetVersionDiff?: JSDatasetVersionDiff,
fileStore?: string
fileStore?: string,
datasetType?: string
): Dataset {
const version = JSDatasetVersionMapper.toVersion(
jsDataset.versionId,
Expand Down Expand Up @@ -100,7 +101,8 @@ export class JSDatasetMapper {
latestPublishedVersionMinorNumber
),
JSDatasetMapper.toRequiresMajorVersionUpdate(datasetVersionDiff),
fileStore
fileStore,
datasetType
).build()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ import {
getDatasetTemplates,
linkDataset,
unlinkDataset,
getDatasetLinkedCollections
getDatasetLinkedCollections,
DatasetType,
getDatasetAvailableDatasetTypes
} from '@iqss/dataverse-client-javascript'
import { JSDatasetMapper } from '../mappers/JSDatasetMapper'
import { DatasetPaginationInfo } from '../../domain/models/DatasetPaginationInfo'
Expand Down Expand Up @@ -258,7 +260,8 @@ export class DatasetJSDataverseRepository implements DatasetRepository {
datasetDetails.latestPublishedVersionMajorNumber,
datasetDetails.latestPublishedVersionMinorNumber,
datasetDetails.datasetVersionDiff,
datasetDetails.fileStore
datasetDetails.fileStore,
datasetDetails.jsDataset.datasetType
)
})
.catch((error: ReadError) => {
Expand Down Expand Up @@ -316,9 +319,13 @@ export class DatasetJSDataverseRepository implements DatasetRepository {
})
}

create(dataset: DatasetDTO, collectionId: string): Promise<{ persistentId: string }> {
create(
dataset: DatasetDTO,
collectionId: string,
datasetType?: string
): Promise<{ persistentId: string }> {
return createDataset
.execute(DatasetDTOMapper.toJSDatasetDTO(dataset), collectionId)
.execute(DatasetDTOMapper.toJSDatasetDTO(dataset), collectionId, datasetType)
.then((jsDatasetIdentifiers: JSDatasetIdentifiers) => ({
persistentId: jsDatasetIdentifiers.persistentId
}))
Expand Down Expand Up @@ -418,6 +425,10 @@ export class DatasetJSDataverseRepository implements DatasetRepository {
return getDatasetLinkedCollections.execute(datasetId)
}

getAvailableDatasetTypes(): Promise<DatasetType[]> {
return getDatasetAvailableDatasetTypes.execute()
}

/*
TODO: This is a temporary solution as this use case doesn't exist in js-dataverse yet and the API should also return the file store type rather than name only.
After https://github.com/IQSS/dataverse/issues/11695 is implemented, create a js-dataverse use case.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ export interface MetadataBlockInfoRepository {
getByName: (name: string) => Promise<MetadataBlockInfoDisplayFormat | undefined>
getAll: () => Promise<MetadataBlockInfo[]>
getDisplayedOnCreateByCollectionId: (
collectionId: number | string
collectionId: number | string,
datasetType?: string
) => Promise<MetadataBlockInfo[]>
getByCollectionId: (
collectionId: number | string,
onlyDisplayedOnCreate?: boolean,
datasetType?: string
) => Promise<MetadataBlockInfo[]>
getByCollectionId: (collectionId: number | string) => Promise<MetadataBlockInfo[]>
getAllFacetableMetadataFields: () => Promise<MetadataField[]>
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { MetadataBlockInfoRepository } from '../repositories/MetadataBlockInfoRe

export async function getDisplayedOnCreateMetadataBlockInfoByCollectionId(
metadataBlockInfoRepository: MetadataBlockInfoRepository,
collectionId: number | string
collectionId: number | string,
datasetType?: string
): Promise<MetadataBlockInfo[]> {
return metadataBlockInfoRepository
.getDisplayedOnCreateByCollectionId(collectionId)
.getDisplayedOnCreateByCollectionId(collectionId, datasetType)
.catch((error: Error) => {
throw new Error(error.message)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ import { MetadataBlockInfoRepository } from '../repositories/MetadataBlockInfoRe

export async function getMetadataBlockInfoByCollectionId(
metadataBlockInfoRepository: MetadataBlockInfoRepository,
collectionId: number | string
collectionId: number | string,
onlyDisplayedOnCreate?: boolean,
datasetType?: string
): Promise<MetadataBlockInfo[]> {
return metadataBlockInfoRepository.getByCollectionId(collectionId).catch((error: Error) => {
throw new Error(error.message)
})
return metadataBlockInfoRepository
.getByCollectionId(collectionId, onlyDisplayedOnCreate, datasetType)
.catch((error: Error) => {
throw new Error(error.message)
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ export class MetadataBlockInfoJSDataverseRepository implements MetadataBlockInfo
})
}

getByCollectionId(collectionIdOrAlias: number | string): Promise<MetadataBlockInfo[]> {
getByCollectionId(
collectionIdOrAlias: number | string,
onlyDisplayedOnCreate?: boolean,
datasetType?: string
): Promise<MetadataBlockInfo[]> {
return getCollectionMetadataBlocks
.execute(collectionIdOrAlias)
.execute(collectionIdOrAlias, onlyDisplayedOnCreate, datasetType)
.then((metadataBlocks: MetadataBlockInfo[]) => {
return metadataBlocks
})
Expand All @@ -49,12 +53,23 @@ export class MetadataBlockInfoJSDataverseRepository implements MetadataBlockInfo
}

getDisplayedOnCreateByCollectionId(
collectionIdOrAlias: number | string
collectionIdOrAlias: number | string,
datasetType?: string
): Promise<MetadataBlockInfo[]> {
return getCollectionMetadataBlocks
.execute(collectionIdOrAlias, true)
.execute(collectionIdOrAlias, true, datasetType)
.then((metadataBlocks: MetadataBlockInfo[]) => {
return metadataBlocks
const metadataBlocksWithFields: MetadataBlockInfo[] = []
metadataBlocks.forEach((block) => {
const numFields = Object.keys(block.metadataFields).length
// numFields can be zero if you pass a datasetType that's linked to
// a metadata block that doesn't have any fields set to displayOnCreate.
// See https://github.com/IQSS/dataverse/blob/v6.7.1/src/test/java/edu/harvard/iq/dataverse/api/DatasetTypesIT.java#L512
if (numFields > 0) {
metadataBlocksWithFields.push(block)
}
})
return metadataBlocksWithFields
})
.catch((error: ReadError) => {
throw new Error(error.message)
Expand Down
1 change: 1 addition & 0 deletions src/sections/Route.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export enum QueryParamKey {
TAB = 'tab',
FILE_ID = 'id',
DATASET_VERSION = 'datasetVersion',
DATASET_TYPE = 'datasetType',
REFERRER = 'referrer',
AUTH_STATE = 'state',
VALID_TOKEN_BUT_NOT_LINKED_ACCOUNT = 'validTokenButNotLinkedAccount',
Expand Down
Loading
Loading