cozy-sharing 31.1.0 → 32.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/components/FederatedFolder/DumbFederatedFolderModal.js +15 -16
  3. package/dist/components/FederatedFolder/FederatedFolderModal.js +78 -103
  4. package/dist/components/FederatedFolder/FederatedFolderModal.spec.js +102 -292
  5. package/dist/components/Recipient/RecipientConfirm.js +0 -5
  6. package/dist/components/ShareAutosuggest.js +9 -4
  7. package/dist/components/ShareByEmail.js +29 -274
  8. package/dist/components/ShareByEmail.spec.js +52 -230
  9. package/dist/components/ShareByLink.js +1 -3
  10. package/dist/components/ShareDialogCozyToCozy.js +169 -35
  11. package/dist/components/ShareDialogCozyToCozy.spec.js +122 -35
  12. package/dist/components/ShareDialogTwoStepsConfirmationContainer.js +13 -3
  13. package/dist/components/ShareModal/SharingDetailsModal.js +0 -5
  14. package/dist/components/ShareRecipientsInput.js +6 -3
  15. package/dist/components/SharedDrive/SharedDriveForm.js +11 -23
  16. package/dist/components/SharedDrive/SharedDriveModal.js +1 -1
  17. package/dist/components/SharedDrive/useSharedDrive.js +33 -57
  18. package/dist/components/SharedDrive/useSharedDrive.spec.js +29 -93
  19. package/dist/components/SharedFolder/DumbBatchSharedFolderModal.js +15 -26
  20. package/dist/components/Sharetypeselect.js +85 -90
  21. package/dist/hooks/usePendingRecipients.js +20 -0
  22. package/dist/hooks/usePendingRecipients.spec.js +30 -0
  23. package/dist/styles/autosuggest.styl +8 -2
  24. package/dist/styles/share.styl +0 -39
  25. package/dist/stylesheet.css +8 -44
  26. package/locales/en.json +5 -9
  27. package/locales/fr.json +5 -9
  28. package/locales/ru.json +5 -9
  29. package/locales/vi.json +5 -9
  30. package/package.json +4 -5
  31. package/src/components/FederatedFolder/DumbFederatedFolderModal.jsx +14 -15
  32. package/src/components/FederatedFolder/FederatedFolderModal.jsx +50 -67
  33. package/src/components/FederatedFolder/FederatedFolderModal.spec.jsx +63 -186
  34. package/src/components/ShareAutosuggest.jsx +7 -2
  35. package/src/components/ShareByEmail.jsx +35 -186
  36. package/src/components/ShareByEmail.spec.jsx +22 -173
  37. package/src/components/ShareByLink.jsx +1 -7
  38. package/src/components/ShareDialogCozyToCozy.jsx +171 -38
  39. package/src/components/ShareDialogCozyToCozy.spec.jsx +66 -0
  40. package/src/components/ShareDialogTwoStepsConfirmationContainer.jsx +11 -1
  41. package/src/components/ShareRecipientsInput.jsx +5 -2
  42. package/src/components/SharedDrive/SharedDriveForm.jsx +10 -23
  43. package/src/components/SharedDrive/SharedDriveModal.jsx +1 -1
  44. package/src/components/SharedDrive/useSharedDrive.js +24 -50
  45. package/src/components/SharedDrive/useSharedDrive.spec.js +19 -67
  46. package/src/components/SharedFolder/DumbBatchSharedFolderModal.jsx +15 -29
  47. package/src/components/Sharetypeselect.jsx +75 -58
  48. package/src/hooks/usePendingRecipients.js +13 -0
  49. package/src/hooks/usePendingRecipients.spec.js +21 -0
  50. package/src/styles/autosuggest.styl +8 -2
  51. package/src/styles/share.styl +0 -39
  52. package/dist/components/SharedDrive/helpers.js +0 -102
  53. package/dist/components/SharedDrive/helpers.spec.js +0 -227
  54. package/dist/components/SharedStatus.js +0 -61
  55. package/dist/components/SharedStatus.spec.js +0 -44
  56. package/dist/components/Sharesubmit.js +0 -28
  57. package/dist/components/__snapshots__/SharedStatus.spec.js.snap +0 -94
  58. package/dist/propTypes.js +0 -26
  59. package/src/components/SharedDrive/helpers.js +0 -108
  60. package/src/components/SharedDrive/helpers.spec.js +0 -177
  61. package/src/components/SharedStatus.jsx +0 -50
  62. package/src/components/SharedStatus.spec.js +0 -48
  63. package/src/components/Sharesubmit.jsx +0 -31
  64. package/src/components/__snapshots__/SharedStatus.spec.js.snap +0 -94
  65. package/src/propTypes.js +0 -29
@@ -1,177 +0,0 @@
1
- import {
2
- mergeAndDeduplicateRecipients,
3
- moveRecipientToReadWrite,
4
- moveRecipientToReadOnly,
5
- formatRecipients,
6
- RECIPIENT_INDEX_PREFIX
7
- } from './helpers'
8
-
9
- describe('mergeAndDeduplicateRecipients', () => {
10
- it('should merge multiple arrays into one', () => {
11
- const result = mergeAndDeduplicateRecipients([
12
- [{ id: '1', name: 'Alice' }],
13
- [{ id: '2', name: 'Bob' }]
14
- ])
15
- expect(result).toEqual([
16
- { id: '1', _id: '1', name: 'Alice' },
17
- { id: '2', _id: '2', name: 'Bob' }
18
- ])
19
- })
20
-
21
- it('should deduplicate recipients with the same id', () => {
22
- const result = mergeAndDeduplicateRecipients([
23
- [{ id: '1', name: 'Alice' }],
24
- [{ id: '1', name: 'Alice' }]
25
- ])
26
- expect(result).toEqual([{ id: '1', _id: '1', name: 'Alice' }])
27
- })
28
-
29
- it('should normalize _id to id for deduplication', () => {
30
- const result = mergeAndDeduplicateRecipients([
31
- [{ _id: '1', name: 'Alice' }],
32
- [{ _id: '2', name: 'Bob' }]
33
- ])
34
- expect(result).toEqual([
35
- { _id: '1', id: '1', name: 'Alice' },
36
- { _id: '2', id: '2', name: 'Bob' }
37
- ])
38
- })
39
-
40
- it('should deduplicate recipients when one has id and the other has _id', () => {
41
- const result = mergeAndDeduplicateRecipients([
42
- [{ id: '1', name: 'Alice' }],
43
- [{ _id: '1', name: 'Alice' }]
44
- ])
45
- expect(result).toEqual([{ id: '1', _id: '1', name: 'Alice' }])
46
- })
47
-
48
- it('should prefer existing id over _id when both are present', () => {
49
- const result = mergeAndDeduplicateRecipients([
50
- [{ id: 'real-id', _id: 'other-id', name: 'Alice' }]
51
- ])
52
- expect(result).toEqual([{ id: 'real-id', _id: 'other-id', name: 'Alice' }])
53
- })
54
-
55
- it('should handle empty arrays', () => {
56
- const result = mergeAndDeduplicateRecipients([[], []])
57
- expect(result).toEqual([])
58
- })
59
- })
60
-
61
- describe('moveRecipientToReadWrite', () => {
62
- it('should move a recipient from readOnly to readWrite', () => {
63
- const state = {
64
- recipients: [{ _id: '1', name: 'Alice' }],
65
- readOnlyRecipients: [{ _id: '2', name: 'Bob' }]
66
- }
67
- const result = moveRecipientToReadWrite(state, '2')
68
- expect(result.recipients).toEqual([
69
- { _id: '1', name: 'Alice' },
70
- { _id: '2', name: 'Bob' }
71
- ])
72
- expect(result.readOnlyRecipients).toEqual([])
73
- })
74
-
75
- it('should return unchanged state if recipient not found', () => {
76
- const state = {
77
- recipients: [{ _id: '1', name: 'Alice' }],
78
- readOnlyRecipients: []
79
- }
80
- const result = moveRecipientToReadWrite(state, '999')
81
- expect(result).toBe(state)
82
- })
83
- })
84
-
85
- describe('moveRecipientToReadOnly', () => {
86
- it('should move a recipient from readWrite to readOnly', () => {
87
- const state = {
88
- recipients: [{ _id: '1', name: 'Alice' }],
89
- readOnlyRecipients: [{ _id: '2', name: 'Bob' }]
90
- }
91
- const result = moveRecipientToReadOnly(state, '1')
92
- expect(result.recipients).toEqual([])
93
- expect(result.readOnlyRecipients).toEqual([
94
- { _id: '2', name: 'Bob' },
95
- { _id: '1', name: 'Alice' }
96
- ])
97
- })
98
-
99
- it('should return unchanged state if recipient not found', () => {
100
- const state = {
101
- recipients: [],
102
- readOnlyRecipients: [{ _id: '1', name: 'Alice' }]
103
- }
104
- const result = moveRecipientToReadOnly(state, '999')
105
- expect(result).toBe(state)
106
- })
107
- })
108
-
109
- describe('formatRecipients', () => {
110
- it('should format readWrite and readOnly recipients with correct types', () => {
111
- const input = {
112
- recipients: [
113
- {
114
- _id: '1',
115
- displayName: 'Alice',
116
- email: [{ address: 'alice@example.com', primary: true }]
117
- }
118
- ],
119
- readOnlyRecipients: [
120
- {
121
- _id: '2',
122
- displayName: 'Bob',
123
- email: [{ address: 'bob@example.com', primary: true }]
124
- }
125
- ]
126
- }
127
- const result = formatRecipients(input)
128
- expect(result).toHaveLength(2)
129
- expect(result[0]).toMatchObject({
130
- index: `${RECIPIENT_INDEX_PREFIX}1`,
131
- type: 'two-way',
132
- public_name: 'Alice'
133
- })
134
- expect(result[1]).toMatchObject({
135
- index: `${RECIPIENT_INDEX_PREFIX}2`,
136
- type: 'one-way',
137
- public_name: 'Bob'
138
- })
139
- })
140
-
141
- it('should flatten an object-shaped contact name into a string public_name', () => {
142
- const input = {
143
- recipients: [
144
- {
145
- _id: '3',
146
- name: { givenName: 'Arya', familyName: 'Stark' },
147
- email: [{ address: 'arya@example.com', primary: true }]
148
- }
149
- ],
150
- readOnlyRecipients: []
151
- }
152
- const result = formatRecipients(input)
153
- expect(typeof result[0].public_name).toBe('string')
154
- expect(result[0].public_name).toBe('Arya Stark')
155
- })
156
-
157
- it('should sort recipients by public_name', () => {
158
- const input = {
159
- recipients: [
160
- {
161
- _id: '1',
162
- displayName: 'Zara',
163
- email: [{ address: 'zara@example.com', primary: true }]
164
- },
165
- {
166
- _id: '2',
167
- displayName: 'Alice',
168
- email: [{ address: 'alice@example.com', primary: true }]
169
- }
170
- ],
171
- readOnlyRecipients: []
172
- }
173
- const result = formatRecipients(input)
174
- expect(result[0].public_name).toBe('Alice')
175
- expect(result[1].public_name).toBe('Zara')
176
- })
177
- })
@@ -1,50 +0,0 @@
1
- import cx from 'classnames'
2
- import React from 'react'
3
-
4
- import { useI18n } from 'twake-i18n'
5
-
6
- import { SharingTooltip, TooltipRecipientList } from './Tooltip'
7
- import LinkIcon from '../assets/icons/icon-link.svg'
8
- import { getDisplayName } from '../models'
9
- import styles from '../styles/status.styl'
10
-
11
- export const SharedStatus = ({ className, docId, recipients, link }) => {
12
- const { t } = useI18n()
13
- return (
14
- <span className={cx(className, styles['shared-status'])}>
15
- {recipients.length > 1 && (
16
- <a
17
- data-tip
18
- data-for={`members${docId}`}
19
- className={styles['shared-status-label']}
20
- >
21
- {t('Share.members.count', { smart_count: recipients.length })}
22
- </a>
23
- )}
24
- {recipients.length > 1 && (
25
- <SharingTooltip id={`members${docId}`}>
26
- <TooltipRecipientList
27
- recipientNames={recipients.map(recipient =>
28
- getDisplayName(recipient)
29
- )}
30
- />
31
- </SharingTooltip>
32
- )}
33
- {link && (
34
- <>
35
- <LinkIcon
36
- style={{ fill: 'var(--iconTextColor)' }}
37
- data-tip
38
- data-for={`linkfor${docId}`}
39
- />
40
-
41
- <SharingTooltip id={`linkfor${docId}`}>
42
- <span>{t('Files.share.sharedByLink')}</span>
43
- </SharingTooltip>
44
- </>
45
- )}
46
- </span>
47
- )
48
- }
49
-
50
- export default SharedStatus
@@ -1,48 +0,0 @@
1
- import { render } from '@testing-library/react'
2
- import React from 'react'
3
-
4
- import { SharedStatus } from './SharedStatus'
5
- import AppLike from '../../test/AppLike'
6
-
7
- describe('SharedStatus component', () => {
8
- it('should just render a span if no sharing', () => {
9
- const { container } = render(
10
- <AppLike>
11
- <SharedStatus docId="1" recipients={[]} />
12
- </AppLike>
13
- )
14
- expect(container).toMatchSnapshot()
15
- })
16
-
17
- it('should have the right display if there is several recipients', () => {
18
- const { container, getByText } = render(
19
- <AppLike>
20
- <SharedStatus
21
- docId="1"
22
- recipients={[
23
- {
24
- _id: 1,
25
- name: '1'
26
- },
27
- {
28
- _id: 2,
29
- name: '2'
30
- }
31
- ]}
32
- />
33
- </AppLike>
34
- )
35
- expect(container).toMatchSnapshot()
36
- expect(getByText('2 members')).toBeTruthy()
37
- })
38
-
39
- it('should display the link if there is a link', () => {
40
- const { container, getByText } = render(
41
- <AppLike>
42
- <SharedStatus docId="1" recipients={[]} link={true} />
43
- </AppLike>
44
- )
45
- expect(container).toMatchSnapshot()
46
- expect(getByText('Shared by link')).toBeTruthy()
47
- })
48
- })
@@ -1,31 +0,0 @@
1
- import PropTypes from 'prop-types'
2
- import React from 'react'
3
-
4
- import Button from 'cozy-ui/transpiled/react/Buttons'
5
-
6
- const ShareSubmit = props => (
7
- <Button
8
- onClick={() => {
9
- props.onSubmit()
10
- }}
11
- size="large"
12
- busy={props.loading}
13
- label={props.label}
14
- disabled={props.disabled}
15
- variant="ghost"
16
- />
17
- )
18
-
19
- ShareSubmit.propTypes = {
20
- onSubmit: PropTypes.func.isRequired,
21
- label: PropTypes.string,
22
- loading: PropTypes.bool,
23
- disabled: PropTypes.bool
24
- }
25
-
26
- ShareSubmit.defaultProps = {
27
- label: 'Submit',
28
- loading: false
29
- }
30
-
31
- export default ShareSubmit
@@ -1,94 +0,0 @@
1
- // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
-
3
- exports[`SharedStatus component should display the link if there is a link 1`] = `
4
- <div>
5
- <div
6
- class="TwakeTheme--light u-dc"
7
- >
8
- <span
9
- class="shared-status"
10
- >
11
- <svg
12
- currentItem="false"
13
- data-for="linkfor1"
14
- data-tip="true"
15
- height="16"
16
- style="fill: var(--iconTextColor);"
17
- viewBox="0 0 16 16"
18
- width="16"
19
- xmlns="http://www.w3.org/2000/svg"
20
- xmlns:xlink="http://www.w3.org/1999/xlink"
21
- >
22
- <defs>
23
- <path
24
- d="M8.88 3.88a1 1 0 1 1-1.415-1.415L9.053.877A2.998 2.998 0 0 1 13.29.876l1.18 1.18a2.998 2.998 0 0 1-.007 4.24L10.999 9.76c-1.535 1.535-4.07 1.583-5.534.12A1 1 0 1 1 6.88 8.465c.67.67 1.94.646 2.705-.119l3.465-3.464a.998.998 0 0 0 .006-1.413l-1.18-1.18a.998.998 0 0 0-1.408.003L8.88 3.88zm-2.415 7.585A1 1 0 1 1 7.88 12.88l-1.587 1.587a2.998 2.998 0 0 1-4.237.002l-1.18-1.18a2.998 2.998 0 0 1 .007-4.24l3.464-3.464c1.534-1.535 4.07-1.583 5.533-.12A1 1 0 1 1 8.465 6.88c-.67-.67-1.94-.646-2.705.119l-3.464 3.464a.998.998 0 0 0-.006 1.413l1.18 1.18a.998.998 0 0 0 1.407-.003l1.588-1.588z"
25
- id="link-1-path-1"
26
- />
27
- </defs>
28
- <use
29
- fill-rule="nonzero"
30
- xlink:href="#link-1-path-1"
31
- />
32
- </svg>
33
- <div
34
- class="__react_component_tooltip place-bottom type-dark "
35
- data-id="tooltip"
36
- id="linkfor1"
37
- >
38
- <span>
39
- Shared by link
40
- </span>
41
- </div>
42
- </span>
43
- </div>
44
- </div>
45
- `;
46
-
47
- exports[`SharedStatus component should have the right display if there is several recipients 1`] = `
48
- <div>
49
- <div
50
- class="TwakeTheme--light u-dc"
51
- >
52
- <span
53
- class="shared-status"
54
- >
55
- <a
56
- class="shared-status-label"
57
- currentitem="false"
58
- data-for="members1"
59
- data-tip="true"
60
- >
61
- 2 members
62
- </a>
63
- <div
64
- class="__react_component_tooltip place-bottom type-dark "
65
- data-id="tooltip"
66
- id="members1"
67
- >
68
- <ul
69
- class="shared-tooltip-list"
70
- >
71
- <li>
72
- 1
73
- </li>
74
- <li>
75
- 2
76
- </li>
77
- </ul>
78
- </div>
79
- </span>
80
- </div>
81
- </div>
82
- `;
83
-
84
- exports[`SharedStatus component should just render a span if no sharing 1`] = `
85
- <div>
86
- <div
87
- class="TwakeTheme--light u-dc"
88
- >
89
- <span
90
- class="shared-status"
91
- />
92
- </div>
93
- </div>
94
- `;
package/src/propTypes.js DELETED
@@ -1,29 +0,0 @@
1
- import PropTypes from 'prop-types'
2
-
3
- import { Contact, Group } from './models'
4
-
5
- export const contactsResponseType = PropTypes.shape({
6
- count: PropTypes.number,
7
- data: PropTypes.arrayOf(Contact.propType),
8
- definition: PropTypes.object,
9
- fetchMore: PropTypes.func,
10
- fetchStatus: PropTypes.string,
11
- hasMore: PropTypes.bool,
12
- id: PropTypes.string,
13
- lastError: PropTypes.string,
14
- lastFetch: PropTypes.number,
15
- lastUpdate: PropTypes.number
16
- })
17
-
18
- export const contactGroupsResponseType = PropTypes.shape({
19
- count: PropTypes.number,
20
- data: PropTypes.arrayOf(Group.propType),
21
- definition: PropTypes.object,
22
- fetchMore: PropTypes.func,
23
- fetchStatus: PropTypes.string,
24
- hasMore: PropTypes.bool,
25
- id: PropTypes.string,
26
- lastError: PropTypes.string,
27
- lastFetch: PropTypes.number,
28
- lastUpdate: PropTypes.number
29
- })