From 21e3eaed0d5d9a2ce7dd4d1d3d32f86b4b90caec Mon Sep 17 00:00:00 2001 From: JF-Cozy Date: Thu, 20 Aug 2020 11:00:10 +0200 Subject: [PATCH] refactor: Add useQuery in ContactCardModal --- src/components/Modals/ContactCardModal.jsx | 127 ++++++++---------- .../Modals/ContactCardModal.spec.jsx | 13 +- src/helpers/queries.js | 34 +++++ src/helpers/utils.js | 17 +++ 4 files changed, 120 insertions(+), 71 deletions(-) create mode 100644 src/helpers/queries.js create mode 100644 src/helpers/utils.js 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() +}