diff --git a/docs/styleguide.config.js b/docs/styleguide.config.js
index 933530fe5..ee4c491b6 100644
--- a/docs/styleguide.config.js
+++ b/docs/styleguide.config.js
@@ -96,6 +96,7 @@ module.exports = {
'../react/QualificationGrid',
'../react/QualificationIconStack',
'../react/QualificationItem',
+ '../react/QualificationModal',
'../react/UploadQueue'
]
},
diff --git a/react/QualificationModal/Readme.md b/react/QualificationModal/Readme.md
new file mode 100644
index 000000000..592b5616e
--- /dev/null
+++ b/react/QualificationModal/Readme.md
@@ -0,0 +1,23 @@
+```jsx
+import DemoProvider from 'cozy-ui/docs/components/DemoProvider'
+import QualificationModal from 'cozy-ui/transpiled/react/QualificationModal'
+import Typography from 'cozy-ui/transpiled/react/Typography'
+import CloudIcon from 'cozy-ui/transpiled/react/Icons/Cloud'
+import FormControlLabel from 'cozy-ui/transpiled/react/FormControlLabel'
+import RadioGroup from 'cozy-ui/transpiled/react/RadioGroup'
+import Radio from 'cozy-ui/transpiled/react/Radios'
+import FormControl from 'cozy-ui/transpiled/react/FormControl'
+import Button from 'cozy-ui/transpiled/react/Buttons'
+
+initialState = { show: isTesting() ? true : false }
+
+const show = () => setState({show: true})
+const hide = () => setState({show: false})
+
+;
+
+
+
+ {state.show && }
+
+```
diff --git a/react/QualificationModal/index.jsx b/react/QualificationModal/index.jsx
new file mode 100644
index 000000000..04553dded
--- /dev/null
+++ b/react/QualificationModal/index.jsx
@@ -0,0 +1,98 @@
+import PropTypes from 'prop-types'
+import React, { useMemo } from 'react'
+
+import { useClient } from 'cozy-client'
+import { themesList } from 'cozy-client/dist/models/document/documentTypeData'
+import { isQualificationNote } from 'cozy-client/dist/models/document/documentTypeDataHelpers'
+import { getBoundT } from 'cozy-client/dist/models/document/locales'
+import { getQualification } from 'cozy-client/dist/models/document/qualification'
+
+import { locales } from './locales'
+import Icon from '../Icon'
+import FileTypeNoteIcon from '../Icons/FileTypeNote'
+import NestedSelectResponsive from '../NestedSelect/NestedSelectResponsive'
+import QualificationIconStack from '../QualificationIconStack'
+import { useI18n, useExtendI18n } from '../providers/I18n'
+
+const makeOptions = lang => {
+ const qualifT = getBoundT(lang)
+
+ return {
+ children: [
+ {
+ id: 'none',
+ title: qualifT('Scan.themes.none'),
+ icon:
+ },
+ ...themesList.map(theme => ({
+ id: theme.id,
+ title: qualifT(`Scan.themes.${theme.label}`),
+ icon: ,
+ children: theme.items.map(item => ({
+ id: item.label,
+ item,
+ title: qualifT(`Scan.items.${item.label}`),
+ icon: isQualificationNote(item) ? (
+
+ ) : (
+
+ )
+ }))
+ }))
+ ]
+ }
+}
+
+const QualificationModal = ({ file, title, onClose }) => {
+ useExtendI18n(locales)
+ const client = useClient()
+ const { t, lang } = useI18n()
+
+ const qualificationLabel = getQualification(file)?.label
+ const options = useMemo(() => makeOptions(lang), [lang])
+
+ const isSelected = ({ id, item }) => {
+ return qualificationLabel
+ ? qualificationLabel === item?.label
+ : id === 'none'
+ }
+
+ const handleClick = async ({ id, item }) => {
+ const fileCollection = client.collection('io.cozy.files')
+ const removeQualification = qualificationLabel && id === 'none'
+
+ if (!qualificationLabel && removeQualification) {
+ return onClose()
+ }
+
+ /*
+ In the case where we remove the qualification it's necessary to define the attribute to `null` and not `undefined`, with `undefined` the stack does not return the attribute and today the Redux store is not updated for a missing attribute.
+ As a result, the UI is not updated and continues to display the qualification on the document, even though it has been deleted in CouchDB.
+ */
+ await fileCollection.updateMetadataAttribute(file._id, {
+ qualification: removeQualification ? null : item
+ })
+
+ onClose()
+ }
+
+ return (
+
+ )
+}
+
+QualificationModal.propTypes = {
+ file: PropTypes.object,
+ title: PropTypes.string,
+ onClose: PropTypes.func
+}
+
+export default QualificationModal
diff --git a/react/QualificationModal/locales/en.json b/react/QualificationModal/locales/en.json
new file mode 100644
index 000000000..2059647f4
--- /dev/null
+++ b/react/QualificationModal/locales/en.json
@@ -0,0 +1,5 @@
+{
+ "QualificationModal": {
+ "title": "Document type"
+ }
+}
diff --git a/react/QualificationModal/locales/fr.json b/react/QualificationModal/locales/fr.json
new file mode 100644
index 000000000..911ca2236
--- /dev/null
+++ b/react/QualificationModal/locales/fr.json
@@ -0,0 +1,5 @@
+{
+ "QualificationModal": {
+ "title": "Type de document"
+ }
+}
diff --git a/react/QualificationModal/locales/index.jsx b/react/QualificationModal/locales/index.jsx
new file mode 100644
index 000000000..125e40920
--- /dev/null
+++ b/react/QualificationModal/locales/index.jsx
@@ -0,0 +1,7 @@
+import en from './en.json'
+import fr from './fr.json'
+
+export const locales = {
+ en,
+ fr
+}
diff --git a/react/index.js b/react/index.js
index b28c6eb9f..bbf3c326e 100644
--- a/react/index.js
+++ b/react/index.js
@@ -125,6 +125,8 @@ export { default as Thumbnail } from './Thumbnail'
export { default as ButtonBase } from './ButtonBase'
export { default as QualificationGrid } from './QualificationGrid'
export { default as QualificationItem } from './QualificationItem'
+export { default as QualificationIconStack } from './QualificationIconStack'
+export { default as QualificationModal } from './QualificationModal'
export { default as Timeline } from './Timeline'
export { default as TimelineConnector } from './TimelineConnector'
export { default as TimelineContent } from './TimelineContent'