cozy-ui 113.9.0 → 114.0.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 +13 -0
- package/package.json +6 -6
- package/react/Paywall/Paywall.spec.jsx +3 -5
- package/react/QualificationModal/Readme.md +28 -0
- package/react/QualificationModal/index.jsx +94 -0
- package/react/QualificationModal/locales/en.json +5 -0
- package/react/QualificationModal/locales/fr.json +5 -0
- package/react/QualificationModal/locales/index.jsx +7 -0
- package/react/index.js +2 -0
- package/transpiled/react/QualificationModal/index.js +126 -0
- package/transpiled/react/QualificationModal/locales/index.js +14 -0
- package/transpiled/react/index.js +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
# [114.0.0](https://github.com/cozy/cozy-ui/compare/v113.9.0...v114.0.0) (2024-12-12)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* Add QualificationModal component ([e2ebcc0](https://github.com/cozy/cozy-ui/commit/e2ebcc0))
|
|
7
|
+
* Upgrade packages ([4ca7867](https://github.com/cozy/cozy-ui/commit/4ca7867))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### BREAKING CHANGES
|
|
11
|
+
|
|
12
|
+
* You must have `cozy-client >= 51.6.0` and `cozy-intent >= 2.29.1`
|
|
13
|
+
|
|
1
14
|
# [113.9.0](https://github.com/cozy/cozy-ui/compare/v113.8.0...v113.9.0) (2024-12-10)
|
|
2
15
|
|
|
3
16
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "114.0.0",
|
|
4
4
|
"description": "Cozy apps UI SDK",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"bin": {
|
|
@@ -92,12 +92,12 @@
|
|
|
92
92
|
"browserslist-config-cozy": "0.4.0",
|
|
93
93
|
"bundlemon": "3.1.0",
|
|
94
94
|
"copyfiles": "2.4.1",
|
|
95
|
-
"cozy-client": "^
|
|
95
|
+
"cozy-client": "^51.6.0",
|
|
96
96
|
"cozy-device-helper": "2.0.0",
|
|
97
97
|
"cozy-flags": "^2.10.1",
|
|
98
|
-
"cozy-intent": "
|
|
98
|
+
"cozy-intent": "^2.29.1",
|
|
99
99
|
"cozy-logger": "^1.9.0",
|
|
100
|
-
"cozy-stack-client": "^
|
|
100
|
+
"cozy-stack-client": "^51.6.0",
|
|
101
101
|
"css-loader": "0.28.11",
|
|
102
102
|
"cssnano": "4.1.11",
|
|
103
103
|
"cssnano-preset-advanced": "4.0.8",
|
|
@@ -181,9 +181,9 @@
|
|
|
181
181
|
"rooks": "^5.11.2"
|
|
182
182
|
},
|
|
183
183
|
"peerDependencies": {
|
|
184
|
-
"cozy-client": ">=
|
|
184
|
+
"cozy-client": ">=51.6.0",
|
|
185
185
|
"cozy-device-helper": "^2.0.0",
|
|
186
|
-
"cozy-intent": ">=
|
|
186
|
+
"cozy-intent": ">=2.29.1",
|
|
187
187
|
"react": "^16.8.6",
|
|
188
188
|
"react-dom": "^16.8.6"
|
|
189
189
|
},
|
|
@@ -42,15 +42,13 @@ describe('Paywall', () => {
|
|
|
42
42
|
useInstanceInfo.mockReturnValue({
|
|
43
43
|
context: {
|
|
44
44
|
data: {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
manager_url: 'http://mycozy.cloud'
|
|
48
|
-
}
|
|
45
|
+
enable_premium_links: enablePremiumLinks,
|
|
46
|
+
manager_url: 'http://mycozy.cloud'
|
|
49
47
|
}
|
|
50
48
|
},
|
|
51
49
|
instance: {
|
|
52
50
|
data: {
|
|
53
|
-
|
|
51
|
+
uuid: hasUuid ? '123' : null
|
|
54
52
|
}
|
|
55
53
|
},
|
|
56
54
|
isLoaded: true
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
```jsx
|
|
2
|
+
import DemoProvider from 'cozy-ui/docs/components/DemoProvider'
|
|
3
|
+
import QualificationModal from 'cozy-ui/transpiled/react/QualificationModal'
|
|
4
|
+
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
5
|
+
import CloudIcon from 'cozy-ui/transpiled/react/Icons/Cloud'
|
|
6
|
+
import FormControlLabel from 'cozy-ui/transpiled/react/FormControlLabel'
|
|
7
|
+
import RadioGroup from 'cozy-ui/transpiled/react/RadioGroup'
|
|
8
|
+
import Radio from 'cozy-ui/transpiled/react/Radios'
|
|
9
|
+
import FormControl from 'cozy-ui/transpiled/react/FormControl'
|
|
10
|
+
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
11
|
+
|
|
12
|
+
initialState = { show: isTesting() ? true : false }
|
|
13
|
+
|
|
14
|
+
const show = () => setState({show: true})
|
|
15
|
+
const hide = () => setState({show: false})
|
|
16
|
+
|
|
17
|
+
;
|
|
18
|
+
|
|
19
|
+
<DemoProvider client={{ collection: () => ({ updateMetadataAttribute: () => {}}) }}>
|
|
20
|
+
<Button label={state.show ? "Close modal" : "Open modal"} variant="ghost" onClick={show} />
|
|
21
|
+
{state.show &&
|
|
22
|
+
<QualificationModal
|
|
23
|
+
file={{ name: "toto.txt", metadata: { qualification: { label: 'isp_invoice' } } }}
|
|
24
|
+
onClose={hide}
|
|
25
|
+
/>
|
|
26
|
+
}
|
|
27
|
+
</DemoProvider>
|
|
28
|
+
```
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import PropTypes from 'prop-types'
|
|
2
|
+
import React, { useMemo } from 'react'
|
|
3
|
+
|
|
4
|
+
import { useClient } from 'cozy-client'
|
|
5
|
+
import { themesList } from 'cozy-client/dist/models/document/documentTypeData'
|
|
6
|
+
import { isQualificationNote } from 'cozy-client/dist/models/document/documentTypeDataHelpers'
|
|
7
|
+
import { getBoundT } from 'cozy-client/dist/models/document/locales'
|
|
8
|
+
import { getQualification } from 'cozy-client/dist/models/document/qualification'
|
|
9
|
+
|
|
10
|
+
import { locales } from './locales'
|
|
11
|
+
import Icon from '../Icon'
|
|
12
|
+
import FileTypeNoteIcon from '../Icons/FileTypeNote'
|
|
13
|
+
import NestedSelectResponsive from '../NestedSelect/NestedSelectResponsive'
|
|
14
|
+
import QualificationIconStack from '../QualificationIconStack'
|
|
15
|
+
import { useI18n, useExtendI18n } from '../providers/I18n'
|
|
16
|
+
|
|
17
|
+
const makeOptions = lang => {
|
|
18
|
+
const qualifT = getBoundT(lang)
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
children: [
|
|
22
|
+
{
|
|
23
|
+
id: 'none',
|
|
24
|
+
title: qualifT('Scan.themes.none'),
|
|
25
|
+
icon: <QualificationIconStack />
|
|
26
|
+
},
|
|
27
|
+
...themesList.map(theme => ({
|
|
28
|
+
id: theme.id,
|
|
29
|
+
title: qualifT(`Scan.themes.${theme.label}`),
|
|
30
|
+
icon: <QualificationIconStack theme={theme.label} />,
|
|
31
|
+
children: theme.items.map(item => ({
|
|
32
|
+
id: item.label,
|
|
33
|
+
item,
|
|
34
|
+
title: qualifT(`Scan.items.${item.label}`),
|
|
35
|
+
icon: isQualificationNote(item) ? (
|
|
36
|
+
<Icon icon={FileTypeNoteIcon} size={64} />
|
|
37
|
+
) : (
|
|
38
|
+
<QualificationIconStack qualification={item.label} />
|
|
39
|
+
)
|
|
40
|
+
}))
|
|
41
|
+
}))
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const QualificationModal = ({ file, title, onClose }) => {
|
|
47
|
+
useExtendI18n(locales)
|
|
48
|
+
const client = useClient()
|
|
49
|
+
const { t, lang } = useI18n()
|
|
50
|
+
|
|
51
|
+
const qualificationLabel = getQualification(file)?.label
|
|
52
|
+
const options = useMemo(() => makeOptions(lang), [lang])
|
|
53
|
+
|
|
54
|
+
const isSelected = ({ id, item }) => {
|
|
55
|
+
return qualificationLabel
|
|
56
|
+
? qualificationLabel === item?.label
|
|
57
|
+
: id === 'none'
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const handleClick = async ({ id, item }) => {
|
|
61
|
+
const fileCollection = client.collection('io.cozy.files')
|
|
62
|
+
const removeQualification = qualificationLabel && id === 'none'
|
|
63
|
+
|
|
64
|
+
/*
|
|
65
|
+
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.
|
|
66
|
+
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.
|
|
67
|
+
*/
|
|
68
|
+
await fileCollection.updateMetadataAttribute(file._id, {
|
|
69
|
+
qualification: removeQualification ? null : item
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
onClose()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<NestedSelectResponsive
|
|
77
|
+
title={title || t('QualificationModal.title')}
|
|
78
|
+
options={options}
|
|
79
|
+
noDivider
|
|
80
|
+
document={file}
|
|
81
|
+
isSelected={isSelected}
|
|
82
|
+
onSelect={handleClick}
|
|
83
|
+
onClose={onClose}
|
|
84
|
+
/>
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
QualificationModal.propTypes = {
|
|
89
|
+
file: PropTypes.object,
|
|
90
|
+
title: PropTypes.string,
|
|
91
|
+
onClose: PropTypes.func
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default QualificationModal
|
package/react/index.js
CHANGED
|
@@ -125,6 +125,8 @@ export { default as Thumbnail } from './Thumbnail'
|
|
|
125
125
|
export { default as ButtonBase } from './ButtonBase'
|
|
126
126
|
export { default as QualificationGrid } from './QualificationGrid'
|
|
127
127
|
export { default as QualificationItem } from './QualificationItem'
|
|
128
|
+
export { default as QualificationIconStack } from './QualificationIconStack'
|
|
129
|
+
export { default as QualificationModal } from './QualificationModal'
|
|
128
130
|
export { default as Timeline } from './Timeline'
|
|
129
131
|
export { default as TimelineConnector } from './TimelineConnector'
|
|
130
132
|
export { default as TimelineContent } from './TimelineContent'
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
3
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
import React, { useMemo } from 'react';
|
|
6
|
+
import { useClient } from 'cozy-client';
|
|
7
|
+
import { themesList } from 'cozy-client/dist/models/document/documentTypeData';
|
|
8
|
+
import { isQualificationNote } from 'cozy-client/dist/models/document/documentTypeDataHelpers';
|
|
9
|
+
import { getBoundT } from 'cozy-client/dist/models/document/locales';
|
|
10
|
+
import { getQualification } from 'cozy-client/dist/models/document/qualification';
|
|
11
|
+
import { locales } from "cozy-ui/transpiled/react/QualificationModal/locales";
|
|
12
|
+
import Icon from "cozy-ui/transpiled/react/Icon";
|
|
13
|
+
import FileTypeNoteIcon from "cozy-ui/transpiled/react/Icons/FileTypeNote";
|
|
14
|
+
import NestedSelectResponsive from "cozy-ui/transpiled/react/NestedSelect/NestedSelectResponsive";
|
|
15
|
+
import QualificationIconStack from "cozy-ui/transpiled/react/QualificationIconStack";
|
|
16
|
+
import { useI18n, useExtendI18n } from "cozy-ui/transpiled/react/providers/I18n";
|
|
17
|
+
|
|
18
|
+
var makeOptions = function makeOptions(lang) {
|
|
19
|
+
var qualifT = getBoundT(lang);
|
|
20
|
+
return {
|
|
21
|
+
children: [{
|
|
22
|
+
id: 'none',
|
|
23
|
+
title: qualifT('Scan.themes.none'),
|
|
24
|
+
icon: /*#__PURE__*/React.createElement(QualificationIconStack, null)
|
|
25
|
+
}].concat(_toConsumableArray(themesList.map(function (theme) {
|
|
26
|
+
return {
|
|
27
|
+
id: theme.id,
|
|
28
|
+
title: qualifT("Scan.themes.".concat(theme.label)),
|
|
29
|
+
icon: /*#__PURE__*/React.createElement(QualificationIconStack, {
|
|
30
|
+
theme: theme.label
|
|
31
|
+
}),
|
|
32
|
+
children: theme.items.map(function (item) {
|
|
33
|
+
return {
|
|
34
|
+
id: item.label,
|
|
35
|
+
item: item,
|
|
36
|
+
title: qualifT("Scan.items.".concat(item.label)),
|
|
37
|
+
icon: isQualificationNote(item) ? /*#__PURE__*/React.createElement(Icon, {
|
|
38
|
+
icon: FileTypeNoteIcon,
|
|
39
|
+
size: 64
|
|
40
|
+
}) : /*#__PURE__*/React.createElement(QualificationIconStack, {
|
|
41
|
+
qualification: item.label
|
|
42
|
+
})
|
|
43
|
+
};
|
|
44
|
+
})
|
|
45
|
+
};
|
|
46
|
+
})))
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
var QualificationModal = function QualificationModal(_ref) {
|
|
51
|
+
var _getQualification;
|
|
52
|
+
|
|
53
|
+
var file = _ref.file,
|
|
54
|
+
title = _ref.title,
|
|
55
|
+
onClose = _ref.onClose;
|
|
56
|
+
useExtendI18n(locales);
|
|
57
|
+
var client = useClient();
|
|
58
|
+
|
|
59
|
+
var _useI18n = useI18n(),
|
|
60
|
+
t = _useI18n.t,
|
|
61
|
+
lang = _useI18n.lang;
|
|
62
|
+
|
|
63
|
+
var qualificationLabel = (_getQualification = getQualification(file)) === null || _getQualification === void 0 ? void 0 : _getQualification.label;
|
|
64
|
+
var options = useMemo(function () {
|
|
65
|
+
return makeOptions(lang);
|
|
66
|
+
}, [lang]);
|
|
67
|
+
|
|
68
|
+
var isSelected = function isSelected(_ref2) {
|
|
69
|
+
var id = _ref2.id,
|
|
70
|
+
item = _ref2.item;
|
|
71
|
+
return qualificationLabel ? qualificationLabel === (item === null || item === void 0 ? void 0 : item.label) : id === 'none';
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
var handleClick = /*#__PURE__*/function () {
|
|
75
|
+
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref3) {
|
|
76
|
+
var id, item, fileCollection, removeQualification;
|
|
77
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
78
|
+
while (1) {
|
|
79
|
+
switch (_context.prev = _context.next) {
|
|
80
|
+
case 0:
|
|
81
|
+
id = _ref3.id, item = _ref3.item;
|
|
82
|
+
fileCollection = client.collection('io.cozy.files');
|
|
83
|
+
removeQualification = qualificationLabel && id === 'none';
|
|
84
|
+
/*
|
|
85
|
+
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.
|
|
86
|
+
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.
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
_context.next = 5;
|
|
90
|
+
return fileCollection.updateMetadataAttribute(file._id, {
|
|
91
|
+
qualification: removeQualification ? null : item
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
case 5:
|
|
95
|
+
onClose();
|
|
96
|
+
|
|
97
|
+
case 6:
|
|
98
|
+
case "end":
|
|
99
|
+
return _context.stop();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}, _callee);
|
|
103
|
+
}));
|
|
104
|
+
|
|
105
|
+
return function handleClick(_x) {
|
|
106
|
+
return _ref4.apply(this, arguments);
|
|
107
|
+
};
|
|
108
|
+
}();
|
|
109
|
+
|
|
110
|
+
return /*#__PURE__*/React.createElement(NestedSelectResponsive, {
|
|
111
|
+
title: title || t('QualificationModal.title'),
|
|
112
|
+
options: options,
|
|
113
|
+
noDivider: true,
|
|
114
|
+
document: file,
|
|
115
|
+
isSelected: isSelected,
|
|
116
|
+
onSelect: handleClick,
|
|
117
|
+
onClose: onClose
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
QualificationModal.propTypes = {
|
|
122
|
+
file: PropTypes.object,
|
|
123
|
+
title: PropTypes.string,
|
|
124
|
+
onClose: PropTypes.func
|
|
125
|
+
};
|
|
126
|
+
export default QualificationModal;
|
|
@@ -98,6 +98,8 @@ export { default as Thumbnail } from './Thumbnail';
|
|
|
98
98
|
export { default as ButtonBase } from './ButtonBase';
|
|
99
99
|
export { default as QualificationGrid } from './QualificationGrid';
|
|
100
100
|
export { default as QualificationItem } from './QualificationItem';
|
|
101
|
+
export { default as QualificationIconStack } from './QualificationIconStack';
|
|
102
|
+
export { default as QualificationModal } from './QualificationModal';
|
|
101
103
|
export { default as Timeline } from './Timeline';
|
|
102
104
|
export { default as TimelineConnector } from './TimelineConnector';
|
|
103
105
|
export { default as TimelineContent } from './TimelineContent';
|