From 18cd43d0e6a869451a5bc384cdca4759060f8ad0 Mon Sep 17 00:00:00 2001
From: PolariTOON <36267812+PolariTOON@users.noreply.github.com>
Date: Wed, 7 Dec 2022 17:25:17 +0100
Subject: [PATCH 1/7] feat: Update `cozy-client` to 34.4.0
`cozy-client` as been upgraded to to `34.4.0` to be able to use paper helpers
BREAKING CHANGE: You need to update `cozy-client` to `>34.4.0`.
---
package.json | 4 ++--
yarn.lock | 25 ++++++++++++++++++++-----
2 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/package.json b/package.json
index c108522f03..386c612e61 100644
--- a/package.json
+++ b/package.json
@@ -90,7 +90,7 @@
"babel-preset-cozy-app": "2.0.2",
"browserslist-config-cozy": "0.4.0",
"copyfiles": "2.4.1",
- "cozy-client": "^33.0.0",
+ "cozy-client": "^34.4.0",
"cozy-device-helper": "2.0.0",
"cozy-flags": "^2.10.1",
"cozy-harvest-lib": "^6.7.3",
@@ -179,7 +179,7 @@
"rooks": "^5.11.2"
},
"peerDependencies": {
- "cozy-client": ">=33.0.0",
+ "cozy-client": ">=34.4.0",
"cozy-device-helper": "^2.0.0",
"cozy-harvest-lib": "^6.7.3",
"cozy-intent": ">=1.3.0",
diff --git a/yarn.lock b/yarn.lock
index 55176afb92..0edaf527b7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5852,16 +5852,17 @@ cozy-bi-auth@0.0.23:
lodash "^4.17.20"
node-jose "^1.1.4"
-cozy-client@^33.0.0:
- version "33.0.0"
- resolved "https://registry.yarnpkg.com/cozy-client/-/cozy-client-33.0.0.tgz#0711096ce281c9ebfe017a95475ceacf7879dd2e"
- integrity sha512-RXzjoii+3/ri99EJTJF+ogEvYKW7qQ2VPcmMS5q1UCBOqziXGnDxND/DbHPX6wZaOynSBfJ/iyBIqhlmEi469w==
+cozy-client@^34.4.0:
+ version "34.4.0"
+ resolved "https://registry.yarnpkg.com/cozy-client/-/cozy-client-34.4.0.tgz#7d72aa3a38c08de4f3597c5fc68998553dd29f2f"
+ integrity sha512-Vh50SGKVHaxT1pDlmXn5AtEd8W2dzPFczXLOm4A9HuBttNUzS8cT2/MXfo9Xs7YV7nU/PhPlKtyvdrZqo9RxXQ==
dependencies:
"@cozy/minilog" "1.0.0"
"@types/jest" "^26.0.20"
"@types/lodash" "^4.14.170"
btoa "^1.2.1"
- cozy-stack-client "^33.0.0"
+ cozy-stack-client "^34.1.5"
+ date-fns "2.29.3"
json-stable-stringify "^1.0.1"
lodash "^4.17.13"
microee "^0.0.6"
@@ -5979,6 +5980,15 @@ cozy-stack-client@^33.0.0:
mime "^2.4.0"
qs "^6.7.0"
+cozy-stack-client@^34.1.5:
+ version "34.1.5"
+ resolved "https://registry.yarnpkg.com/cozy-stack-client/-/cozy-stack-client-34.1.5.tgz#28fbc22b72f6343d968d4899d91c70f0261252f4"
+ integrity sha512-i0GsaaHNI2XmXUncbNPzuFY+DDC4/io3m7mwCmhAFyI/REHPdqOi3Oo5Mb7Euuky4A6iZjAWn5t0F69itv3rvg==
+ dependencies:
+ detect-node "^2.0.4"
+ mime "^2.4.0"
+ qs "^6.7.0"
+
create-ecdh@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff"
@@ -6450,6 +6460,11 @@ data-urls@^2.0.0:
whatwg-mimetype "^2.3.0"
whatwg-url "^8.0.0"
+date-fns@2.29.3:
+ version "2.29.3"
+ resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8"
+ integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==
+
date-fns@^1.28.5, date-fns@^1.30.1:
version "1.30.1"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
From 7705cae041bae0409e42cbf669c13988013da31c Mon Sep 17 00:00:00 2001
From: PolariTOON <36267812+PolariTOON@users.noreply.github.com>
Date: Wed, 7 Dec 2022 15:47:26 +0100
Subject: [PATCH 2/7] feat: Add an `ExpirationAnnotation` component
---
.../components/ExpirationAnnotation.jsx | 38 +++++++++++++++++++
react/Viewer/locales/en.json | 4 +-
react/Viewer/locales/fr.json | 4 +-
3 files changed, 44 insertions(+), 2 deletions(-)
create mode 100644 react/Viewer/components/ExpirationAnnotation.jsx
diff --git a/react/Viewer/components/ExpirationAnnotation.jsx b/react/Viewer/components/ExpirationAnnotation.jsx
new file mode 100644
index 0000000000..3379d68650
--- /dev/null
+++ b/react/Viewer/components/ExpirationAnnotation.jsx
@@ -0,0 +1,38 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+
+import { models } from 'cozy-client'
+
+import Typography from '../../Typography'
+import { useI18n } from '../../I18n'
+import { formatLocallyDistanceToNow } from '../../I18n/format'
+
+const { computeExpirationDate, isExpired } = models.paper
+
+const ExpirationAnnotation = ({ file }) => {
+ const { t } = useI18n()
+
+ if (isExpired(file)) {
+ return (
+
+ {t('Viewer.panel.qualification.expired')}
+
+ )
+ }
+
+ const expirationDate = computeExpirationDate(file)
+
+ return (
+
+ {t('Viewer.panel.qualification.expiresIn', {
+ duration: formatLocallyDistanceToNow(expirationDate)
+ })}
+
+ )
+}
+
+ExpirationAnnotation.propTypes = {
+ file: PropTypes.object.isRequired
+}
+
+export default ExpirationAnnotation
diff --git a/react/Viewer/locales/en.json b/react/Viewer/locales/en.json
index 35fc3c54b1..de1e4e3988 100644
--- a/react/Viewer/locales/en.json
+++ b/react/Viewer/locales/en.json
@@ -72,7 +72,9 @@
"copy": "Copy",
"copyClipboard": "Copy to clipboard",
"edit": "Edit"
- }
+ },
+ "expired": "Expired",
+ "expiresIn": "Expires in %{duration}"
},
"title": "Useful information"
},
diff --git a/react/Viewer/locales/fr.json b/react/Viewer/locales/fr.json
index 50455706e0..ab68a301c1 100644
--- a/react/Viewer/locales/fr.json
+++ b/react/Viewer/locales/fr.json
@@ -72,7 +72,9 @@
"copy": "Copier",
"copyClipboard": "Copier dans le presse-papier",
"edit": "Modifier"
- }
+ },
+ "expired": "Expiré",
+ "expiresIn": "Expire dans %{duration}"
},
"title": "Informations utiles"
},
From 763790dcfba862b88f1b320521b7562e63ae3972 Mon Sep 17 00:00:00 2001
From: PolariTOON <36267812+PolariTOON@users.noreply.github.com>
Date: Wed, 7 Dec 2022 15:47:34 +0100
Subject: [PATCH 3/7] feat: Add expiration annotations to date qualifications
---
.../Panel/QualificationListItemDate.jsx | 25 +++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/react/Viewer/Panel/QualificationListItemDate.jsx b/react/Viewer/Panel/QualificationListItemDate.jsx
index 107b0e1241..11c655a3ec 100644
--- a/react/Viewer/Panel/QualificationListItemDate.jsx
+++ b/react/Viewer/Panel/QualificationListItemDate.jsx
@@ -1,17 +1,23 @@
import React, { forwardRef } from 'react'
import PropTypes from 'prop-types'
+import { models } from 'cozy-client'
+
import ListItem from '../../MuiCozyTheme/ListItem'
import ListItemSecondaryAction from '../../MuiCozyTheme/ListItemSecondaryAction'
import IconButton from '../../IconButton'
import Icon from '../../Icon'
import Dots from '../../Icons/Dots'
+import Typography from '../../Typography'
+import ExpirationAnnotation from '../components/ExpirationAnnotation'
import QualificationListItemText from './QualificationListItemText'
import { useI18n } from '../../I18n'
import { formatDate } from '../helpers'
+const { isExpired, isExpiringSoon } = models.paper
+
const QualificationListItemDate = forwardRef(
- ({ formatedMetadataQualification, toggleActionsMenu }, ref) => {
+ ({ file, formatedMetadataQualification, toggleActionsMenu }, ref) => {
const { t, f, lang } = useI18n()
const { name, value } = formatedMetadataQualification
const formattedDate = value
@@ -22,7 +28,21 @@ const QualificationListItemDate = forwardRef(
+
+ {formattedDate}
+
+ {(isExpired(file) || isExpiringSoon(file)) && (
+ <>
+
+ {' · '}
+
+
+ >
+ )}
+ >
+ }
disabled={!value}
/>
@@ -41,6 +61,7 @@ const QualificationListItemDate = forwardRef(
QualificationListItemDate.displayName = 'QualificationListItemDate'
QualificationListItemDate.propTypes = {
+ file: PropTypes.object.isRequired,
formatedMetadataQualification: PropTypes.shape({
name: PropTypes.string,
value: PropTypes.string
From 36d019d33655aa8ce2f81a2187b5e1d0f6ac0ef4 Mon Sep 17 00:00:00 2001
From: PolariTOON <36267812+PolariTOON@users.noreply.github.com>
Date: Wed, 7 Dec 2022 17:34:16 +0100
Subject: [PATCH 4/7] feat: Add an `ExpirationAlert` component
---
react/Viewer/components/ExpirationAlert.jsx | 81 +++++++++++++++++++++
react/Viewer/locales/en.json | 4 +
react/Viewer/locales/fr.json | 4 +
3 files changed, 89 insertions(+)
create mode 100644 react/Viewer/components/ExpirationAlert.jsx
diff --git a/react/Viewer/components/ExpirationAlert.jsx b/react/Viewer/components/ExpirationAlert.jsx
new file mode 100644
index 0000000000..21b8cc4842
--- /dev/null
+++ b/react/Viewer/components/ExpirationAlert.jsx
@@ -0,0 +1,81 @@
+import React, { useState } from 'react'
+import PropTypes from 'prop-types'
+
+import { useClient, models } from 'cozy-client'
+
+import Alert from '../../Alert'
+import Button from '../../Buttons'
+import Link from '../../Link'
+import Typography from '../../Typography'
+import { withViewerLocales } from '../hoc/withViewerLocales'
+import { useI18n } from '../../I18n'
+import { formatLocallyDistanceToNow } from '../../I18n/format'
+
+const FILES_DOCTYPE = 'io.cozy.files'
+
+const { computeExpirationDate, computeExpirationNoticeLink } = models.paper
+
+const ExpirationAlert = ({ file }) => {
+ const { t } = useI18n()
+ const client = useClient()
+ const [isBusy, setIsBusy] = useState(false)
+
+ const handleClose = async () => {
+ setIsBusy(true)
+ await client.collection(FILES_DOCTYPE).updateMetadataAttribute(file.id, {
+ ...file.metadata,
+ hideExpirationAlert: true
+ })
+ setIsBusy(false)
+ }
+
+ const expirationDate = computeExpirationDate(file)
+ const expirationNoticeLink = computeExpirationNoticeLink(file)
+
+ return (
+
+ }
+ className="u-mt-1 u-mh-1"
+ >
+
+
+ {t('Viewer.panel.expiration.description', {
+ duration: formatLocallyDistanceToNow(expirationDate)
+ })}
+
+ {expirationNoticeLink && (
+ <>
+
+ {' : '}
+
+
+ {new URL(expirationNoticeLink).hostname}
+
+ >
+ )}
+
+
+ )
+}
+
+ExpirationAlert.propTypes = {
+ file: PropTypes.object.isRequired
+}
+
+export default withViewerLocales(ExpirationAlert)
diff --git a/react/Viewer/locales/en.json b/react/Viewer/locales/en.json
index de1e4e3988..7363e4682d 100644
--- a/react/Viewer/locales/en.json
+++ b/react/Viewer/locales/en.json
@@ -76,6 +76,10 @@
"expired": "Expired",
"expiresIn": "Expires in %{duration}"
},
+ "expiration": {
+ "description": "This document will expire in %{duration}, consider renewing it",
+ "dismiss": "I understood"
+ },
"title": "Useful information"
},
"previous": "Previous",
diff --git a/react/Viewer/locales/fr.json b/react/Viewer/locales/fr.json
index ab68a301c1..93349bee81 100644
--- a/react/Viewer/locales/fr.json
+++ b/react/Viewer/locales/fr.json
@@ -76,6 +76,10 @@
"expired": "Expiré",
"expiresIn": "Expire dans %{duration}"
},
+ "expiration": {
+ "description": "Ce document expirera dans %{duration}, pensez à le renouveler",
+ "dismiss": "J'ai compris"
+ },
"title": "Informations utiles"
},
"previous": "Précédente",
From 2afb4457fb95c60807b24452b8a13483d3a04910 Mon Sep 17 00:00:00 2001
From: PolariTOON <36267812+PolariTOON@users.noreply.github.com>
Date: Wed, 7 Dec 2022 15:49:34 +0100
Subject: [PATCH 5/7] feat: Add the expiration alert to the qualification block
---
react/Viewer/Panel/Qualification.jsx | 56 ++++++++++++++++------------
1 file changed, 33 insertions(+), 23 deletions(-)
diff --git a/react/Viewer/Panel/Qualification.jsx b/react/Viewer/Panel/Qualification.jsx
index d43b97561a..2eee3ec901 100644
--- a/react/Viewer/Panel/Qualification.jsx
+++ b/react/Viewer/Panel/Qualification.jsx
@@ -1,6 +1,8 @@
import React, { useRef, useState, createRef, useMemo, useEffect } from 'react'
import PropTypes from 'prop-types'
+import { models } from 'cozy-client'
+
import List from '../../MuiCozyTheme/List'
import { withViewerLocales } from '../hoc/withViewerLocales'
import {
@@ -9,12 +11,15 @@ import {
knownInformationMetadataNames,
knownOtherMetadataNames
} from '../helpers'
+import ExpirationAlert from '../components/ExpirationAlert'
import QualificationListItemContact from './QualificationListItemContact'
import ActionMenuWrapper from './ActionMenuWrapper'
import QualificationListItemDate from './QualificationListItemDate'
import QualificationListItemInformation from './QualificationListItemInformation'
import QualificationListItemOther from './QualificationListItemOther'
+const { isExpiringSoon } = models.paper
+
const makeQualificationListItemComp = metadataName => {
if (knownDateMetadataNames.includes(metadataName)) {
return QualificationListItemDate
@@ -63,31 +68,36 @@ const Qualification = ({ file = {} }) => {
}, [formatedMetadataQualification])
return (
-
- {formatedMetadataQualification.map((meta, idx) => {
- const { name } = meta
- const QualificationListItemComp = makeQualificationListItemComp(name)
-
- return (
-
+ {isExpiringSoon(file) && !file?.metadata?.hideExpirationAlert && (
+
+ )}
+
+ {formatedMetadataQualification.map((meta, idx) => {
+ const { name } = meta
+ const QualificationListItemComp = makeQualificationListItemComp(name)
+
+ return (
+ toggleActionsMenu(idx, name, val)}
+ />
+ )
+ })}
+
+ {optionFile.name && (
+ toggleActionsMenu(idx, name, val)}
+ optionFile={optionFile}
+ ref={actionBtnRef.current[optionFile.id]}
/>
- )
- })}
-
- {optionFile.name && (
-
- )}
-
+ )}
+
+ >
)
}
From 27fff188a767ce93e6c15420150d0eaa30517f58 Mon Sep 17 00:00:00 2001
From: PolariTOON <36267812+PolariTOON@users.noreply.github.com>
Date: Wed, 7 Dec 2022 17:32:48 +0100
Subject: [PATCH 6/7] fix: Require `file` prop in `Qualification`
---
react/Viewer/Panel/Qualification.jsx | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/react/Viewer/Panel/Qualification.jsx b/react/Viewer/Panel/Qualification.jsx
index 2eee3ec901..ee59bfbce2 100644
--- a/react/Viewer/Panel/Qualification.jsx
+++ b/react/Viewer/Panel/Qualification.jsx
@@ -37,7 +37,11 @@ const makeQualificationListItemComp = metadataName => {
}
}
-const Qualification = ({ file = {} }) => {
+const isExpirationAlertHidden = file => {
+ return file?.metadata?.hideExpirationAlert ?? false
+}
+
+const Qualification = ({ file }) => {
const { metadata = {} } = file
const actionBtnRef = useRef([])
const [optionFile, setOptionFile] = useState({
@@ -69,7 +73,7 @@ const Qualification = ({ file = {} }) => {
return (
<>
- {isExpiringSoon(file) && !file?.metadata?.hideExpirationAlert && (
+ {isExpiringSoon(file) && !isExpirationAlertHidden(file) && (
)}
@@ -102,7 +106,7 @@ const Qualification = ({ file = {} }) => {
}
Qualification.propTypes = {
- file: PropTypes.object
+ file: PropTypes.object.isRequired
}
export default withViewerLocales(Qualification)
From a12d0d852786e6d61c57184f5555c7360df06151 Mon Sep 17 00:00:00 2001
From: PolariTOON <36267812+PolariTOON@users.noreply.github.com>
Date: Wed, 30 Nov 2022 12:36:35 +0100
Subject: [PATCH 7/7] docs: Add an example of a file with many panel blocks in
the viewer
Including an expiration alert.
---
react/Viewer/Readme.md | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/react/Viewer/Readme.md b/react/Viewer/Readme.md
index 591a3b8a07..a19db18c02 100644
--- a/react/Viewer/Readme.md
+++ b/react/Viewer/Readme.md
@@ -122,7 +122,16 @@ const files = [
_id: 'image',
class: 'image',
name: 'Demo.jpg',
- mime: 'image/jpg'
+ mime: 'image/jpg',
+ metadata: {
+ carbonCopy: true,
+ electronicSafe: true,
+ referencedDate: new Date(Date.now() - 357 * 24 * 60 * 60 * 1000).toISOString(),
+ datetimeLabel: "referencedDate",
+ qualification: {
+ label: 'personal_sporting_licence'
+ }
+ }
},
{
_id: 'none',