Skip to content

Commit 08bc177

Browse files
authored
Merge pull request #823 from IQSS/feat/189-add-export-metadata-dropdown
Add Export Metadata Dropdown
2 parents ccba0af + 910fe24 commit 08bc177

38 files changed

Lines changed: 891 additions & 233 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel
99
### Added
1010

1111
- Dataset Templates Selector in the Create Dataset page.
12+
- Metadata Export Dropdown to the metadata tab of Dataset Page and File Page.
1213

1314
### Changed
1415

packages/design-system/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
99
- Add `customToggle` prop to allow custom toggle components.
1010
- Add `customToggleClassname` and `customToggleMenuClassname` props to allow custom styling of the custom toggle dropdown wrapper and menu.
1111
- Add `align` prop to control the alignment of the dropdown menu.
12+
- Add `size` prop to control the size of the button (e.g., 'sm', 'lg').
1213
- **DropdownButtonItem:**
1314
- Add `type` prop to allow specifying the type of the element.
1415
- **SelectAdvanced:**

packages/design-system/src/lib/components/dropdown-button/DropdownButton.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ interface DropdownButtonProps {
2727
customToggleClassname?: string
2828
customToggleMenuClassname?: string
2929
align?: 'end' | 'start'
30+
size?: 'sm' | 'lg'
3031
}
3132

3233
export function DropdownButton({
@@ -43,6 +44,7 @@ export function DropdownButton({
4344
customToggleClassname,
4445
customToggleMenuClassname,
4546
align,
47+
size,
4648
children
4749
}: DropdownButtonProps) {
4850
// If customToggle is provided, use Dropdown instead of DropdownButtonBS
@@ -58,6 +60,7 @@ export function DropdownButton({
5860
return (
5961
<DropdownButtonBS
6062
className={withSpacing ? styles.spacing : ''}
63+
size={size}
6164
id={id}
6265
title={
6366
<>

packages/design-system/src/lib/components/dropdown-button/dropdown-button-item/DropdownButtonItem.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ interface DropdownItemProps extends React.HTMLAttributes<HTMLElement> {
99
children: ReactNode
1010
as?: ElementType
1111
to?: string // When passing <Link> as the `as` prop, this prop is used to pass the URL <DropdownButtonItem as={Link} to="/some-path">...</DropdownButtonItem>
12+
target?: string // For anchor elements
1213
type?: string // For button or input elements
1314
active?: boolean
1415
className?: string

packages/design-system/src/lib/stories/dropdown-button/DropdownButton.stories.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { CanvasFixedHeight } from '../CanvasFixedHeight'
77
import { DropdownSeparator } from '../../components/dropdown-button/dropdown-separator/DropdownSeparator'
88
import { DropdownHeader } from '../../components/dropdown-button/dropdown-header/DropdownHeader'
99
import { Icon } from '../../components/icon/Icon'
10+
import { Stack } from '../../components/stack/Stack'
1011

1112
/**
1213
* ## Description
@@ -237,3 +238,42 @@ export const WithCustomToggle: Story = {
237238
</CanvasFixedHeight>
238239
)
239240
}
241+
242+
export const AllSizesAtAGlance: Story = {
243+
name: 'All sizes at a glance',
244+
render: () => (
245+
<CanvasFixedHeight height={200}>
246+
<Stack direction="horizontal" gap={3}>
247+
<DropdownButton
248+
withSpacing
249+
title="Large size"
250+
id="dropdown-large"
251+
variant="primary"
252+
size="lg">
253+
<DropdownButtonItem href="/item-1">Item 1</DropdownButtonItem>
254+
<DropdownButtonItem href="/item-2">Item 2</DropdownButtonItem>
255+
<DropdownButtonItem href="/item-3">Item 3</DropdownButtonItem>
256+
</DropdownButton>
257+
<DropdownButton
258+
withSpacing
259+
title="Medium size (default)"
260+
id="dropdown-medium"
261+
variant="secondary">
262+
<DropdownButtonItem href="/item-1">Item 1</DropdownButtonItem>
263+
<DropdownButtonItem href="/item-2">Item 2</DropdownButtonItem>
264+
<DropdownButtonItem href="/item-3">Item 3</DropdownButtonItem>
265+
</DropdownButton>
266+
<DropdownButton
267+
withSpacing
268+
title="Small size"
269+
id="dropdown-small"
270+
variant="secondary"
271+
size="sm">
272+
<DropdownButtonItem href="/item-1">Item 1</DropdownButtonItem>
273+
<DropdownButtonItem href="/item-2">Item 2</DropdownButtonItem>
274+
<DropdownButtonItem href="/item-3">Item 3</DropdownButtonItem>
275+
</DropdownButton>
276+
</Stack>
277+
</CanvasFixedHeight>
278+
)
279+
}

public/locales/en/shared.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"dragHandleLabel": "press space to select and keys to drag",
2828
"unknown": "Unknown",
2929
"find": "Find",
30+
"exportMetadata": "Export Metadata",
3031
"pageNumberNotFound": {
3132
"heading": "Page Number Not Found",
3233
"message": "The page number you requested does not exist. Please try a different page number."
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { useCallback, useEffect, useState } from 'react'
2+
import { ReadError } from '@iqss/dataverse-client-javascript'
3+
import { DataverseInfoRepository } from '../repositories/DataverseInfoRepository'
4+
import { JSDataverseReadErrorHandler } from '@/shared/helpers/JSDataverseReadErrorHandler'
5+
import { getAvailableDatasetMetadataExportFormats } from '../useCases/getAvailableDatasetMetadataExportFormats'
6+
import { DatasetMetadataExportFormats } from '../models/DatasetMetadataExportFormats'
7+
8+
interface useGetAvailableDatasetMetadataExportFormatsProps {
9+
dataverseInfoRepository: DataverseInfoRepository
10+
autoFetch?: boolean
11+
}
12+
13+
export const useGetAvailableDatasetMetadataExportFormats = ({
14+
dataverseInfoRepository,
15+
autoFetch = true
16+
}: useGetAvailableDatasetMetadataExportFormatsProps) => {
17+
const [datasetMetadataExportFormats, setDatasetMetadataExportFormats] =
18+
useState<DatasetMetadataExportFormats | null>(null)
19+
const [isLoadingExportFormats, setIsLoadingExportFormats] = useState<boolean>(autoFetch)
20+
const [errorGetExportFormats, setErrorGetExportFormats] = useState<string | null>(null)
21+
22+
const fetchDatasetMetadataExportFormats = useCallback(async () => {
23+
setIsLoadingExportFormats(true)
24+
setErrorGetExportFormats(null)
25+
26+
try {
27+
const exportFormatsResponse = await getAvailableDatasetMetadataExportFormats(
28+
dataverseInfoRepository
29+
)
30+
31+
setDatasetMetadataExportFormats(exportFormatsResponse)
32+
} catch (err) {
33+
if (err instanceof ReadError) {
34+
const error = new JSDataverseReadErrorHandler(err)
35+
const formattedError =
36+
error.getReasonWithoutStatusCode() ?? /* istanbul ignore next */ error.getErrorMessage()
37+
38+
setErrorGetExportFormats(formattedError)
39+
} else {
40+
setErrorGetExportFormats(
41+
'Something went wrong getting the dataset export formats. Try again later.'
42+
)
43+
}
44+
} finally {
45+
setIsLoadingExportFormats(false)
46+
}
47+
}, [dataverseInfoRepository])
48+
49+
useEffect(() => {
50+
if (autoFetch) {
51+
void fetchDatasetMetadataExportFormats()
52+
}
53+
}, [autoFetch, fetchDatasetMetadataExportFormats])
54+
55+
return {
56+
datasetMetadataExportFormats,
57+
isLoadingExportFormats,
58+
errorGetExportFormats,
59+
fetchDatasetMetadataExportFormats
60+
}
61+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export type DatasetMetadataExportFormats = Record<string, DatasetMetadataExportFormat>
2+
3+
type DatasetMetadataExportFormat = DatasetMetadataExportFormatBase | XmlDatasetMetadataExportFormat
4+
5+
interface DatasetMetadataExportFormatBase {
6+
displayName: string
7+
mediaType: string
8+
isHarvestable: boolean
9+
isVisibleInUserInterface: boolean
10+
}
11+
12+
interface XmlDatasetMetadataExportFormat extends DatasetMetadataExportFormatBase {
13+
XMLNameSpace: string
14+
XMLSchemaLocation: string
15+
XMLSchemaVersion: string
16+
}

src/info/domain/repositories/DataverseInfoRepository.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ZipDownloadLimit } from '@/settings/domain/models/ZipDownloadLimit'
22
import { DataverseVersion } from '../models/DataverseVersion'
33
import { TermsOfUse } from '../models/TermsOfUse'
44
import { Setting } from '@/settings/domain/models/Setting'
5+
import { DatasetMetadataExportFormats } from '../models/DatasetMetadataExportFormats'
56

67
export interface DataverseInfoRepository {
78
getVersion(): Promise<DataverseVersion>
@@ -10,4 +11,5 @@ export interface DataverseInfoRepository {
1011
getMaxEmbargoDurationInMonths: () => Promise<Setting<number>>
1112
getHasPublicStore: () => Promise<Setting<boolean>>
1213
getExternalStatusesAllowed: () => Promise<Setting<string[]>>
14+
getAvailableDatasetMetadataExportFormats: () => Promise<DatasetMetadataExportFormats>
1315
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { DataverseInfoRepository } from '../repositories/DataverseInfoRepository'
2+
import { DatasetMetadataExportFormats } from '../models/DatasetMetadataExportFormats'
3+
4+
export function getAvailableDatasetMetadataExportFormats(
5+
dataverseInfoRepository: DataverseInfoRepository
6+
): Promise<DatasetMetadataExportFormats> {
7+
return dataverseInfoRepository.getAvailableDatasetMetadataExportFormats()
8+
}

0 commit comments

Comments
 (0)