cozy-ui 111.21.0 → 112.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/package.json +4 -3
- package/react/FileImageLoader/Readme.md +66 -3
- package/react/FileImageLoader/index.jsx +3 -3
- package/react/FileImageLoader/index.spec.jsx +1 -1
- package/react/hooks/useClientErrors.jsx +140 -0
- package/react/hooks/useClientErrors.spec.jsx +102 -0
- package/react/index.js +0 -1
- package/transpiled/react/FileImageLoader/index.js +3 -3
- package/transpiled/react/hooks/useClientErrors.js +167 -0
- package/transpiled/react/index.js +0 -1
- package/transpiled/react/stylesheet.css +1 -1
- package/react/Viewer/Footer/BottomSheetContent.jsx +0 -29
- package/react/Viewer/Footer/DownloadButton.jsx +0 -67
- package/react/Viewer/Footer/FooterActionButtons.jsx +0 -22
- package/react/Viewer/Footer/FooterActionButtons.spec.jsx +0 -30
- package/react/Viewer/Footer/FooterContent.jsx +0 -99
- package/react/Viewer/Footer/ForwardButton.jsx +0 -95
- package/react/Viewer/Footer/ForwardButton.spec.jsx +0 -87
- package/react/Viewer/Footer/ForwardOrDownloadButton.jsx +0 -24
- package/react/Viewer/Footer/Sharing.jsx +0 -60
- package/react/Viewer/Footer/helpers.js +0 -107
- package/react/Viewer/Footer/helpers.spec.js +0 -77
- package/react/Viewer/NoViewer/DownloadButton.jsx +0 -28
- package/react/Viewer/NoViewer/FileIcon.jsx +0 -46
- package/react/Viewer/NoViewer/NoViewer.jsx +0 -29
- package/react/Viewer/NoViewer/NoViewer.spec.jsx +0 -44
- package/react/Viewer/NoViewer/__snapshots__/NoViewer.spec.jsx.snap +0 -82
- package/react/Viewer/NoViewer/index.jsx +0 -1
- package/react/Viewer/Panel/ActionMenuDesktop.jsx +0 -66
- package/react/Viewer/Panel/ActionMenuMobile.jsx +0 -74
- package/react/Viewer/Panel/ActionMenuWrapper.jsx +0 -104
- package/react/Viewer/Panel/Certifications.jsx +0 -62
- package/react/Viewer/Panel/PanelContent.jsx +0 -49
- package/react/Viewer/Panel/Qualification.jsx +0 -114
- package/react/Viewer/Panel/QualificationListItemContact.jsx +0 -85
- package/react/Viewer/Panel/QualificationListItemDate.jsx +0 -77
- package/react/Viewer/Panel/QualificationListItemInformation.jsx +0 -68
- package/react/Viewer/Panel/QualificationListItemInformation.spec.jsx +0 -73
- package/react/Viewer/Panel/QualificationListItemOther.jsx +0 -61
- package/react/Viewer/Panel/QualificationListItemText.jsx +0 -30
- package/react/Viewer/Panel/getPanelBlocks.jsx +0 -56
- package/react/Viewer/Panel/getPanelBlocks.spec.jsx +0 -79
- package/react/Viewer/Panel/styles.styl +0 -13
- package/react/Viewer/Readme.md +0 -352
- package/react/Viewer/Viewer.jsx +0 -134
- package/react/Viewer/ViewerContainer.jsx +0 -169
- package/react/Viewer/ViewerExposer.js +0 -3
- package/react/Viewer/ViewerInformationsWrapper.jsx +0 -69
- package/react/Viewer/ViewerInformationsWrapper.spec.jsx +0 -63
- package/react/Viewer/ViewerWithCustomPanelAndFooter.jsx +0 -55
- package/react/Viewer/ViewersByFile/AudioViewer.jsx +0 -21
- package/react/Viewer/ViewersByFile/AudioViewer.spec.jsx +0 -39
- package/react/Viewer/ViewersByFile/BlankPaperViewer.jsx +0 -46
- package/react/Viewer/ViewersByFile/ImageViewer.jsx +0 -330
- package/react/Viewer/ViewersByFile/ImageViewer.spec.jsx +0 -70
- package/react/Viewer/ViewersByFile/NoNetworkViewer.jsx +0 -17
- package/react/Viewer/ViewersByFile/OnlyOfficeViewer.jsx +0 -28
- package/react/Viewer/ViewersByFile/PdfJsViewer.jsx +0 -210
- package/react/Viewer/ViewersByFile/PdfJsViewer.spec.jsx +0 -160
- package/react/Viewer/ViewersByFile/PdfMobileViewer.jsx +0 -106
- package/react/Viewer/ViewersByFile/PdfMobileViewer.spec.jsx +0 -76
- package/react/Viewer/ViewersByFile/ShortcutViewer.jsx +0 -38
- package/react/Viewer/ViewersByFile/ShortcutViewer.spec.jsx +0 -32
- package/react/Viewer/ViewersByFile/TextViewer.jsx +0 -126
- package/react/Viewer/ViewersByFile/TextViewer.spec.jsx +0 -118
- package/react/Viewer/ViewersByFile/VideoViewer.jsx +0 -13
- package/react/Viewer/ViewersByFile/VideoViewer.spec.jsx +0 -39
- package/react/Viewer/ViewersByFile/__snapshots__/AudioViewer.spec.jsx.snap +0 -43
- package/react/Viewer/ViewersByFile/__snapshots__/ShortcutViewer.spec.jsx.snap +0 -57
- package/react/Viewer/ViewersByFile/__snapshots__/TextViewer.spec.jsx.snap +0 -100
- package/react/Viewer/ViewersByFile/__snapshots__/VideoViewer.spec.jsx.snap +0 -19
- package/react/Viewer/ViewersByFile/styles.styl +0 -87
- package/react/Viewer/assets/IlluGenericNewPage.svg +0 -10
- package/react/Viewer/components/ExpirationAlert.jsx +0 -86
- package/react/Viewer/components/ExpirationAnnotation.jsx +0 -40
- package/react/Viewer/components/Footer.jsx +0 -13
- package/react/Viewer/components/InformationPanel.jsx +0 -26
- package/react/Viewer/components/Navigation.jsx +0 -39
- package/react/Viewer/components/PdfToolbarButton.jsx +0 -26
- package/react/Viewer/components/PrintButton.jsx +0 -90
- package/react/Viewer/components/Toolbar.jsx +0 -111
- package/react/Viewer/components/ToolbarButtons.jsx +0 -11
- package/react/Viewer/components/ToolbarFilePath.jsx +0 -61
- package/react/Viewer/components/ViewerByFile.jsx +0 -112
- package/react/Viewer/components/ViewerByFile.spec.jsx +0 -100
- package/react/Viewer/components/ViewerControls.jsx +0 -190
- package/react/Viewer/components/ViewerControls.spec.jsx +0 -54
- package/react/Viewer/components/ViewerSpinner.jsx +0 -17
- package/react/Viewer/components/styles.styl +0 -93
- package/react/Viewer/helpers.js +0 -131
- package/react/Viewer/helpers.spec.js +0 -136
- package/react/Viewer/hoc/withFileUrl.jsx +0 -93
- package/react/Viewer/hoc/withViewerLocales.jsx +0 -4
- package/react/Viewer/hooks/useReferencedContactName.jsx +0 -26
- package/react/Viewer/index.jsx +0 -12
- package/react/Viewer/locales/en.json +0 -66
- package/react/Viewer/locales/fr.json +0 -66
- package/react/Viewer/locales/index.js +0 -4
- package/react/Viewer/proptypes.js +0 -12
- package/react/Viewer/providers/ActionMenuProvider.jsx +0 -35
- package/react/Viewer/queries.js +0 -20
- package/react/Viewer/styles.styl +0 -22
- package/react/Viewer/vars.styl +0 -6
- package/transpiled/react/Viewer/Footer/BottomSheetContent.js +0 -28
- package/transpiled/react/Viewer/Footer/DownloadButton.js +0 -91
- package/transpiled/react/Viewer/Footer/FooterActionButtons.js +0 -21
- package/transpiled/react/Viewer/Footer/FooterContent.js +0 -98
- package/transpiled/react/Viewer/Footer/ForwardButton.js +0 -143
- package/transpiled/react/Viewer/Footer/ForwardOrDownloadButton.js +0 -25
- package/transpiled/react/Viewer/Footer/Sharing.js +0 -57
- package/transpiled/react/Viewer/Footer/helpers.js +0 -151
- package/transpiled/react/Viewer/NoViewer/DownloadButton.js +0 -34
- package/transpiled/react/Viewer/NoViewer/FileIcon.js +0 -57
- package/transpiled/react/Viewer/NoViewer/NoViewer.js +0 -49
- package/transpiled/react/Viewer/NoViewer/index.js +0 -1
- package/transpiled/react/Viewer/Panel/ActionMenuDesktop.js +0 -68
- package/transpiled/react/Viewer/Panel/ActionMenuMobile.js +0 -70
- package/transpiled/react/Viewer/Panel/ActionMenuWrapper.js +0 -129
- package/transpiled/react/Viewer/Panel/Certifications.js +0 -56
- package/transpiled/react/Viewer/Panel/PanelContent.js +0 -48
- package/transpiled/react/Viewer/Panel/Qualification.js +0 -119
- package/transpiled/react/Viewer/Panel/QualificationListItemContact.js +0 -96
- package/transpiled/react/Viewer/Panel/QualificationListItemDate.js +0 -64
- package/transpiled/react/Viewer/Panel/QualificationListItemInformation.js +0 -59
- package/transpiled/react/Viewer/Panel/QualificationListItemOther.js +0 -53
- package/transpiled/react/Viewer/Panel/QualificationListItemText.js +0 -29
- package/transpiled/react/Viewer/Panel/getPanelBlocks.js +0 -62
- package/transpiled/react/Viewer/Viewer.js +0 -172
- package/transpiled/react/Viewer/ViewerContainer.js +0 -189
- package/transpiled/react/Viewer/ViewerExposer.js +0 -2
- package/transpiled/react/Viewer/ViewerInformationsWrapper.js +0 -49
- package/transpiled/react/Viewer/ViewerWithCustomPanelAndFooter.js +0 -56
- package/transpiled/react/Viewer/ViewersByFile/AudioViewer.js +0 -41
- package/transpiled/react/Viewer/ViewersByFile/BlankPaperViewer.js +0 -74
- package/transpiled/react/Viewer/ViewersByFile/ImageViewer.js +0 -367
- package/transpiled/react/Viewer/ViewersByFile/NoNetworkViewer.js +0 -38
- package/transpiled/react/Viewer/ViewersByFile/OnlyOfficeViewer.js +0 -29
- package/transpiled/react/Viewer/ViewersByFile/PdfJsViewer.js +0 -254
- package/transpiled/react/Viewer/ViewersByFile/PdfMobileViewer.js +0 -153
- package/transpiled/react/Viewer/ViewersByFile/ShortcutViewer.js +0 -42
- package/transpiled/react/Viewer/ViewersByFile/TextViewer.js +0 -219
- package/transpiled/react/Viewer/ViewersByFile/VideoViewer.js +0 -33
- package/transpiled/react/Viewer/assets/IlluGenericNewPage.svg +0 -10
- package/transpiled/react/Viewer/components/ExpirationAlert.js +0 -100
- package/transpiled/react/Viewer/components/ExpirationAnnotation.js +0 -41
- package/transpiled/react/Viewer/components/Footer.js +0 -29
- package/transpiled/react/Viewer/components/InformationPanel.js +0 -23
- package/transpiled/react/Viewer/components/Navigation.js +0 -47
- package/transpiled/react/Viewer/components/PdfToolbarButton.js +0 -28
- package/transpiled/react/Viewer/components/PrintButton.js +0 -137
- package/transpiled/react/Viewer/components/Toolbar.js +0 -115
- package/transpiled/react/Viewer/components/ToolbarButtons.js +0 -9
- package/transpiled/react/Viewer/components/ToolbarFilePath.js +0 -71
- package/transpiled/react/Viewer/components/ViewerByFile.js +0 -105
- package/transpiled/react/Viewer/components/ViewerControls.js +0 -226
- package/transpiled/react/Viewer/components/ViewerSpinner.js +0 -17
- package/transpiled/react/Viewer/helpers.js +0 -147
- package/transpiled/react/Viewer/hoc/withFileUrl.js +0 -207
- package/transpiled/react/Viewer/hoc/withViewerLocales.js +0 -3
- package/transpiled/react/Viewer/hooks/useReferencedContactName.js +0 -32
- package/transpiled/react/Viewer/index.js +0 -11
- package/transpiled/react/Viewer/locales/index.js +0 -136
- package/transpiled/react/Viewer/proptypes.js +0 -14
- package/transpiled/react/Viewer/providers/ActionMenuProvider.js +0 -34
- package/transpiled/react/Viewer/queries.js +0 -26
- /package/react/{Viewer/providers/EncryptedProvider.jsx → providers/Encrypted/index.jsx} +0 -0
- /package/transpiled/react/{Viewer/providers/EncryptedProvider.js → providers/Encrypted/index.js} +0 -0
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import cx from 'classnames'
|
|
2
|
-
import PropTypes from 'prop-types'
|
|
3
|
-
import React, { useMemo } from 'react'
|
|
4
|
-
|
|
5
|
-
import BottomSheetContent from './BottomSheetContent'
|
|
6
|
-
import { extractChildrenCompByName } from './helpers'
|
|
7
|
-
import BottomSheet, { BottomSheetHeader } from '../../BottomSheet'
|
|
8
|
-
import { makeStyles } from '../../styles'
|
|
9
|
-
import PrintButton from '../components/PrintButton'
|
|
10
|
-
import { isValidForPanel } from '../helpers'
|
|
11
|
-
|
|
12
|
-
const FooterButtons = ({
|
|
13
|
-
file,
|
|
14
|
-
FooterActionButtonsWithFile = { FooterActionButtonsWithFile }
|
|
15
|
-
}) => {
|
|
16
|
-
return (
|
|
17
|
-
<>
|
|
18
|
-
{FooterActionButtonsWithFile}
|
|
19
|
-
<PrintButton file={file} variant="button" />
|
|
20
|
-
</>
|
|
21
|
-
)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const useStyles = makeStyles(theme => ({
|
|
25
|
-
footer: {
|
|
26
|
-
display: 'flex',
|
|
27
|
-
alignItems: 'center',
|
|
28
|
-
width: 'calc(100% - 2rem)',
|
|
29
|
-
height: '100%',
|
|
30
|
-
paddingLeft: '1rem',
|
|
31
|
-
paddingRight: '1rem',
|
|
32
|
-
borderTop: `1px solid ${theme.palette.divider}`,
|
|
33
|
-
columnGap: '0.5rem'
|
|
34
|
-
},
|
|
35
|
-
bottomSheetHeader: {
|
|
36
|
-
columnGap: '0.5rem'
|
|
37
|
-
}
|
|
38
|
-
}))
|
|
39
|
-
|
|
40
|
-
const FooterContent = ({ file, toolbarRef, children, isPublic }) => {
|
|
41
|
-
const styles = useStyles()
|
|
42
|
-
|
|
43
|
-
const toolbarProps = useMemo(() => ({ ref: toolbarRef }), [toolbarRef])
|
|
44
|
-
|
|
45
|
-
const FooterActionButtonsWithFile = extractChildrenCompByName({
|
|
46
|
-
children,
|
|
47
|
-
file,
|
|
48
|
-
name: 'FooterActionButtons'
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
const bottomSheetSettings = {
|
|
52
|
-
isOpenMin: isPublic ? true : false,
|
|
53
|
-
mediumHeightRatio: isPublic ? undefined : 0.5
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (isValidForPanel({ file })) {
|
|
57
|
-
return (
|
|
58
|
-
<BottomSheet
|
|
59
|
-
toolbarProps={toolbarProps}
|
|
60
|
-
portalProps={{ disablePortal: true }}
|
|
61
|
-
settings={bottomSheetSettings}
|
|
62
|
-
>
|
|
63
|
-
<BottomSheetHeader
|
|
64
|
-
className={cx('u-ph-1 u-pb-1', styles.bottomSheetHeader)}
|
|
65
|
-
>
|
|
66
|
-
<FooterButtons
|
|
67
|
-
file={file}
|
|
68
|
-
FooterActionButtonsWithFile={FooterActionButtonsWithFile}
|
|
69
|
-
/>
|
|
70
|
-
</BottomSheetHeader>
|
|
71
|
-
<BottomSheetContent file={file} isPublic={isPublic} />
|
|
72
|
-
</BottomSheet>
|
|
73
|
-
)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// If `FooterActionButtons` hasn't children
|
|
77
|
-
if (!FooterActionButtonsWithFile) return null
|
|
78
|
-
|
|
79
|
-
return (
|
|
80
|
-
<div className={styles.footer}>
|
|
81
|
-
<FooterButtons
|
|
82
|
-
file={file}
|
|
83
|
-
FooterActionButtonsWithFile={FooterActionButtonsWithFile}
|
|
84
|
-
/>
|
|
85
|
-
</div>
|
|
86
|
-
)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
FooterContent.propTypes = {
|
|
90
|
-
file: PropTypes.object.isRequired,
|
|
91
|
-
toolbarRef: PropTypes.object,
|
|
92
|
-
isPublic: PropTypes.bool,
|
|
93
|
-
children: PropTypes.oneOfType([
|
|
94
|
-
PropTypes.node,
|
|
95
|
-
PropTypes.arrayOf(PropTypes.node)
|
|
96
|
-
])
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export default FooterContent
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import PropTypes from 'prop-types'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
|
|
4
|
-
import { useClient } from 'cozy-client'
|
|
5
|
-
import { getSharingLink } from 'cozy-client/dist/models/sharing'
|
|
6
|
-
import { isIOS, isMobileApp } from 'cozy-device-helper'
|
|
7
|
-
|
|
8
|
-
import { exportFilesNative } from './helpers'
|
|
9
|
-
import Button from '../../Buttons'
|
|
10
|
-
import Icon from '../../Icon'
|
|
11
|
-
import IconButton from '../../IconButton'
|
|
12
|
-
import ReplyIcon from '../../Icons/Reply'
|
|
13
|
-
import ShareIosIcon from '../../Icons/ShareIos'
|
|
14
|
-
import Alerter from '../../deprecated/Alerter'
|
|
15
|
-
import { useI18n } from '../../providers/I18n'
|
|
16
|
-
|
|
17
|
-
const ForwardIcon = isIOS() ? ShareIosIcon : ReplyIcon
|
|
18
|
-
|
|
19
|
-
const ForwardButton = ({ file, variant, onClick }) => {
|
|
20
|
-
const { t } = useI18n()
|
|
21
|
-
const client = useClient()
|
|
22
|
-
|
|
23
|
-
const icon = <Icon icon={ForwardIcon} />
|
|
24
|
-
const label = t('Viewer.actions.forward')
|
|
25
|
-
|
|
26
|
-
const onFileOpen = async file => {
|
|
27
|
-
if (isMobileApp()) {
|
|
28
|
-
try {
|
|
29
|
-
await exportFilesNative(client, [file])
|
|
30
|
-
} catch (error) {
|
|
31
|
-
Alerter.info(`Viewer.error.${error}`, { fileMime: file.mime })
|
|
32
|
-
}
|
|
33
|
-
} else {
|
|
34
|
-
try {
|
|
35
|
-
const url = await getSharingLink(client, [file.id])
|
|
36
|
-
const shareData = {
|
|
37
|
-
title: t('Viewer.share.title', { name: file.name }),
|
|
38
|
-
text: t('Viewer.share.text', { name: file.name }),
|
|
39
|
-
url
|
|
40
|
-
}
|
|
41
|
-
navigator.share(shareData)
|
|
42
|
-
} catch (error) {
|
|
43
|
-
Alerter.error('Viewer.share.error', { error: error })
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const handleClick = () => {
|
|
49
|
-
if (onClick) onClick()
|
|
50
|
-
else onFileOpen(file)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (variant === 'iconButton') {
|
|
54
|
-
return (
|
|
55
|
-
<IconButton className="u-white" aria-label={label} onClick={handleClick}>
|
|
56
|
-
{icon}
|
|
57
|
-
</IconButton>
|
|
58
|
-
)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (variant === 'buttonIcon') {
|
|
62
|
-
return (
|
|
63
|
-
<Button
|
|
64
|
-
variant="secondary"
|
|
65
|
-
label={icon}
|
|
66
|
-
aria-label={label}
|
|
67
|
-
onClick={handleClick}
|
|
68
|
-
/>
|
|
69
|
-
)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return (
|
|
73
|
-
<Button
|
|
74
|
-
fullWidth
|
|
75
|
-
variant="secondary"
|
|
76
|
-
startIcon={icon}
|
|
77
|
-
data-testid="openFileButton"
|
|
78
|
-
label={label}
|
|
79
|
-
onClick={handleClick}
|
|
80
|
-
/>
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
ForwardButton.propTypes = {
|
|
85
|
-
file: PropTypes.object.isRequired,
|
|
86
|
-
variant: PropTypes.oneOf(['default', 'iconButton', 'buttonIcon']),
|
|
87
|
-
onClick: PropTypes.func
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
ForwardButton.defaultProptypes = {
|
|
91
|
-
variant: 'default'
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export { exportFilesNative }
|
|
95
|
-
export default ForwardButton
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { render, fireEvent } from '@testing-library/react'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
|
|
4
|
-
import { getSharingLink } from 'cozy-client/dist/models/sharing'
|
|
5
|
-
import { isMobileApp } from 'cozy-device-helper'
|
|
6
|
-
|
|
7
|
-
import ForwardButton from './ForwardButton'
|
|
8
|
-
import { exportFilesNative } from './helpers'
|
|
9
|
-
import DemoProvider from '../docs/DemoProvider'
|
|
10
|
-
|
|
11
|
-
jest.mock('cozy-device-helper')
|
|
12
|
-
jest.mock('cozy-client/dist/models/sharing', () => ({
|
|
13
|
-
...jest.requireActual('cozy-client/dist/models/sharing'),
|
|
14
|
-
getSharingLink: jest.fn()
|
|
15
|
-
}))
|
|
16
|
-
jest.mock('./helpers')
|
|
17
|
-
|
|
18
|
-
const file = {
|
|
19
|
-
_id: '123',
|
|
20
|
-
name: 'filename.pdf'
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const setup = ({ isMobileApplication, onClick }) => {
|
|
24
|
-
isMobileApp.mockReturnValue(isMobileApplication)
|
|
25
|
-
return render(
|
|
26
|
-
<DemoProvider>
|
|
27
|
-
<ForwardButton file={file} onClick={onClick} />
|
|
28
|
-
</DemoProvider>
|
|
29
|
-
)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
describe('ForwardButton', () => {
|
|
33
|
-
beforeEach(() => {
|
|
34
|
-
jest.resetAllMocks()
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
describe('exportFilesNative', () => {
|
|
38
|
-
it('should call it if is on native app', async () => {
|
|
39
|
-
const { findByTestId } = setup({ isMobileApplication: true })
|
|
40
|
-
|
|
41
|
-
const btn = await findByTestId('openFileButton')
|
|
42
|
-
fireEvent.click(btn)
|
|
43
|
-
|
|
44
|
-
expect(exportFilesNative).toHaveBeenCalledTimes(1)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('should not call it if is on web app', async () => {
|
|
48
|
-
const { findByTestId } = setup({ isMobileApplication: false })
|
|
49
|
-
|
|
50
|
-
const btn = await findByTestId('openFileButton')
|
|
51
|
-
fireEvent.click(btn)
|
|
52
|
-
|
|
53
|
-
expect(exportFilesNative).toHaveBeenCalledTimes(0)
|
|
54
|
-
})
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
describe('getSharingLink', () => {
|
|
58
|
-
it('should not call it if is on native app', async () => {
|
|
59
|
-
const { findByTestId } = setup({ isMobileApplication: true })
|
|
60
|
-
|
|
61
|
-
const btn = await findByTestId('openFileButton')
|
|
62
|
-
fireEvent.click(btn)
|
|
63
|
-
|
|
64
|
-
expect(getSharingLink).toHaveBeenCalledTimes(0)
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
it('should not call it if the "onClick" prop is passed', async () => {
|
|
68
|
-
const onClick = jest.fn()
|
|
69
|
-
const { findByTestId } = setup({ isMobileApplication: true, onClick })
|
|
70
|
-
|
|
71
|
-
const btn = await findByTestId('openFileButton')
|
|
72
|
-
fireEvent.click(btn)
|
|
73
|
-
|
|
74
|
-
expect(getSharingLink).toHaveBeenCalledTimes(0)
|
|
75
|
-
expect(onClick).toHaveBeenCalledTimes(1)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
it('should call it if is on web app', async () => {
|
|
79
|
-
const { findByTestId } = setup({ isMobileApplication: false })
|
|
80
|
-
|
|
81
|
-
const btn = await findByTestId('openFileButton')
|
|
82
|
-
fireEvent.click(btn)
|
|
83
|
-
|
|
84
|
-
expect(getSharingLink).toHaveBeenCalledTimes(1)
|
|
85
|
-
})
|
|
86
|
-
})
|
|
87
|
-
})
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import PropTypes from 'prop-types'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
|
|
4
|
-
import { useClient } from 'cozy-client'
|
|
5
|
-
|
|
6
|
-
import DownloadButton from './DownloadButton'
|
|
7
|
-
import ForwardButton from './ForwardButton'
|
|
8
|
-
import { shouldBeForwardButton } from './helpers'
|
|
9
|
-
|
|
10
|
-
const ForwardOrDownloadButton = ({ file, ...props }) => {
|
|
11
|
-
const client = useClient()
|
|
12
|
-
|
|
13
|
-
const FileActionButton = shouldBeForwardButton(client)
|
|
14
|
-
? ForwardButton
|
|
15
|
-
: DownloadButton
|
|
16
|
-
|
|
17
|
-
return <FileActionButton file={file} {...props} />
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
ForwardOrDownloadButton.propTypes = {
|
|
21
|
-
file: PropTypes.object
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export default ForwardOrDownloadButton
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import PropTypes from 'prop-types'
|
|
2
|
-
import React, { useState } from 'react'
|
|
3
|
-
|
|
4
|
-
import { useClient } from 'cozy-client'
|
|
5
|
-
import { ShareModal, ShareButton } from 'cozy-sharing'
|
|
6
|
-
import { SharingProvider } from 'cozy-sharing/dist/SharingProvider'
|
|
7
|
-
|
|
8
|
-
import Icon from '../../Icon'
|
|
9
|
-
import IconButton from '../../IconButton'
|
|
10
|
-
import ShareIcon from '../../Icons/Share'
|
|
11
|
-
|
|
12
|
-
const Sharing = ({ file, variant }) => {
|
|
13
|
-
const client = useClient()
|
|
14
|
-
const [showShareModal, setShowShareModal] = useState(false)
|
|
15
|
-
|
|
16
|
-
const SharingButton =
|
|
17
|
-
variant === 'iconButton' ? (
|
|
18
|
-
<IconButton className="u-white" onClick={() => setShowShareModal(true)}>
|
|
19
|
-
<Icon icon={ShareIcon} />
|
|
20
|
-
</IconButton>
|
|
21
|
-
) : (
|
|
22
|
-
<ShareButton
|
|
23
|
-
fullWidth
|
|
24
|
-
useShortLabel
|
|
25
|
-
docId={file.id}
|
|
26
|
-
onClick={() => setShowShareModal(true)}
|
|
27
|
-
/>
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<>
|
|
32
|
-
<SharingProvider
|
|
33
|
-
client={client}
|
|
34
|
-
doctype="io.cozy.files"
|
|
35
|
-
documentType="Files"
|
|
36
|
-
>
|
|
37
|
-
{showShareModal && (
|
|
38
|
-
<ShareModal
|
|
39
|
-
document={file}
|
|
40
|
-
documentType="Files"
|
|
41
|
-
sharingDesc={file.name}
|
|
42
|
-
onClose={() => setShowShareModal(false)}
|
|
43
|
-
/>
|
|
44
|
-
)}
|
|
45
|
-
{SharingButton}
|
|
46
|
-
</SharingProvider>
|
|
47
|
-
</>
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
Sharing.propTypes = {
|
|
52
|
-
file: PropTypes.object,
|
|
53
|
-
variant: PropTypes.oneOf(['default', 'iconButton'])
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
Sharing.defaultProptypes = {
|
|
57
|
-
variant: 'default'
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export default Sharing
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { isValidElement, Children, cloneElement } from 'react'
|
|
2
|
-
|
|
3
|
-
import { saveFileWithCordova } from 'cozy-client/dist/models/fsnative'
|
|
4
|
-
import { isIOS, isMobileApp } from 'cozy-device-helper'
|
|
5
|
-
|
|
6
|
-
import Alerter from '../../deprecated/Alerter'
|
|
7
|
-
|
|
8
|
-
export const shouldBeForwardButton = client => {
|
|
9
|
-
const isDrive = client?.appMetadata?.slug === 'drive'
|
|
10
|
-
if (isMobileApp() || (navigator.share && !isDrive)) return true
|
|
11
|
-
return false
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const isMissingFileError = error => error.status === 404
|
|
15
|
-
const downloadFileError = error => {
|
|
16
|
-
return isMissingFileError(error)
|
|
17
|
-
? 'Viewer.error.downloadFile.missing'
|
|
18
|
-
: 'Viewer.error.missing'
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* exportFilesNative - Triggers a prompt to download a file on mobile devices
|
|
23
|
-
*
|
|
24
|
-
* @param {CozyClient} client
|
|
25
|
-
* @param {array} files One or more files to download
|
|
26
|
-
* @param {string} filename The name of the file that will be saved
|
|
27
|
-
*/
|
|
28
|
-
export const exportFilesNative = async (client, files, filename) => {
|
|
29
|
-
const downloadAllFiles = files.map(async file => {
|
|
30
|
-
const response = await client
|
|
31
|
-
.collection('io.cozy.files')
|
|
32
|
-
.fetchFileContentById(file.id)
|
|
33
|
-
|
|
34
|
-
const blob = await response.blob()
|
|
35
|
-
const filenameToUse = filename ? filename : file.name
|
|
36
|
-
const localFile = await saveFileWithCordova(blob, filenameToUse)
|
|
37
|
-
return localFile.nativeURL
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
Alerter.info('Viewer.alert.preparing', {
|
|
42
|
-
duration: Math.min(downloadAllFiles.length * 2000, 6000)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
const urls = await Promise.all(downloadAllFiles)
|
|
46
|
-
if (urls.length === 1 && isIOS()) {
|
|
47
|
-
// TODO
|
|
48
|
-
// It seems that files: is not well supported on iOS. url seems to work well
|
|
49
|
-
// at with one file. Need to check when severals
|
|
50
|
-
window.plugins.socialsharing.shareWithOptions(
|
|
51
|
-
{
|
|
52
|
-
url: urls[0]
|
|
53
|
-
},
|
|
54
|
-
result => {
|
|
55
|
-
if (result.completed === true) {
|
|
56
|
-
Alerter.success('Viewer.share.success')
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
error => {
|
|
60
|
-
throw error
|
|
61
|
-
}
|
|
62
|
-
)
|
|
63
|
-
} else {
|
|
64
|
-
window.plugins.socialsharing.shareWithOptions(
|
|
65
|
-
{
|
|
66
|
-
files: urls
|
|
67
|
-
},
|
|
68
|
-
null,
|
|
69
|
-
error => {
|
|
70
|
-
throw error
|
|
71
|
-
}
|
|
72
|
-
)
|
|
73
|
-
}
|
|
74
|
-
} catch (error) {
|
|
75
|
-
Alerter.error(downloadFileError(error))
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export const mapToAllChildren = (children, cb) => {
|
|
80
|
-
return Children.map(children, child => {
|
|
81
|
-
if (!isValidElement(child)) return child
|
|
82
|
-
|
|
83
|
-
const grandchildren = child.props.children
|
|
84
|
-
if (grandchildren) {
|
|
85
|
-
return cloneElement(child, {
|
|
86
|
-
children: mapToAllChildren(grandchildren, cb)
|
|
87
|
-
})
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return cb(child)
|
|
91
|
-
})
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export const extractChildrenCompByName = ({ children, file, name }) => {
|
|
95
|
-
const ChildrenComp =
|
|
96
|
-
Children.toArray(children).find(child => {
|
|
97
|
-
return child.type.name === name || child.type.displayName === name
|
|
98
|
-
}) || null
|
|
99
|
-
|
|
100
|
-
const ChildrenCompWithFile = isValidElement(ChildrenComp)
|
|
101
|
-
? cloneElement(ChildrenComp, {
|
|
102
|
-
file
|
|
103
|
-
})
|
|
104
|
-
: null
|
|
105
|
-
|
|
106
|
-
return ChildrenCompWithFile
|
|
107
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { isMobileApp } from 'cozy-device-helper'
|
|
2
|
-
|
|
3
|
-
import { shouldBeForwardButton } from './helpers'
|
|
4
|
-
|
|
5
|
-
jest.mock('cozy-device-helper')
|
|
6
|
-
|
|
7
|
-
describe('shouldBeForwardButton', () => {
|
|
8
|
-
const setup = ({ isMobileApplication = false, appSlug = '' }) => {
|
|
9
|
-
const mockClient = { appMetadata: { slug: appSlug } }
|
|
10
|
-
isMobileApp.mockReturnValue(isMobileApplication)
|
|
11
|
-
|
|
12
|
-
return mockClient
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
describe('Mobile native', () => {
|
|
16
|
-
it('should be true if the mobile native application is "Drive"', () => {
|
|
17
|
-
global.navigator.share = null
|
|
18
|
-
const mockClient = setup({
|
|
19
|
-
appSlug: 'drive',
|
|
20
|
-
isMobileApplication: true
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
expect(shouldBeForwardButton(mockClient)).toBe(true)
|
|
24
|
-
})
|
|
25
|
-
it('should be true if the mobile native application is not "Drive"', () => {
|
|
26
|
-
global.navigator.share = null
|
|
27
|
-
const mockClient = setup({
|
|
28
|
-
appSlug: 'other',
|
|
29
|
-
isMobileApplication: true
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
expect(shouldBeForwardButton(mockClient)).toBe(true)
|
|
33
|
-
})
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
describe('Mobile web', () => {
|
|
37
|
-
it('should be false if the mobile web application is "Drive"', () => {
|
|
38
|
-
global.navigator.share = () => {}
|
|
39
|
-
const mockClient = setup({
|
|
40
|
-
appSlug: 'drive',
|
|
41
|
-
isMobileApplication: false
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
expect(shouldBeForwardButton(mockClient)).toBe(false)
|
|
45
|
-
})
|
|
46
|
-
it('should be true if the mobile web application is not "Drive"', () => {
|
|
47
|
-
global.navigator.share = () => {}
|
|
48
|
-
const mockClient = setup({
|
|
49
|
-
appSlug: 'other',
|
|
50
|
-
isMobileApplication: false
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
expect(shouldBeForwardButton(mockClient)).toBe(true)
|
|
54
|
-
})
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
describe('Desktop', () => {
|
|
58
|
-
it('should be false if the desktop application is "Drive"', () => {
|
|
59
|
-
global.navigator.share = null
|
|
60
|
-
const mockClient = setup({
|
|
61
|
-
appSlug: 'drive',
|
|
62
|
-
isMobileApplication: false
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
expect(shouldBeForwardButton(mockClient)).toBe(false)
|
|
66
|
-
})
|
|
67
|
-
it('should be false if the desktop application is not "Drive"', () => {
|
|
68
|
-
global.navigator.share = null
|
|
69
|
-
const mockClient = setup({
|
|
70
|
-
appSlug: 'other',
|
|
71
|
-
isMobileApplication: false
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
expect(shouldBeForwardButton(mockClient)).toBe(false)
|
|
75
|
-
})
|
|
76
|
-
})
|
|
77
|
-
})
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import PropTypes from 'prop-types'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
|
|
4
|
-
import { withClient } from 'cozy-client'
|
|
5
|
-
|
|
6
|
-
import Button from '../../deprecated/Button'
|
|
7
|
-
import { FileDoctype } from '../../proptypes'
|
|
8
|
-
import { useI18n } from '../../providers/I18n'
|
|
9
|
-
import { downloadFile } from '../helpers'
|
|
10
|
-
|
|
11
|
-
const DownloadButton = ({ client, file, url }) => {
|
|
12
|
-
const { t } = useI18n()
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
<Button
|
|
16
|
-
onClick={() => downloadFile({ client, file, url })}
|
|
17
|
-
label={t('Viewer.download')}
|
|
18
|
-
/>
|
|
19
|
-
)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
DownloadButton.propTypes = {
|
|
23
|
-
client: PropTypes.object.isRequired,
|
|
24
|
-
file: FileDoctype,
|
|
25
|
-
url: PropTypes.string
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export default withClient(DownloadButton)
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
|
-
import Icon from '../../Icon'
|
|
4
|
-
import FileTypeBinIcon from '../../Icons/FileTypeBin'
|
|
5
|
-
import FileTypeCodeIcon from '../../Icons/FileTypeCode'
|
|
6
|
-
import FileTypeFilesIcon from '../../Icons/FileTypeFiles'
|
|
7
|
-
import FileTypePdfIcon from '../../Icons/FileTypePdf'
|
|
8
|
-
import FileTypeSheetIcon from '../../Icons/FileTypeSheet'
|
|
9
|
-
import FileTypeSlideIcon from '../../Icons/FileTypeSlide'
|
|
10
|
-
import FileTypeTextIcon from '../../Icons/FileTypeText'
|
|
11
|
-
import FileTypeZipIcon from '../../Icons/FileTypeZip'
|
|
12
|
-
|
|
13
|
-
const FileIcon = ({ type }) => {
|
|
14
|
-
let icon
|
|
15
|
-
|
|
16
|
-
switch (type) {
|
|
17
|
-
case 'bin':
|
|
18
|
-
icon = FileTypeBinIcon
|
|
19
|
-
break
|
|
20
|
-
case 'code':
|
|
21
|
-
icon = FileTypeCodeIcon
|
|
22
|
-
break
|
|
23
|
-
case 'spreadsheet':
|
|
24
|
-
icon = FileTypeSheetIcon
|
|
25
|
-
break
|
|
26
|
-
case 'slide':
|
|
27
|
-
icon = FileTypeSlideIcon
|
|
28
|
-
break
|
|
29
|
-
case 'text':
|
|
30
|
-
icon = FileTypeTextIcon
|
|
31
|
-
break
|
|
32
|
-
case 'zip':
|
|
33
|
-
icon = FileTypeZipIcon
|
|
34
|
-
break
|
|
35
|
-
case 'pdf':
|
|
36
|
-
icon = FileTypePdfIcon
|
|
37
|
-
break
|
|
38
|
-
default:
|
|
39
|
-
icon = FileTypeFilesIcon
|
|
40
|
-
break
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return <Icon icon={icon} width={160} height={140} />
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export default FileIcon
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import PropTypes from 'prop-types'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
|
|
4
|
-
import DownloadButton from './DownloadButton'
|
|
5
|
-
import FileIcon from './FileIcon'
|
|
6
|
-
import { FileDoctype } from '../../proptypes'
|
|
7
|
-
import styles from '../ViewersByFile/styles.styl'
|
|
8
|
-
|
|
9
|
-
const NoViewer = ({ file, url, renderFallbackExtraContent }) => (
|
|
10
|
-
<div className={styles['viewer-noviewer']}>
|
|
11
|
-
<FileIcon type={file.class} />
|
|
12
|
-
<p className={styles['viewer-filename']}>{file.name}</p>
|
|
13
|
-
{renderFallbackExtraContent(file, url)}
|
|
14
|
-
</div>
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
NoViewer.propTypes = {
|
|
18
|
-
file: FileDoctype.isRequired,
|
|
19
|
-
renderFallbackExtraContent: PropTypes.func,
|
|
20
|
-
url: PropTypes.string
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
NoViewer.defaultProps = {
|
|
24
|
-
renderFallbackExtraContent: (file, url) => (
|
|
25
|
-
<DownloadButton file={file} url={url} />
|
|
26
|
-
)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export default NoViewer
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { render } from '@testing-library/react'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
|
|
4
|
-
import NoViewer from './NoViewer'
|
|
5
|
-
import DemoProvider from '../docs/DemoProvider'
|
|
6
|
-
|
|
7
|
-
const file = {
|
|
8
|
-
_id: 'notSupported',
|
|
9
|
-
class: 'notSupported',
|
|
10
|
-
mime: 'notSupported',
|
|
11
|
-
name: 'notSupported.xyz'
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const setup = ({ renderFallbackExtraContent } = {}) => {
|
|
15
|
-
const root = render(
|
|
16
|
-
<DemoProvider>
|
|
17
|
-
<NoViewer
|
|
18
|
-
file={file}
|
|
19
|
-
renderFallbackExtraContent={renderFallbackExtraContent}
|
|
20
|
-
/>
|
|
21
|
-
</DemoProvider>
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
return { root }
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
describe('NoViewer', () => {
|
|
28
|
-
it('should render the viewer', () => {
|
|
29
|
-
const { root } = setup()
|
|
30
|
-
const { container } = root
|
|
31
|
-
|
|
32
|
-
expect(container).toMatchSnapshot()
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it('should render the viewer with specific extra content', () => {
|
|
36
|
-
const renderFallbackExtraContent = () => (
|
|
37
|
-
<div>with specific extra content</div>
|
|
38
|
-
)
|
|
39
|
-
const { root } = setup({ renderFallbackExtraContent })
|
|
40
|
-
const { container } = root
|
|
41
|
-
|
|
42
|
-
expect(container).toMatchSnapshot()
|
|
43
|
-
})
|
|
44
|
-
})
|