diff --git a/src/components/Modals/ContactCardModal.jsx b/src/components/Modals/ContactCardModal.jsx index 80812ca95..05b9b83a6 100644 --- a/src/components/Modals/ContactCardModal.jsx +++ b/src/components/Modals/ContactCardModal.jsx @@ -1,96 +1,80 @@ -import React from 'react' +import React, { useState } from 'react' import { PropTypes } from 'prop-types' +import { flow } from 'lodash' + +import { useQuery, isQueryLoading, hasQueryBeenLoaded } 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 { buildContactQuery, queryAllGroups } from '../../helpers/queries' -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 queryContactById = buildContactQuery(id) + const resultContactById = useQuery( + queryContactById.definition, + queryContactById.options + ) + const resultAllGroups = useQuery( + queryAllGroups.definition, + queryAllGroups.options + ) + + const dataHaveBeenLoaded = + (!isQueryLoading(resultContactById) || + hasQueryBeenLoaded(resultContactById)) && + (!isQueryLoading(resultAllGroups) || hasQueryBeenLoaded(resultAllGroups)) + + return ( + + {dataHaveBeenLoaded ? ( + + ) : ( + + )} + + ) } 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..10746037c --- /dev/null +++ b/src/helpers/queries.js @@ -0,0 +1,34 @@ +import { Q, fetchPolicies } from 'cozy-client' +import { DOCTYPE_CONTACTS } from './doctypes' + +const olderThan30sec = fetchPolicies.olderThan(30 * 1000) + +export const buildContactQuery = id => ({ + definition: () => Q(DOCTYPE_CONTACTS).getById(id), + options: { + as: `contactById-${id}`, + fetchPolicy: olderThan30sec + } +}) + +export const queryAllGroups = { + definition: () => + Q('io.cozy.contacts.groups') + .where({ + $or: [ + { + trashed: { + $exists: false + } + }, + { + trashed: false + } + ] + }) + .sortBy([{ name: 'asc' }]), + options: { + as: 'allGroups', + fetchPolicy: olderThan30sec + } +}