diff --git a/src/components/ContactCard/ContactFields/ContactField.jsx b/src/components/ContactCard/ContactFields/ContactField.jsx
index 5442bb968..c81cb29f8 100644
--- a/src/components/ContactCard/ContactFields/ContactField.jsx
+++ b/src/components/ContactCard/ContactFields/ContactField.jsx
@@ -9,6 +9,7 @@ const iconsByType = {
birthday: 'calendar',
note: 'comment',
company: 'company',
+ relationship: 'relationship',
jobTitle: 'people',
cozy: 'cloud',
email: 'email',
diff --git a/src/components/ContactCard/ContactFields/FieldByType.jsx b/src/components/ContactCard/ContactFields/FieldByType.jsx
index d5ef2b361..be6f0d0ee 100644
--- a/src/components/ContactCard/ContactFields/FieldByType.jsx
+++ b/src/components/ContactCard/ContactFields/FieldByType.jsx
@@ -3,7 +3,15 @@ import React from 'react'
import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
-import { Birthday, Location, Email, Phone, Cozy, Default } from './FieldTypes'
+import {
+ Birthday,
+ Location,
+ Email,
+ Phone,
+ Cozy,
+ Default,
+ Relationship
+} from './FieldTypes'
const FieldByType = ({ value, type }) => {
const { t, f } = useI18n()
@@ -20,6 +28,8 @@ const FieldByType = ({ value, type }) => {
return
case 'cozy':
return
+ case 'relationship':
+ return
default:
return
}
diff --git a/src/components/ContactCard/ContactFields/FieldTypes/index.jsx b/src/components/ContactCard/ContactFields/FieldTypes/index.jsx
index 9969910c9..fa66ce67f 100644
--- a/src/components/ContactCard/ContactFields/FieldTypes/index.jsx
+++ b/src/components/ContactCard/ContactFields/FieldTypes/index.jsx
@@ -1,5 +1,7 @@
import React from 'react'
+import { generateWebLink, useClient } from 'cozy-client'
+
import { getFormattedAddress } from '../../../../helpers/contacts'
export const Location = ({ value, t }) => {
@@ -37,6 +39,23 @@ export const Cozy = ({ url }) => {
)
}
+export const Relationship = ({ name, id }) => {
+ const client = useClient()
+ const link = generateWebLink({
+ slug: 'contacts',
+ cozyUrl: client.getStackClient().uri,
+ subDomainType: client.getInstanceOptions().subdomain,
+ pathname: '/',
+ hash: id
+ })
+
+ return (
+
+ {name}
+
+ )
+}
+
export const Birthday = ({ value, t, f }) => {
return f(new Date(value), t('formatted.date'))
}
diff --git a/src/components/ContactCard/ContactFields/helpers.js b/src/components/ContactCard/ContactFields/helpers.js
index 2bd95f235..00eb1fb63 100644
--- a/src/components/ContactCard/ContactFields/helpers.js
+++ b/src/components/ContactCard/ContactFields/helpers.js
@@ -7,6 +7,11 @@ const makeCustomOrSupportedLabel = ({ type, value, hasPrefix, t }) => {
return makeCustomLabel(JSON.stringify(value), t)
}
+ // If contact has a related contact, but no relation type
+ if (value.label === 'related') {
+ return ''
+ }
+
if (value.label) {
return hasPrefix
? t(`label.${type}.${value.label}`)
@@ -26,7 +31,7 @@ const makeCustomOrSupportedLabel = ({ type, value, hasPrefix, t }) => {
* @returns {string|null}
*/
export const makeTLabel = ({ type, value, t, polyglot }) => {
- const hasPrefix = ['phone', 'address'].includes(type)
+ const hasPrefix = ['phone', 'address', 'relationship'].includes(type)
if (hasPrefix) {
if (type === 'phone') {
diff --git a/src/helpers/contacts.js b/src/helpers/contacts.js
index a183c45d9..539d2581c 100644
--- a/src/helpers/contacts.js
+++ b/src/helpers/contacts.js
@@ -1,6 +1,7 @@
import sortBy from 'lodash/sortBy'
import { models, HasMany } from 'cozy-client'
+import { getHasManyItem } from 'cozy-client/dist/associations/HasMany'
const { makeFullname, makeDefaultSortIndexValue, makeDisplayName } =
models.contact
@@ -13,6 +14,7 @@ export const supportedFieldsInOrder = [
'company',
'jobTitle',
'birthday',
+ 'relationship',
'note'
]
@@ -63,6 +65,26 @@ export const groupUnsupportedFields = (fields, supportedFieldTypes) => {
])
}
+export const makeRelatedContactField = contact => {
+ if (!contact.related) return null
+
+ const relatedFieldValues = contact.related.data.flatMap(related => {
+ const relatedRelationships = getHasManyItem(contact, 'related', related._id)
+ return relatedRelationships.metadata.relationTypes.map(type => {
+ return {
+ label: type,
+ name: related.displayName,
+ id: related._id
+ }
+ })
+ })
+
+ return {
+ type: 'relationship', // To match the translation key already in place
+ values: relatedFieldValues
+ }
+}
+
export const orderFieldList = (fields, fieldsInOrder) =>
fields.slice().sort((a, b) => {
const indexA = fieldsInOrder.includes(a.type)
@@ -85,7 +107,11 @@ export const getConnectedAccounts = contact =>
export const normalizeFields = contact => {
const fields = getFieldListFrom(contact)
- const filteredFields = filterFieldList(fields)
+ const filteredFields = filterFieldList(fields, contact)
+ const relatedField = makeRelatedContactField(contact)
+ if (relatedField) {
+ filteredFields.push(relatedField)
+ }
const groupedFields = groupUnsupportedFields(
filteredFields,
supportedFieldsInOrder
diff --git a/src/helpers/contacts.spec.js b/src/helpers/contacts.spec.js
index f36e55662..1daab94e5 100644
--- a/src/helpers/contacts.spec.js
+++ b/src/helpers/contacts.spec.js
@@ -10,7 +10,7 @@ import {
getFormattedAddress,
makeContactWithIdentitiesAddresses
} from './contacts'
-import { johnDoeContact } from './testData'
+import { johnDoeContact, johnDoeContactWithRelated } from './testData'
const MOCKED_DATE = '2018-01-01T12:00:00.210Z'
@@ -127,6 +127,16 @@ describe('normalizeFields', () => {
{ type: 'company', values: ['Cozy cloud'] },
{ type: 'jobTitle', values: ['Dreamer'] },
{ type: 'birthday', values: ['1999-5-1'] },
+ {
+ type: 'relationship',
+ values: [
+ {
+ name: 'Alice Doe',
+ label: 'spouse',
+ id: '5b49553c5916cf7b5b2a5f48600078a8'
+ }
+ ]
+ },
{
type: 'note',
values: [
@@ -136,7 +146,7 @@ describe('normalizeFields', () => {
{ type: 'other', values: [] }
]
- expect(normalizeFields(johnDoeContact)).toEqual(expected)
+ expect(normalizeFields(johnDoeContactWithRelated)).toEqual(expected)
})
})
diff --git a/src/helpers/testData.js b/src/helpers/testData.js
index 055117af3..9d0f98b29 100644
--- a/src/helpers/testData.js
+++ b/src/helpers/testData.js
@@ -146,6 +146,108 @@ export const johnDoeFormValues = {
]
}
+export const johnDoeContactWithRelated = {
+ id: '9ecfbf4b-20e7-4bac-87f1-eea53350857d',
+ _id: '9ecfbf4b-20e7-4bac-87f1-eea53350857d',
+ _type: 'io.cozy.contacts',
+ _rev: '1-19c313536e8b27473aa26bf105b03269',
+ address: [
+ {
+ formattedAddress: '94 Hinton Road 05034 Fresno, Singapore',
+ type: 'Home',
+ primary: true
+ },
+ {
+ pobox: '2',
+ street: '426 Runolfsson Knolls',
+ city: 'Port Easter',
+ region: undefined,
+ country: 'Cocos (Keeling) Islands',
+ postcode: '84573',
+ type: 'Work'
+ }
+ ],
+ email: [
+ {
+ address: 'john.doe@posteo.net',
+ type: 'personal',
+ primary: false
+ },
+ {
+ address: 'john.doe@cozycloud.cc',
+ primary: true
+ }
+ ],
+ birthday: '1999-5-1',
+ birthplace: 'somewhere',
+ gender: 'male',
+ company: 'Cozy cloud',
+ jobTitle: 'Dreamer',
+ cozy: [
+ {
+ type: 'MyCozy',
+ primary: true,
+ url: 'https://johndoe.mycozy.cloud'
+ }
+ ],
+ fullname: 'John Doe',
+ name: {
+ givenName: 'John',
+ familyName: 'Doe',
+ additionalName: 'J.'
+ },
+ metadata: {
+ cozy: true,
+ version: 1
+ },
+ note: 'Atque cupiditate saepe omnis quos ut molestiae labore voluptates omnis.',
+ phone: [
+ {
+ number: '+33 (2)0 90 00 54 04',
+ primary: true
+ },
+ {
+ number: '+33 6 77 11 22 33',
+ primary: false
+ }
+ ],
+
+ relationships: {
+ accounts: { data: [] },
+ groups: { data: [] },
+ related: {
+ data: [
+ {
+ metadata: { relationTypes: ['spouse'] },
+ _id: '5b49553c5916cf7b5b2a5f48600078a8',
+ _type: 'io.cozy.contacts'
+ }
+ ]
+ }
+ },
+ related: {
+ target: {
+ id: '4e33fd27e1d8e55a34742bac6d16d3bd',
+ _id: '4e33fd27e1d8e55a34742bac6d16d3bd',
+ _type: 'io.cozy.contacts',
+ _rev: '6-57f4ab78b1fb97bb90ea273ec881f196',
+ company: '',
+ fullname: 'John Doe',
+ me: true,
+ note: ''
+ },
+ name: 'related',
+ doctype: 'io.cozy.contacts',
+ data: [
+ {
+ displayName: 'Alice Doe',
+ _id: '5b49553c5916cf7b5b2a5f48600078a8',
+ _type: 'io.cozy.contacts'
+ }
+ ]
+ }
+}
+
export const contactWithGroup = {
id: '4e33fd27e1d8e55a34742bac6d16d3bd',
_id: '4e33fd27e1d8e55a34742bac6d16d3bd',