cozy-ui 121.1.2 → 121.3.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/assets/icons/twake/illus/twake_workplace.svg +1 -0
  3. package/dist/cozy-ui.min.css +1 -1
  4. package/package.json +1 -1
  5. package/react/Buttons/Readme.md +37 -2
  6. package/react/Buttons/index.jsx +16 -3
  7. package/react/Icon/Readme.md +3 -1
  8. package/react/Icons/TwakeWorkplace.jsx +83 -0
  9. package/react/Layout/Layout.jsx +3 -1
  10. package/react/MuiCozyTheme/overrides/makeLightNormalOverrides.js +24 -3
  11. package/react/MuiCozyTheme/overrides/twake/makeLightNormalOverrides.js +16 -1
  12. package/react/Sidebar/index.jsx +7 -1
  13. package/react/UploadQueue/FileUploadProgress.jsx +49 -0
  14. package/react/UploadQueue/Item.jsx +99 -0
  15. package/react/UploadQueue/Pending.jsx +12 -0
  16. package/react/UploadQueue/Readme.md +10 -3
  17. package/react/UploadQueue/RemainingTime.jsx +26 -0
  18. package/react/UploadQueue/helpers.js +3 -0
  19. package/react/UploadQueue/index.jsx +3 -172
  20. package/react/UploadQueue/styles.styl +4 -2
  21. package/react/UploadQueue/useStatusIcon.js +34 -0
  22. package/stylus/objects/layouts.styl +12 -2
  23. package/stylus/objects/sidebar.styl +6 -1
  24. package/transpiled/react/Buttons/index.js +7 -4
  25. package/transpiled/react/Icons/TwakeWorkplace.js +86 -0
  26. package/transpiled/react/Layout/Layout.js +6 -2
  27. package/transpiled/react/MuiCozyTheme/overrides/makeDarkInvertedOverrides.d.ts +24 -3
  28. package/transpiled/react/MuiCozyTheme/overrides/makeDarkNormalOverrides.d.ts +24 -3
  29. package/transpiled/react/MuiCozyTheme/overrides/makeLightInvertedOverrides.d.ts +24 -3
  30. package/transpiled/react/MuiCozyTheme/overrides/makeLightNormalOverrides.d.ts +24 -3
  31. package/transpiled/react/MuiCozyTheme/overrides/makeLightNormalOverrides.js +24 -3
  32. package/transpiled/react/MuiCozyTheme/overrides/twake/makeDarkInvertedOverrides.d.ts +40 -4
  33. package/transpiled/react/MuiCozyTheme/overrides/twake/makeDarkNormalOverrides.d.ts +40 -4
  34. package/transpiled/react/MuiCozyTheme/overrides/twake/makeLightInvertedOverrides.d.ts +40 -4
  35. package/transpiled/react/MuiCozyTheme/overrides/twake/makeLightNormalOverrides.d.ts +40 -4
  36. package/transpiled/react/MuiCozyTheme/overrides/twake/makeLightNormalOverrides.js +16 -1
  37. package/transpiled/react/Sidebar/index.js +6 -2
  38. package/transpiled/react/UploadQueue/FileUploadProgress.js +66 -0
  39. package/transpiled/react/UploadQueue/Item.js +106 -0
  40. package/transpiled/react/UploadQueue/Pending.js +10 -0
  41. package/transpiled/react/UploadQueue/RemainingTime.js +43 -0
  42. package/transpiled/react/UploadQueue/helpers.js +4 -0
  43. package/transpiled/react/UploadQueue/index.js +5 -169
  44. package/transpiled/react/UploadQueue/useStatusIcon.js +45 -0
  45. package/transpiled/react/stylesheet.css +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-ui",
3
- "version": "121.1.2",
3
+ "version": "121.3.0",
4
4
  "description": "Cozy apps UI SDK",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -125,14 +125,14 @@ const iconPositions = ['startIcon', 'endIcon']
125
125
  {variants.map(variant =>
126
126
  <div key={variant}>
127
127
  <Button
128
- className="u-miw-auto u-w-2 u-h-2 u-bdrs-circle"
128
+ className="u-miw-auto u-mih-auto u-w-2 u-h-2 u-bdrs-circle"
129
129
  classes={{ label: "u-flex u-w-auto" }}
130
130
  size={isTwakeTheme() ? "small" : "medium"}
131
131
  label={<Icon icon={StopIcon} size={12} />}
132
132
  variant={variant}
133
133
  />
134
134
  <Button
135
- className="u-ml-1 u-miw-auto u-w-2 u-h-2 u-bdrs-circle"
135
+ className="u-ml-1 u-miw-auto u-mih-auto u-w-2 u-h-2 u-bdrs-circle"
136
136
  classes={{ label: "u-flex u-w-auto" }}
137
137
  label={<Icon icon={StopIcon} size={12} />}
138
138
  size={isTwakeTheme() ? "small" : "medium"}
@@ -271,3 +271,38 @@ const colors = ['default', 'inherit', 'primary', 'secondary', 'success', 'error'
271
271
  )}
272
272
  </Grid>
273
273
  ```
274
+
275
+ ### Auto height
276
+
277
+ ```jsx
278
+ import Button from 'cozy-ui/transpiled/react/Buttons'
279
+ import Stack from 'cozy-ui/transpiled/react/Stack'
280
+ import Grid from 'cozy-ui/transpiled/react/Grid'
281
+ import Paper from 'cozy-ui/transpiled/react/Paper'
282
+ import Variants from 'cozy-ui/docs/components/Variants'
283
+
284
+ const buttonVariants = ['primary', 'secondary', 'ghost', 'text']
285
+ const sizes = ['small', 'medium', 'large']
286
+ const initialVariants = [{ autoHeight: false }]
287
+
288
+ ;
289
+
290
+ <Variants initialVariants={initialVariants} screenshotAllVariants>
291
+ {variant => (
292
+ <Grid container>
293
+ {sizes.map(size =>
294
+ <Grid item xs={12} sm={4} className="u-mb-1" key={size}>
295
+ <Stack spacing="s">
296
+ <div>{size}</div>
297
+ {buttonVariants.map(buttonVariant =>
298
+ <div key={buttonVariant + size} className="u-w-4">
299
+ <Button label={`${buttonVariant} with long label`} variant={buttonVariant} size={size} height={variant.autoHeight ? 'auto' : 'default'} />
300
+ </div>
301
+ )}
302
+ </Stack>
303
+ </Grid>
304
+ )}
305
+ </Grid>
306
+ )}
307
+ </Variants>
308
+ ```
@@ -10,7 +10,17 @@ const CUSTOM_COLORS = ['success', 'error', 'warning', 'info']
10
10
 
11
11
  const DefaultButton = forwardRef(
12
12
  (
13
- { variant, className, color, label, busy, disabled, endIcon, ...props },
13
+ {
14
+ variant,
15
+ className,
16
+ color,
17
+ label,
18
+ busy,
19
+ disabled,
20
+ height,
21
+ endIcon,
22
+ ...props
23
+ },
14
24
  ref
15
25
  ) => {
16
26
  const customColor = CUSTOM_COLORS.includes(color) ? color : 'primary'
@@ -24,6 +34,7 @@ const DefaultButton = forwardRef(
24
34
  ref={ref}
25
35
  className={cx(
26
36
  { [`customColor-${customColor}`]: customColor },
37
+ { [`customSize-${height}`]: height },
27
38
  className
28
39
  )}
29
40
  color={_color}
@@ -103,11 +114,13 @@ Buttons.propTypes = {
103
114
  'error',
104
115
  'warning',
105
116
  'info'
106
- ])
117
+ ]),
118
+ height: PropTypes.oneOf(['default', 'auto'])
107
119
  }
108
120
 
109
121
  Buttons.defaultProps = {
110
- variant: 'primary'
122
+ variant: 'primary',
123
+ height: 'default'
111
124
  }
112
125
 
113
126
  export default Buttons
@@ -720,6 +720,7 @@ import ShareGrey08Icon from 'cozy-ui/transpiled/react/Icons/ShareGrey08'
720
720
  import StoreIcon from 'cozy-ui/transpiled/react/Icons/Store'
721
721
  import TopSelectIcon from 'cozy-ui/transpiled/react/Icons/TopSelect'
722
722
  import TrashDuotoneIcon from 'cozy-ui/transpiled/react/Icons/TrashDuotone'
723
+ import TwakeWorkplace from 'cozy-ui/transpiled/react/Icons/TwakeWorkplace'
723
724
 
724
725
  const icons = [
725
726
  AccountIcon,
@@ -768,7 +769,8 @@ const icons = [
768
769
  ShareGrey08Icon,
769
770
  StoreIcon,
770
771
  TopSelectIcon,
771
- TrashDuotoneIcon
772
+ TrashDuotoneIcon,
773
+ ...(isTwakeTheme() ? [TwakeWorkplace] : []),
772
774
  ]
773
775
 
774
776
  const wrapperStyle = {
@@ -0,0 +1,83 @@
1
+ // Automatically created, please run `scripts/generate-svgr-icon.sh assets/icons/twake/illus/workplace_twake.svg` to regenerate;
2
+ import React from 'react'
3
+
4
+ function SvgTwakeWorkplace(props) {
5
+ return (
6
+ <svg viewBox="0 0 22 22" fill="none" {...props}>
7
+ <rect
8
+ x={0.498}
9
+ y={0.495}
10
+ width={21.51}
11
+ height={21.51}
12
+ rx={6.563}
13
+ fill="#fff"
14
+ />
15
+ <rect
16
+ x={0.498}
17
+ y={0.495}
18
+ width={21.51}
19
+ height={21.51}
20
+ rx={6.563}
21
+ fill="url(#workplace_twake_svg__paint0_linear_1573_14803)"
22
+ />
23
+ <rect
24
+ x={0.498}
25
+ y={0.495}
26
+ width={21.51}
27
+ height={21.51}
28
+ rx={6.563}
29
+ fill="url(#workplace_twake_svg__paint1_linear_1573_14803)"
30
+ />
31
+ <rect
32
+ x={0.498}
33
+ y={0.495}
34
+ width={21.51}
35
+ height={21.51}
36
+ rx={6.563}
37
+ fill="url(#workplace_twake_svg__paint2_linear_1573_14803)"
38
+ />
39
+ <path
40
+ d="M11.281 3.7c.008.006.017.01.027.012l.014.002a.405.405 0 01.156.05c.015.007.03.016.044.024l1.068.605 1.25.707.906.512.056.032a.487.487 0 01.229.363l.002.1v3.145a.489.489 0 01-.71.401c-.017-.008-.034-.018-.05-.027l-1.606-.909-1.138-.642-.056-.032a.542.542 0 00-.178-.051h-.058a.462.462 0 00-.213.053c-.02.01-.038.021-.056.032l-1.215.696-1.458.835a3.52 3.52 0 01-.063.036.533.533 0 01-.176.058l-.07.002a.433.433 0 01-.195-.046.48.48 0 01-.283-.433V6.05a.483.483 0 01.224-.404l.05-.029.86-.493 1.021-.585 1.033-.59.256-.147.056-.032a.553.553 0 01.107-.044.53.53 0 01.071-.013.048.048 0 00.025-.012l.07-.002zm-7.514 8.774a.036.036 0 00.026-.032.487.487 0 01.27-.389l.652-.376 1.455-.84.566-.326.063-.036a.49.49 0 01.702.418v3.209a.49.49 0 00.213.394.671.671 0 00.068.04l.62.348 1.278.714.792.442.062.035c.11.064.188.168.22.29a.463.463 0 01.013.192.476.476 0 01-.224.35c-.02.013-.042.024-.063.036L8.411 18.08l-.704.386c-.019.01-.036.022-.057.031a.494.494 0 01-.48-.016l-.217-.127-2.877-1.692a.533.533 0 01-.055-.033.487.487 0 01-.219-.306c-.005-.02-.007-.043-.01-.064a.028.028 0 00-.018-.02.04.04 0 00-.007-.003v-3.763zm11.207 6.103a.078.078 0 00-.017-.012.533.533 0 00-.055-.016.47.47 0 01-.127-.049l-.069-.04-1.063-.613-1.573-.907-.05-.03a.477.477 0 01-.224-.4.477.477 0 01.27-.448l.896-.514 1.21-.692.566-.325.074-.043a.487.487 0 00.227-.35 1.02 1.02 0 00.006-.115v-3.092c0-.024 0-.04.002-.058a.481.481 0 01.356-.43.471.471 0 01.113-.019.492.492 0 01.285.084l.722.415 1.268.733.665.383.062.036a.469.469 0 01.19.218.15.15 0 01.015.048.083.083 0 00.016.032v3.964a.032.032 0 00-.015.023.178.178 0 01-.017.055.48.48 0 01-.18.208.67.67 0 01-.062.035l-.978.56-2.18 1.25a.376.376 0 01-.055.032.468.468 0 01-.127.05.389.389 0 00-.048.013.03.03 0 00-.016.014h-.087z"
41
+ fill="#fff"
42
+ />
43
+ <defs>
44
+ <linearGradient
45
+ id="workplace_twake_svg__paint0_linear_1573_14803"
46
+ x1={22.008}
47
+ y1={13.042}
48
+ x2={0.498}
49
+ y2={13.042}
50
+ gradientUnits="userSpaceOnUse"
51
+ >
52
+ <stop offset={0.13} stopColor="#A033FF" />
53
+ <stop offset={0.61} stopColor="#0094FF" />
54
+ <stop offset={1} stopColor="#4FB500" />
55
+ </linearGradient>
56
+ <linearGradient
57
+ id="workplace_twake_svg__paint1_linear_1573_14803"
58
+ x1={10.356}
59
+ y1={7.217}
60
+ x2={3.634}
61
+ y2={20.66}
62
+ gradientUnits="userSpaceOnUse"
63
+ >
64
+ <stop stopColor="#FFD600" stopOpacity={0} />
65
+ <stop offset={0.563} stopColor="#FFC700" />
66
+ </linearGradient>
67
+ <linearGradient
68
+ id="workplace_twake_svg__paint2_linear_1573_14803"
69
+ x1={12.149}
70
+ y1={13.042}
71
+ x2={19.767}
72
+ y2={21.109}
73
+ gradientUnits="userSpaceOnUse"
74
+ >
75
+ <stop offset={0.03} stopColor="#FF3B30" stopOpacity={0} />
76
+ <stop offset={0.843} stopColor="#E73B2D" />
77
+ </linearGradient>
78
+ </defs>
79
+ </svg>
80
+ )
81
+ }
82
+
83
+ export default SvgTwakeWorkplace
@@ -3,13 +3,15 @@ import PropTypes from 'prop-types'
3
3
  import React, { Component } from 'react'
4
4
 
5
5
  import styles from './styles.styl'
6
+ import { isTwakeTheme } from '../helpers/isTwakeTheme'
6
7
 
7
8
  export const Layout = ({ children, className, monoColumn, ...rest }) => {
8
9
  return (
9
10
  <div
10
11
  className={cx(
11
12
  monoColumn ? styles['o-layout'] : styles['o-layout-2panes'],
12
- className
13
+ className,
14
+ { [styles['o-layout--rounded']]: isTwakeTheme() }
13
15
  )}
14
16
  {...rest}
15
17
  >
@@ -160,9 +160,16 @@ export const makeLightNormalOverrides = theme => ({
160
160
  MuiButton: {
161
161
  root: {
162
162
  borderRadius: 2,
163
- height: '2.5rem',
164
163
  lineHeight: 'normal',
165
164
  padding: '0 1rem',
165
+ '&.customSize': {
166
+ '&-default': {
167
+ height: '2.5rem'
168
+ },
169
+ '&-auto': {
170
+ minHeight: '2.5rem'
171
+ }
172
+ },
166
173
  '&.ghost': {
167
174
  borderStyle: 'dashed !important', // important needed to override disable state
168
175
  '&:hover': {
@@ -171,15 +178,29 @@ export const makeLightNormalOverrides = theme => ({
171
178
  }
172
179
  },
173
180
  sizeSmall: {
174
- height: '2rem',
175
181
  padding: '0 0.75rem',
182
+ '&.customSize': {
183
+ '&-default': {
184
+ height: '2rem'
185
+ },
186
+ '&-auto': {
187
+ minHeight: '2rem'
188
+ }
189
+ },
176
190
  '&$text': {
177
191
  padding: '8px 6px'
178
192
  }
179
193
  },
180
194
  sizeLarge: {
181
- height: '3rem',
182
195
  padding: '0 1.25rem',
196
+ '&.customSize': {
197
+ '&-default': {
198
+ height: '3rem'
199
+ },
200
+ '&-auto': {
201
+ minHeight: '3rem'
202
+ }
203
+ },
183
204
  '&$text': {
184
205
  padding: '14px 10px'
185
206
  }
@@ -64,6 +64,14 @@ export const makeLightNormalTwakeOverrides = theme => {
64
64
  }
65
65
  }
66
66
  },
67
+ MuiLinearProgress: {
68
+ root: {
69
+ height: 3
70
+ },
71
+ colorPrimary: {
72
+ backgroundColor: theme.palette.divider
73
+ }
74
+ },
67
75
  MuiButton: {
68
76
  root: {
69
77
  borderRadius: 100,
@@ -76,8 +84,15 @@ export const makeLightNormalTwakeOverrides = theme => {
76
84
  }
77
85
  },
78
86
  sizeSmall: {
79
- height: '2.25rem',
80
87
  padding: '10px 16px',
88
+ '&.customSize': {
89
+ '&-default': {
90
+ height: '2.25rem'
91
+ },
92
+ '&-auto': {
93
+ minHeight: '2.25rem'
94
+ }
95
+ },
81
96
  '&$text': {
82
97
  padding: '8px 16px'
83
98
  }
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types'
4
4
  import React from 'react'
5
5
 
6
6
  import styles from './styles.styl'
7
+ import { isTwakeTheme } from '../helpers/isTwakeTheme'
7
8
  import { useSetFlagshipUI } from '../hooks/useSetFlagshipUi/useSetFlagshipUI'
8
9
  import { useCozyTheme } from '../providers/CozyTheme'
9
10
 
@@ -25,7 +26,12 @@ const Sidebar = ({ children, className, ...restProps }) => {
25
26
  return (
26
27
  <aside
27
28
  id="sidebar"
28
- className={cx(styles['o-sidebar'], className)}
29
+ className={cx(
30
+ styles['o-sidebar'],
31
+ { [styles['o-sidebar--border']]: !isTwakeTheme() },
32
+ { [styles['o-sidebar--large']]: isTwakeTheme() },
33
+ className
34
+ )}
29
35
  {...restProps}
30
36
  >
31
37
  {children}
@@ -0,0 +1,49 @@
1
+ import LinearProgress from '@material-ui/core/LinearProgress'
2
+ import React, { useState } from 'react'
3
+ import { useIntervalWhen } from 'rooks'
4
+
5
+ import RemainingTime from './RemainingTime'
6
+ import styles from './styles.styl'
7
+ import { withStyles } from '../styles'
8
+
9
+ const FileLinearProgress = withStyles(theme => ({
10
+ root: {
11
+ borderRadius: theme.shape.borderRadius
12
+ },
13
+ colorPrimary: {
14
+ backgroundColor: theme.palette.background.default
15
+ },
16
+ barColorPrimary: {
17
+ backgroundColor: 'var(--emerald)'
18
+ }
19
+ }))(LinearProgress)
20
+
21
+ const FileUploadProgress = ({ progress: progressProps }) => {
22
+ const [progress, setProgress] = useState(progressProps)
23
+ useIntervalWhen(
24
+ () => {
25
+ setProgress(progressProps)
26
+ },
27
+ 1000,
28
+ true,
29
+ true
30
+ )
31
+
32
+ return (
33
+ <div className={styles['upload-queue__upload-progress']}>
34
+ <div className="u-flex-grow-1 u-pr-1">
35
+ <FileLinearProgress
36
+ variant="determinate"
37
+ value={(progress.loaded / progress.total) * 100}
38
+ />
39
+ </div>
40
+ <div className="u-flex-shrink">
41
+ {progress.remainingTime ? (
42
+ <RemainingTime durationInSec={progress.remainingTime} />
43
+ ) : null}
44
+ </div>
45
+ </div>
46
+ )
47
+ }
48
+
49
+ export default FileUploadProgress
@@ -0,0 +1,99 @@
1
+ import cx from 'classnames'
2
+ import React from 'react'
3
+
4
+ import { splitFilename } from 'cozy-client/dist/models/file'
5
+
6
+ import FileUploadProgress from './FileUploadProgress'
7
+ import Pending from './Pending'
8
+ import { uploadStatus } from './index'
9
+ import styles from './styles.styl'
10
+ import { useStatusIcon } from './useStatusIcon'
11
+ import Icon from '../Icon'
12
+ import ListItem from '../ListItem'
13
+ import ListItemIcon from '../ListItemIcon'
14
+ import ListItemText from '../ListItemText'
15
+ import Typography from '../Typography'
16
+ import { Img } from '../deprecated/Media'
17
+ import { translate } from '../providers/I18n'
18
+
19
+ const Item = ({ file, status, isDirectory, progress, getMimeTypeIcon }) => {
20
+ const { CANCEL, LOADING, DONE_STATUSES, ERROR_STATUSES, PENDING } =
21
+ uploadStatus
22
+ const { filename, extension } = splitFilename(file)
23
+ let done = false
24
+ let error = false
25
+ /**
26
+ * Status came from the Upload Queue, but sometimes we're using
27
+ * manual upload without using the Upload Queue system but we're still
28
+ * using the UI component. When this is the case, the file handles on
29
+ * his own its status.
30
+ */
31
+ const statusToUse = file.status ? file.status : status
32
+
33
+ if (statusToUse !== LOADING && statusToUse !== CANCEL) {
34
+ if (ERROR_STATUSES.includes(statusToUse)) {
35
+ error = true
36
+ } else if (DONE_STATUSES.includes(statusToUse)) {
37
+ done = true
38
+ }
39
+ }
40
+
41
+ const statusIcon = useStatusIcon(statusToUse, progress)
42
+
43
+ const isPending =
44
+ statusToUse !== LOADING &&
45
+ statusToUse !== CANCEL &&
46
+ !ERROR_STATUSES.includes(statusToUse) &&
47
+ !DONE_STATUSES.includes(statusToUse) &&
48
+ statusToUse === PENDING
49
+
50
+ return (
51
+ <ListItem
52
+ divider
53
+ data-testid="upload-queue-item"
54
+ className={cx({
55
+ [styles['upload-queue-item--done']]: done,
56
+ [styles['upload-queue-item--error']]: error
57
+ })}
58
+ >
59
+ {getMimeTypeIcon ? (
60
+ <ListItemIcon className="u-ta-center">
61
+ <Icon
62
+ icon={getMimeTypeIcon(isDirectory, file.name, file.type)}
63
+ size={32}
64
+ className="u-mr-1"
65
+ />
66
+ </ListItemIcon>
67
+ ) : null}
68
+ <ListItemText
69
+ disableTypography
70
+ primary={
71
+ <div data-testid="upload-queue-item-name" className="u-ellipsis">
72
+ <Typography variant="body1" className="u-ellipsis">
73
+ {filename}
74
+ {extension && (
75
+ <Typography
76
+ component="span"
77
+ variant="body1"
78
+ color="textSecondary"
79
+ className="u-dib"
80
+ >
81
+ {extension}
82
+ </Typography>
83
+ )}
84
+ </Typography>
85
+ </div>
86
+ }
87
+ secondary={progress ? <FileUploadProgress progress={progress} /> : null}
88
+ />
89
+ {statusIcon && (
90
+ <ListItemIcon>
91
+ <Img>{statusIcon}</Img>
92
+ </ListItemIcon>
93
+ )}
94
+ {isPending && <Pending />}
95
+ </ListItem>
96
+ )
97
+ }
98
+
99
+ export default translate()(Item)
@@ -0,0 +1,12 @@
1
+ import React from 'react'
2
+
3
+ import Typography from '../Typography'
4
+ import { translate } from '../providers/I18n'
5
+
6
+ const Pending = translate()(props => (
7
+ <Typography variant="subtitle1" color="primary">
8
+ {props.t('item.pending')}
9
+ </Typography>
10
+ ))
11
+
12
+ export default Pending
@@ -12,7 +12,8 @@ the upload queue:
12
12
  ```jsx
13
13
  import isTesting from '../helpers/isTesting'
14
14
  import FileIcon from 'cozy-ui/transpiled/react/Icons/File'
15
- import UploadQueue from 'cozy-ui/transpiled/react/UploadQueue';
15
+ import UploadQueue from 'cozy-ui/transpiled/react/UploadQueue'
16
+ import Checkbox from 'cozy-ui/transpiled/react/Checkbox'
16
17
 
17
18
  const initialState = {
18
19
  popover: false
@@ -34,6 +35,9 @@ const data = {
34
35
  }, {
35
36
  file: { name: 'Photo - generic failure error.jpg', type: 'file' },
36
37
  status: 'failed'
38
+ }, {
39
+ file: { name: 'Photo - generic failure error with a very long name - really long - 2020/04/16.txt', type: 'file' },
40
+ status: 'failed'
37
41
  }, {
38
42
  file: { name: 'File with a very long name - really long - 2020/04/16.txt', type: 'file' },
39
43
  progress: {
@@ -49,10 +53,12 @@ const data = {
49
53
  }],
50
54
  doneCount: 1,
51
55
  successCount: 1
52
- };
56
+ }
57
+
58
+ ;
53
59
 
54
60
  <>
55
- popover: <input type="checkbox" value={state.popover} onChange={() => setState({ popover: !state.popover })}/>
61
+ <Checkbox label="Popover" value={state.popover} onChange={() => setState({ popover: !state.popover })} />
56
62
  <UploadQueue
57
63
  lang='fr'
58
64
  app='Cozy Drive'
@@ -61,6 +67,7 @@ const data = {
61
67
  doneCount={data.doneCount}
62
68
  successCount={data.successCount}
63
69
  popover={state.popover}
70
+ purgeQueue={() => {}}
64
71
  />
65
72
  {isTesting() && (
66
73
  <>
@@ -0,0 +1,26 @@
1
+ import cx from 'classnames'
2
+ import React from 'react'
3
+
4
+ import { numberOfReferencesForPluralForm } from './helpers'
5
+ import { formatRemainingTime } from './index'
6
+ import styles from './styles.styl'
7
+ import Typography from '../Typography'
8
+ import { useI18n } from '../providers/I18n'
9
+
10
+ const RemainingTime = ({ durationInSec }) => {
11
+ const { t } = useI18n()
12
+
13
+ return (
14
+ <Typography
15
+ variant="caption"
16
+ className={cx(styles['upload-queue__progress-caption'], 'u-ellipsis')}
17
+ >
18
+ {t('item.remainingTime', {
19
+ time: formatRemainingTime(durationInSec),
20
+ smart_count: numberOfReferencesForPluralForm(durationInSec)
21
+ })}
22
+ </Typography>
23
+ )
24
+ }
25
+
26
+ export default RemainingTime
@@ -0,0 +1,3 @@
1
+ // https://date-fns.org/v2.28.0/docs/formatDistanceToNow
2
+ export const numberOfReferencesForPluralForm = durationInSec =>
3
+ durationInSec < 90 || (durationInSec > 2670 && durationInSec < 5370) ? 1 : 2