cozy-sharing 28.6.0 → 28.7.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 CHANGED
@@ -3,6 +3,13 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [28.7.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@28.6.0...cozy-sharing@28.7.0) (2026-03-12)
7
+
8
+ ### Features
9
+
10
+ - Allow to change link editing rights directly from the share modal ([57c3e61](https://github.com/cozy/cozy-libs/commit/57c3e6144649d3102c37961b4953219bdfe553a3))
11
+ - Display the Share restriction modal on click on the sharing link ([a875c36](https://github.com/cozy/cozy-libs/commit/a875c36e7b6ea592b25cbc8386a305b1c1dac516))
12
+
6
13
  # [28.6.0](https://github.com/cozy/cozy-libs/compare/cozy-sharing@28.5.0...cozy-sharing@28.6.0) (2026-03-11)
7
14
 
8
15
  ### Features
@@ -755,9 +755,12 @@ export var SharingProvider = /*#__PURE__*/function (_Component) {
755
755
 
756
756
  case 11:
757
757
  resp = _context14.t0;
758
+
759
+ _this2.dispatch(updateSharingLink(resp.data));
760
+
758
761
  return _context14.abrupt("return", resp);
759
762
 
760
- case 13:
763
+ case 14:
761
764
  case "end":
762
765
  return _context14.stop();
763
766
  }
@@ -1,21 +1,23 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
3
  import PropTypes from 'prop-types';
3
- import React from 'react';
4
+ import React, { useState } from 'react';
4
5
  import { useI18n } from 'twake-i18n';
5
6
  import Avatar from 'cozy-ui/transpiled/react/Avatar';
7
+ import DropdownButton from 'cozy-ui/transpiled/react/DropdownButton';
6
8
  import Fade from 'cozy-ui/transpiled/react/Fade';
7
9
  import Icon from 'cozy-ui/transpiled/react/Icon';
8
10
  import LinkIcon from 'cozy-ui/transpiled/react/Icons/Link';
9
11
  import ListItem from 'cozy-ui/transpiled/react/ListItem';
10
12
  import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon';
11
13
  import ListItemText from 'cozy-ui/transpiled/react/ListItemText';
12
- import Typography from 'cozy-ui/transpiled/react/Typography';
13
14
  import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints';
14
15
  import LinkRecipientPermissions from './LinkRecipientPermissions';
15
16
  import RecipientConfirm from './RecipientConfirm';
16
17
  import { checkIsPermissionHasPassword, getPermissionExpiresDate } from '../../helpers/permissions';
17
18
  import { FADE_IN_DURATION } from '../../helpers/recipients';
18
19
  import { useSharingContext } from '../../hooks/useSharingContext';
20
+ import { ShareRestrictionModal } from '../ShareRestrictionModal/ShareRestrictionModal';
19
21
 
20
22
  var LinkRecipient = function LinkRecipient(props) {
21
23
  var _useI18n = useI18n(),
@@ -33,6 +35,12 @@ var LinkRecipient = function LinkRecipient(props) {
33
35
  verifyRecipient = props.verifyRecipient,
34
36
  fadeIn = props.fadeIn,
35
37
  document = props.document;
38
+
39
+ var _useState = useState(false),
40
+ _useState2 = _slicedToArray(_useState, 2),
41
+ openShareRestrictionModal = _useState2[0],
42
+ setOpenShareRestrictionModal = _useState2[1];
43
+
36
44
  var permissions = getDocumentPermissions(document === null || document === void 0 ? void 0 : document._id);
37
45
  var hasPassword = checkIsPermissionHasPassword(permissions);
38
46
  var expiresDate = getPermissionExpiresDate(permissions);
@@ -61,11 +69,19 @@ var LinkRecipient = function LinkRecipient(props) {
61
69
  }, /*#__PURE__*/React.createElement(Icon, {
62
70
  icon: LinkIcon
63
71
  }))), /*#__PURE__*/React.createElement(ListItemText, {
64
- primary: /*#__PURE__*/React.createElement(Typography, {
65
- variant: "body1"
72
+ primary: /*#__PURE__*/React.createElement(DropdownButton, {
73
+ textVariant: "body1",
74
+ onClick: function onClick() {
75
+ return setOpenShareRestrictionModal(true);
76
+ }
66
77
  }, textPrimary),
67
78
  secondary: textSecondary
68
- }), RightPart));
79
+ }), RightPart, openShareRestrictionModal && /*#__PURE__*/React.createElement(ShareRestrictionModal, {
80
+ file: document,
81
+ onClose: function onClose() {
82
+ return setOpenShareRestrictionModal(false);
83
+ }
84
+ })));
69
85
  };
70
86
 
71
87
  LinkRecipient.propTypes = {
@@ -2,14 +2,20 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  import PropTypes from 'prop-types';
3
3
  import React, { useState, useRef } from 'react';
4
4
  import { useI18n } from 'twake-i18n';
5
+ import ActionsMenu from 'cozy-ui/transpiled/react/ActionsMenu';
6
+ import { makeActions, divider } from 'cozy-ui/transpiled/react/ActionsMenu/Actions';
5
7
  import DropdownButton from 'cozy-ui/transpiled/react/DropdownButton';
8
+ import { revokeLink } from './actions/revokeLink';
9
+ import { setReadOnlySharedPermission } from './actions/setReadOnlySharedPermission';
10
+ import { setReadWriteSharedPermission } from './actions/setReadWriteSharedPermission';
11
+ import { isOnlyReadOnlyLinkAllowed } from '../../helpers/link';
6
12
  import { checkIsReadOnlyPermissions } from '../../helpers/permissions';
7
- import { ShareRestrictionModal } from '../ShareRestrictionModal/ShareRestrictionModal';
13
+ import { useSharingContext } from '../../hooks/useSharingContext';
14
+ import { WRITE_PERMS, READ_ONLY_PERMS } from '../ShareRestrictionModal/helpers';
8
15
 
9
16
  var LinkRecipientPermissions = function LinkRecipientPermissions(_ref) {
10
17
  var className = _ref.className,
11
- document = _ref.document,
12
- permissions = _ref.permissions;
18
+ document = _ref.document;
13
19
 
14
20
  var _useI18n = useI18n(),
15
21
  t = _useI18n.t;
@@ -18,29 +24,70 @@ var LinkRecipientPermissions = function LinkRecipientPermissions(_ref) {
18
24
 
19
25
  var _useState = useState(false),
20
26
  _useState2 = _slicedToArray(_useState, 2),
21
- openShareRestrictionModal = _useState2[0],
22
- setOpenShareRestrictionModal = _useState2[1];
27
+ isMenuDisplayed = _useState2[0],
28
+ setMenuDisplayed = _useState2[1];
23
29
 
30
+ var _useSharingContext = useSharingContext(),
31
+ updateDocumentPermissions = _useSharingContext.updateDocumentPermissions,
32
+ revokeSharingLink = _useSharingContext.revokeSharingLink,
33
+ documentType = _useSharingContext.documentType,
34
+ getDocumentPermissions = _useSharingContext.getDocumentPermissions;
35
+
36
+ var permissions = getDocumentPermissions(document._id);
24
37
  var isReadOnlyPermissions = checkIsReadOnlyPermissions(permissions);
38
+ var type = isReadOnlyPermissions ? 'one-way' : 'two-way';
39
+
40
+ var toggleMenu = function toggleMenu() {
41
+ return setMenuDisplayed(!isMenuDisplayed);
42
+ };
43
+
44
+ var hideMenu = function hideMenu() {
45
+ return setMenuDisplayed(false);
46
+ };
47
+
48
+ var handleSetType = function handleSetType(newType) {
49
+ var verbs = newType === 'one-way' ? READ_ONLY_PERMS : WRITE_PERMS;
50
+ updateDocumentPermissions(document, {
51
+ verbs: verbs
52
+ });
53
+ };
54
+
55
+ var handleRevocation = function handleRevocation() {
56
+ return revokeSharingLink(document);
57
+ };
58
+
59
+ var actionsToShow = [setReadOnlySharedPermission];
60
+
61
+ if (!isOnlyReadOnlyLinkAllowed({
62
+ documentType: documentType
63
+ })) {
64
+ actionsToShow.push(setReadWriteSharedPermission);
65
+ }
66
+
67
+ actionsToShow.push(divider, revokeLink);
68
+ var actions = makeActions(actionsToShow, {
69
+ t: t,
70
+ type: type,
71
+ setType: handleSetType,
72
+ handleRevocation: handleRevocation
73
+ });
25
74
  return /*#__PURE__*/React.createElement("div", {
26
75
  className: className
27
76
  }, /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DropdownButton, {
28
77
  ref: buttonRef,
29
78
  textVariant: "body2",
30
- onClick: function onClick() {
31
- return setOpenShareRestrictionModal(true);
32
- }
33
- }, t("Share.type.".concat(isReadOnlyPermissions ? 'one-way' : 'two-way')).toLowerCase()), openShareRestrictionModal && /*#__PURE__*/React.createElement(ShareRestrictionModal, {
34
- file: document,
35
- onClose: function onClose() {
36
- return setOpenShareRestrictionModal(false);
37
- }
79
+ onClick: toggleMenu
80
+ }, t("Share.type.".concat(type)).toLowerCase()), /*#__PURE__*/React.createElement(ActionsMenu, {
81
+ ref: buttonRef,
82
+ open: isMenuDisplayed,
83
+ actions: actions,
84
+ autoClose: true,
85
+ onClose: hideMenu
38
86
  })));
39
87
  };
40
88
 
41
89
  LinkRecipientPermissions.propTypes = {
42
90
  className: PropTypes.string,
43
- document: PropTypes.object.isRequired,
44
- permissions: PropTypes.arrayOf(PropTypes.object).isRequired
91
+ document: PropTypes.object.isRequired
45
92
  };
46
93
  export default LinkRecipientPermissions;
@@ -0,0 +1,34 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React, { forwardRef } from 'react';
3
+ import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem';
4
+ import Icon from 'cozy-ui/transpiled/react/Icon';
5
+ import TrashIcon from 'cozy-ui/transpiled/react/Icons/Trash';
6
+ import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon';
7
+ import ListItemText from 'cozy-ui/transpiled/react/ListItemText';
8
+ import Typography from 'cozy-ui/transpiled/react/Typography';
9
+
10
+ var revokeLink = function revokeLink(_ref) {
11
+ var t = _ref.t,
12
+ handleRevocation = _ref.handleRevocation;
13
+ var title = t('Share.permissionLink.deactivate');
14
+ return {
15
+ name: 'revokeLink',
16
+ label: title,
17
+ icon: TrashIcon,
18
+ action: handleRevocation,
19
+ Component: /*#__PURE__*/forwardRef(function RevokeLinkItem(props, ref) {
20
+ return /*#__PURE__*/React.createElement(ActionsMenuItem, _extends({}, props, {
21
+ ref: ref
22
+ }), /*#__PURE__*/React.createElement(ListItemIcon, null, /*#__PURE__*/React.createElement(Icon, {
23
+ icon: TrashIcon,
24
+ color: "var(--errorColor)"
25
+ })), /*#__PURE__*/React.createElement(ListItemText, {
26
+ primary: /*#__PURE__*/React.createElement(Typography, {
27
+ color: "error"
28
+ }, title)
29
+ }));
30
+ })
31
+ };
32
+ };
33
+
34
+ export { revokeLink };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-sharing",
3
- "version": "28.6.0",
3
+ "version": "28.7.0",
4
4
  "description": "Provides sharing login for React applications.",
5
5
  "main": "dist/index.js",
6
6
  "author": "Cozy",
@@ -83,5 +83,5 @@
83
83
  "sideEffects": [
84
84
  "*.css"
85
85
  ],
86
- "gitHead": "64311a9d08372224b5214cbf49f7d658d93f9af9"
86
+ "gitHead": "421077ecc24c9a15a3a1c22d9c3442917292f8ba"
87
87
  }
@@ -488,6 +488,7 @@ export class SharingProvider extends Component {
488
488
  updatedPermissions,
489
489
  { expiresAt, password }
490
490
  )
491
+ this.dispatch(updateSharingLink(resp.data))
491
492
  return resp
492
493
  })
493
494
  )
@@ -1,15 +1,15 @@
1
1
  import PropTypes from 'prop-types'
2
- import React from 'react'
2
+ import React, { useState } from 'react'
3
3
  import { useI18n } from 'twake-i18n'
4
4
 
5
5
  import Avatar from 'cozy-ui/transpiled/react/Avatar'
6
+ import DropdownButton from 'cozy-ui/transpiled/react/DropdownButton'
6
7
  import Fade from 'cozy-ui/transpiled/react/Fade'
7
8
  import Icon from 'cozy-ui/transpiled/react/Icon'
8
9
  import LinkIcon from 'cozy-ui/transpiled/react/Icons/Link'
9
10
  import ListItem from 'cozy-ui/transpiled/react/ListItem'
10
11
  import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
11
12
  import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
12
- import Typography from 'cozy-ui/transpiled/react/Typography'
13
13
  import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints'
14
14
 
15
15
  import LinkRecipientPermissions from './LinkRecipientPermissions'
@@ -20,6 +20,7 @@ import {
20
20
  } from '../../helpers/permissions'
21
21
  import { FADE_IN_DURATION } from '../../helpers/recipients'
22
22
  import { useSharingContext } from '../../hooks/useSharingContext'
23
+ import { ShareRestrictionModal } from '../ShareRestrictionModal/ShareRestrictionModal'
23
24
 
24
25
  const LinkRecipient = props => {
25
26
  const { t, f, lang } = useI18n()
@@ -28,6 +29,9 @@ const LinkRecipient = props => {
28
29
 
29
30
  const { recipientConfirmationData, verifyRecipient, fadeIn, document } = props
30
31
 
32
+ const [openShareRestrictionModal, setOpenShareRestrictionModal] =
33
+ useState(false)
34
+
31
35
  const permissions = getDocumentPermissions(document?._id)
32
36
  const hasPassword = checkIsPermissionHasPassword(permissions)
33
37
  const expiresDate = getPermissionExpiresDate(permissions)
@@ -63,10 +67,23 @@ const LinkRecipient = props => {
63
67
  </Avatar>
64
68
  </ListItemIcon>
65
69
  <ListItemText
66
- primary={<Typography variant="body1">{textPrimary}</Typography>}
70
+ primary={
71
+ <DropdownButton
72
+ textVariant="body1"
73
+ onClick={() => setOpenShareRestrictionModal(true)}
74
+ >
75
+ {textPrimary}
76
+ </DropdownButton>
77
+ }
67
78
  secondary={textSecondary}
68
79
  />
69
80
  {RightPart}
81
+ {openShareRestrictionModal && (
82
+ <ShareRestrictionModal
83
+ file={document}
84
+ onClose={() => setOpenShareRestrictionModal(false)}
85
+ />
86
+ )}
70
87
  </ListItem>
71
88
  </Fade>
72
89
  )
@@ -2,18 +2,58 @@ import PropTypes from 'prop-types'
2
2
  import React, { useState, useRef } from 'react'
3
3
  import { useI18n } from 'twake-i18n'
4
4
 
5
+ import ActionsMenu from 'cozy-ui/transpiled/react/ActionsMenu'
6
+ import {
7
+ makeActions,
8
+ divider
9
+ } from 'cozy-ui/transpiled/react/ActionsMenu/Actions'
5
10
  import DropdownButton from 'cozy-ui/transpiled/react/DropdownButton'
6
11
 
12
+ import { revokeLink } from './actions/revokeLink'
13
+ import { setReadOnlySharedPermission } from './actions/setReadOnlySharedPermission'
14
+ import { setReadWriteSharedPermission } from './actions/setReadWriteSharedPermission'
15
+ import { isOnlyReadOnlyLinkAllowed } from '../../helpers/link'
7
16
  import { checkIsReadOnlyPermissions } from '../../helpers/permissions'
8
- import { ShareRestrictionModal } from '../ShareRestrictionModal/ShareRestrictionModal'
17
+ import { useSharingContext } from '../../hooks/useSharingContext'
18
+ import { WRITE_PERMS, READ_ONLY_PERMS } from '../ShareRestrictionModal/helpers'
9
19
 
10
- const LinkRecipientPermissions = ({ className, document, permissions }) => {
20
+ const LinkRecipientPermissions = ({ className, document }) => {
11
21
  const { t } = useI18n()
12
22
  const buttonRef = useRef()
13
- const [openShareRestrictionModal, setOpenShareRestrictionModal] =
14
- useState(false)
23
+ const [isMenuDisplayed, setMenuDisplayed] = useState(false)
24
+ const {
25
+ updateDocumentPermissions,
26
+ revokeSharingLink,
27
+ documentType,
28
+ getDocumentPermissions
29
+ } = useSharingContext()
15
30
 
31
+ const permissions = getDocumentPermissions(document._id)
16
32
  const isReadOnlyPermissions = checkIsReadOnlyPermissions(permissions)
33
+ const type = isReadOnlyPermissions ? 'one-way' : 'two-way'
34
+
35
+ const toggleMenu = () => setMenuDisplayed(!isMenuDisplayed)
36
+ const hideMenu = () => setMenuDisplayed(false)
37
+
38
+ const handleSetType = newType => {
39
+ const verbs = newType === 'one-way' ? READ_ONLY_PERMS : WRITE_PERMS
40
+ updateDocumentPermissions(document, { verbs })
41
+ }
42
+
43
+ const handleRevocation = () => revokeSharingLink(document)
44
+
45
+ const actionsToShow = [setReadOnlySharedPermission]
46
+ if (!isOnlyReadOnlyLinkAllowed({ documentType })) {
47
+ actionsToShow.push(setReadWriteSharedPermission)
48
+ }
49
+ actionsToShow.push(divider, revokeLink)
50
+
51
+ const actions = makeActions(actionsToShow, {
52
+ t,
53
+ type,
54
+ setType: handleSetType,
55
+ handleRevocation
56
+ })
17
57
 
18
58
  return (
19
59
  <div className={className}>
@@ -21,18 +61,17 @@ const LinkRecipientPermissions = ({ className, document, permissions }) => {
21
61
  <DropdownButton
22
62
  ref={buttonRef}
23
63
  textVariant="body2"
24
- onClick={() => setOpenShareRestrictionModal(true)}
64
+ onClick={toggleMenu}
25
65
  >
26
- {t(
27
- `Share.type.${isReadOnlyPermissions ? 'one-way' : 'two-way'}`
28
- ).toLowerCase()}
66
+ {t(`Share.type.${type}`).toLowerCase()}
29
67
  </DropdownButton>
30
- {openShareRestrictionModal && (
31
- <ShareRestrictionModal
32
- file={document}
33
- onClose={() => setOpenShareRestrictionModal(false)}
34
- />
35
- )}
68
+ <ActionsMenu
69
+ ref={buttonRef}
70
+ open={isMenuDisplayed}
71
+ actions={actions}
72
+ autoClose
73
+ onClose={hideMenu}
74
+ />
36
75
  </>
37
76
  </div>
38
77
  )
@@ -40,8 +79,7 @@ const LinkRecipientPermissions = ({ className, document, permissions }) => {
40
79
 
41
80
  LinkRecipientPermissions.propTypes = {
42
81
  className: PropTypes.string,
43
- document: PropTypes.object.isRequired,
44
- permissions: PropTypes.arrayOf(PropTypes.object).isRequired
82
+ document: PropTypes.object.isRequired
45
83
  }
46
84
 
47
85
  export default LinkRecipientPermissions
@@ -0,0 +1,33 @@
1
+ import React, { forwardRef } from 'react'
2
+
3
+ import ActionsMenuItem from 'cozy-ui/transpiled/react/ActionsMenu/ActionsMenuItem'
4
+ import Icon from 'cozy-ui/transpiled/react/Icon'
5
+ import TrashIcon from 'cozy-ui/transpiled/react/Icons/Trash'
6
+ import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
7
+ import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
8
+ import Typography from 'cozy-ui/transpiled/react/Typography'
9
+
10
+ const revokeLink = ({ t, handleRevocation }) => {
11
+ const title = t('Share.permissionLink.deactivate')
12
+
13
+ return {
14
+ name: 'revokeLink',
15
+ label: title,
16
+ icon: TrashIcon,
17
+ action: handleRevocation,
18
+ Component: forwardRef(function RevokeLinkItem(props, ref) {
19
+ return (
20
+ <ActionsMenuItem {...props} ref={ref}>
21
+ <ListItemIcon>
22
+ <Icon icon={TrashIcon} color="var(--errorColor)" />
23
+ </ListItemIcon>
24
+ <ListItemText
25
+ primary={<Typography color="error">{title}</Typography>}
26
+ />
27
+ </ActionsMenuItem>
28
+ )
29
+ })
30
+ }
31
+ }
32
+
33
+ export { revokeLink }