Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel
### Added

- Dataset Templates UI integration, including create/edit flows, previews, and skeleton states.
- Storage Driver selection in Create Collection form, with dynamic fetching of available storage drivers from the backend.

### Changed

Expand Down
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.1.0-alpha.4",
"@iqss/dataverse-client-javascript": "2.2.0-alpha.10",
"@iqss/dataverse-design-system": "*",
"@istanbuljs/nyc-config-typescript": "1.0.2",
"@tanstack/react-table": "8.9.2",
Expand Down
1 change: 1 addition & 0 deletions public/locales/en/collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"helpText": "Share this collection on your favorite social media networks."
},
"editedAlert": "You have successfully updated your collection!",
"storageDriverUpdateFailed": "The collection was created, but the storage driver could not be updated.",
"editCollection": {
"edit": "Edit",
"generalInfo": "General Information",
Expand Down
3 changes: 2 additions & 1 deletion public/locales/en/shared.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@
},
"storage": {
"label": "Storage",
"description": "A storage service to be used for datasets in this collection."
"description": "A storage service to be used for datasets in this collection.",
"inheritedOrDefaultOption": "Use inherited or default storage driver ({{storageDriver}})"
},
"type": {
"label": "Category",
Expand Down
1 change: 1 addition & 0 deletions public/locales/es/collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"helpText": "Comparte esta colección en tus redes sociales favoritas."
},
"editedAlert": "¡Has actualizado tu colección correctamente!",
"storageDriverUpdateFailed": "La colección se creó, pero no se pudo actualizar el driver de almacenamiento.",
"editCollection": {
"edit": "Editar",
"generalInfo": "Información general",
Expand Down
3 changes: 2 additions & 1 deletion public/locales/es/shared.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@
},
"storage": {
"label": "Almacenamiento",
"description": "Un servicio de almacenamiento que se usará para los conjuntos de datos en esta colección."
"description": "Un servicio de almacenamiento que se usará para los conjuntos de datos en esta colección.",
"inheritedOrDefaultOption": "Usar el driver de almacenamiento heredado o predeterminado ({{storageDriver}})"
},
"type": {
"label": "Categoría",
Expand Down
1 change: 1 addition & 0 deletions src/collection/domain/models/AllowedStorageDrivers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type AllowedStorageDrivers = Record<string, string>
8 changes: 8 additions & 0 deletions src/collection/domain/models/StorageDriver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface StorageDriver {
name: string
type?: string
label?: string
directUpload: boolean
directDownload: boolean
uploadOutOfBand: boolean
}
9 changes: 9 additions & 0 deletions src/collection/domain/repositories/CollectionRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { PublicationStatus } from '@/shared/core/domain/models/PublicationStatus
import { LinkingObjectType } from '../useCases/getCollectionsForLinking'
import { CollectionSummary } from '../models/CollectionSummary'
import { CollectionLinks } from '../models/CollectionLinks'
import { AllowedStorageDrivers } from '../models/AllowedStorageDrivers'
import { StorageDriver } from '../models/StorageDriver'

export interface CollectionRepository {
getById: (id?: string) => Promise<Collection>
Expand Down Expand Up @@ -58,4 +60,11 @@ export interface CollectionRepository {
linkingCollectionIdOrAlias: number | string
): Promise<void>
getLinks(collectionIdOrAlias: number | string): Promise<CollectionLinks>
getAllowedStorageDrivers(collectionIdOrAlias: number | string): Promise<AllowedStorageDrivers>
getStorageDriver(
collectionIdOrAlias: number | string,
getEffective?: boolean
): Promise<StorageDriver | undefined>
setStorageDriver(collectionIdOrAlias: number | string, driverLabel: string): Promise<string>
deleteStorageDriver(collectionIdOrAlias: number | string): Promise<string>
}
8 changes: 8 additions & 0 deletions src/collection/domain/useCases/deleteCollectionDriver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { CollectionRepository } from '../repositories/CollectionRepository'

export async function deleteCollectionDriver(
collectionRepository: CollectionRepository,
collectionIdOrAlias: number | string
): Promise<string> {
return collectionRepository.deleteStorageDriver(collectionIdOrAlias)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { AllowedStorageDrivers } from '../models/AllowedStorageDrivers'
import { CollectionRepository } from '../repositories/CollectionRepository'

export async function getCollectionAllowedStorageDrivers(
collectionRepository: CollectionRepository,
collectionIdOrAlias: number | string
): Promise<AllowedStorageDrivers> {
return collectionRepository.getAllowedStorageDrivers(collectionIdOrAlias)
}
10 changes: 10 additions & 0 deletions src/collection/domain/useCases/getCollectionStorageDriver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { StorageDriver } from '../models/StorageDriver'
import { CollectionRepository } from '../repositories/CollectionRepository'

export async function getCollectionStorageDriver(
collectionRepository: CollectionRepository,
collectionIdOrAlias: number | string,
getEffective?: boolean
): Promise<StorageDriver | undefined> {
return collectionRepository.getStorageDriver(collectionIdOrAlias, getEffective)
}
9 changes: 9 additions & 0 deletions src/collection/domain/useCases/setCollectionDriver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { CollectionRepository } from '../repositories/CollectionRepository'

export async function setCollectionDriver(
collectionRepository: CollectionRepository,
collectionIdOrAlias: number | string,
driverLabel: string
): Promise<string> {
return collectionRepository.setStorageDriver(collectionIdOrAlias, driverLabel)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ import {
deleteCollectionFeaturedItem,
getCollectionsForLinking,
linkCollection,
getCollectionLinks
getCollectionLinks,
getAllowedCollectionStorageDrivers,
getCollectionStorageDriver,
setCollectionStorageDriver,
deleteCollectionStorageDriver
} from '@iqss/dataverse-client-javascript'
import { JSCollectionMapper } from '../mappers/JSCollectionMapper'
import { CollectionDTO } from '../../domain/useCases/DTOs/CollectionDTO'
Expand All @@ -34,6 +38,8 @@ import { PublicationStatus } from '@/shared/core/domain/models/PublicationStatus
import { CollectionSummary } from '@/collection/domain/models/CollectionSummary'
import { LinkingObjectType } from '@/collection/domain/useCases/getCollectionsForLinking'
import { CollectionLinks } from '@/collection/domain/models/CollectionLinks'
import { AllowedStorageDrivers } from '@/collection/domain/models/AllowedStorageDrivers'
import { StorageDriver } from '@/collection/domain/models/StorageDriver'

export class CollectionJSDataverseRepository implements CollectionRepository {
getById(id?: string): Promise<Collection> {
Expand Down Expand Up @@ -174,4 +180,23 @@ export class CollectionJSDataverseRepository implements CollectionRepository {
getLinks(collectionIdOrAlias: number | string): Promise<CollectionLinks> {
return getCollectionLinks.execute(collectionIdOrAlias)
}

getAllowedStorageDrivers(collectionIdOrAlias: number | string): Promise<AllowedStorageDrivers> {
return getAllowedCollectionStorageDrivers.execute(collectionIdOrAlias)
}

getStorageDriver(
collectionIdOrAlias: number | string,
getEffective?: boolean
): Promise<StorageDriver | undefined> {
return getCollectionStorageDriver.execute(collectionIdOrAlias, getEffective)
}

setStorageDriver(collectionIdOrAlias: number | string, driverLabel: string): Promise<string> {
return setCollectionStorageDriver.execute(collectionIdOrAlias, driverLabel)
}

deleteStorageDriver(collectionIdOrAlias: number | string): Promise<string> {
return deleteCollectionStorageDriver.execute(collectionIdOrAlias)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { CollectionHelper } from '@/sections/collection/CollectionHelper'
import { MetadataFieldsHelper } from '../DatasetMetadataForm/MetadataFieldsHelper'
import { MetadataBlockInfo } from '@/metadata-block-info/domain/models/MetadataBlockInfo'
import { useCollectionRepositories } from '@/shared/contexts/repositories/RepositoriesProvider'
import { useGetCollectionAllowedStorageDrivers } from '@/shared/hooks/useGetCollectionAllowedStorageDrivers'
import { useGetCollectionStorageDriver } from '@/shared/hooks/useGetCollectionStorageDriver'

export const METADATA_BLOCKS_NAMES_GROUPER = 'metadataBlockNames'
export const USE_FIELDS_FROM_PARENT = 'useFieldsFromParent'
Expand Down Expand Up @@ -66,6 +68,8 @@ export const EditCreateCollectionForm = ({
const onEditMode = mode === 'edit'
const isEditingRootCollection =
onEditMode && CollectionHelper.isRootCollection(collection.hierarchy)
const canSelectStorageDriver = user.superuser
const storageDriverCollectionId = onEditMode ? collection.id : parentCollection.id

const {
metadataBlocksInfo,
Expand Down Expand Up @@ -102,6 +106,38 @@ export const EditCreateCollectionForm = ({
metadataBlockInfoRepository
})

const {
allowedStorageDrivers,
isLoading: isLoadingAllowedStorageDrivers,
error: allowedStorageDriversError
} = useGetCollectionAllowedStorageDrivers({
collectionIdOrAlias: storageDriverCollectionId,
collectionRepository,
enabled: canSelectStorageDriver
})

const {
storageDriver,
isLoading: isLoadingStorageDriver,
error: storageDriverError
} = useGetCollectionStorageDriver({
collectionIdOrAlias: storageDriverCollectionId,
collectionRepository,
enabled: canSelectStorageDriver,
getEffective: false
})

const {
storageDriver: effectiveStorageDriver,
isLoading: isLoadingEffectiveStorageDriver,
error: effectiveStorageDriverError
} = useGetCollectionStorageDriver({
collectionIdOrAlias: storageDriverCollectionId,
collectionRepository,
enabled: canSelectStorageDriver,
getEffective: true
})

const baseInputLevels: FormattedCollectionInputLevels = useDeepCompareMemo(() => {
return CollectionFormHelper.defineBaseInputLevels(allMetadataBlocksInfoNormalized)
}, [allMetadataBlocksInfoNormalized])
Expand Down Expand Up @@ -149,13 +185,19 @@ export const EditCreateCollectionForm = ({
isLoadingMetadataBlocksInfo ||
isLoadingAllMetadataBlocksInfo ||
isLoadingCollectionFacets ||
isLoadingFacetableMetadataFields
isLoadingFacetableMetadataFields ||
isLoadingAllowedStorageDrivers ||
isLoadingStorageDriver ||
isLoadingEffectiveStorageDriver

const dataLoadingErrors = [
metadataBlockInfoError,
allMetadataBlocksInfoError,
collectionFacetsError,
facetableMetadataFieldsError
facetableMetadataFieldsError,
allowedStorageDriversError,
storageDriverError,
effectiveStorageDriverError
]

useEffect(() => {
Expand Down Expand Up @@ -204,6 +246,21 @@ export const EditCreateCollectionForm = ({
mode === 'edit' ? collection.isFacetRoot : undefined
)

const currentStorageDriverLabel = storageDriver?.label ?? storageDriver?.name
const effectiveStorageDriverLabel = effectiveStorageDriver?.label ?? effectiveStorageDriver?.name
const effectiveStorageDriverDisplayName =
effectiveStorageDriverLabel && allowedStorageDrivers[effectiveStorageDriverLabel] !== undefined
? allowedStorageDrivers[effectiveStorageDriverLabel]
: effectiveStorageDriverLabel
const defaultStorageDriver =
storageDriver === null
? ''
: (currentStorageDriverLabel && allowedStorageDrivers[currentStorageDriverLabel] !== undefined
? currentStorageDriverLabel
: undefined) ??
Object.keys(allowedStorageDrivers)[0] ??
''

const formDefaultValues: CollectionFormData = {
hostCollection: isEditingRootCollection
? null
Expand All @@ -213,7 +270,7 @@ export const EditCreateCollectionForm = ({
type: onEditMode ? collection.type : '',
contacts: defaultContacts,
affiliation: onEditMode ? collection.affiliation ?? '' : user?.affiliation ?? '',
storage: 'S3',
storage: defaultStorageDriver,
description: onEditMode ? collection.description ?? '' : '',
[USE_FIELDS_FROM_PARENT]: useFieldsFromParentDefault,
[METADATA_BLOCKS_NAMES_GROUPER]: defaultBlocksNames,
Expand All @@ -231,6 +288,9 @@ export const EditCreateCollectionForm = ({
allFacetableMetadataFields={facetableMetadataFields}
defaultCollectionFacets={defaultCollectionFacets}
isEditingRootCollection={isEditingRootCollection}
canSelectStorageDriver={canSelectStorageDriver}
allowedStorageDrivers={allowedStorageDrivers}
inheritedOrDefaultStorageDriverName={effectiveStorageDriverDisplayName}
/>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { EditCreateCollectionFormMode } from '../EditCreateCollectionForm'
import { RouteWithParams } from '@/sections/Route.enum'
import { useCollectionRepositories } from '@/shared/contexts/repositories/RepositoriesProvider'
import styles from './CollectionForm.module.scss'
import { AllowedStorageDrivers } from '@/collection/domain/models/AllowedStorageDrivers'

export interface CollectionFormProps {
mode: EditCreateCollectionFormMode
Expand All @@ -26,6 +27,9 @@ export interface CollectionFormProps {
allFacetableMetadataFields: MetadataField[]
defaultCollectionFacets: CollectionFormFacet[]
isEditingRootCollection: boolean
canSelectStorageDriver: boolean
allowedStorageDrivers: AllowedStorageDrivers
inheritedOrDefaultStorageDriverName?: string
}

export const CollectionForm = ({
Expand All @@ -35,7 +39,10 @@ export const CollectionForm = ({
allMetadataBlocksInfo,
allFacetableMetadataFields,
defaultCollectionFacets,
isEditingRootCollection
isEditingRootCollection,
canSelectStorageDriver,
allowedStorageDrivers,
inheritedOrDefaultStorageDriverName
}: CollectionFormProps) => {
const { collectionRepository } = useCollectionRepositories()
const formContainerRef = useRef<HTMLDivElement>(null)
Expand All @@ -53,7 +60,8 @@ export const CollectionForm = ({
collectionIdOrParentCollectionId,
collectionRepository,
onSubmittedCollectionError,
form.formState.dirtyFields
form.formState.dirtyFields,
canSelectStorageDriver
)

function onSubmittedCollectionError() {
Expand Down Expand Up @@ -92,7 +100,12 @@ export const CollectionForm = ({
onSubmit={form.handleSubmit(submitForm)}
noValidate={true}
data-testid="collection-form">
<TopFieldsSection isEditingRootCollection={isEditingRootCollection} />
<TopFieldsSection
isEditingRootCollection={isEditingRootCollection}
canSelectStorageDriver={canSelectStorageDriver}
allowedStorageDrivers={allowedStorageDrivers}
inheritedOrDefaultStorageDriverName={inheritedOrDefaultStorageDriverName}
/>

<SeparationLine />

Expand Down
Loading
Loading