Skip to content

Commit e866b6c

Browse files
committed
feat(mespapiers): Use queries instead of sessionStorage to manage
...contactList when creating a new paper. In the Contact step, we want to keep the previously selected contact list for longer than the duration of a session.
1 parent 49ffd0f commit e866b6c

File tree

3 files changed

+76
-40
lines changed

3 files changed

+76
-40
lines changed

packages/cozy-mespapiers-lib/src/components/ModelSteps/ContactDialog.jsx

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,17 @@ const ContactDialog = ({ currentStep, onClose, onBack, onSubmit }) => {
6767
iconSize="small"
6868
title={t(text)}
6969
text={
70-
currentUser && (
71-
<Paper elevation={2} className="u-mt-1 u-mh-half">
72-
<ContactList
73-
className="u-pv-0"
74-
multiple={multiple}
75-
selected={contactsSelected}
76-
currentUser={currentUser}
77-
onSelection={handleContactSelection}
78-
contactModalOpened={contactModalOpened}
79-
setContactModalOpened={setContactModalOpened}
80-
/>
81-
</Paper>
82-
)
70+
<Paper elevation={2} className="u-mt-1 u-mh-half">
71+
<ContactList
72+
className="u-pv-0"
73+
multiple={multiple}
74+
selected={contactsSelected}
75+
currentUser={currentUser}
76+
onSelection={handleContactSelection}
77+
contactModalOpened={contactModalOpened}
78+
setContactModalOpened={setContactModalOpened}
79+
/>
80+
</Paper>
8381
}
8482
/>
8583
}

packages/cozy-mespapiers-lib/src/components/ModelSteps/ContactDialog.spec.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ jest.mock('./widgets/ConfirmReplaceFile', () => () => (
2929
jest.mock('./widgets/SubmitButton', () => () => (
3030
<div data-testid="SubmitButton" />
3131
))
32+
jest.mock('./ContactList', () => () => <div data-testid="ContactList" />)
3233
/* eslint-enable react/display-name */
3334

3435
const setup = ({

packages/cozy-mespapiers-lib/src/components/ModelSteps/ContactList.jsx

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import PropTypes from 'prop-types'
2-
import React, { useState, useMemo } from 'react'
2+
import React, { useCallback, useMemo } from 'react'
33

4+
import { isQueryLoading, useClient, useQuery, useQueryAll } from 'cozy-client'
45
import Avatar from 'cozy-ui/transpiled/react/Avatar'
56
import ContactsListModal from 'cozy-ui/transpiled/react/ContactsListModal'
67
import Divider from 'cozy-ui/transpiled/react/Divider'
@@ -9,16 +10,20 @@ import List from 'cozy-ui/transpiled/react/List'
910
import ListItem from 'cozy-ui/transpiled/react/ListItem'
1011
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
1112
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
13+
import ListItemSkeleton from 'cozy-ui/transpiled/react/Skeletons/ListItemSkeleton'
1214
import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
1315

1416
import Contact from './Contact'
15-
import { useSessionstorage } from '../Hooks/useSessionstorage'
17+
import { SETTINGS_DOCTYPE } from '../../doctypes'
18+
import { buildContactsQueryByIds, getAppSettings } from '../../helpers/queries'
1619

1720
const styleAvatar = {
1821
color: 'var(--primaryColor)',
1922
backgroundColor: 'var(--primaryColorLightest)'
2023
}
2124

25+
let contactList = []
26+
2227
const ContactList = ({
2328
multiple,
2429
currentUser,
@@ -30,23 +35,40 @@ const ContactList = ({
3035
onSelection
3136
}) => {
3237
const { t } = useI18n()
38+
const client = useClient()
3339

34-
const [contactsLocalSession, setContactLocalSession] = useSessionstorage(
35-
'contactList',
36-
[]
40+
const { data: settingsData, ...settingsQuery } = useQuery(
41+
getAppSettings.definition,
42+
getAppSettings.options
3743
)
38-
const [contactsList, setContactsList] = useState([
39-
currentUser,
40-
...contactsLocalSession
41-
])
44+
const isLoadingSettings = isQueryLoading(settingsQuery)
45+
46+
const suggestedContactIds = settingsData[0]?.suggestedContactIds || []
47+
const contactsQueryByIds = buildContactsQueryByIds(
48+
suggestedContactIds,
49+
!isLoadingSettings
50+
)
51+
const { data: contacts, ...contactQueryResult } = useQueryAll(
52+
contactsQueryByIds.definition,
53+
contactsQueryByIds.options
54+
)
55+
const isLoadingContacts =
56+
isQueryLoading(contactQueryResult) || contactQueryResult.hasMore
57+
58+
if (!isLoadingSettings && !isLoadingContacts && currentUser) {
59+
contactList = [currentUser, ...contacts]
60+
}
4261

4362
const idsSelected = useMemo(() => selected.map(v => v._id), [selected])
4463

45-
const onClickContactsListModal = contact => {
46-
const contactAlreadyListed = contactsList.some(cl => cl._id === contact._id)
64+
const onClickContactsListModal = async contact => {
65+
const contactAlreadyListed = contactList.some(cl => cl._id === contact._id)
4766
if (!contactAlreadyListed) {
48-
setContactsList(prev => [...prev, contact])
49-
setContactLocalSession(prev => [...prev, contact])
67+
await client.save({
68+
...settingsData[0],
69+
suggestedContactIds: [...suggestedContactIds, contact._id],
70+
_type: SETTINGS_DOCTYPE
71+
})
5072
}
5173
onSelection(multiple ? [...selected, contact] : [contact])
5274
setContactModalOpened(false)
@@ -63,29 +85,44 @@ const ContactList = ({
6385
else newContactIdSelected.push(newValue)
6486

6587
onSelection(
66-
contactsList.filter(contact =>
88+
contactList.filter(contact =>
6789
newContactIdSelected.includes(contact._id)
6890
)
6991
)
7092
} else {
71-
onSelection(contactsList.filter(contact => contact.id === newValue))
93+
onSelection(contactList.filter(contact => contact.id === newValue))
7294
}
7395
}
7496

97+
// Returns a number of Skeletons based on the number of contactIds in the app settings + the current user
98+
const Skeleton = useCallback(
99+
() =>
100+
Array.from(Array(suggestedContactIds.length + 1), (_, idx) => (
101+
<ListItemSkeleton key={idx} />
102+
)),
103+
[suggestedContactIds.length]
104+
)
105+
75106
return (
76107
<>
77108
<List className={className}>
78-
<div className="u-mah-5 u-ov-auto">
79-
{contactsList.map(contact => (
80-
<Contact
81-
key={contact._id}
82-
contact={contact}
83-
multiple={multiple}
84-
selected={idsSelected.includes(contact._id)}
85-
onSelection={onClickContactLine}
86-
/>
87-
))}
88-
</div>
109+
{contactList.length === 0 &&
110+
(isLoadingSettings || isLoadingContacts) ? (
111+
<Skeleton />
112+
) : (
113+
<div className="u-mah-5 u-ov-auto">
114+
{contactList.map(contact => (
115+
<Contact
116+
key={contact._id}
117+
contact={contact}
118+
multiple={multiple}
119+
selected={idsSelected.includes(contact._id)}
120+
onSelection={onClickContactLine}
121+
/>
122+
))}
123+
</div>
124+
)}
125+
89126
{!withoutDivider && <Divider variant="inset" component="li" />}
90127
<ListItem button onClick={() => setContactModalOpened(true)}>
91128
<ListItemIcon>
@@ -116,7 +153,7 @@ ContactList.propTypes = {
116153
/** Determine whether the user can select several contacts */
117154
multiple: PropTypes.bool.isRequired,
118155
/** Contact object representing the current user */
119-
currentUser: PropTypes.object.isRequired,
156+
currentUser: PropTypes.object,
120157
className: PropTypes.string,
121158
contactModalOpened: PropTypes.bool.isRequired,
122159
setContactModalOpened: PropTypes.func.isRequired,

0 commit comments

Comments
 (0)