Skip to content

Commit

Permalink
Merge pull request #110 from InseeFr/feat/communicationRequest
Browse files Browse the repository at this point in the history
  • Loading branch information
ddecrulle committed Jun 30, 2023
2 parents d650a25 + c2e6f8c commit 66c898a
Show file tree
Hide file tree
Showing 45 changed files with 1,065 additions and 138 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pearl",
"version": "1.0.1",
"version": "1.1.0",
"private": true,
"dependencies": {
"@date-io/date-fns": "1.x",
Expand Down
1 change: 0 additions & 1 deletion src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ function App() {
const { pathname } = useLocation();
const { authenticated } = useAuth();
const serviceWorkerInfo = useServiceWorker(authenticated);

return (
<ThemeProvider theme={theme}>
<CssBaseline />
Expand Down
11 changes: 5 additions & 6 deletions src/Root.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import React, { useEffect, useState } from 'react';
import { useQueenFromConfig } from 'utils/hooks/useQueenFromConfig';
import React, { useEffect, useMemo, useState } from 'react';

import AppRouter from 'AppRooter';
import { BrowserRouter as Router } from 'react-router-dom';
import { useConfiguration } from 'utils/hooks/configuration';
import { addOnlineStatusObserver } from 'utils';
import AppRouter from 'AppRooter';
import { useConfiguration } from 'utils/hooks/configuration';

export const AppContext = React.createContext();

function Root() {
const { configuration } = useConfiguration();

const [online, setOnline] = useState(navigator.onLine);

useEffect(() => {
Expand All @@ -18,7 +17,7 @@ function Root() {
});
}, []);

const context = { ...configuration, online };
const context = useMemo(() => ({ ...configuration, online }), [configuration]);

return (
<>
Expand Down
12 changes: 8 additions & 4 deletions src/components/common/navigation/component.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NavLink, Route } from 'react-router-dom';
import React, { useContext } from 'react';
import React, { useContext, useMemo } from 'react';

import AppBar from '@material-ui/core/AppBar';
import Badge from '@material-ui/core/Badge';
Expand All @@ -22,15 +22,19 @@ import Synchronize from 'components/common/synchronize';
import Toolbar from '@material-ui/core/Toolbar';
import Tooltip from '@material-ui/core/Tooltip';
import Typography from '@material-ui/core/Typography';
import { UserContext } from 'components/panel-body/home/UserContext';
import { makeStyles } from '@material-ui/core/styles';

export const NavigationContext = React.createContext();

const Navigation = ({ textSearch, setTextSearch, setOpenDrawer }) => {
const { unReadNotificationsNumber } = useContext(NotificationWrapperContext);
const user = useContext(UserContext);
const interviewerFromLocalStorage = window.localStorage.getItem(PEARL_USER_KEY);

const getName = () => {
const interviewerFromLocalStorage = window.localStorage.getItem(PEARL_USER_KEY);
if (user !== undefined) return `${user.firstName} ${user.lastName}`;

return interviewerFromLocalStorage
? `${JSON.parse(interviewerFromLocalStorage).firstName} ${
JSON.parse(interviewerFromLocalStorage).lastName
Expand Down Expand Up @@ -93,10 +97,10 @@ const Navigation = ({ textSearch, setTextSearch, setOpenDrawer }) => {
setOpen(o => !o);
};

const context = { setOpen };
const contextValue = useMemo(() => ({ setOpen }), [setOpen]);

return (
<NavigationContext.Provider value={context}>
<NavigationContext.Provider value={contextValue}>
<AppBar position="sticky" className={classes.appBar} elevation={0}>
<Toolbar className={classes.appBar}>
<NavLink activeClassName="active" exact to="/">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ export const EditableTextFieldWithClickableIcon = ({
defaultValue={defaultValue}
onChangeFunction={onChangeFunction}
/>
{icons.map(Icon => (
<Icon />
))}
{icons.map(icon => icon)}
</div>
);
};
8 changes: 4 additions & 4 deletions src/components/common/sharedComponents/GenericTile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ const useStyles = makeStyles(() => ({
},
}));

const GenericTile = ({ title, children, icon: Icon, editionIcon: EditionIcon }) => {
const GenericTile = ({ title, children, icon, editionIcon }) => {
const classes = useStyles();
return (
<Paper className={classes.root} elevation={0}>
<div className={classes.row}>
<div className={classes.row}>
<Icon />
{icon}
<Typography variant="h5">{title}</Typography>
</div>
{EditionIcon && <EditionIcon />}
{editionIcon}
</div>
{children}
</Paper>
Expand All @@ -42,5 +42,5 @@ export default GenericTile;
GenericTile.propTypes = {
title: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
icon: PropTypes.func.isRequired,
icon: PropTypes.node.isRequired,
};
4 changes: 3 additions & 1 deletion src/components/common/sharedComponents/LabelledText.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ const LabelledText = ({ labelText, value }) => {
<div className={classes.column}>
{Array.isArray(labelText) ? (
labelText.map(labelTextLine => (
<Typography color="textSecondary">{labelTextLine}</Typography>
<Typography key={labelTextLine} color="textSecondary">
{labelTextLine}
</Typography>
))
) : (
<Typography color="textSecondary">{labelText}</Typography>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import D from 'i18n';
import { HEALTHY_COMMUNICATION_REQUEST_STATUS } from 'utils/constants';
import MaterialIcons from 'utils/icons/materialIcons';
import { findCommunicationStatusValueByType } from 'utils/enum/CommunicationEnums';
import { getDateAttributes } from 'utils/functions/dateFunctions';
import { makeStyles } from '@material-ui/core';

const useStyles = makeStyles((healthy = false) => ({
row: {
display: 'flex',
justifyContent: 'flex-end',
alignItems: 'center',
gap: '1em',
flexGrow: '1',
},
}));

const isHealthyStatus = status => HEALTHY_COMMUNICATION_REQUEST_STATUS.includes(status);

export const CommunicationRequestStatus = ({ status, date }) => {
const classes = useStyles();
const { dayOfWeek, twoDigitdayNumber, year, month } = getDateAttributes(date);
const dateLabel = `${dayOfWeek} ${twoDigitdayNumber} ${month} ${year}`;

const healthyStatus = isHealthyStatus(status);
const statusValue = findCommunicationStatusValueByType(status);
const statusLabel = `${statusValue} ${D.communicationStatusOn} ${dateLabel}`;
return (
<div className={classes.row}>
<div>{statusLabel}</div>
<MaterialIcons type={`${healthyStatus ? 'checked' : 'cross'}`} />
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Divider, makeStyles } from '@material-ui/core';
import {
findCommunicationMediumValueByType,
findCommunicationReasonValueByType,
findCommunicationTypeValueByType,
} from 'utils/enum/CommunicationEnums';

import { CommunicationRequestStatus } from './CommuncationRequestStatus';
import D from 'i18n';
import MaterialIcons from 'utils/icons/materialIcons';
import Paper from '@material-ui/core/Paper';
import { getCommunicationIconFromType } from 'utils/functions/communicationFunctions';
import { getDateAttributes } from 'utils/functions/dateFunctions';
import { grey } from '@material-ui/core/colors';

const useStyles = makeStyles(() => ({
row: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '1em',
padding: '1em',
backgroundColor: grey[100],
borderRadius: '15px',
},
divider: {
fontWeight: 'bold',
},
}));

const getContentLabel = status => {
const { type, medium, reason } = status;
const mediumLabel = findCommunicationMediumValueByType(medium);
const typeLabel = findCommunicationTypeValueByType(type);
const reasonLabel = findCommunicationReasonValueByType(reason);

return `${mediumLabel} - ${typeLabel}${reason ? ', ' + reasonLabel : ''}`;
};

const getDateLabel = date => {
const { dayOfWeek, twoDigitdayNumber, year, month, hour, minutes } = getDateAttributes(date);
const upcasedDayOfWeek = dayOfWeek[0].toUpperCase() + dayOfWeek.slice(1);
return `${upcasedDayOfWeek} ${twoDigitdayNumber} ${month} ${year} ${D.at} ${hour}h${minutes}`;
};

export const CommunicationRequestLine = ({ mailRequest }) => {
const classes = useStyles();
const { status, emiter } = mailRequest;
const iconType = getCommunicationIconFromType(emiter);

const sortedStatus = status.sort((s1, s2) => s1.date > s2.date);
const firstStatus = sortedStatus.at(0);
const lastStatus = sortedStatus.at(-1);

const contentLabel = getContentLabel(mailRequest);
const dateLabel = getDateLabel(firstStatus.date);

return (
<Paper key={lastStatus.date} className={classes.row} elevation={0}>
<MaterialIcons type={iconType} />
<div>{dateLabel}</div>
<Divider className={classes.divider} orientation="vertical" flexItem />
<div>{contentLabel}</div>
<CommunicationRequestStatus status={lastStatus.status} date={lastStatus.date} />
</Paper>
);
};
89 changes: 89 additions & 0 deletions src/components/panel-body/UEpage/communication/component.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { Dialog, makeStyles } from '@material-ui/core';
import React, { useContext, useState } from 'react';
import {
canSendCommunication,
getRecipientInformation,
} from 'utils/functions/communicationFunctions';

import { COMMUNICATION_REQUEST_STUB } from 'utils/constants';
import { CommunicationRequestForm } from './form/CommunicationRequestForm';
import { CommunicationRequestLine } from './CommunicationRequestLine';
import D from 'i18n';
import IconButton from 'components/common/sharedComponents/IconButton';
import SurveyUnitContext from '../UEContext';
import { UserContext } from 'components/panel-body/home/UserContext';
import surveyUnitIdbService from 'utils/indexeddb/services/surveyUnit-idb-service';

const useStyles = makeStyles(() => ({
column: {
display: 'flex',
flexDirection: 'column',
gap: '1em',
},
modalPaper: {
boxShadow: 'unset',
borderRadius: '15px',
padding: '1em',
gap: '1.5em',
alignItems: 'center',
},
}));

const Communication = () => {
const classes = useStyles();
const { surveyUnit } = useContext(SurveyUnitContext);
const user = useContext(UserContext);
const [isOpenModal, setOpenModal] = useState(false);

const openModal = () => setOpenModal(true);
const closeModal = () => setOpenModal(false);

const recipientInformation = getRecipientInformation(surveyUnit);

// TODO : remove stub when feature is finished
const { communicationRequests = COMMUNICATION_REQUEST_STUB } = surveyUnit;
const disabled = !canSendCommunication(surveyUnit);
const addCommunicationRequest = communicationRequest => {
const previousCommunicationRequests = communicationRequests ?? [];
closeModal();
surveyUnitIdbService.addOrUpdateSU({
...surveyUnit,
communicationRequests: [...previousCommunicationRequests, communicationRequest],
});
};

return (
<>
<div className={classes.column}>
<IconButton
iconType="add"
label={D.sendCommunication}
disabled={disabled}
onClickFunction={openModal}
/>
{communicationRequests?.map(mailRequest => (
<CommunicationRequestLine key={mailRequest.status[0].date} mailRequest={mailRequest} />
))}
</div>
<Dialog
maxWidth={false}
className={classes.modal}
open={isOpenModal}
onClose={closeModal}
disableScrollLock
aria-labelledby="Communication-request-validation"
aria-describedby="simple-modal-description"
PaperProps={{ className: classes.modalPaper }}
>
<CommunicationRequestForm
closeModalFunction={closeModal}
userInformation={user}
recipientInformation={recipientInformation}
saveFunction={addCommunicationRequest}
/>
</Dialog>
</>
);
};

export default Communication;
Loading

0 comments on commit 66c898a

Please sign in to comment.