Skip to content

Commit

Permalink
feat: Add contact relations to ContactInfoModal
Browse files Browse the repository at this point in the history
  • Loading branch information
Merkur39 committed Nov 19, 2024
1 parent a6b972d commit 9b62cc0
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/components/ContactCard/ContactFields/ContactField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const iconsByType = {
birthday: 'calendar',
note: 'comment',
company: 'company',
relationship: 'relationship',
jobTitle: 'people',
cozy: 'cloud',
email: 'email',
Expand Down
12 changes: 11 additions & 1 deletion src/components/ContactCard/ContactFields/FieldByType.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -20,6 +28,8 @@ const FieldByType = ({ value, type }) => {
return <Phone number={value.number} />
case 'cozy':
return <Cozy url={value.url} />
case 'relationship':
return <Relationship name={value.name} id={value.id} />
default:
return <Default value={value} />
}
Expand Down
19 changes: 19 additions & 0 deletions src/components/ContactCard/ContactFields/FieldTypes/index.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React from 'react'

import { generateWebLink, useClient } from 'cozy-client'

import { getFormattedAddress } from '../../../../helpers/contacts'

export const Location = ({ value, t }) => {
Expand Down Expand Up @@ -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 (
<a href={link} className="u-link" target="_blank" rel="noreferrer">
{name}
</a>
)
}

export const Birthday = ({ value, t, f }) => {
return f(new Date(value), t('formatted.date'))
}
Expand Down
7 changes: 6 additions & 1 deletion src/components/ContactCard/ContactFields/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}`)
Expand All @@ -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') {
Expand Down
28 changes: 27 additions & 1 deletion src/helpers/contacts.js
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -13,6 +14,7 @@ export const supportedFieldsInOrder = [
'company',
'jobTitle',
'birthday',
'relationship',
'note'
]

Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down
14 changes: 12 additions & 2 deletions src/helpers/contacts.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -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: [
Expand All @@ -136,7 +146,7 @@ describe('normalizeFields', () => {
{ type: 'other', values: [] }
]

expect(normalizeFields(johnDoeContact)).toEqual(expected)
expect(normalizeFields(johnDoeContactWithRelated)).toEqual(expected)
})
})

Expand Down
102 changes: 102 additions & 0 deletions src/helpers/testData.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: '[email protected]',
type: 'personal',
primary: false
},
{
address: '[email protected]',
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',
Expand Down

0 comments on commit 9b62cc0

Please sign in to comment.