cozy-ui 74.4.0 → 74.5.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 +38 -0
- package/package.json +2 -2
- package/react/Snackbar/Readme.md +10 -4
- package/react/Snackbar/index.js +12 -5
- package/react/Viewer/Footer/BottomSheetContent.jsx +2 -2
- package/react/Viewer/Footer/FooterContent.jsx +13 -8
- package/react/Viewer/Panel/ActionMenuWrapper.jsx +69 -0
- package/react/Viewer/Panel/Qualification.jsx +86 -63
- package/react/Viewer/Panel/QualificationListItemContact.jsx +76 -0
- package/react/Viewer/Panel/QualificationListItemDate.jsx +47 -0
- package/react/Viewer/Panel/QualificationListItemNumber.jsx +42 -0
- package/react/Viewer/Panel/QualificationListItemOther.jsx +64 -0
- package/react/Viewer/Readme.md +8 -9
- package/react/Viewer/ViewerContainer.jsx +23 -18
- package/react/Viewer/helpers.js +64 -0
- package/react/Viewer/helpers.spec.js +50 -1
- package/react/Viewer/{Footer → hooks}/useReferencedContactName.jsx +5 -2
- package/react/Viewer/locales/en.json +27 -8
- package/react/Viewer/locales/fr.json +27 -8
- package/react/Viewer/snackbar/ViewerSnackbar.jsx +30 -0
- package/react/Viewer/snackbar/ViewerSnackbarProvider.jsx +64 -0
- package/transpiled/react/Snackbar/index.js +10 -5
- package/transpiled/react/Viewer/Footer/BottomSheetContent.js +2 -4
- package/transpiled/react/Viewer/Footer/FooterContent.js +12 -12
- package/transpiled/react/Viewer/Panel/ActionMenuWrapper.js +72 -0
- package/transpiled/react/Viewer/Panel/Qualification.js +104 -47
- package/transpiled/react/Viewer/Panel/QualificationListItemContact.js +89 -0
- package/transpiled/react/Viewer/Panel/QualificationListItemDate.js +49 -0
- package/transpiled/react/Viewer/Panel/QualificationListItemNumber.js +41 -0
- package/transpiled/react/Viewer/Panel/QualificationListItemOther.js +50 -0
- package/transpiled/react/Viewer/ViewerContainer.js +4 -2
- package/transpiled/react/Viewer/helpers.js +57 -0
- package/transpiled/react/Viewer/{Footer → hooks}/useReferencedContactName.js +3 -2
- package/transpiled/react/Viewer/snackbar/ViewerSnackbar.js +25 -0
- package/transpiled/react/Viewer/snackbar/ViewerSnackbarProvider.js +73 -0
- package/transpiled/react/Viewer/withViewerLocales.js +54 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,41 @@
|
|
|
1
|
+
# [74.5.0](https://github.com/cozy/cozy-ui/compare/v74.4.2...v74.5.0) (2022-09-09)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Change defaultProps to Snackbar component ([c749957](https://github.com/cozy/cozy-ui/commit/c749957))
|
|
7
|
+
* Disabling the Portal on the BottomSheet component in the Viewer ([35ede40](https://github.com/cozy/cozy-ui/commit/35ede40))
|
|
8
|
+
* Translations of the Qualification Viewer ([489f27a](https://github.com/cozy/cozy-ui/commit/489f27a))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* Add ActionMenuWrapper component ([653e7d5](https://github.com/cozy/cozy-ui/commit/653e7d5))
|
|
14
|
+
* Add arrays of known metadata names ([ab84458](https://github.com/cozy/cozy-ui/commit/ab84458))
|
|
15
|
+
* Add helper for formatting all known metadata ([2fa5906](https://github.com/cozy/cozy-ui/commit/2fa5906))
|
|
16
|
+
* Add QualificationListItem's components ([93f2dd1](https://github.com/cozy/cozy-ui/commit/93f2dd1))
|
|
17
|
+
* Add QualificationListItem's components to Qualification ([c987346](https://github.com/cozy/cozy-ui/commit/c987346))
|
|
18
|
+
* Add ViewerSnackbar component to display alerts in Viewer ([1aef68c](https://github.com/cozy/cozy-ui/commit/1aef68c))
|
|
19
|
+
* Add ViewerSnackbarContext to manage internal Snackbar component ([ce4d2f1](https://github.com/cozy/cozy-ui/commit/ce4d2f1))
|
|
20
|
+
* Create an alert when the attribute is copied ([ccbd467](https://github.com/cozy/cozy-ui/commit/ccbd467))
|
|
21
|
+
* Implement ViewerSnackbar in ViewerContainer component ([3c5eeae](https://github.com/cozy/cozy-ui/commit/3c5eeae))
|
|
22
|
+
* Move `useReferencedContactName` call to Qualification component ([39ccd6e](https://github.com/cozy/cozy-ui/commit/39ccd6e))
|
|
23
|
+
* Update Viewer locales files ([f418f95](https://github.com/cozy/cozy-ui/commit/f418f95))
|
|
24
|
+
|
|
25
|
+
## [74.4.2](https://github.com/cozy/cozy-ui/compare/v74.4.1...v74.4.2) (2022-09-08)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* isLoadingContacts on useReferencedContactName hook ([dab3e09](https://github.com/cozy/cozy-ui/commit/dab3e09))
|
|
31
|
+
|
|
32
|
+
## [74.4.1](https://github.com/cozy/cozy-ui/compare/v74.4.0...v74.4.1) (2022-09-08)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### Bug Fixes
|
|
36
|
+
|
|
37
|
+
* Restore BottomSheet items' gap in `FooterContent` container ([7ba1caf](https://github.com/cozy/cozy-ui/commit/7ba1caf))
|
|
38
|
+
|
|
1
39
|
# [74.4.0](https://github.com/cozy/cozy-ui/compare/v74.3.0...v74.4.0) (2022-09-06)
|
|
2
40
|
|
|
3
41
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-ui",
|
|
3
|
-
"version": "74.
|
|
3
|
+
"version": "74.5.0",
|
|
4
4
|
"description": "Cozy apps UI SDK",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"bin": {
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"intersection-observer"
|
|
66
66
|
],
|
|
67
67
|
"devDependencies": {
|
|
68
|
+
"@argos-ci/cli": "^0.2.1",
|
|
68
69
|
"@babel/cli": "7.17.6",
|
|
69
70
|
"@babel/core": "7.17.8",
|
|
70
71
|
"@babel/helper-builder-react-jsx": "7.16.7",
|
|
@@ -80,7 +81,6 @@
|
|
|
80
81
|
"@testing-library/react": "11.2.7",
|
|
81
82
|
"@testing-library/react-hooks": "^3.2.1",
|
|
82
83
|
"@testing-library/user-event": "^14.4.2",
|
|
83
|
-
"argos-cli": "^0.3.3",
|
|
84
84
|
"autoprefixer-stylus": "1.0.0",
|
|
85
85
|
"babel-loader": "8.2.4",
|
|
86
86
|
"babel-plugin-css-modules-transform": "1.6.2",
|
package/react/Snackbar/Readme.md
CHANGED
|
@@ -7,6 +7,9 @@ import IconButton from 'cozy-ui/transpiled/react/IconButton'
|
|
|
7
7
|
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
8
8
|
import Icon from 'cozy-ui/transpiled/react/Icon'
|
|
9
9
|
import InfoIcon from 'cozy-ui/transpiled/react/Icons/Info'
|
|
10
|
+
import {
|
|
11
|
+
BreakpointsProvider
|
|
12
|
+
} from 'cozy-ui/transpiled/react/hooks/useBreakpoints'
|
|
10
13
|
|
|
11
14
|
initialState = { open: false }
|
|
12
15
|
|
|
@@ -14,7 +17,7 @@ const handleToggle = () => {setState(state => ({ open: !state.open }))}
|
|
|
14
17
|
|
|
15
18
|
;
|
|
16
19
|
|
|
17
|
-
|
|
20
|
+
<BreakpointsProvider>
|
|
18
21
|
<Button
|
|
19
22
|
variant="ghost"
|
|
20
23
|
size="small"
|
|
@@ -34,7 +37,7 @@ const handleToggle = () => {setState(state => ({ open: !state.open }))}
|
|
|
34
37
|
}
|
|
35
38
|
onClose={handleToggle}
|
|
36
39
|
/>
|
|
37
|
-
|
|
40
|
+
</BreakpointsProvider>
|
|
38
41
|
```
|
|
39
42
|
|
|
40
43
|
### With `Alert` inside the `Snackbar`
|
|
@@ -44,6 +47,9 @@ import Snackbar from 'cozy-ui/transpiled/react/Snackbar'
|
|
|
44
47
|
import Alert from 'cozy-ui/transpiled/react/Alert'
|
|
45
48
|
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
46
49
|
import Variants from 'cozy-ui/docs/components/Variants'
|
|
50
|
+
import {
|
|
51
|
+
BreakpointsProvider
|
|
52
|
+
} from 'cozy-ui/transpiled/react/hooks/useBreakpoints'
|
|
47
53
|
|
|
48
54
|
initialState = { open: isTesting() }
|
|
49
55
|
|
|
@@ -54,7 +60,7 @@ const initialVariants = [{ primary: true, secondary: true, success: false, error
|
|
|
54
60
|
|
|
55
61
|
;
|
|
56
62
|
|
|
57
|
-
|
|
63
|
+
<BreakpointsProvider>
|
|
58
64
|
<Variants initialVariants={initialVariants} radio>
|
|
59
65
|
{variant => (
|
|
60
66
|
<>
|
|
@@ -77,5 +83,5 @@ const initialVariants = [{ primary: true, secondary: true, success: false, error
|
|
|
77
83
|
label="Open snackbar"
|
|
78
84
|
onClick={handleToggle}
|
|
79
85
|
/>
|
|
80
|
-
|
|
86
|
+
</BreakpointsProvider>
|
|
81
87
|
```
|
package/react/Snackbar/index.js
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react'
|
|
2
2
|
import MuiSnackbar from '@material-ui/core/Snackbar'
|
|
3
|
+
import useBreakpoints from '../hooks/useBreakpoints'
|
|
3
4
|
|
|
4
5
|
const Snackbar = forwardRef(({ children, ...props }, ref) => {
|
|
6
|
+
const { isDesktop } = useBreakpoints()
|
|
7
|
+
|
|
5
8
|
return (
|
|
6
|
-
<MuiSnackbar
|
|
9
|
+
<MuiSnackbar
|
|
10
|
+
ref={ref}
|
|
11
|
+
anchorOrigin={{
|
|
12
|
+
vertical: !isDesktop ? 'bottom' : 'top',
|
|
13
|
+
horizontal: 'center'
|
|
14
|
+
}}
|
|
15
|
+
{...props}
|
|
16
|
+
>
|
|
7
17
|
{children}
|
|
8
18
|
</MuiSnackbar>
|
|
9
19
|
)
|
|
@@ -12,10 +22,7 @@ const Snackbar = forwardRef(({ children, ...props }, ref) => {
|
|
|
12
22
|
Snackbar.displayName = 'Snackbar'
|
|
13
23
|
|
|
14
24
|
Snackbar.defaultProps = {
|
|
15
|
-
|
|
16
|
-
vertical: 'top',
|
|
17
|
-
horizontal: 'center'
|
|
18
|
-
}
|
|
25
|
+
autoHideDuration: 2000
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
export default Snackbar
|
|
@@ -5,7 +5,7 @@ import { BottomSheetItem } from '../../BottomSheet'
|
|
|
5
5
|
|
|
6
6
|
import getPanelBlocks, { panelBlocksSpecs } from '../Panel/getPanelBlocks'
|
|
7
7
|
|
|
8
|
-
const BottomSheetContent = ({ file
|
|
8
|
+
const BottomSheetContent = ({ file }) => {
|
|
9
9
|
const panelBlocks = getPanelBlocks({ panelBlocksSpecs, file })
|
|
10
10
|
|
|
11
11
|
return panelBlocks.map((PanelBlock, index) => (
|
|
@@ -14,7 +14,7 @@ const BottomSheetContent = ({ file, contactsFullname }) => {
|
|
|
14
14
|
disableGutters
|
|
15
15
|
disableElevation={index === panelBlocks.length - 1}
|
|
16
16
|
>
|
|
17
|
-
<PanelBlock file={file}
|
|
17
|
+
<PanelBlock file={file} />
|
|
18
18
|
</BottomSheetItem>
|
|
19
19
|
))
|
|
20
20
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React, { useMemo, Children, cloneElement, isValidElement } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { makeStyles } from '@material-ui/core/styles'
|
|
4
|
+
import cx from 'classnames'
|
|
4
5
|
|
|
5
6
|
import BottomSheet, { BottomSheetHeader } from '../../BottomSheet'
|
|
6
7
|
|
|
7
8
|
import { isValidForPanel } from '../helpers'
|
|
8
9
|
import BottomSheetContent from './BottomSheetContent'
|
|
9
|
-
import useReferencedContactName from './useReferencedContactName'
|
|
10
10
|
|
|
11
11
|
const useStyles = makeStyles(theme => ({
|
|
12
12
|
footer: {
|
|
@@ -18,6 +18,9 @@ const useStyles = makeStyles(theme => ({
|
|
|
18
18
|
paddingRight: '1rem',
|
|
19
19
|
borderTop: `1px solid ${theme.palette.divider}`,
|
|
20
20
|
columnGap: '0.5rem'
|
|
21
|
+
},
|
|
22
|
+
bottomSheetHeader: {
|
|
23
|
+
columnGap: '0.5rem'
|
|
21
24
|
}
|
|
22
25
|
}))
|
|
23
26
|
|
|
@@ -26,8 +29,6 @@ const FooterContent = ({ file, toolbarRef, children }) => {
|
|
|
26
29
|
|
|
27
30
|
const toolbarProps = useMemo(() => ({ ref: toolbarRef }), [toolbarRef])
|
|
28
31
|
|
|
29
|
-
const { contactName, isLoadingContacts } = useReferencedContactName(file)
|
|
30
|
-
|
|
31
32
|
const FooterActionButtons =
|
|
32
33
|
Children.toArray(children).find(child => {
|
|
33
34
|
return (
|
|
@@ -42,14 +43,18 @@ const FooterContent = ({ file, toolbarRef, children }) => {
|
|
|
42
43
|
})
|
|
43
44
|
: null
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
if (isValidForPanel({ file }) && !isLoadingContacts) {
|
|
46
|
+
if (isValidForPanel({ file })) {
|
|
47
47
|
return (
|
|
48
|
-
<BottomSheet
|
|
49
|
-
|
|
48
|
+
<BottomSheet
|
|
49
|
+
toolbarProps={toolbarProps}
|
|
50
|
+
portalProps={{ disablePortal: true }}
|
|
51
|
+
>
|
|
52
|
+
<BottomSheetHeader
|
|
53
|
+
className={cx('u-ph-1 u-pb-1', styles.bottomSheetHeader)}
|
|
54
|
+
>
|
|
50
55
|
{FooterActionButtonsWithFile}
|
|
51
56
|
</BottomSheetHeader>
|
|
52
|
-
<BottomSheetContent file={file}
|
|
57
|
+
<BottomSheetContent file={file} />
|
|
53
58
|
</BottomSheet>
|
|
54
59
|
)
|
|
55
60
|
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
import List from '../../MuiCozyTheme/List'
|
|
5
|
+
import ListItem from '../../MuiCozyTheme/ListItem'
|
|
6
|
+
import ListItemIcon from '../../MuiCozyTheme/ListItemIcon'
|
|
7
|
+
import ListItemText from '../../ListItemText'
|
|
8
|
+
import Icon from '../../Icon'
|
|
9
|
+
import Copy from '../../Icons/Copy'
|
|
10
|
+
import BottomSheet, { BottomSheetItem } from '../../BottomSheet'
|
|
11
|
+
import ActionMenu, { ActionMenuItem } from '../../ActionMenu'
|
|
12
|
+
import Typography from '../../Typography'
|
|
13
|
+
import useBreakpoints from '../../hooks/useBreakpoints'
|
|
14
|
+
import { useI18n } from '../../I18n'
|
|
15
|
+
import useViewerSnackbar from '../snackbar/ViewerSnackbarProvider'
|
|
16
|
+
|
|
17
|
+
const ActionMenuWrapper = forwardRef(({ onClose, value }, ref) => {
|
|
18
|
+
const { isMobile } = useBreakpoints()
|
|
19
|
+
const { t } = useI18n()
|
|
20
|
+
const { showViewerSnackbar } = useViewerSnackbar()
|
|
21
|
+
|
|
22
|
+
const handleCopy = () => {
|
|
23
|
+
if (navigator?.clipboard) {
|
|
24
|
+
navigator.clipboard.writeText(value)
|
|
25
|
+
showViewerSnackbar(
|
|
26
|
+
'secondary',
|
|
27
|
+
t(`Viewer.snackbar.copiedToClipboard.success`)
|
|
28
|
+
)
|
|
29
|
+
} else {
|
|
30
|
+
showViewerSnackbar('error', t(`Viewer.snackbar.copiedToClipboard.error`))
|
|
31
|
+
}
|
|
32
|
+
onClose()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (isMobile) {
|
|
36
|
+
return (
|
|
37
|
+
<BottomSheet backdrop onClose={onClose}>
|
|
38
|
+
<BottomSheetItem disableGutters>
|
|
39
|
+
<List>
|
|
40
|
+
<ListItem button onClick={handleCopy}>
|
|
41
|
+
<ListItemIcon>
|
|
42
|
+
<Icon icon={Copy} />
|
|
43
|
+
</ListItemIcon>
|
|
44
|
+
<ListItemText
|
|
45
|
+
primary={t(`Viewer.panel.qualification.actions.copyClipboard`)}
|
|
46
|
+
/>
|
|
47
|
+
</ListItem>
|
|
48
|
+
</List>
|
|
49
|
+
</BottomSheetItem>
|
|
50
|
+
</BottomSheet>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<ActionMenu onClose={onClose} anchorElRef={ref}>
|
|
56
|
+
<ActionMenuItem onClick={handleCopy} left={<Icon icon={Copy} />}>
|
|
57
|
+
<Typography>{t(`Viewer.panel.qualification.actions.copy`)}</Typography>
|
|
58
|
+
</ActionMenuItem>
|
|
59
|
+
</ActionMenu>
|
|
60
|
+
)
|
|
61
|
+
})
|
|
62
|
+
ActionMenuWrapper.displayName = 'ActionMenuWrapper'
|
|
63
|
+
|
|
64
|
+
ActionMenuWrapper.propTypes = {
|
|
65
|
+
onClose: PropTypes.func,
|
|
66
|
+
value: PropTypes.string
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default ActionMenuWrapper
|
|
@@ -1,84 +1,107 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { useRef, useState, createRef, useMemo, useEffect } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
|
|
4
|
-
import { models } from 'cozy-client'
|
|
5
|
-
|
|
6
4
|
import List from '../../MuiCozyTheme/List'
|
|
7
|
-
import ListItem from '../../MuiCozyTheme/ListItem'
|
|
8
|
-
import QualificationListItemText from './QualificationListItemText'
|
|
9
5
|
import { withViewerLocales } from '../withViewerLocales'
|
|
10
|
-
import
|
|
6
|
+
import {
|
|
7
|
+
formatMetadataQualification,
|
|
8
|
+
knownDateMetadataNames,
|
|
9
|
+
knowNumberMetadataNames,
|
|
10
|
+
knowOtherMetadataNames
|
|
11
|
+
} from '../helpers'
|
|
12
|
+
import QualificationListItemContact from './QualificationListItemContact'
|
|
13
|
+
import ActionMenuWrapper from './ActionMenuWrapper'
|
|
14
|
+
import QualificationListItemDate from './QualificationListItemDate'
|
|
15
|
+
import QualificationListItemNumber from './QualificationListItemNumber'
|
|
16
|
+
import QualificationListItemOther from './QualificationListItemOther'
|
|
17
|
+
|
|
18
|
+
const Qualification = ({ file = {} }) => {
|
|
19
|
+
const { metadata = {} } = file
|
|
20
|
+
const actionBtnRef = useRef([])
|
|
21
|
+
const [optionFile, setOptionFile] = useState({
|
|
22
|
+
isOpen: false,
|
|
23
|
+
id: '',
|
|
24
|
+
value: ''
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const hideActionsMenu = () => {
|
|
28
|
+
setOptionFile({ isOpen: false, id: '', value: '' })
|
|
29
|
+
}
|
|
11
30
|
|
|
12
|
-
const {
|
|
13
|
-
|
|
14
|
-
|
|
31
|
+
const toggleActionsMenu = (id, value) => {
|
|
32
|
+
setOptionFile(prev => {
|
|
33
|
+
if (prev.isOpen) return { isOpen: false, id: '', value: '' }
|
|
34
|
+
return { isOpen: true, id, value }
|
|
35
|
+
})
|
|
15
36
|
}
|
|
16
|
-
} = models
|
|
17
37
|
|
|
18
|
-
const
|
|
19
|
-
|
|
38
|
+
const metadataComputed = useMemo(() => {
|
|
39
|
+
return formatMetadataQualification(metadata)
|
|
40
|
+
}, [metadata])
|
|
20
41
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
datetimeLabel
|
|
27
|
-
} = metadata
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
actionBtnRef.current = metadataComputed.map(
|
|
44
|
+
(_, idx) => actionBtnRef.current[idx] ?? createRef()
|
|
45
|
+
)
|
|
46
|
+
}, [metadataComputed])
|
|
28
47
|
|
|
29
48
|
return (
|
|
30
49
|
<List className={'u-pv-1'}>
|
|
31
|
-
{
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
secondary={f(datetime, 'DD/MM/YYYY')}
|
|
42
|
-
/>
|
|
43
|
-
</ListItem>
|
|
44
|
-
)}
|
|
45
|
-
{contactsFullname && (
|
|
46
|
-
<ListItem className={'u-ph-2'}>
|
|
47
|
-
<QualificationListItemText
|
|
48
|
-
primary={t('Viewer.panel.qualification.identity')}
|
|
49
|
-
secondary={contactsFullname}
|
|
50
|
-
/>
|
|
51
|
-
</ListItem>
|
|
52
|
-
)}
|
|
53
|
-
<ListItem className={'u-ph-2'}>
|
|
54
|
-
<QualificationListItemText
|
|
55
|
-
primary={t('Viewer.panel.qualification.label.title')}
|
|
56
|
-
secondary={
|
|
57
|
-
<MidEllipsis
|
|
58
|
-
text={
|
|
59
|
-
pageLabel
|
|
60
|
-
? t(`Viewer.panel.qualification.label.${pageLabel}`)
|
|
61
|
-
: filename
|
|
62
|
-
}
|
|
50
|
+
{metadataComputed.map((meta, idx) => {
|
|
51
|
+
const { name } = meta
|
|
52
|
+
|
|
53
|
+
if (knownDateMetadataNames.includes(name)) {
|
|
54
|
+
return (
|
|
55
|
+
<QualificationListItemDate
|
|
56
|
+
key={idx}
|
|
57
|
+
ref={actionBtnRef.current[idx]}
|
|
58
|
+
metadataComputed={meta}
|
|
59
|
+
toggleActionsMenu={val => toggleActionsMenu(idx, val)}
|
|
63
60
|
/>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (knowNumberMetadataNames.includes(name)) {
|
|
65
|
+
return (
|
|
66
|
+
<QualificationListItemNumber
|
|
67
|
+
key={idx}
|
|
68
|
+
ref={actionBtnRef.current[idx]}
|
|
69
|
+
metadataComputed={meta}
|
|
70
|
+
toggleActionsMenu={val => toggleActionsMenu(idx, val)}
|
|
71
|
+
/>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (knowOtherMetadataNames.includes(name)) {
|
|
76
|
+
if (name === 'owner') {
|
|
77
|
+
return <QualificationListItemContact key={idx} file={file} />
|
|
64
78
|
}
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<QualificationListItemOther
|
|
82
|
+
key={idx}
|
|
83
|
+
ref={actionBtnRef.current[idx]}
|
|
84
|
+
filename={file.name}
|
|
85
|
+
metadataComputed={meta}
|
|
86
|
+
toggleActionsMenu={val => toggleActionsMenu(idx, val)}
|
|
87
|
+
/>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
})}
|
|
91
|
+
|
|
92
|
+
{optionFile.isOpen && (
|
|
93
|
+
<ActionMenuWrapper
|
|
94
|
+
onClose={hideActionsMenu}
|
|
95
|
+
value={optionFile.value}
|
|
96
|
+
ref={actionBtnRef.current[optionFile.id]}
|
|
65
97
|
/>
|
|
66
|
-
|
|
67
|
-
<ListItem className={'u-ph-2'}>
|
|
68
|
-
<QualificationListItemText
|
|
69
|
-
primary={t('Viewer.panel.qualification.qualification')}
|
|
70
|
-
secondary={scannerT(`Scan.items.${qualification.label}`)}
|
|
71
|
-
/>
|
|
72
|
-
</ListItem>
|
|
98
|
+
)}
|
|
73
99
|
</List>
|
|
74
100
|
)
|
|
75
101
|
}
|
|
76
102
|
|
|
77
103
|
Qualification.propTypes = {
|
|
78
|
-
file: PropTypes.object
|
|
79
|
-
t: PropTypes.func.isRequired,
|
|
80
|
-
f: PropTypes.func.isRequired,
|
|
81
|
-
lang: PropTypes.string.isRequired
|
|
104
|
+
file: PropTypes.object
|
|
82
105
|
}
|
|
83
106
|
|
|
84
|
-
export default withViewerLocales(Qualification)
|
|
107
|
+
export default withViewerLocales(React.memo(Qualification))
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React, { useRef, useState } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
import ListItem from '../../MuiCozyTheme/ListItem'
|
|
5
|
+
import ListItemSecondaryAction from '../../MuiCozyTheme/ListItemSecondaryAction'
|
|
6
|
+
import IconButton from '../../IconButton'
|
|
7
|
+
import Icon from '../../Icon'
|
|
8
|
+
import Dots from '../../Icons/Dots'
|
|
9
|
+
import QualificationListItemText from './QualificationListItemText'
|
|
10
|
+
import Spinner from '../../Spinner'
|
|
11
|
+
import useReferencedContactName from '../hooks/useReferencedContactName'
|
|
12
|
+
import { useI18n } from '../../I18n'
|
|
13
|
+
import ActionMenuWrapper from './ActionMenuWrapper'
|
|
14
|
+
|
|
15
|
+
const QualificationListItemContact = ({ file }) => {
|
|
16
|
+
const { t } = useI18n()
|
|
17
|
+
const actionBtnRef = useRef()
|
|
18
|
+
const [optionFile, setOptionFile] = useState({
|
|
19
|
+
isOpen: false,
|
|
20
|
+
value: ''
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const hideActionsMenu = () => setOptionFile({ isOpen: false, value: '' })
|
|
24
|
+
const toggleActionsMenu = value =>
|
|
25
|
+
setOptionFile(prev => {
|
|
26
|
+
if (prev.isOpen) return { isOpen: false, value: '' }
|
|
27
|
+
return { isOpen: true, value }
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const { contactName, isLoadingContacts } = useReferencedContactName(file)
|
|
31
|
+
|
|
32
|
+
if (isLoadingContacts) {
|
|
33
|
+
return (
|
|
34
|
+
<ListItem className={'u-pl-2 u-pr-3'}>
|
|
35
|
+
<Spinner color="var(--secondaryTextColor)" />
|
|
36
|
+
</ListItem>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!isLoadingContacts && !contactName) {
|
|
41
|
+
return null
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<>
|
|
46
|
+
<ListItem className={'u-ph-2'}>
|
|
47
|
+
<QualificationListItemText
|
|
48
|
+
primary={t('Viewer.panel.qualification.owner')}
|
|
49
|
+
secondary={contactName}
|
|
50
|
+
/>
|
|
51
|
+
<ListItemSecondaryAction>
|
|
52
|
+
<IconButton
|
|
53
|
+
ref={actionBtnRef}
|
|
54
|
+
onClick={() => toggleActionsMenu(contactName)}
|
|
55
|
+
>
|
|
56
|
+
<Icon icon={Dots} />
|
|
57
|
+
</IconButton>
|
|
58
|
+
</ListItemSecondaryAction>
|
|
59
|
+
</ListItem>
|
|
60
|
+
|
|
61
|
+
{optionFile.isOpen && (
|
|
62
|
+
<ActionMenuWrapper
|
|
63
|
+
onClose={hideActionsMenu}
|
|
64
|
+
value={optionFile.value}
|
|
65
|
+
ref={actionBtnRef}
|
|
66
|
+
/>
|
|
67
|
+
)}
|
|
68
|
+
</>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
QualificationListItemContact.propTypes = {
|
|
73
|
+
file: PropTypes.object.isRequired
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default QualificationListItemContact
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
import ListItem from '../../MuiCozyTheme/ListItem'
|
|
5
|
+
import ListItemSecondaryAction from '../../MuiCozyTheme/ListItemSecondaryAction'
|
|
6
|
+
import IconButton from '../../IconButton'
|
|
7
|
+
import Icon from '../../Icon'
|
|
8
|
+
import Dots from '../../Icons/Dots'
|
|
9
|
+
import QualificationListItemText from './QualificationListItemText'
|
|
10
|
+
import { useI18n } from '../../I18n'
|
|
11
|
+
import { formatDate } from '../helpers'
|
|
12
|
+
|
|
13
|
+
const QualificationListItemDate = forwardRef(
|
|
14
|
+
({ metadataComputed, toggleActionsMenu }, ref) => {
|
|
15
|
+
const { t, f, lang } = useI18n()
|
|
16
|
+
const { name, value } = metadataComputed
|
|
17
|
+
const formattedDate = formatDate({ f, lang, date: value })
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<ListItem className={'u-pl-2 u-pr-3'}>
|
|
21
|
+
<QualificationListItemText
|
|
22
|
+
primary={t(`Viewer.panel.qualification.date.title.${name}`)}
|
|
23
|
+
secondary={formattedDate}
|
|
24
|
+
/>
|
|
25
|
+
<ListItemSecondaryAction>
|
|
26
|
+
<IconButton
|
|
27
|
+
ref={ref}
|
|
28
|
+
onClick={() => toggleActionsMenu(formattedDate)}
|
|
29
|
+
>
|
|
30
|
+
<Icon icon={Dots} />
|
|
31
|
+
</IconButton>
|
|
32
|
+
</ListItemSecondaryAction>
|
|
33
|
+
</ListItem>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
QualificationListItemDate.displayName = 'QualificationListItemDate'
|
|
38
|
+
|
|
39
|
+
QualificationListItemDate.propTypes = {
|
|
40
|
+
metadataComputed: PropTypes.shape({
|
|
41
|
+
name: PropTypes.string,
|
|
42
|
+
value: PropTypes.string
|
|
43
|
+
}).isRequired,
|
|
44
|
+
toggleActionsMenu: PropTypes.func.isRequired
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default QualificationListItemDate
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
import ListItem from '../../MuiCozyTheme/ListItem'
|
|
5
|
+
import ListItemSecondaryAction from '../../MuiCozyTheme/ListItemSecondaryAction'
|
|
6
|
+
import IconButton from '../../IconButton'
|
|
7
|
+
import Icon from '../../Icon'
|
|
8
|
+
import Dots from '../../Icons/Dots'
|
|
9
|
+
import QualificationListItemText from './QualificationListItemText'
|
|
10
|
+
import { useI18n } from '../../I18n'
|
|
11
|
+
|
|
12
|
+
const QualificationListItemNumber = forwardRef(
|
|
13
|
+
({ metadataComputed, toggleActionsMenu }, ref) => {
|
|
14
|
+
const { t } = useI18n()
|
|
15
|
+
const { name, value } = metadataComputed
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<ListItem className={'u-pl-2 u-pr-3'}>
|
|
19
|
+
<QualificationListItemText
|
|
20
|
+
primary={t(`Viewer.panel.qualification.number.title.${name}`)}
|
|
21
|
+
secondary={value}
|
|
22
|
+
/>
|
|
23
|
+
<ListItemSecondaryAction>
|
|
24
|
+
<IconButton ref={ref} onClick={() => toggleActionsMenu(value)}>
|
|
25
|
+
<Icon icon={Dots} />
|
|
26
|
+
</IconButton>
|
|
27
|
+
</ListItemSecondaryAction>
|
|
28
|
+
</ListItem>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
QualificationListItemNumber.displayName = 'QualificationListItemNumber'
|
|
33
|
+
|
|
34
|
+
QualificationListItemNumber.propTypes = {
|
|
35
|
+
metadataComputed: PropTypes.shape({
|
|
36
|
+
name: PropTypes.string,
|
|
37
|
+
value: PropTypes.string
|
|
38
|
+
}).isRequired,
|
|
39
|
+
toggleActionsMenu: PropTypes.func.isRequired
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default QualificationListItemNumber
|