Skip to content

Commit 6ac9379

Browse files
authored
Merge pull request #859 from IQSS/feat/855-contact-owner-and-share-file
Contact Owner and Share buttons in File page
2 parents 2b38ef0 + 297f14d commit 6ac9379

File tree

11 files changed

+126
-7
lines changed

11 files changed

+126
-7
lines changed

CHANGELOG.md

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

1111
- Added the value entered by the user in the error messages for metadata field validation errors in EMAIL and URL type fields. For example, instead of showing “Point of Contact E-mail is not a valid email address.“, we now show “Point of Contact E-mail foo is not a valid email address.”
12+
- Contact Owner button in File Page.
13+
- Share button in File Page.
1214

1315
### Changed
1416

public/locales/en/file.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@
8585
"replace": "Replace",
8686
"delete": "Delete"
8787
}
88+
},
89+
"share": {
90+
"title": "Share File",
91+
"helpText": "Share this file on your favorite social media networks."
8892
}
8993
},
9094
"deleteFileModal": {

src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ export function DatasetActionButtons({
3030

3131
const isCurrentVersionDeaccessioned =
3232
dataset.version.publishingStatus === DatasetPublishingStatus.DEACCESSIONED
33-
const canUpdateDataset = dataset.permissions.canUpdateDataset
3433

3534
return (
3635
<ButtonGroup aria-label={t('datasetActionButtons.title')} vertical className={styles.group}>
@@ -59,7 +58,7 @@ export function DatasetActionButtons({
5958
contactRepository={contactRepository}
6059
/>
6160

62-
{(!isCurrentVersionDeaccessioned || canUpdateDataset) && <ShareDatasetButton />}
61+
{!isCurrentVersionDeaccessioned && <ShareDatasetButton />}
6362
</ButtonGroup>
6463
</ButtonGroup>
6564
)

src/sections/file/File.module.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,9 @@
4545
width: 100%;
4646
margin: 0.5rem 0;
4747
}
48+
49+
.contact-owner-and-share-group {
50+
> button {
51+
width: 50%;
52+
}
53+
}

src/sections/file/File.tsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,16 @@ import { FilePageHelper } from './FilePageHelper'
2424
import { FileEmbeddedExternalTool } from './file-embedded-external-tool/FileEmbeddedExternalTool'
2525
import { useScrollTop } from '@/shared/hooks/useScrollTop'
2626
import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository'
27+
import { ContactRepository } from '@/contact/domain/repositories/ContactRepository'
28+
import { ContactButton } from '../shared/contact/ContactButton'
29+
import { ShareFileButton } from './share-file-button/ShareFileButton'
2730

2831
interface FileProps {
2932
id: number
3033
repository: FileRepository
3134
datasetRepository: DatasetRepository
3235
dataverseInfoRepository: DataverseInfoRepository
36+
contactRepository: ContactRepository
3337
datasetVersionNumber?: string
3438
toolTypeSelectedQueryParam?: string
3539
}
@@ -39,6 +43,7 @@ export function File({
3943
repository,
4044
datasetRepository,
4145
dataverseInfoRepository,
46+
contactRepository,
4247
datasetVersionNumber,
4348
toolTypeSelectedQueryParam
4449
}: FileProps) {
@@ -68,6 +73,9 @@ export function File({
6873
file?.metadata.type.value
6974
)
7075

76+
const isDeaccessioned =
77+
file?.datasetVersion.publishingStatus === DatasetPublishingStatus.DEACCESSIONED
78+
7179
useEffect(() => {
7280
setIsLoading(isLoading)
7381
}, [isLoading, setIsLoading])
@@ -144,9 +152,7 @@ export function File({
144152
userHasDownloadPermission={file.permissions.canDownloadFile}
145153
metadata={file.metadata}
146154
ingestInProgress={file.ingest.isInProgress}
147-
isDeaccessioned={
148-
file.datasetVersion.publishingStatus === DatasetPublishingStatus.DEACCESSIONED
149-
}
155+
isDeaccessioned={isDeaccessioned}
150156
isDraft={file.datasetVersion.publishingStatus === DatasetPublishingStatus.DRAFT}
151157
/>
152158
{file.permissions.canEditOwnerDataset && (
@@ -169,6 +175,17 @@ export function File({
169175
datasetRepository={datasetRepository}
170176
/>
171177
)}
178+
179+
<ButtonGroup className={styles['contact-owner-and-share-group']}>
180+
<ContactButton
181+
toContactName={file.datasetVersion.title}
182+
contactObjectType="dataset"
183+
id={file.datasetPersistentId}
184+
contactRepository={contactRepository}
185+
/>
186+
187+
{!isDeaccessioned && <ShareFileButton />}
188+
</ButtonGroup>
172189
</ButtonGroup>
173190
</Col>
174191
</Row>

src/sections/file/FileFactory.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import { NotFoundPage } from '../not-found-page/NotFoundPage'
77
import { searchParamVersionToDomainVersion } from '../../router'
88
import { QueryParamKey } from '../Route.enum'
99
import { DataverseInfoJSDataverseRepository } from '@/info/infrastructure/repositories/DataverseInfoJSDataverseRepository'
10+
import { ContactJSDataverseRepository } from '@/contact/infrastructure/ContactJSDataverseRepository'
1011

1112
const repository = new FileJSDataverseRepository()
1213
const datasetRepository = new DatasetJSDataverseRepository()
1314
const dataverseInfoRepository = new DataverseInfoJSDataverseRepository()
15+
const contactRepository = new ContactJSDataverseRepository()
1416

1517
export class FileFactory {
1618
static create(): ReactElement {
@@ -39,6 +41,7 @@ function FileWithSearchParams() {
3941
datasetRepository={datasetRepository}
4042
toolTypeSelectedQueryParam={toolTypeSelectedQueryParam}
4143
dataverseInfoRepository={dataverseInfoRepository}
44+
contactRepository={contactRepository}
4245
/>
4346
)
4447
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { useState } from 'react'
2+
import { useTranslation } from 'react-i18next'
3+
import { Button } from '@iqss/dataverse-design-system'
4+
import { SocialShareModal } from '@/sections/shared/social-share-modal/SocialShareModal'
5+
6+
export const ShareFileButton = () => {
7+
const { t } = useTranslation('file')
8+
const { t: tShared } = useTranslation('shared')
9+
const [showShareModal, setShowShareModal] = useState(false)
10+
11+
const openShareModal = () => setShowShareModal(true)
12+
const closeShareModal = () => setShowShareModal(false)
13+
14+
return (
15+
<>
16+
<Button variant="secondary" onClick={openShareModal} size="sm">
17+
{tShared('share')}
18+
</Button>
19+
20+
<SocialShareModal
21+
shareUrl={window.location.href}
22+
show={showShareModal}
23+
handleClose={closeShareModal}
24+
title={t('actionButtons.share.title')}
25+
helpText={t('actionButtons.share.helpText')}
26+
/>
27+
</>
28+
)
29+
}

src/stories/file/File.stories.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { ExternalToolsMockRepository } from '../shared-mock-repositories/externa
1212
import { FakerHelper } from '@tests/component/shared/FakerHelper'
1313
import { ExternalToolsMother } from '@tests/component/externalTools/domain/models/ExternalToolsMother'
1414
import { DataverseInfoMockRepository } from '../shared-mock-repositories/info/DataverseInfoMockRepository'
15+
import { ContactMockRepository } from '../shared-mock-repositories/contact/ContactMockRepository'
1516

1617
const meta: Meta<typeof File> = {
1718
title: 'Pages/File',
@@ -32,6 +33,7 @@ export const Default: Story = {
3233
repository={new FileMockRepository()}
3334
datasetRepository={new DatasetMockRepository()}
3435
dataverseInfoRepository={new DataverseInfoMockRepository()}
36+
contactRepository={new ContactMockRepository()}
3537
id={56}
3638
/>
3739
)
@@ -43,6 +45,7 @@ export const Restricted: Story = {
4345
repository={new FileMockRepository(FileMother.createRestricted())}
4446
datasetRepository={new DatasetMockRepository()}
4547
dataverseInfoRepository={new DataverseInfoMockRepository()}
48+
contactRepository={new ContactMockRepository()}
4649
id={56}
4750
/>
4851
)
@@ -54,6 +57,7 @@ export const RestrictedWithAccessGranted: Story = {
5457
repository={new FileMockRepository(FileMother.createRestrictedWithAccessGranted())}
5558
datasetRepository={new DatasetMockRepository()}
5659
dataverseInfoRepository={new DataverseInfoMockRepository()}
60+
contactRepository={new ContactMockRepository()}
5761
id={56}
5862
/>
5963
)
@@ -65,6 +69,7 @@ export const Loading: Story = {
6569
repository={new FileMockLoadingRepository()}
6670
datasetRepository={new DatasetMockRepository()}
6771
dataverseInfoRepository={new DataverseInfoMockRepository()}
72+
contactRepository={new ContactMockRepository()}
6873
id={56}
6974
/>
7075
)
@@ -76,6 +81,7 @@ export const FileNotFound: Story = {
7681
repository={new FileMockNoDataRepository()}
7782
datasetRepository={new DatasetMockRepository()}
7883
dataverseInfoRepository={new DataverseInfoMockRepository()}
84+
contactRepository={new ContactMockRepository()}
7985
id={56}
8086
/>
8187
)
@@ -88,6 +94,7 @@ export const WithMultipleExternalTools: Story = {
8894
repository={new FileMockRepository(FileMother.createRealistic())}
8995
datasetRepository={new DatasetMockRepository()}
9096
dataverseInfoRepository={new DataverseInfoMockRepository()}
97+
contactRepository={new ContactMockRepository()}
9198
id={56}
9299
toolTypeSelectedQueryParam="preview"
93100
/>
@@ -111,6 +118,7 @@ export const WithOnlyOnePreviewExternalTool: Story = {
111118
repository={new FileMockRepository(FileMother.createRealistic())}
112119
datasetRepository={new DatasetMockRepository()}
113120
dataverseInfoRepository={new DataverseInfoMockRepository()}
121+
contactRepository={new ContactMockRepository()}
114122
id={56}
115123
toolTypeSelectedQueryParam="preview"
116124
/>
@@ -134,6 +142,7 @@ export const WithOnlyOneQueryExternalTool: Story = {
134142
repository={new FileMockRepository(FileMother.createRealistic())}
135143
datasetRepository={new DatasetMockRepository()}
136144
dataverseInfoRepository={new DataverseInfoMockRepository()}
145+
contactRepository={new ContactMockRepository()}
137146
id={56}
138147
toolTypeSelectedQueryParam="query"
139148
/>

tests/component/sections/dataset/dataset-action-buttons/DatasetActionButtons.spec.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,10 @@ describe('DatasetActionButtons', () => {
7373
cy.findByRole('button', { name: 'Share' }).should('exist')
7474
})
7575

76-
it('should not render Share button if the the dataset is deaccessioned and user has no edit permission', () => {
77-
const dataset = DatasetMother.createDeaccessionedwithNoEditPermission()
76+
it('should not render Share button if the the dataset is deaccessioned', () => {
77+
const dataset = DatasetMother.create({
78+
version: DatasetVersionMother.createDeaccessioned()
79+
})
7880
cy.mountAuthenticated(
7981
<DatasetActionButtons
8082
dataset={dataset}

tests/component/sections/file/File.spec.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { ExternalToolsProvider } from '@/shared/contexts/external-tools/External
77
import { ExternalToolsMother } from '@tests/component/externalTools/domain/models/ExternalToolsMother'
88
import { FileExternalToolResolvedMother } from '@tests/component/externalTools/domain/models/FileExternalToolResolvedMother'
99
import { DataverseInfoMockRepository } from '@/stories/shared-mock-repositories/info/DataverseInfoMockRepository'
10+
import { ContactMockRepository } from '@/stories/shared-mock-repositories/contact/ContactMockRepository'
11+
import { DatasetVersionMother } from '@tests/component/dataset/domain/models/DatasetMother'
1012

1113
const fileRepository: FileRepository = {} as FileRepository
1214

@@ -21,6 +23,7 @@ describe('File', () => {
2123
id={19}
2224
datasetRepository={new DatasetMockRepository()}
2325
dataverseInfoRepository={new DataverseInfoMockRepository()}
26+
contactRepository={new ContactMockRepository()}
2427
/>
2528
)
2629

@@ -54,6 +57,7 @@ describe('File', () => {
5457
id={19}
5558
datasetRepository={new DatasetMockRepository()}
5659
dataverseInfoRepository={new DataverseInfoMockRepository()}
60+
contactRepository={new ContactMockRepository()}
5761
/>
5862
)
5963

@@ -71,6 +75,7 @@ describe('File', () => {
7175
id={19}
7276
datasetRepository={new DatasetMockRepository()}
7377
dataverseInfoRepository={new DataverseInfoMockRepository()}
78+
contactRepository={new ContactMockRepository()}
7479
/>
7580
)
7681

@@ -87,6 +92,7 @@ describe('File', () => {
8792
id={19}
8893
datasetRepository={new DatasetMockRepository()}
8994
dataverseInfoRepository={new DataverseInfoMockRepository()}
95+
contactRepository={new ContactMockRepository()}
9096
/>
9197
)
9298

@@ -104,6 +110,7 @@ describe('File', () => {
104110
datasetVersionNumber={'2.0'}
105111
datasetRepository={new DatasetMockRepository()}
106112
dataverseInfoRepository={new DataverseInfoMockRepository()}
113+
contactRepository={new ContactMockRepository()}
107114
/>
108115
)
109116

@@ -117,6 +124,26 @@ describe('File', () => {
117124
cy.contains('Published On').should('exist')
118125
})
119126

127+
it('should not render Share button if the the file dataset version is deaccessioned', () => {
128+
const testFile = FileMother.createRealistic({
129+
datasetVersion: DatasetVersionMother.createDeaccessioned()
130+
})
131+
fileRepository.getById = cy.stub().as('getFile').resolves(testFile)
132+
133+
cy.customMount(
134+
<File
135+
repository={fileRepository}
136+
id={19}
137+
datasetVersionNumber={'2.0'}
138+
datasetRepository={new DatasetMockRepository()}
139+
dataverseInfoRepository={new DataverseInfoMockRepository()}
140+
contactRepository={new ContactMockRepository()}
141+
/>
142+
)
143+
cy.findByText('Deaccessioned').should('exist')
144+
cy.findByRole('button', { name: 'Share' }).should('not.exist')
145+
})
146+
120147
describe('external tools tab', () => {
121148
const externalToolsRepository: ExternalToolsRepository = {} as ExternalToolsRepository
122149

@@ -139,6 +166,7 @@ describe('File', () => {
139166
id={19}
140167
datasetRepository={new DatasetMockRepository()}
141168
dataverseInfoRepository={new DataverseInfoMockRepository()}
169+
contactRepository={new ContactMockRepository()}
142170
/>
143171
</ExternalToolsProvider>
144172
)
@@ -158,6 +186,7 @@ describe('File', () => {
158186
id={19}
159187
datasetRepository={new DatasetMockRepository()}
160188
dataverseInfoRepository={new DataverseInfoMockRepository()}
189+
contactRepository={new ContactMockRepository()}
161190
/>
162191
</ExternalToolsProvider>
163192
)
@@ -180,6 +209,7 @@ describe('File', () => {
180209
id={19}
181210
datasetRepository={new DatasetMockRepository()}
182211
dataverseInfoRepository={new DataverseInfoMockRepository()}
212+
contactRepository={new ContactMockRepository()}
183213
/>
184214
</ExternalToolsProvider>
185215
)
@@ -197,6 +227,7 @@ describe('File', () => {
197227
id={19}
198228
datasetRepository={new DatasetMockRepository()}
199229
dataverseInfoRepository={new DataverseInfoMockRepository()}
230+
contactRepository={new ContactMockRepository()}
200231
/>
201232
</ExternalToolsProvider>
202233
)
@@ -217,6 +248,7 @@ describe('File', () => {
217248
id={19}
218249
datasetRepository={new DatasetMockRepository()}
219250
dataverseInfoRepository={new DataverseInfoMockRepository()}
251+
contactRepository={new ContactMockRepository()}
220252
/>
221253
</ExternalToolsProvider>
222254
)

0 commit comments

Comments
 (0)