diff --git a/src/components/Modals/ContactCardModal.jsx b/src/components/Modals/ContactCardModal.jsx
index 80812ca95..6f57c45fe 100644
--- a/src/components/Modals/ContactCardModal.jsx
+++ b/src/components/Modals/ContactCardModal.jsx
@@ -1,96 +1,85 @@
-import React from 'react'
+import React, { useState } from 'react'
import { PropTypes } from 'prop-types'
+import { flow } from 'lodash'
+
+import { useQuery } from 'cozy-client'
+import Button from 'cozy-ui/transpiled/react/Button'
import { translate } from 'cozy-ui/transpiled/react/I18n'
import Modal, {
ModalHeader,
ModalContent
} from 'cozy-ui/transpiled/react/Modal'
-import { DOCTYPE_CONTACTS } from '../../helpers/doctypes'
-import { getConnectedAccounts } from '../../helpers/contacts'
+import { getConnectedAccounts } from '../../helpers/contacts'
import withContactsMutations from '../../connections/allContacts'
import ContactCard from '../ContactCard/ContactCard'
import SpinnerContact from '../Components/Spinner'
import ContactFormModal from './ContactFormModal'
import ContactGroups from '../ContactCard/ContactGroups'
-import Button from 'cozy-ui/transpiled/react/Button'
-import { Query } from 'cozy-client'
-import { flow } from 'lodash'
+import { queryContactById, queryAllGroups } from '../../helpers/queries'
+import { isCollectionInCache, isCollectionLoading } from '../../helpers/utils'
-export class ContactCardModal extends React.Component {
- state = {
- editMode: false,
- shouldDisplayConfirmDeleteModal: false
- }
+const ContactCardModal = props => {
+ const [editMode, setEditMode] = useState(false)
+ const [
+ shouldDisplayConfirmDeleteModal,
+ setShouldDisplayConfirmDeleteModal
+ ] = useState(false)
- toggleConfirmDeleteModal = () => {
- this.setState(state => ({
- shouldDisplayConfirmDeleteModal: !state.shouldDisplayConfirmDeleteModal
- }))
+ const toggleConfirmDeleteModal = () => {
+ setShouldDisplayConfirmDeleteModal(!shouldDisplayConfirmDeleteModal)
}
- deleteContact = async (contactParam = null) => {
- const { contact, deleteContact, onDeleteContact, onClose } = this.props
+ const deleteContact = async (contactParam = null) => {
+ const { contact, deleteContact, onDeleteContact, onClose } = props
onClose && onClose()
await deleteContact(contactParam ? contactParam : contact)
onDeleteContact && onDeleteContact(contactParam ? contactParam : contact)
}
- toggleEditMode = () => {
- this.setState(state => ({
- editMode: !state.editMode
- }))
+ const toggleEditMode = () => {
+ setEditMode(!editMode)
}
- render() {
- const { onClose, t, id } = this.props
- const { editMode, shouldDisplayConfirmDeleteModal } = this.state
+ const { onClose, t, id } = props
- return (
-
- client.get(DOCTYPE_CONTACTS, id)}>
- {({ data: contact, fetchStatus: fetchContactStatus }) => {
- return (
-
- client
- .find('io.cozy.contacts.groups')
- .where({
- trashed: { $exists: false }
- })
- .sortBy([{ name: 'asc' }])
- .indexFields(['name'])
- }
- >
- {({ data: allGroups, fetchStatus: allGroupsContactStatus }) => {
- if (
- fetchContactStatus !== 'loaded' ||
- allGroupsContactStatus !== 'loaded'
- ) {
- return
- }
- return (
-
- )
- }}
-
- )
- }}
-
-
- )
- }
+ const resultContactById = useQuery(
+ queryContactById(id).definition,
+ queryContactById(id).options
+ )
+ const resultAllGroups = useQuery(
+ queryAllGroups.definition,
+ queryAllGroups.options
+ )
+
+ const showResult =
+ (!isCollectionLoading(resultContactById) ||
+ isCollectionInCache(resultContactById)) &&
+ (!isCollectionLoading(resultAllGroups) ||
+ isCollectionInCache(resultAllGroups))
+
+ const contact =
+ resultContactById.data !== null ? resultContactById.data[0] : {}
+ const allGroups = resultAllGroups.data !== null ? resultAllGroups.data : []
+
+ return (
+
+ {showResult ? (
+
+ ) : (
+
+ )}
+
+ )
}
export const DumbContactCardModal = ({
diff --git a/src/components/Modals/ContactCardModal.spec.jsx b/src/components/Modals/ContactCardModal.spec.jsx
index c36313e2e..9ac0fb7b8 100644
--- a/src/components/Modals/ContactCardModal.spec.jsx
+++ b/src/components/Modals/ContactCardModal.spec.jsx
@@ -1,9 +1,11 @@
import React from 'react'
-import { ContactCardModal, DumbContactCardModal } from './ContactCardModal'
+import ContactCardModal, { DumbContactCardModal } from './ContactCardModal'
import { render } from '@testing-library/react'
-import { createMockClient } from 'cozy-client'
import AppLike from '../../tests/Applike'
import { contactWithGroup as contact, groups } from '../../helpers/testData'
+import { createMockClient, useQuery } from 'cozy-client'
+
+jest.mock('cozy-client/dist/hooks/useQuery', () => jest.fn())
const client = createMockClient({})
const setup = ({
@@ -31,6 +33,13 @@ describe('ContactCardModal', () => {
onClose: jest.fn,
deleteContact: jest.fn
}
+ useQuery.mockReturnValue({
+ data: [],
+ fetchStatus: 'pending',
+ hasMore: true,
+ fetchMore: jest.fn()
+ })
+
const jsx = (
diff --git a/src/helpers/queries.js b/src/helpers/queries.js
new file mode 100644
index 000000000..6373ce142
--- /dev/null
+++ b/src/helpers/queries.js
@@ -0,0 +1,34 @@
+import { Q, fetchPolicies } from 'cozy-client'
+import { DOCTYPE_CONTACTS } from './doctypes'
+
+export const cacheTime = 30000
+
+export const queryContactById = id => ({
+ definition: () => Q(DOCTYPE_CONTACTS).getById(id),
+ options: {
+ as: `contactById-${id}`,
+ fetchPolicy: fetchPolicies.olderThan(cacheTime)
+ }
+})
+
+export const queryAllGroups = {
+ definition: () =>
+ Q('io.cozy.contacts.groups')
+ .where({
+ $or: [
+ {
+ trashed: {
+ $exists: false
+ }
+ },
+ {
+ trashed: false
+ }
+ ]
+ })
+ .sortBy([{ name: 'asc' }]),
+ options: {
+ as: 'allGroups',
+ fetchPolicy: fetchPolicies.olderThan(cacheTime)
+ }
+}
diff --git a/src/helpers/utils.js b/src/helpers/utils.js
new file mode 100644
index 000000000..46948d077
--- /dev/null
+++ b/src/helpers/utils.js
@@ -0,0 +1,17 @@
+import { cacheTime } from './queries'
+
+export const isCollectionLoading = col => {
+ if (!col) {
+ console.warn('isCollectionLoading called on falsy value.') // eslint-disable-line no-console
+ return false
+ }
+ return col.fetchStatus === 'loading' || col.fetchStatus === 'pending'
+}
+
+export const isCollectionInCache = col => {
+ if (!col) {
+ console.warn('isCollectionInCache called on falsy value.') // eslint-disable-line no-console
+ return false
+ }
+ return col.lastFetch + cacheTime >= Date.now()
+}