cozy-sharing 12.3.0 → 13.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/.storybook/preview.jsx +1 -0
  2. package/CHANGELOG.md +29 -0
  3. package/dist/components/ContactSuggestion.js +7 -3
  4. package/dist/components/ContactSuggestion.spec.js +7 -1
  5. package/dist/components/Recipient/GroupRecipient.js +14 -7
  6. package/dist/components/Recipient/GroupRecipientDetail.js +4 -2
  7. package/dist/components/Recipient/GroupRecipientDetailWithAccess.js +9 -11
  8. package/dist/components/Recipient/GroupRecipientDetailWithoutAccess.js +8 -4
  9. package/dist/components/Recipient/GroupRecipientPermissions.js +3 -6
  10. package/dist/components/Recipient/MemberRecipient.js +1 -2
  11. package/dist/components/Recipient/MemberRecipientPermissions.js +1 -1
  12. package/dist/components/ShareAutosuggest.js +16 -9
  13. package/dist/components/ShareAutosuggest.spec.js +38 -13
  14. package/dist/components/ShareAutosuggest.stories.js +61 -0
  15. package/dist/components/ShareByEmail.js +15 -15
  16. package/dist/components/ShareByEmail.spec.js +0 -6
  17. package/dist/components/ShareDialogCozyToCozy.js +1 -5
  18. package/dist/components/ShareDialogCozyToCozy.spec.js +0 -61
  19. package/dist/components/ShareDialogTwoStepsConfirmationContainer.js +1 -5
  20. package/dist/components/ShareDialogTwoStepsConfirmationContainer.spec.js +0 -61
  21. package/dist/components/ShareModal/EditableSharingModal.js +3 -10
  22. package/dist/components/ShareModal/EditableSharingModal.spec.js +0 -6
  23. package/dist/components/ShareModal.js +1 -8
  24. package/dist/components/ShareRecipientsInput.js +46 -49
  25. package/dist/components/ShareRecipientsInput.spec.js +120 -144
  26. package/dist/helpers/contacts.js +12 -1
  27. package/dist/helpers/recipients.js +16 -9
  28. package/dist/helpers/successMessage.js +58 -16
  29. package/dist/helpers/successMessage.spec.js +122 -57
  30. package/dist/queries/queries.js +37 -5
  31. package/dist/styles/autosuggest.styl +2 -1
  32. package/dist/stylesheet.css +2 -1
  33. package/locales/en.json +23 -10
  34. package/locales/fr.json +23 -8
  35. package/package.json +4 -4
  36. package/src/components/ContactSuggestion.jsx +9 -3
  37. package/src/components/ContactSuggestion.spec.jsx +10 -1
  38. package/src/components/Recipient/GroupRecipient.jsx +17 -10
  39. package/src/components/Recipient/GroupRecipientDetail.jsx +5 -2
  40. package/src/components/Recipient/GroupRecipientDetailWithAccess.jsx +9 -14
  41. package/src/components/Recipient/GroupRecipientDetailWithoutAccess.jsx +8 -3
  42. package/src/components/Recipient/GroupRecipientPermissions.jsx +3 -8
  43. package/src/components/Recipient/MemberRecipient.jsx +4 -3
  44. package/src/components/Recipient/MemberRecipientPermissions.jsx +1 -1
  45. package/src/components/ShareAutosuggest.jsx +16 -11
  46. package/src/components/ShareAutosuggest.spec.jsx +31 -10
  47. package/src/components/ShareAutosuggest.stories.jsx +63 -0
  48. package/src/components/ShareByEmail.jsx +11 -11
  49. package/src/components/ShareByEmail.spec.jsx +0 -4
  50. package/src/components/ShareDialogCozyToCozy.jsx +0 -4
  51. package/src/components/ShareDialogCozyToCozy.spec.jsx +0 -67
  52. package/src/components/ShareDialogTwoStepsConfirmationContainer.jsx +0 -4
  53. package/src/components/ShareDialogTwoStepsConfirmationContainer.spec.jsx +0 -67
  54. package/src/components/ShareModal/EditableSharingModal.jsx +3 -21
  55. package/src/components/ShareModal/EditableSharingModal.spec.jsx +0 -2
  56. package/src/components/ShareModal.jsx +1 -7
  57. package/src/components/ShareRecipientsInput.jsx +84 -52
  58. package/src/components/ShareRecipientsInput.spec.jsx +140 -145
  59. package/src/helpers/contacts.js +8 -0
  60. package/src/helpers/recipients.js +24 -15
  61. package/src/helpers/successMessage.js +71 -21
  62. package/src/helpers/successMessage.spec.js +129 -69
  63. package/src/queries/queries.js +36 -5
  64. package/src/styles/autosuggest.styl +2 -1
  65. package/test/AppLike.jsx +6 -3
@@ -1,9 +1,9 @@
1
- import get from 'lodash/get'
2
-
3
1
  import flag from 'cozy-flags'
4
2
 
5
3
  import { Group } from '../models'
6
4
 
5
+ export const DEFAULT_DISPLAY_NAME = 'Share.contacts.defaultDisplayName'
6
+
7
7
  export const filterAndReworkRecipients = (recipients, previousRecipients) => {
8
8
  return recipients
9
9
  .filter(recipient => recipient.status !== 'owner')
@@ -52,26 +52,16 @@ export const hasReachRecipientsLimit = (current, next) => {
52
52
 
53
53
  /**
54
54
  * Merges the recipients list with a new recipient and their associated contacts.
55
+ * Only used when flag sharing.show-recipient-groups is not enabled.
55
56
  * @param {object[]} recipients - The list of recipients.
56
57
  * @param {object} recipient - The new recipient.
57
58
  * @param {object[]} contacts - The list of contacts.
58
59
  * @returns {object[]} - The merged recipients list.
59
60
  */
60
- export const spreadGroupAndMergeRecipients = (
61
- recipients,
62
- newRecipient,
63
- contacts
64
- ) => {
61
+ export const spreadGroupAndMergeRecipients = (recipients, newRecipient) => {
65
62
  let contactsToAdd
66
63
  if (newRecipient._type === Group.doctype) {
67
- const groupId = newRecipient.id
68
- contactsToAdd = contacts.data.filter(contact => {
69
- const contactGroupIds = get(contact, 'relationships.groups.data', []).map(
70
- group => group._id
71
- )
72
-
73
- return contactGroupIds.includes(groupId)
74
- })
64
+ contactsToAdd = newRecipient.members
75
65
  } else {
76
66
  contactsToAdd = [newRecipient]
77
67
  }
@@ -90,3 +80,22 @@ export const spreadGroupAndMergeRecipients = (
90
80
  export const mergeRecipients = (recipients, newRecipient) => {
91
81
  return [...recipients, newRecipient]
92
82
  }
83
+
84
+ export const getGroupRecipientSecondaryText = ({
85
+ nbMember,
86
+ nbMemberReady,
87
+ t,
88
+ isUserInsideMembers
89
+ }) => {
90
+ const memberCount =
91
+ nbMember === nbMemberReady ? nbMember : [nbMemberReady, nbMember].join('/')
92
+ const secondary = t('GroupRecipient.secondary', {
93
+ memberCount,
94
+ smart_count: nbMember
95
+ })
96
+
97
+ return (
98
+ secondary +
99
+ (isUserInsideMembers ? ` (${t('GroupRecipient.secondary_you')})` : '')
100
+ )
101
+ }
@@ -1,16 +1,40 @@
1
1
  import { models } from 'cozy-client'
2
2
 
3
- import { Contact } from '../models'
3
+ import { Contact, Group } from '../models'
4
+
4
5
  export const countNewRecipients = (currentRecipients, newRecipients) => {
5
- return newRecipients.filter(contact => {
6
- const email = models.contact.getPrimaryEmail(contact)
7
- const cozyUrl = models.contact.getPrimaryCozy(contact)
8
- return !currentRecipients.find(
9
- r =>
10
- (email && r.email && r.email === email) ||
11
- (cozyUrl && r.instance && r.instance === cozyUrl)
12
- )
13
- }).length
6
+ const newRecipientsNotAlreadyIncluded = newRecipients.filter(recipient => {
7
+ if (Contact.isContact(recipient)) {
8
+ const email = models.contact.getPrimaryEmail(recipient)
9
+ const cozyUrl = models.contact.getPrimaryCozy(recipient)
10
+ return !currentRecipients.find(
11
+ r =>
12
+ (email && r.email && r.email === email) ||
13
+ (cozyUrl && r.instance && r.instance === cozyUrl)
14
+ )
15
+ }
16
+ return true
17
+ })
18
+
19
+ return newRecipientsNotAlreadyIncluded.reduce(
20
+ (acc, recipient) => {
21
+ if (recipient._type === Group.doctype) {
22
+ return {
23
+ ...acc,
24
+ group: acc.group + 1
25
+ }
26
+ } else {
27
+ return {
28
+ ...acc,
29
+ contact: acc.contact + 1
30
+ }
31
+ }
32
+ },
33
+ {
34
+ group: 0,
35
+ contact: 0
36
+ }
37
+ )
14
38
  }
15
39
 
16
40
  export const getSuccessMessage = (
@@ -24,35 +48,61 @@ export const getSuccessMessage = (
24
48
  ? models.contact.getPrimaryEmail(recipient)
25
49
  : recipient.email
26
50
  const cozyUrl = models.contact.getPrimaryCozy(recipient)
51
+ const isContactGroup = recipient._type === Group.doctype
27
52
 
28
- if (email) {
53
+ if (isContactGroup) {
29
54
  return [
30
- `${documentType}.share.shareByEmail.success`,
55
+ `${documentType}.share.shareByEmail.singleGroupSuccess`,
56
+ {
57
+ groupName: recipient.name
58
+ }
59
+ ]
60
+ } else if (email) {
61
+ return [
62
+ `${documentType}.share.shareByEmail.singleContactSuccess`,
31
63
  {
32
64
  email
33
65
  }
34
66
  ]
35
67
  } else if (cozyUrl) {
36
68
  return [
37
- `${documentType}.share.shareByEmail.success`,
69
+ `${documentType}.share.shareByEmail.singleContactSuccess`,
38
70
  {
39
71
  email: cozyUrl
40
72
  }
41
73
  ]
42
74
  } else {
43
75
  return [
44
- `${documentType}.share.shareByEmail.genericSuccess`,
76
+ `${documentType}.share.shareByEmail.contactSuccess`,
45
77
  {
46
- count: 1
78
+ smart_count: 1
47
79
  }
48
80
  ]
49
81
  }
50
82
  } else {
51
- return [
52
- `${documentType}.share.shareByEmail.genericSuccess`,
53
- {
54
- count: countNewRecipients(recipientsBefore, recipientsAfter)
55
- }
56
- ]
83
+ const count = countNewRecipients(recipientsBefore, recipientsAfter)
84
+ if (count.contact > 0 && count.group > 0) {
85
+ return [
86
+ `${documentType}.share.shareByEmail.contactAndGroupSuccess`,
87
+ {
88
+ nbContact: count.contact,
89
+ nbGroup: count.group
90
+ }
91
+ ]
92
+ } else if (count.group > 0) {
93
+ return [
94
+ `${documentType}.share.shareByEmail.groupSuccess`,
95
+ {
96
+ smart_count: count.group
97
+ }
98
+ ]
99
+ } else {
100
+ return [
101
+ `${documentType}.share.shareByEmail.contactSuccess`,
102
+ {
103
+ smart_count: count.contact
104
+ }
105
+ ]
106
+ }
57
107
  }
58
108
  }
@@ -2,18 +2,6 @@ import { getSuccessMessage, countNewRecipients } from './successMessage'
2
2
 
3
3
  describe('getSuccessMessage method', () => {
4
4
  const props = {
5
- contacts: {
6
- id: 'contacts',
7
- data: [],
8
- hasMore: false,
9
- fetchStatus: 'loaded'
10
- },
11
- contactGroups: {
12
- id: 'groups',
13
- data: [],
14
- hasMore: false,
15
- fetchStatus: 'loaded'
16
- },
17
5
  currentRecipients: [{ email: 'sansa.stark@winterfell.westeros' }],
18
6
  documentType: 'Files',
19
7
  sharingDesc: 'fake-doc.odt',
@@ -23,17 +11,17 @@ describe('getSuccessMessage method', () => {
23
11
 
24
12
  it('should return a success message and its params for multiple recipients', () => {
25
13
  const recipientsAfter = [
26
- { email: 'jon.snow@thewall.westeros' },
27
- { email: 'arya.stark@winterfell.westeros' },
28
- { email: 'sansa.stark@winterfell.westeros' }
14
+ { _type: 'io.cozy.contacts', email: 'jon.snow@thewall.westeros' },
15
+ { _type: 'io.cozy.contacts', email: 'arya.stark@winterfell.westeros' },
16
+ { _type: 'io.cozy.contacts', email: 'sansa.stark@winterfell.westeros' }
29
17
  ]
30
18
  const [message, params] = getSuccessMessage(
31
19
  props.currentRecipients,
32
20
  recipientsAfter,
33
21
  props.documentType
34
22
  )
35
- expect(message).toEqual('Files.share.shareByEmail.genericSuccess')
36
- expect(params).toEqual({ count: 2 })
23
+ expect(message).toEqual('Files.share.shareByEmail.contactSuccess')
24
+ expect(params).toEqual({ smart_count: 2 })
37
25
  })
38
26
 
39
27
  it('should return a success message and its params for one recipient with email', () => {
@@ -43,7 +31,7 @@ describe('getSuccessMessage method', () => {
43
31
  [{ email: 'jon.snow@thewall.westeros' }],
44
32
  props.documentType
45
33
  )
46
- expect(message).toEqual('Files.share.shareByEmail.success')
34
+ expect(message).toEqual('Files.share.shareByEmail.singleContactSuccess')
47
35
  expect(params).toEqual({ email: 'jon.snow@thewall.westeros' })
48
36
  })
49
37
 
@@ -70,7 +58,7 @@ describe('getSuccessMessage method', () => {
70
58
  ],
71
59
  props.documentType
72
60
  )
73
- expect(message).toEqual('Files.share.shareByEmail.success')
61
+ expect(message).toEqual('Files.share.shareByEmail.singleContactSuccess')
74
62
  expect(params).toEqual({ email: 'jon.snow@thewall.westeros' })
75
63
  })
76
64
 
@@ -89,11 +77,11 @@ describe('getSuccessMessage method', () => {
89
77
  ],
90
78
  props.documentType
91
79
  )
92
- expect(message).toEqual('Files.share.shareByEmail.success')
80
+ expect(message).toEqual('Files.share.shareByEmail.singleContactSuccess')
93
81
  expect(params).toEqual({ email: 'https://doranmartell.mycozy.cloud' })
94
82
  })
95
83
 
96
- it('should use generic success message if recipient has no email and no cozy', () => {
84
+ it('should use contact success message if recipient has no email and no cozy', () => {
97
85
  const recipientsBefore = props.currentRecipients
98
86
  const [message, params] = getSuccessMessage(
99
87
  recipientsBefore,
@@ -104,12 +92,90 @@ describe('getSuccessMessage method', () => {
104
92
  ],
105
93
  props.documentType
106
94
  )
107
- expect(message).toEqual('Files.share.shareByEmail.genericSuccess')
108
- expect(params).toEqual({ count: 1 })
95
+ expect(message).toEqual('Files.share.shareByEmail.contactSuccess')
96
+ expect(params).toEqual({ smart_count: 1 })
97
+ })
98
+
99
+ it('should use single group success message if recipient is a group', () => {
100
+ const recipientsBefore = props.currentRecipients
101
+ const [message, params] = getSuccessMessage(
102
+ recipientsBefore,
103
+ [
104
+ {
105
+ _type: 'io.cozy.contacts.groups',
106
+ name: 'Stark family'
107
+ }
108
+ ],
109
+ props.documentType
110
+ )
111
+ expect(message).toEqual('Files.share.shareByEmail.singleGroupSuccess')
112
+ expect(params).toEqual({ groupName: 'Stark family' })
113
+ })
114
+
115
+ it('should use contact success message if recipient has only multiple contacts', () => {
116
+ const recipientsBefore = props.currentRecipients
117
+ const [message, params] = getSuccessMessage(
118
+ recipientsBefore,
119
+ [
120
+ {
121
+ _type: 'io.cozy.contacts'
122
+ },
123
+ {
124
+ _type: 'io.cozy.contacts'
125
+ },
126
+ {
127
+ _type: 'io.cozy.contacts'
128
+ }
129
+ ],
130
+ props.documentType
131
+ )
132
+ expect(message).toEqual('Files.share.shareByEmail.contactSuccess')
133
+ expect(params).toEqual({ smart_count: 3 })
134
+ })
135
+
136
+ it('should use group success message if recipient has only multiple groups', () => {
137
+ const recipientsBefore = props.currentRecipients
138
+ const [message, params] = getSuccessMessage(
139
+ recipientsBefore,
140
+ [
141
+ {
142
+ _type: 'io.cozy.contacts.groups'
143
+ },
144
+ {
145
+ _type: 'io.cozy.contacts.groups'
146
+ }
147
+ ],
148
+ props.documentType
149
+ )
150
+ expect(message).toEqual('Files.share.shareByEmail.groupSuccess')
151
+ expect(params).toEqual({ smart_count: 2 })
152
+ })
153
+
154
+ it('should use contact and group success message if recipient has multiple contacts and groups', () => {
155
+ const recipientsBefore = props.currentRecipients
156
+ const [message, params] = getSuccessMessage(
157
+ recipientsBefore,
158
+ [
159
+ {
160
+ _type: 'io.cozy.contacts'
161
+ },
162
+ {
163
+ _id: 'fcb16b9e-7421',
164
+ _type: 'io.cozy.contacts.groups'
165
+ },
166
+ {
167
+ _id: 'f45b16be-7523',
168
+ _type: 'io.cozy.contacts.groups'
169
+ }
170
+ ],
171
+ props.documentType
172
+ )
173
+ expect(message).toEqual('Files.share.shareByEmail.contactAndGroupSuccess')
174
+ expect(params).toEqual({ nbContact: 1, nbGroup: 2 })
109
175
  })
110
176
  })
111
177
 
112
- describe('countNewRecipients function', () => {
178
+ describe('countNewRecipients', () => {
113
179
  const currentRecipients = [
114
180
  {
115
181
  email: 'arya.stark@winterfell.westeros'
@@ -123,64 +189,42 @@ describe('countNewRecipients function', () => {
123
189
  ]
124
190
  const addedRecipients = [
125
191
  {
126
- id: '5d4916fa-e193',
192
+ _id: 'e8c0e15f-da7d',
193
+ _type: 'io.cozy.contacts',
194
+ fullname: 'Jon Snow',
127
195
  email: [
128
196
  {
129
197
  address: 'jon.snow@thewall.westeros',
130
- type: 'primary'
198
+ primary: true
199
+ },
200
+ {
201
+ address: 'jon.snow@winterfell.westeros',
202
+ primary: false
131
203
  }
132
204
  ]
133
205
  },
134
206
  {
135
- id: '4df64228-ce84',
136
- email: [
137
- {
138
- address: 'sansa.stark@winterfell.westeros',
139
- type: 'primary'
140
- }
141
- ]
207
+ _id: 'fcb16b9e-7421',
208
+ _type: 'io.cozy.contacts'
142
209
  },
143
210
  {
144
- id: 'ff955bb1-f696',
145
- email: [
211
+ _id: 'f45b16be-7523',
212
+ _type: 'io.cozy.contacts',
213
+ cozy: [
146
214
  {
147
- address: 'bran.stark@winterfell.westeros',
148
- type: 'primary'
215
+ url: 'https://doranmartell.mycozy.cloud'
149
216
  }
150
217
  ]
151
218
  }
152
219
  ]
153
220
 
154
- it('should count only the new recipients using email', () => {
221
+ it('should count the new recipients with email', () => {
155
222
  const result = countNewRecipients(currentRecipients, addedRecipients)
156
- expect(result).toEqual(1)
223
+ expect(result.contact).toEqual(2)
224
+ expect(result.group).toEqual(0)
157
225
  })
158
226
 
159
- it('should count the new recipients when there are no current recipients', () => {
160
- const result = countNewRecipients([], addedRecipients)
161
- expect(result).toEqual(3)
162
- })
163
-
164
- it('should return 0 if there is no new recipients', () => {
165
- const currentRecipients = [
166
- {
167
- email: 'arya.stark@winterfell.westeros'
168
- },
169
- {
170
- email: 'sansa.stark@winterfell.westeros'
171
- },
172
- {
173
- email: 'jon.snow@thewall.westeros'
174
- },
175
- {
176
- email: 'bran.stark@winterfell.westeros'
177
- }
178
- ]
179
- const result = countNewRecipients(currentRecipients, addedRecipients)
180
- expect(result).toEqual(0)
181
- })
182
-
183
- it('should count the new recipients using cozy url', () => {
227
+ it('should count the new recipients with cozy url', () => {
184
228
  const currentRecipients = [
185
229
  {
186
230
  instance: 'https://bran.mycozy.cloud'
@@ -191,7 +235,7 @@ describe('countNewRecipients function', () => {
191
235
  ]
192
236
  const addedRecipients = [
193
237
  {
194
- id: '5d4916fa-e193',
238
+ _type: 'io.cozy.contacts',
195
239
  cozy: [
196
240
  {
197
241
  url: 'https://jon.mycozy.cloud',
@@ -200,7 +244,7 @@ describe('countNewRecipients function', () => {
200
244
  ]
201
245
  },
202
246
  {
203
- id: '4df64228-ce84',
247
+ _type: 'io.cozy.contacts',
204
248
  cozy: [
205
249
  {
206
250
  url: 'https://sansa.mycozy.cloud',
@@ -209,7 +253,7 @@ describe('countNewRecipients function', () => {
209
253
  ]
210
254
  },
211
255
  {
212
- id: 'ff955bb1-f696',
256
+ _type: 'io.cozy.contacts',
213
257
  cozy: [
214
258
  {
215
259
  url: 'https://bran.mycozy.cloud',
@@ -218,7 +262,7 @@ describe('countNewRecipients function', () => {
218
262
  ]
219
263
  },
220
264
  {
221
- id: '0761944a-c740',
265
+ _type: 'io.cozy.contacts',
222
266
  cozy: [
223
267
  {
224
268
  url: 'https://arya.mycozy.cloud',
@@ -228,6 +272,22 @@ describe('countNewRecipients function', () => {
228
272
  }
229
273
  ]
230
274
  const result = countNewRecipients(currentRecipients, addedRecipients)
231
- expect(result).toEqual(2)
275
+ expect(result.contact).toEqual(2)
276
+ expect(result.group).toEqual(0)
277
+ })
278
+
279
+ it('should count the new recipients with groups', () => {
280
+ const result = countNewRecipients(currentRecipients, [
281
+ ...addedRecipients,
282
+ { _id: 'f45b16be-7523', _type: 'io.cozy.contacts.groups' }
283
+ ])
284
+ expect(result.contact).toEqual(2)
285
+ expect(result.group).toEqual(1)
286
+ })
287
+
288
+ it('should return 0 if there are no new recipients', () => {
289
+ const result = countNewRecipients(currentRecipients, [])
290
+ expect(result.contact).toEqual(0)
291
+ expect(result.group).toEqual(0)
232
292
  })
233
293
  })
@@ -24,7 +24,7 @@ export const buildSharingsByIdQuery = sharingId => ({
24
24
  }
25
25
  })
26
26
 
27
- export const buildContactsQuery = () => ({
27
+ export const buildReachableContactsQuery = () => ({
28
28
  definition: Q(Contact.doctype)
29
29
  .where({
30
30
  _id: {
@@ -55,14 +55,45 @@ export const buildContactsQuery = () => ({
55
55
  .indexFields(['_id'])
56
56
  .limitBy(1000),
57
57
  options: {
58
- as: 'io.cozy.contacts'
58
+ as: 'io.cozy.contacts/reachable'
59
59
  }
60
60
  })
61
61
 
62
- export const buildContactGroupsQuery = () => ({
63
- definition: Q(Group.doctype),
62
+ export const buildContactGroupsByIdsQuery = ids => ({
63
+ definition: Q(Group.doctype).getByIds(ids),
64
64
  options: {
65
- as: 'io.cozy.contacts.groups'
65
+ as: `io.cozy.contacts.groups/by-ids/${ids.join('/')}`,
66
+ fetchPolicy: defaultFetchPolicy,
67
+ enabled: ids.length > 0
68
+ }
69
+ })
70
+
71
+ export const buildUnreachableContactsWithGroupsQuery = () => ({
72
+ definition: Q(Contact.doctype)
73
+ .where({
74
+ _id: {
75
+ $gt: null
76
+ }
77
+ })
78
+ .partialIndex({
79
+ trashed: {
80
+ $or: [{ $eq: false }, { $exists: false }]
81
+ },
82
+ cozy: {
83
+ $size: 0
84
+ },
85
+ email: {
86
+ $size: 0
87
+ },
88
+ 'relationships.groups.data': {
89
+ $exists: true
90
+ }
91
+ })
92
+ .indexFields(['_id'])
93
+ .limitBy(1000),
94
+ options: {
95
+ as: 'io.cozy.contacts/unreachable-with-groups',
96
+ fetchPolicy: defaultFetchPolicy
66
97
  }
67
98
  })
68
99
 
@@ -33,6 +33,7 @@
33
33
  .recipientsContainer
34
34
  display flex
35
35
  flex-wrap wrap
36
+ align-items center
36
37
  padding .25rem .5rem
37
38
  border-radius .25rem
38
39
  border 1px solid var(--borderMainColor)
@@ -55,7 +56,7 @@
55
56
  &:hover
56
57
  &:focus
57
58
  border none
58
- &:only-child
59
+ &:first-child
59
60
  padding .25rem .5rem
60
61
 
61
62
  .recipientChip
package/test/AppLike.jsx CHANGED
@@ -1,6 +1,7 @@
1
1
  import React from 'react'
2
2
 
3
3
  import { CozyProvider, createMockClient } from 'cozy-client'
4
+ import AlertProvider from 'cozy-ui/transpiled/react/providers/Alert'
4
5
  import { BreakpointsProvider } from 'cozy-ui/transpiled/react/providers/Breakpoints'
5
6
  import CozyTheme from 'cozy-ui/transpiled/react/providers/CozyTheme'
6
7
  import { I18n } from 'cozy-ui/transpiled/react/providers/I18n'
@@ -11,9 +12,11 @@ const AppLike = ({ children, client }) => (
11
12
  <BreakpointsProvider>
12
13
  <CozyTheme>
13
14
  <I18n lang="en" dictRequire={() => langEn}>
14
- <CozyProvider client={client || createMockClient({})}>
15
- {children}
16
- </CozyProvider>
15
+ <AlertProvider>
16
+ <CozyProvider client={client || createMockClient({})}>
17
+ {children}
18
+ </CozyProvider>
19
+ </AlertProvider>
17
20
  </I18n>
18
21
  </CozyTheme>
19
22
  </BreakpointsProvider>