diff --git a/package.json b/package.json index c2433fd47..f82a0c370 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pearl", - "version": "0.5.4", + "version": "0.5.5", "private": true, "dependencies": { "@date-io/date-fns": "1.x", @@ -13,7 +13,10 @@ "@testing-library/user-event": "^11.2.5", "clsx": "^1.1.1", "date-fns": "^2.18.0", - "dexie": "^2.0.4", + "dexie": "^3.2.1", + "dexie-export-import": "^1.0.3", + "dexie-react-hooks": "^1.1.1", + "downloadjs": "^1.4.7", "font-awesome": "^4.7.0", "keycloak-js": "^10.0.2", "prop-types": "^15.7.2", diff --git a/src/App.js b/src/App.js index 0afad7658..3cd2bc939 100644 --- a/src/App.js +++ b/src/App.js @@ -1,17 +1,21 @@ -import { useAuth } from 'utils/auth/initAuth'; -import { useServiceWorker } from 'utils/hooks/useServiceWorker'; -import Preloader from 'components/common/loader'; -import Notification from 'components/common/Notification'; -import { ThemeProvider, CssBaseline } from '@material-ui/core'; -import theme from './theme'; -import Palette from 'components/common/palette'; -import Home from 'components/panel-body/home'; -import D from 'i18n'; import React from 'react'; +import CssBaseline from '@material-ui/core/CssBaseline'; +import { ThemeProvider } from '@material-ui/core/styles'; + import { Route, useLocation } from 'react-router-dom'; -import SynchronizeWrapper from 'components/sychronizeWrapper'; + +import D from 'i18n'; +import { DatabaseConsole } from 'components/panel-body/databaseConsole'; +import Home from 'components/panel-body/home'; +import Notification from 'components/common/Notification'; import { NotificationWrapper } from 'components/notificationWrapper'; +import Palette from 'components/common/palette'; +import Preloader from 'components/common/loader'; import { ResetData } from 'components/panel-body/resetData'; +import SynchronizeWrapper from 'components/sychronizeWrapper'; +import theme from './theme'; +import { useAuth } from 'utils/auth/initAuth'; +import { useServiceWorker } from 'utils/hooks/useServiceWorker'; function App() { const { pathname } = useLocation(); @@ -32,6 +36,7 @@ function App() { )} + )} diff --git a/src/AppRooter.js b/src/AppRooter.js index dffd19077..b2863db59 100644 --- a/src/AppRooter.js +++ b/src/AppRooter.js @@ -1,6 +1,6 @@ +import React from 'react'; import App from 'App'; import QueenContainer from 'components/panel-body/queen-container'; -import React from 'react'; import { Route, Switch, useLocation } from 'react-router-dom'; function AppRooter() { diff --git a/src/Root.js b/src/Root.js index f0c1b7f75..55db6a491 100644 --- a/src/Root.js +++ b/src/Root.js @@ -1,5 +1,5 @@ -import { useQueenFromConfig } from 'utils/hooks/useQueenFromConfig'; import React, { useEffect, useState } from 'react'; +import { useQueenFromConfig } from 'utils/hooks/useQueenFromConfig'; import { BrowserRouter as Router } from 'react-router-dom'; import { useConfiguration } from 'utils/hooks/configuration'; import { addOnlineStatusObserver } from 'utils'; diff --git a/src/components/common/IconStatus.js b/src/components/common/IconStatus.js index 1e20a1cbd..390e5d55b 100644 --- a/src/components/common/IconStatus.js +++ b/src/components/common/IconStatus.js @@ -1,6 +1,8 @@ import React from 'react'; -import { CheckCircleOutline, Warning, Clear } from '@material-ui/icons'; -import { makeStyles } from '@material-ui/core'; +import CheckCircleOutline from '@material-ui/icons/CheckCircleOutline'; +import Warning from '@material-ui/icons/Warning'; +import Clear from '@material-ui/icons/Clear'; +import { makeStyles } from '@material-ui/core/styles'; const useStyles = makeStyles(theme => ({ success: { diff --git a/src/components/common/Notification/index.js b/src/components/common/Notification/index.js index be7ce2e6c..4d0a158fd 100644 --- a/src/components/common/Notification/index.js +++ b/src/components/common/Notification/index.js @@ -1,7 +1,11 @@ -import { Box, Button, makeStyles, Slide, Snackbar } from '@material-ui/core'; -import D from 'i18n'; import React, { useEffect, useState } from 'react'; -import { Alert } from '@material-ui/lab'; +import { makeStyles } from '@material-ui/core/styles'; +import Box from '@material-ui/core/Box'; +import Button from '@material-ui/core/Button'; +import Slide from '@material-ui/core/Slide'; +import Snackbar from '@material-ui/core/Snackbar'; +import D from 'i18n'; +import Alert from '@material-ui/lab/Alert'; const useStyles = makeStyles(theme => ({ root: { diff --git a/src/components/common/Notification/notificationItem.js b/src/components/common/Notification/notificationItem.js index bb25f9e8b..b88272f88 100644 --- a/src/components/common/Notification/notificationItem.js +++ b/src/components/common/Notification/notificationItem.js @@ -1,14 +1,18 @@ -import { Link, makeStyles, Typography } from '@material-ui/core'; -import { FiberManualRecord } from '@material-ui/icons'; -import { SynchronizeWrapperContext } from 'components/sychronizeWrapper'; -import { formatDistance } from 'date-fns'; import React, { useContext } from 'react'; -import { dateFnsLocal } from 'utils'; +import Link from '@material-ui/core/Link'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; + import { NOTIFICATION_TYPE_MANAGEMENT, NOTIFICATION_TYPE_SYNC } from 'utils/constants'; -import { NavigationContext } from '../navigation/component'; + import D from 'i18n'; +import { FiberManualRecord } from '@material-ui/icons'; +import { NavigationContext } from '../navigation/component'; import { NotificationWrapperContext } from 'components/notificationWrapper'; -import syncReportIdbService from 'indexedbb/services/syncReport-idb-service'; +import { SynchronizeWrapperContext } from 'components/sychronizeWrapper'; +import { dateFnsLocal } from 'utils'; +import { formatDistance } from 'date-fns'; +import syncReportIdbService from 'utils/indexeddb/services/syncReport-idb-service'; const useStyles = makeStyles(theme => ({ root: { padding: '1em' }, diff --git a/src/components/common/Notification/notificationsRoot.js b/src/components/common/Notification/notificationsRoot.js index 765c7468b..bd12ff315 100644 --- a/src/components/common/Notification/notificationsRoot.js +++ b/src/components/common/Notification/notificationsRoot.js @@ -1,16 +1,14 @@ import React, { useContext } from 'react'; import D from 'i18n'; -import { - Divider, - FormControl, - FormHelperText, - IconButton, - makeStyles, - NativeSelect, - Paper, - Tooltip, - Typography, -} from '@material-ui/core'; +import Divider from '@material-ui/core/Divider'; +import FormControl from '@material-ui/core/FormControl'; +import FormHelperText from '@material-ui/core/FormHelperText'; +import IconButton from '@material-ui/core/IconButton'; +import NativeSelect from '@material-ui/core/NativeSelect'; +import Paper from '@material-ui/core/Paper'; +import Tooltip from '@material-ui/core/Tooltip'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; import { NotificationItem } from './notificationItem'; import { NotificationWrapperContext } from 'components/notificationWrapper'; import { Delete, Drafts } from '@material-ui/icons'; diff --git a/src/components/common/loader/index.js b/src/components/common/loader/index.js index 575f2a1bf..e2dcdb07f 100644 --- a/src/components/common/loader/index.js +++ b/src/components/common/loader/index.js @@ -1,4 +1,5 @@ -import { Backdrop, makeStyles } from '@material-ui/core'; +import { makeStyles } from '@material-ui/core/styles'; +import Backdrop from '@material-ui/core/Backdrop'; import D from 'i18n'; import imgPreloader from 'img/loader.svg'; import PropTypes from 'prop-types'; diff --git a/src/components/common/navigation/component.js b/src/components/common/navigation/component.js index aa94946ba..ceafd8a8a 100644 --- a/src/components/common/navigation/component.js +++ b/src/components/common/navigation/component.js @@ -1,35 +1,33 @@ -import { - Badge, - Card, - CardMedia, - ClickAwayListener, - Fade, - IconButton, - Popper, - Tooltip, -} from '@material-ui/core'; -import { NavLink, Route } from 'react-router-dom'; import React, { useContext, useEffect, useState } from 'react'; - +import { NavLink, Route } from 'react-router-dom'; import AppBar from '@material-ui/core/AppBar'; +import Badge from '@material-ui/core/Badge'; +import Card from '@material-ui/core/Card'; +import CardMedia from '@material-ui/core/CardMedia'; +import ClickAwayListener from '@material-ui/core/ClickAwayListener'; +import Fade from '@material-ui/core/Fade'; +import IconButton from '@material-ui/core/IconButton'; +import Popper from '@material-ui/core/Popper'; +import Tooltip from '@material-ui/core/Tooltip'; +import MenuIcon from '@material-ui/icons/Menu'; +import Notifications from '@material-ui/icons/Notifications'; +import Toolbar from '@material-ui/core/Toolbar'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; + import D from 'i18n'; import InfoTile from 'components/panel-body/UEpage/infoTile/infoTile'; -import MenuIcon from '@material-ui/icons/Menu'; import { NotificationWrapperContext } from 'components/notificationWrapper'; -import { Notifications } from '@material-ui/icons'; import { NotificationsRoot } from '../Notification/notificationsRoot'; import OnlineStatus from '../online-status'; import { PEARL_USER_KEY } from 'utils/constants'; import PropTypes from 'prop-types'; import SearchBar from '../search/component'; import Synchronize from 'components/common/synchronize'; -import Toolbar from '@material-ui/core/Toolbar'; -import Typography from '@material-ui/core/Typography'; -import { makeStyles } from '@material-ui/core/styles'; export const NavigationContext = React.createContext(); -const Navigation = ({ location, textSearch, setTextSearch, setOpenDrawer, refresh }) => { +const Navigation = ({ location, textSearch, setTextSearch, setOpenDrawer }) => { const { unReadNotificationsNumber } = useContext(NotificationWrapperContext); const [disabled, setDisable] = useState(location.pathname.startsWith('/queen')); @@ -133,10 +131,7 @@ const Navigation = ({ location, textSearch, setTextSearch, setOpenDrawer, refres )} /> - } - /> + } />
@@ -183,7 +178,5 @@ Navigation.propTypes = { }).isRequired, textSearch: PropTypes.string.isRequired, setTextSearch: PropTypes.func.isRequired, - setOpenDrawer: PropTypes.func.isRequired, - refresh: PropTypes.bool.isRequired, }; diff --git a/src/components/common/online-status/index.js b/src/components/common/online-status/index.js index 818dd7ba9..794a1c327 100644 --- a/src/components/common/online-status/index.js +++ b/src/components/common/online-status/index.js @@ -1,7 +1,7 @@ +import React, { useContext } from 'react'; import { makeStyles } from '@material-ui/core/styles'; import WifiIcon from '@material-ui/icons/Wifi'; import clsx from 'clsx'; -import React, { useContext } from 'react'; import { AppContext } from 'Root'; const useStyles = makeStyles(theme => ({ diff --git a/src/components/common/palette.js b/src/components/common/palette.js index acbd9040b..791454886 100644 --- a/src/components/common/palette.js +++ b/src/components/common/palette.js @@ -1,5 +1,7 @@ -import { makeStyles, Paper, Typography } from '@material-ui/core'; import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; const useStyles = makeStyles(theme => ({ primaryMain: { diff --git a/src/components/common/search/component.js b/src/components/common/search/component.js index 09cae0c32..39fac0248 100644 --- a/src/components/common/search/component.js +++ b/src/components/common/search/component.js @@ -1,7 +1,7 @@ +import React from 'react'; import InputBase from '@material-ui/core/InputBase'; import { makeStyles } from '@material-ui/core/styles'; import PropTypes from 'prop-types'; -import React from 'react'; const SearchBar = ({ textSearch, setTextSearch }) => { const handleChange = e => { diff --git a/src/components/common/synchronize/component.js b/src/components/common/synchronize/component.js index f183060d6..f5696353a 100644 --- a/src/components/common/synchronize/component.js +++ b/src/components/common/synchronize/component.js @@ -1,8 +1,9 @@ -import { makeStyles, Tooltip } from '@material-ui/core'; +import React, { useContext } from 'react'; +import Tooltip from '@material-ui/core/Tooltip'; import IconButton from '@material-ui/core/IconButton'; +import { makeStyles } from '@material-ui/core/styles'; import SyncIcon from 'utils/icons/SyncIcon'; import PropTypes from 'prop-types'; -import React, { useContext } from 'react'; import { AppContext } from 'Root'; import D from 'i18n'; import { SynchronizeWrapperContext } from 'components/sychronizeWrapper'; diff --git a/src/components/notificationWrapper/index.js b/src/components/notificationWrapper/index.js index e761afd40..013881305 100644 --- a/src/components/notificationWrapper/index.js +++ b/src/components/notificationWrapper/index.js @@ -1,7 +1,8 @@ import React, { useEffect, useState } from 'react'; -import notificationIdbService from 'indexedbb/services/notification-idb-service'; -import syncReportIdbService from 'indexedbb/services/syncReport-idb-service'; + import { NOTIFICATION_TYPE_SYNC } from 'utils/constants'; +import notificationIdbService from 'utils/indexeddb/services/notification-idb-service'; +import syncReportIdbService from 'utils/indexeddb/services/syncReport-idb-service'; export const NotificationWrapperContext = React.createContext(); diff --git a/src/components/panel-body/UESpage/component.js b/src/components/panel-body/UESpage/component.js index eb2efbaed..ee15adb50 100644 --- a/src/components/panel-body/UESpage/component.js +++ b/src/components/panel-body/UESpage/component.js @@ -1,19 +1,18 @@ -import { Grid } from '@material-ui/core'; -import { makeStyles } from '@material-ui/core/styles'; -import { applyFilters, sortOnColumnCompareFunction, updateStateWithDates } from 'utils/functions'; -import surveyUnitDBService from 'indexedbb/services/surveyUnit-idb-service'; -import PropTypes from 'prop-types'; import React, { useEffect, useState } from 'react'; +import { applyFilters, sortOnColumnCompareFunction, updateStateWithDates } from 'utils/functions'; +import { useMissingSurveyUnits, useSurveyUnits } from 'utils/hooks/database'; + import FilterPanel from './filterPanel'; +import Grid from '@material-ui/core/Grid'; +import PropTypes from 'prop-types'; import SurveyUnitCard from './material/surveyUnitCard'; -import surveyUnitMissingIdbService from 'indexedbb/services/surveyUnitMissing-idb-service'; +import { makeStyles } from '@material-ui/core/styles'; const UESPage = ({ textSearch }) => { const [surveyUnits, setSurveyUnits] = useState([]); const [filteredSurveyUnits, setFilteredSurveyUnits] = useState([]); const [searchEchoes, setSearchEchoes] = useState([0, 0]); const [campaigns, setCampaigns] = useState([]); - const [init, setInit] = useState(false); const [sortCriteria, setSortCriteria] = useState('remainingDays'); const [filters, setFilters] = useState({ search: textSearch, @@ -25,32 +24,27 @@ const UESPage = ({ textSearch }) => { const [inaccessibles, setInaccessibles] = useState([]); + const missingSurveyUnits = useMissingSurveyUnits(); + const idbSurveyUnits = useSurveyUnits(); + useEffect(() => { - if (!init) { - setInit(true); - surveyUnitMissingIdbService - .getAll() - .then(units => setInaccessibles(units.map(({ id }) => id))); + setInaccessibles(missingSurveyUnits.map(({ id }) => id)); + }, [missingSurveyUnits]); - surveyUnitDBService.getAll().then(units => { - const initializedSU = units.map(su => ({ ...su, selected: false })); - setCampaigns([...new Set(units.map(unit => unit.campaign))]); - setSurveyUnits(initializedSU); - setSearchEchoes([initializedSU.length, initializedSU.length]); - }); - } - }, [init]); + useEffect(() => { + idbSurveyUnits.forEach(su => updateStateWithDates(su)); + }, [idbSurveyUnits]); useEffect(() => { - setFilters(f => ({ ...f, search: textSearch })); - }, [textSearch]); + const initializedSU = idbSurveyUnits.map(su => ({ ...su, selected: false })); + setCampaigns([...new Set(idbSurveyUnits.map(unit => unit.campaign))]); + setSurveyUnits(initializedSU); + setSearchEchoes([initializedSU.length, initializedSU.length]); + }, [idbSurveyUnits]); useEffect(() => { - surveyUnitDBService.getAll().then(units => { - const updateNb = units.map(su => updateStateWithDates(su)).reduce((a, b) => a + b, 0); - if (updateNb > 0) setInit(false); - }); - }, [surveyUnits]); + setFilters(f => ({ ...f, search: textSearch })); + }, [textSearch]); useEffect(() => { const sortSU = su => su.sort(sortOnColumnCompareFunction(sortCriteria)); diff --git a/src/components/panel-body/UESpage/filterPanel/component.js b/src/components/panel-body/UESpage/filterPanel/component.js index 8e4cfe99a..2d3c4d1df 100644 --- a/src/components/panel-body/UESpage/filterPanel/component.js +++ b/src/components/panel-body/UESpage/filterPanel/component.js @@ -1,3 +1,4 @@ +import React, { useState } from 'react'; import Accordion from '@material-ui/core/Accordion'; import AccordionDetails from '@material-ui/core/AccordionDetails'; import AccordionSummary from '@material-ui/core/AccordionSummary'; @@ -13,7 +14,6 @@ import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import toDoEnum from 'utils/enum/SUToDoEnum'; import D from 'i18n'; import PropTypes from 'prop-types'; -import React, { useState } from 'react'; const FilterPanel = ({ searchEchoes, diff --git a/src/components/panel-body/UESpage/material/surveyUnitCard.js b/src/components/panel-body/UESpage/material/surveyUnitCard.js index 066d36839..53cd6a568 100644 --- a/src/components/panel-body/UESpage/material/surveyUnitCard.js +++ b/src/components/panel-body/UESpage/material/surveyUnitCard.js @@ -1,3 +1,4 @@ +import React from 'react'; import Card from '@material-ui/core/Card'; import CardContent from '@material-ui/core/CardContent'; import { makeStyles } from '@material-ui/core/styles'; @@ -16,7 +17,6 @@ import { isSelectable, } from 'utils/functions/surveyUnitFunctions'; import PropTypes from 'prop-types'; -import React from 'react'; import { useHistory } from 'react-router-dom'; import { Tooltip } from '@material-ui/core'; import D from 'i18n'; diff --git a/src/components/panel-body/UEpage/atomicInfoTile.js b/src/components/panel-body/UEpage/atomicInfoTile.js index 95d1c14a4..5c1a68a49 100644 --- a/src/components/panel-body/UEpage/atomicInfoTile.js +++ b/src/components/panel-body/UEpage/atomicInfoTile.js @@ -1,8 +1,9 @@ -import { Paper, Typography } from '@material-ui/core'; +import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; import MaterialIcons from 'utils/icons/materialIcons'; import PropTypes from 'prop-types'; -import React from 'react'; const useStyles = makeStyles(theme => ({ root: { diff --git a/src/components/panel-body/UEpage/comments/comment/component.js b/src/components/panel-body/UEpage/comments/comment/component.js index c9b8477e9..50034ddf4 100644 --- a/src/components/panel-body/UEpage/comments/comment/component.js +++ b/src/components/panel-body/UEpage/comments/comment/component.js @@ -1,9 +1,13 @@ -import { makeStyles, Paper, TextareaAutosize } from '@material-ui/core'; -import { getCommentByType } from 'utils/functions/surveyUnitFunctions'; +import React, { useContext, useState } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import TextareaAutosize from '@material-ui/core/TextareaAutosize'; +import Paper from '@material-ui/core/Paper'; + import D from 'i18n'; import PropTypes from 'prop-types'; -import React, { useContext, useState } from 'react'; import SurveyUnitContext from '../../UEContext'; +import { getCommentByType } from 'utils/functions/surveyUnitFunctions'; +import surveyUnitIdbService from 'utils/indexeddb/services/surveyUnit-idb-service'; const useStyles = makeStyles(() => ({ noResize: { @@ -20,7 +24,7 @@ const useStyles = makeStyles(() => ({ }, })); -const Comment = ({ editable, save }) => { +const Comment = ({ editable }) => { const { surveyUnit } = useContext(SurveyUnitContext); const value = editable ? getCommentByType('INTERVIEWER', surveyUnit) @@ -36,7 +40,7 @@ const Comment = ({ editable, save }) => { newComments.push(managementComment); newComments.push(newInterviewerComment); surveyUnit.comments = newComments; - save(surveyUnit); + surveyUnitIdbService.addOrUpdate(surveyUnit); }; const onChange = event => { @@ -53,7 +57,7 @@ const Comment = ({ editable, save }) => { cols={50} placeholder={D.organizationComment} defaultValue={interviewerComment} - onChange={onChange} + onBlur={onChange} /> ); @@ -62,5 +66,4 @@ const Comment = ({ editable, save }) => { export default Comment; Comment.propTypes = { editable: PropTypes.bool.isRequired, - save: PropTypes.func.isRequired, }; diff --git a/src/components/panel-body/UEpage/comments/component.js b/src/components/panel-body/UEpage/comments/component.js index a9abf6adb..baf050df1 100644 --- a/src/components/panel-body/UEpage/comments/component.js +++ b/src/components/panel-body/UEpage/comments/component.js @@ -1,10 +1,6 @@ -import PropTypes from 'prop-types'; import React from 'react'; import Comment from './comment'; -const Comments = ({ save }) => ; +const Comments = () => ; export default Comments; -Comments.propTypes = { - save: PropTypes.func.isRequired, -}; diff --git a/src/components/panel-body/UEpage/component.js b/src/components/panel-body/UEpage/component.js index 4f9885250..63c5867fb 100644 --- a/src/components/panel-body/UEpage/component.js +++ b/src/components/panel-body/UEpage/component.js @@ -1,65 +1,48 @@ import React, { useEffect, useState } from 'react'; import { addNewState, getLastState } from 'utils/functions'; import { useHistory, useParams } from 'react-router-dom'; - import D from 'i18n'; import PropTypes from 'prop-types'; import Router from './router'; import { SurveyUnitProvider } from './UEContext'; -import surveyUnitDBService from 'indexedbb/services/surveyUnit-idb-service'; -import surveyUnitMissingIdbService from 'indexedbb/services/surveyUnitMissing-idb-service'; +import surveyUnitMissingIdbService from 'utils/indexeddb/services/surveyUnitMissing-idb-service'; import { surveyUnitStateEnum } from 'utils/enum/SUStateEnum'; +import { useSurveyUnit } from 'utils/hooks/database'; -const UEPage = ({ match, refresh: homeRefresh }) => { - const [surveyUnit, setSurveyUnit] = useState(undefined); - const [shouldRefresh, setShouldRefresh] = useState(true); +const UEPage = ({ match }) => { const [inaccessible, setInaccessible] = useState(false); const [loading, setLoading] = useState(true); const history = useHistory(); const { id } = useParams(); + const surveyUnit = useSurveyUnit(id); useEffect(() => { const updateSurveyUnit = async () => { setLoading(true); - const ue = await surveyUnitDBService.getById(id); - if (ue) setSurveyUnit({ ...ue }); const isMissing = await surveyUnitMissingIdbService.getById(id); - if (isMissing) setInaccessible(true); + setInaccessible(!!isMissing); setLoading(false); }; - if (shouldRefresh) { + if (surveyUnit) { updateSurveyUnit(); - setShouldRefresh(false); } - }, [id, shouldRefresh]); - - const refresh = () => { - setShouldRefresh(true); - homeRefresh(); - }; - - const saveUE = ue => { - setSurveyUnit(ue); - surveyUnitDBService.update(ue); - // history.push(url); // force to update - }; + }, [id, surveyUnit]); useEffect(() => { if (surveyUnit !== undefined) { const lastState = getLastState(surveyUnit); if (lastState.type === surveyUnitStateEnum.VISIBLE_AND_CLICKABLE.type) { addNewState(surveyUnit, surveyUnitStateEnum.IN_PREPARATION.type); - history.push(history.location.pathname); } } - }, [surveyUnit, history]); + }, [surveyUnit]); return ( <> {surveyUnit && !loading && ( - + )} diff --git a/src/components/panel-body/UEpage/contacts/component.js b/src/components/panel-body/UEpage/contacts/component.js index 382a9bca5..a23930321 100644 --- a/src/components/panel-body/UEpage/contacts/component.js +++ b/src/components/panel-body/UEpage/contacts/component.js @@ -1,6 +1,6 @@ -import { Grid } from '@material-ui/core'; -import PropTypes from 'prop-types'; import React from 'react'; +import Grid from '@material-ui/core/Grid'; +import PropTypes from 'prop-types'; import ContactAttempts from './contactAttempts'; import ContactOutcome from './contactOutcome'; diff --git a/src/components/panel-body/UEpage/contacts/contactAttempts/component.js b/src/components/panel-body/UEpage/contacts/contactAttempts/component.js index 16cff6e12..284704dfb 100644 --- a/src/components/panel-body/UEpage/contacts/contactAttempts/component.js +++ b/src/components/panel-body/UEpage/contacts/contactAttempts/component.js @@ -1,9 +1,11 @@ -import { makeStyles, Paper, Typography } from '@material-ui/core'; +import React, { useContext, useEffect, useState } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; import formEnum from 'utils/enum/formEnum'; import { getSortedContactAttempts } from 'utils/functions'; import D from 'i18n'; import PropTypes from 'prop-types'; -import React, { useContext, useEffect, useState } from 'react'; import SurveyUnitContext from '../../UEContext'; import ContactAttemptLine from './contactAttemptLine'; diff --git a/src/components/panel-body/UEpage/contacts/contactAttempts/contactAttemptLine.js b/src/components/panel-body/UEpage/contacts/contactAttempts/contactAttemptLine.js index 7d70a222e..52602b9d1 100644 --- a/src/components/panel-body/UEpage/contacts/contactAttempts/contactAttemptLine.js +++ b/src/components/panel-body/UEpage/contacts/contactAttempts/contactAttemptLine.js @@ -1,10 +1,11 @@ -import { makeStyles, Typography } from '@material-ui/core'; +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import Typography from '@material-ui/core/Typography'; import DeleteIcon from '@material-ui/icons/Delete'; import { findContactAttemptValueByType } from 'utils/enum/ContactAttemptEnum'; import format from 'date-fns/format'; import { fr } from 'date-fns/locale'; import PropTypes from 'prop-types'; -import React from 'react'; const useStyles = makeStyles(() => ({ button: { diff --git a/src/components/panel-body/UEpage/contacts/contactAttempts/formPanel.js b/src/components/panel-body/UEpage/contacts/contactAttempts/formPanel.js index 7a7c699f1..a3cb24041 100644 --- a/src/components/panel-body/UEpage/contacts/contactAttempts/formPanel.js +++ b/src/components/panel-body/UEpage/contacts/contactAttempts/formPanel.js @@ -1,7 +1,13 @@ -import { Button, DialogActions, Fab, makeStyles, Paper, Typography } from '@material-ui/core'; +import React from 'react'; +import Button from '@material-ui/core/Button'; +import DialogActions from '@material-ui/core/DialogActions'; +import Fab from '@material-ui/core/Fab'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; + +import { makeStyles } from '@material-ui/core/styles'; import ChevronLeftIcon from '@material-ui/icons/ChevronLeft'; import PropTypes from 'prop-types'; -import React from 'react'; const useStyles = makeStyles(() => ({ column: { diff --git a/src/components/panel-body/UEpage/contacts/contactAttempts/upDownCounter.js b/src/components/panel-body/UEpage/contacts/contactAttempts/upDownCounter.js index 6fa4772e2..86248363d 100644 --- a/src/components/panel-body/UEpage/contacts/contactAttempts/upDownCounter.js +++ b/src/components/panel-body/UEpage/contacts/contactAttempts/upDownCounter.js @@ -1,10 +1,11 @@ -import { IconButton, makeStyles } from '@material-ui/core'; +import React, { useEffect } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import IconButton from '@material-ui/core/IconButton'; import ExpandLessIcon from '@material-ui/icons/ExpandLess'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import useCounter from 'utils/hooks/useCounter'; import { getHours, getMinutes, setHours, setMinutes } from 'date-fns'; import PropTypes from 'prop-types'; -import React, { useEffect } from 'react'; const useStyles = makeStyles(() => ({ icon: { diff --git a/src/components/panel-body/UEpage/contacts/contactOutcome/component.js b/src/components/panel-body/UEpage/contacts/contactOutcome/component.js index 6250d2913..09d3788c2 100644 --- a/src/components/panel-body/UEpage/contacts/contactOutcome/component.js +++ b/src/components/panel-body/UEpage/contacts/contactOutcome/component.js @@ -1,6 +1,7 @@ -import { Paper, Typography, makeStyles } from '@material-ui/core'; import React, { useContext, useEffect, useState } from 'react'; - +import { makeStyles } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; import D from 'i18n'; import PropTypes from 'prop-types'; import SurveyUnitContext from '../../UEContext'; diff --git a/src/components/panel-body/UEpage/details/component.js b/src/components/panel-body/UEpage/details/component.js index eefd59954..3445a3004 100644 --- a/src/components/panel-body/UEpage/details/component.js +++ b/src/components/panel-body/UEpage/details/component.js @@ -1,8 +1,8 @@ +import React, { useContext } from 'react'; import formEnum from 'utils/enum/formEnum'; import { getAddressData, personPlaceholder } from 'utils/functions'; import D from 'i18n'; import PropTypes from 'prop-types'; -import React, { useContext } from 'react'; import AtomicInfoTile from '../atomicInfoTile'; import SurveyUnitContext from '../UEContext'; import Contact from './contact'; diff --git a/src/components/panel-body/UEpage/details/contact.js b/src/components/panel-body/UEpage/details/contact.js index c66f4848a..13e225379 100644 --- a/src/components/panel-body/UEpage/details/contact.js +++ b/src/components/panel-body/UEpage/details/contact.js @@ -1,9 +1,9 @@ -import { Grid } from '@material-ui/core'; +import React from 'react'; +import Grid from '@material-ui/core/Grid'; import formEnum from 'utils/enum/formEnum'; import { getMailData, getPhoneData, getUserData } from 'utils/functions'; import D from 'i18n'; import PropTypes from 'prop-types'; -import React from 'react'; import AtomicInfoTile from '../atomicInfoTile'; import DetailTile from './detailTile'; import PhoneTile from './phoneTile'; diff --git a/src/components/panel-body/UEpage/details/detailTile.js b/src/components/panel-body/UEpage/details/detailTile.js index 43f628ac2..5d0a10c4e 100644 --- a/src/components/panel-body/UEpage/details/detailTile.js +++ b/src/components/panel-body/UEpage/details/detailTile.js @@ -1,6 +1,8 @@ -import { makeStyles, Paper, Typography } from '@material-ui/core'; -import PropTypes from 'prop-types'; import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; +import PropTypes from 'prop-types'; const useStyles = makeStyles(() => ({ root: { diff --git a/src/components/panel-body/UEpage/details/phoneList.js b/src/components/panel-body/UEpage/details/phoneList.js index 65603c7e7..298360d4f 100644 --- a/src/components/panel-body/UEpage/details/phoneList.js +++ b/src/components/panel-body/UEpage/details/phoneList.js @@ -1,9 +1,10 @@ -import { TextField, Typography } from '@material-ui/core'; +import React from 'react'; +import TextField from '@material-ui/core/TextField'; +import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; import { getPhoneSource } from 'utils/functions'; import MaterialIcons from 'utils/icons/materialIcons'; import PropTypes from 'prop-types'; -import React from 'react'; const useStyles = makeStyles(theme => ({ root: { diff --git a/src/components/panel-body/UEpage/details/phoneTile.js b/src/components/panel-body/UEpage/details/phoneTile.js index 971ea8af5..206182a03 100644 --- a/src/components/panel-body/UEpage/details/phoneTile.js +++ b/src/components/panel-body/UEpage/details/phoneTile.js @@ -1,9 +1,9 @@ -import { Paper } from '@material-ui/core'; +import React from 'react'; +import Paper from '@material-ui/core/Paper'; import { makeStyles } from '@material-ui/core/styles'; import { sortPhoneNumbers } from 'utils/functions'; import MaterialIcons from 'utils/icons/materialIcons'; import PropTypes from 'prop-types'; -import React from 'react'; import PhoneList from './phoneList'; const useStyles = makeStyles(() => ({ diff --git a/src/components/panel-body/UEpage/forms/addressForm.js b/src/components/panel-body/UEpage/forms/addressForm.js index 19cb36636..9d3c7809c 100644 --- a/src/components/panel-body/UEpage/forms/addressForm.js +++ b/src/components/panel-body/UEpage/forms/addressForm.js @@ -1,5 +1,9 @@ -import { Button, DialogActions, DialogTitle, TextField, makeStyles } from '@material-ui/core'; import React, { useContext, useState } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import Button from '@material-ui/core/Button'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import TextField from '@material-ui/core/TextField'; import D from 'i18n'; import PropTypes from 'prop-types'; diff --git a/src/components/panel-body/UEpage/forms/contactAttemptsForm.js b/src/components/panel-body/UEpage/forms/contactAttemptsForm.js index 682efd0fc..0bff89f3c 100644 --- a/src/components/panel-body/UEpage/forms/contactAttemptsForm.js +++ b/src/components/panel-body/UEpage/forms/contactAttemptsForm.js @@ -1,15 +1,20 @@ -import { DatePicker, KeyboardTimePicker, MuiPickersUtilsProvider } from '@material-ui/pickers'; -import { Fab, Paper, Typography, makeStyles } from '@material-ui/core'; import React, { useContext, useEffect, useState } from 'react'; -import { addNewState, areCaEqual, getSortedContactAttempts } from 'utils/functions'; +import { DatePicker, KeyboardTimePicker, MuiPickersUtilsProvider } from '@material-ui/pickers'; +import { makeStyles } from '@material-ui/core/styles'; +import Fab from '@material-ui/core/Fab'; +import Typography from '@material-ui/core/Typography'; +import Paper from '@material-ui/core/Paper'; import AddIcon from '@material-ui/icons/Add'; +import ScheduleIcon from '@material-ui/icons/Schedule'; + +import { addNewState, areCaEqual, getSortedContactAttempts } from 'utils/functions'; + import ContactAttemptLine from '../contacts/contactAttempts/contactAttemptLine'; import D from 'i18n'; import DateFnsUtils from '@date-io/date-fns'; import FormPanel from '../contacts/contactAttempts/formPanel'; import PropTypes from 'prop-types'; -import ScheduleIcon from '@material-ui/icons/Schedule'; import SurveyUnitContext from '../UEContext'; import { contactAttemptEnum } from 'utils/enum/ContactAttemptEnum'; import frLocale from 'date-fns/locale/fr'; diff --git a/src/components/panel-body/UEpage/forms/contactOutcomeForm.js b/src/components/panel-body/UEpage/forms/contactOutcomeForm.js index db48fe852..33d18bfd4 100644 --- a/src/components/panel-body/UEpage/forms/contactOutcomeForm.js +++ b/src/components/panel-body/UEpage/forms/contactOutcomeForm.js @@ -1,7 +1,9 @@ -import { Fab, Grid, Paper, Typography, makeStyles } from '@material-ui/core'; import React, { useContext, useEffect, useState } from 'react'; -import { contactOutcomeEnum, findContactOutcomeValueByType } from 'utils/enum/ContactOutcomeEnum'; - +import { makeStyles } from '@material-ui/core/styles'; +import Fab from '@material-ui/core/Fab'; +import Typography from '@material-ui/core/Typography'; +import Paper from '@material-ui/core/Paper'; +import Grid from '@material-ui/core/Grid'; import AddIcon from '@material-ui/icons/Add'; import D from 'i18n'; import FormPanel from '../contacts/contactAttempts/formPanel'; @@ -9,6 +11,7 @@ import PropTypes from 'prop-types'; import RemoveIcon from '@material-ui/icons/Remove'; import SurveyUnitContext from '../UEContext'; import { addNewState } from 'utils/functions'; +import { contactOutcomeEnum, findContactOutcomeValueByType } from 'utils/enum/ContactOutcomeEnum'; import { surveyUnitStateEnum } from 'utils/enum/SUStateEnum'; const useStyles = makeStyles(theme => ({ diff --git a/src/components/panel-body/UEpage/forms/index.js b/src/components/panel-body/UEpage/forms/index.js index 71fbd2e1d..00ce602c9 100644 --- a/src/components/panel-body/UEpage/forms/index.js +++ b/src/components/panel-body/UEpage/forms/index.js @@ -1,24 +1,23 @@ -import formEnum from 'utils/enum/formEnum'; -import { deleteContactAttempt, getAddressData, getCommentByType } from 'utils/functions'; import React from 'react'; +import { deleteContactAttempt, getAddressData, getCommentByType } from 'utils/functions'; import AddressForm from './addressForm'; import ContactAttemptsForm from './contactAttemptsForm'; import ContactOutcomeForm from './contactOutcomeForm'; import MailForm from './mailForm'; import PhoneForm from './phoneForm'; import UserForm from './userForm'; +import formEnum from 'utils/enum/formEnum'; +import surveyUnitIdbService from 'utils/indexeddb/services/surveyUnit-idb-service'; -export const getForm = (formType, saveFunction, previousValue, closeModal, refresh) => { +export const getForm = (formType, previousValue, closeModal) => { const saveAndClose = surveyUnit => { closeModal(); - saveFunction(surveyUnit); - refresh(); + surveyUnitIdbService.addOrUpdate(surveyUnit); }; const deleteAndClose = (surveyUnit, contactAttempt) => { closeModal(); deleteContactAttempt(surveyUnit, contactAttempt); - refresh(); }; switch (formType) { diff --git a/src/components/panel-body/UEpage/forms/mailForm.js b/src/components/panel-body/UEpage/forms/mailForm.js index 109eb0946..426be5ddc 100644 --- a/src/components/panel-body/UEpage/forms/mailForm.js +++ b/src/components/panel-body/UEpage/forms/mailForm.js @@ -1,8 +1,12 @@ -import { Button, DialogActions, DialogTitle, makeStyles, TextField } from '@material-ui/core'; +import React, { useContext, useState } from 'react'; +import Button from '@material-ui/core/Button'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import TextField from '@material-ui/core/TextField'; +import { makeStyles } from '@material-ui/core/styles'; import MaterialIcons from 'utils/icons/materialIcons'; import D from 'i18n'; import PropTypes from 'prop-types'; -import React, { useContext, useState } from 'react'; import SurveyUnitContext from '../UEContext'; const useStyles = makeStyles(() => ({ diff --git a/src/components/panel-body/UEpage/forms/phoneForm.js b/src/components/panel-body/UEpage/forms/phoneForm.js index 4c8fae469..45f1777de 100644 --- a/src/components/panel-body/UEpage/forms/phoneForm.js +++ b/src/components/panel-body/UEpage/forms/phoneForm.js @@ -1,8 +1,11 @@ -import { Button, DialogActions, DialogTitle, makeStyles } from '@material-ui/core'; +import React, { useContext, useState } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import Button from '@material-ui/core/Button'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogTitle from '@material-ui/core/DialogTitle'; import { sortPhoneNumbers } from 'utils/functions'; import D from 'i18n'; import PropTypes from 'prop-types'; -import React, { useContext, useState } from 'react'; import PhoneTile from '../details/phoneTile'; import SurveyUnitContext from '../UEContext'; diff --git a/src/components/panel-body/UEpage/forms/userForm.js b/src/components/panel-body/UEpage/forms/userForm.js index 8450b0373..ab213b273 100644 --- a/src/components/panel-body/UEpage/forms/userForm.js +++ b/src/components/panel-body/UEpage/forms/userForm.js @@ -1,11 +1,15 @@ +import React, { useContext, useState } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import Button from '@material-ui/core/Button'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import TextField from '@material-ui/core/TextField'; import DateFnsUtils from '@date-io/date-fns'; -import { Button, DialogActions, DialogTitle, makeStyles, TextField } from '@material-ui/core'; import { DatePicker, MuiPickersUtilsProvider } from '@material-ui/pickers'; import { getTitle } from 'utils/functions'; import frLocale from 'date-fns/locale/fr'; import D from 'i18n'; import PropTypes from 'prop-types'; -import React, { useContext, useState } from 'react'; import SurveyUnitContext from '../UEContext'; const useStyles = makeStyles(() => ({ diff --git a/src/components/panel-body/UEpage/identification/component.js b/src/components/panel-body/UEpage/identification/component.js index 94bce0e39..abf67d2c4 100644 --- a/src/components/panel-body/UEpage/identification/component.js +++ b/src/components/panel-body/UEpage/identification/component.js @@ -1,6 +1,6 @@ -import { Paper } from '@material-ui/core'; -import { makeStyles } from '@material-ui/core/styles'; import React from 'react'; +import Paper from '@material-ui/core/Paper'; +import { makeStyles } from '@material-ui/core/styles'; const Identification = () => { const useStyles = makeStyles(() => ({ diff --git a/src/components/panel-body/UEpage/infoTile/infoTile.js b/src/components/panel-body/UEpage/infoTile/infoTile.js index 88cf6fba7..e2ae6b5f1 100644 --- a/src/components/panel-body/UEpage/infoTile/infoTile.js +++ b/src/components/panel-body/UEpage/infoTile/infoTile.js @@ -1,14 +1,15 @@ -import React, { useEffect, useState } from 'react'; - +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; import Card from '@material-ui/core/Card'; import CardContent from '@material-ui/core/CardContent'; import PersonIcon from '@material-ui/icons/Person'; -import { Skeleton } from '@material-ui/lab'; +import Skeleton from '@material-ui/lab/Skeleton'; import Typography from '@material-ui/core/Typography'; + import { getprivilegedPerson } from 'utils/functions'; -import { makeStyles } from '@material-ui/core/styles'; -import surveyUnitDBService from 'indexedbb/services/surveyUnit-idb-service'; + import { useParams } from 'react-router-dom'; +import { useSurveyUnit } from 'utils/hooks/database'; const useStyles = makeStyles({ root: { paddingRight: '3em' }, @@ -39,14 +40,9 @@ const useStyles = makeStyles({ }, }); -const InfoTile = ({ refresh }) => { - const [surveyUnit, setSurveyUnit] = useState(undefined); +const InfoTile = () => { const { id } = useParams(); - useEffect(() => { - surveyUnitDBService.getById(id).then(ue => { - setSurveyUnit(ue); - }); - }, [id, refresh]); + const surveyUnit = useSurveyUnit(id); const classes = useStyles(); const { firstName, lastName } = getprivilegedPerson(surveyUnit); diff --git a/src/components/panel-body/UEpage/infoTile/infoTile.test.js b/src/components/panel-body/UEpage/infoTile/infoTile.test.js index fba5836fd..65a544eef 100644 --- a/src/components/panel-body/UEpage/infoTile/infoTile.test.js +++ b/src/components/panel-body/UEpage/infoTile/infoTile.test.js @@ -5,24 +5,15 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import { render } from '@testing-library/react'; -jest.mock('indexedbb/services/surveyUnit-idb-service', () => { - const originalModule = jest.requireActual('indexedbb/services/surveyUnit-idb-service'); - const suIdbService = originalModule.default; - suIdbService.getById = async () => { - return Promise.resolve({ - persons: [{ firstName: 'FirstName', lastName: 'LastName', privileged: true }], - campaign: 'Mocked campaign', - sampleIdentifiers: { ssech: '1' }, - }); - }; - originalModule.default = suIdbService; - return { - __esModule: true, - ...originalModule, - }; -}); +jest.mock('utils/hooks/database', () => ({ + useSurveyUnit: () => ({ + persons: [{ firstName: 'FirstName', lastName: 'LastName', privileged: true }], + campaign: 'Mocked campaign', + sampleIdentifiers: { ssech: '1' }, + }), +})); -const SuIdbService = require('indexedbb/services/surveyUnit-idb-service'); +const dataBaseHooks = require('utils/hooks/database'); const MemoryRouterWithInitialRoutes = ({ children }) => ( @@ -38,15 +29,15 @@ const customRender = ui => { const wait = async () => new Promise(resolve => setTimeout(resolve, 0)); it('renders correctly', async () => { - const result = customRender(); + const result = customRender(); await act(async () => { await wait(); }); expect(result.baseElement).toMatchSnapshot(); - const { getById } = SuIdbService.default; + const { useSurveyUnit } = dataBaseHooks; // check if mock is done - await expect(getById(5)).resolves.toStrictEqual({ + await expect(useSurveyUnit(5)).toStrictEqual({ persons: [{ firstName: 'FirstName', lastName: 'LastName', privileged: true }], campaign: 'Mocked campaign', sampleIdentifiers: { ssech: '1' }, diff --git a/src/components/panel-body/UEpage/letters/component.js b/src/components/panel-body/UEpage/letters/component.js index 077286605..1e8503a3b 100644 --- a/src/components/panel-body/UEpage/letters/component.js +++ b/src/components/panel-body/UEpage/letters/component.js @@ -1,6 +1,6 @@ -import { Paper } from '@material-ui/core'; -import { makeStyles } from '@material-ui/core/styles'; import React from 'react'; +import Paper from '@material-ui/core/Paper'; +import { makeStyles } from '@material-ui/core/styles'; const Letters = () => { const useStyles = makeStyles(() => ({ diff --git a/src/components/panel-body/UEpage/navigation/component.js b/src/components/panel-body/UEpage/navigation/component.js index 2b7933079..6e43735c3 100644 --- a/src/components/panel-body/UEpage/navigation/component.js +++ b/src/components/panel-body/UEpage/navigation/component.js @@ -1,12 +1,17 @@ -import { Button, Tab, Tabs, Tooltip, makeStyles } from '@material-ui/core'; import React, { useContext, useState } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import Button from '@material-ui/core/Button'; +import Tab from '@material-ui/core/Tab'; +import Tabs from '@material-ui/core/Tabs'; +import Tooltip from '@material-ui/core/Tooltip'; +import WarningIcon from '@material-ui/icons/Warning'; + import { addNewState, isQuestionnaireAvailable, isValidForTransmission } from 'utils/functions'; import { useHistory, useParams } from 'react-router-dom'; import D from 'i18n'; import PropTypes from 'prop-types'; import SurveyUnitContext from '../UEContext'; -import WarningIcon from '@material-ui/icons/Warning'; import { surveyUnitStateEnum } from 'utils/enum/SUStateEnum'; const useStyles = makeStyles(theme => ({ diff --git a/src/components/panel-body/UEpage/router.js b/src/components/panel-body/UEpage/router.js index c971656a7..84e31f583 100644 --- a/src/components/panel-body/UEpage/router.js +++ b/src/components/panel-body/UEpage/router.js @@ -1,14 +1,17 @@ -import { Dialog, Grid, makeStyles } from '@material-ui/core'; -import D from 'i18n'; -import PropTypes from 'prop-types'; import React, { useContext, useEffect, useRef, useState } from 'react'; +import Dialog from '@material-ui/core/Dialog'; +import Grid from '@material-ui/core/Grid'; +import { makeStyles } from '@material-ui/core/styles'; + +import { getForm, getPreviousValue, smartForms } from './forms'; import Comments from './comments'; import Contacts from './contacts'; +import D from 'i18n'; import Details from './details'; -import { getForm, getPreviousValue, smartForms } from './forms'; import Identification from './identification'; import Letters from './letters'; import Navigation from './navigation/component'; +import PropTypes from 'prop-types'; import StateLine from './stateLine'; import SurveyUnitContext from './UEContext'; import UeSubInfoTile from './ueSubInfoTile'; @@ -33,7 +36,7 @@ const useStyles = makeStyles(() => ({ }, })); -const Router = ({ match, saveUE, refresh }) => { +const Router = ({ match }) => { const { surveyUnit } = useContext(SurveyUnitContext); /** refs are used for scrolling, dispatched to the clickable link and linked element */ @@ -71,7 +74,7 @@ const Router = ({ match, saveUE, refresh }) => { setOpenModal(false); }; - const selectedForm = getForm(formType, saveUE, previousValue, closeModal, refresh); + const selectedForm = getForm(formType, previousValue, closeModal); const classes = useStyles(); @@ -106,7 +109,7 @@ const Router = ({ match, saveUE, refresh }) => { title={D.goToCommentsPage} className={classes.ajustScroll} > - +
@@ -134,6 +137,4 @@ Router.propTypes = { params: PropTypes.shape({ id: PropTypes.string.isRequired }).isRequired, url: PropTypes.string.isRequired, }).isRequired, - saveUE: PropTypes.func.isRequired, - refresh: PropTypes.func.isRequired, }; diff --git a/src/components/panel-body/UEpage/stateLine.js b/src/components/panel-body/UEpage/stateLine.js index b6d66a99a..06320a286 100644 --- a/src/components/panel-body/UEpage/stateLine.js +++ b/src/components/panel-body/UEpage/stateLine.js @@ -1,3 +1,4 @@ +import React, { useContext } from 'react'; import Step from '@material-ui/core/Step'; import StepLabel from '@material-ui/core/StepLabel'; import Stepper from '@material-ui/core/Stepper'; @@ -7,7 +8,6 @@ import RadioButtonUncheckedIcon from '@material-ui/icons/RadioButtonUnchecked'; import toDoEnum from 'utils/enum/SUToDoEnum'; import { convertSUStateInToDo, getLastState } from 'utils/functions'; import PropTypes from 'prop-types'; -import React, { useContext } from 'react'; import SurveyUnitContext from './UEContext'; const StateLine = () => { diff --git a/src/components/panel-body/UEpage/ueSubInfoTile.js b/src/components/panel-body/UEpage/ueSubInfoTile.js index f328de32e..a8acd50f0 100644 --- a/src/components/panel-body/UEpage/ueSubInfoTile.js +++ b/src/components/panel-body/UEpage/ueSubInfoTile.js @@ -1,7 +1,7 @@ -import { Typography } from '@material-ui/core'; +import React from 'react'; +import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; import PropTypes from 'prop-types'; -import React from 'react'; const useStyles = makeStyles(() => ({ root: { diff --git a/src/components/panel-body/databaseConsole/index.js b/src/components/panel-body/databaseConsole/index.js new file mode 100644 index 000000000..86fcd33b1 --- /dev/null +++ b/src/components/panel-body/databaseConsole/index.js @@ -0,0 +1,115 @@ +import React from 'react'; + +import BackupIcon from '@material-ui/icons/Backup'; +import Button from '@material-ui/core/Button'; +import Typography from '@material-ui/core/Typography'; +import Warning from '@material-ui/icons/Warning'; +import { makeStyles } from '@material-ui/core/styles'; + +import { PEARL_USER_KEY } from 'utils/constants'; + +import { db } from 'utils/indexeddb/idb-config'; +import D from 'i18n'; +import Dexie from 'dexie'; +import download from 'downloadjs'; +import { exportDB } from 'dexie-export-import'; + +const useStyles = makeStyles(theme => ({ + titleWrapper: { + marginTop: '2em', + marginBottom: '2em', + display: 'flex', + justifyContent: 'center', + }, + warningIcon: { + color: 'black', + fontSize: '11em', + }, + title: { + padding: '10px 50px 10px 50px', + alignSelf: 'center', + textAlign: 'center', + marginLeft: '20px', + textTransform: 'uppercase', + fontWeight: 'bold', + borderRadius: '30px', + backgroundColor: '#edc520', + }, + subTitle: { fontSize: '4em' }, + exportBtn: { + marginLeft: '1em', + backgroundColor: theme.palette.success.main, + }, + body: { + textAlign: 'center', + }, + actions: { + marginTop: '2em', + }, +})); + +export const DatabaseConsole = () => { + const classes = useStyles(); + + const questionnaireDataDB = new Dexie('Queen'); + questionnaireDataDB.open(); + + const interviewerFromLocalStorage = window.localStorage.getItem(PEARL_USER_KEY); + const userId = interviewerFromLocalStorage ? JSON.parse(interviewerFromLocalStorage).id : 'guest'; + + const progressCallback = ({ totalRows, completedRows }) => + console.log(`Progress: ${completedRows} of ${totalRows} rows completed`); + + const exportData = async () => { + console.log('Exporting data from IDB'); + const timestamp = new Date().getTime(); + try { + const blob = await exportDB(db, { prettyJson: true, progressCallback }); + download(blob, `data-export-${userId}-${timestamp}.json`, 'application/json'); + } catch (error) { + console.log('error when exporting'); + console.error('' + error.message); + } + }; + + const exportQuestionnaireData = async () => { + console.log('Exporting questionnaire data from IDB'); + const timestamp = new Date().getTime(); + try { + const blob = await exportDB(questionnaireDataDB, { prettyJson: true, progressCallback }); + download(blob, `questionnaire-data-export-${userId}-${timestamp}.json`, 'application/json'); + } catch (error) { + console.log('error when exporting'); + console.error('' + error.message); + } + }; + + return ( +
+
+
+ +
+
+ {D.mainTitle.split(' ').map(v => ( + + {v} + + ))} +
+
+
+
+ + +
+
+
+ ); +}; diff --git a/src/components/panel-body/home/component.js b/src/components/panel-body/home/component.js index cfcbd0648..e8c7a210c 100644 --- a/src/components/panel-body/home/component.js +++ b/src/components/panel-body/home/component.js @@ -1,20 +1,16 @@ +import React, { useState } from 'react'; + +import LateralMenu from '../lateralMenu'; import Navigation from 'components/common/navigation/component'; -import UEPage from 'components/panel-body/UEpage'; -import UESPage from 'components/panel-body/UESpage'; import PropTypes from 'prop-types'; -import React, { useState } from 'react'; import { Route } from 'react-router-dom'; +import UEPage from 'components/panel-body/UEpage'; +import UESPage from 'components/panel-body/UESpage'; import { version } from '../../../../package.json'; -import LateralMenu from '../lateralMenu'; const Home = ({ location, match }) => { const [textSearch, setTextSearch] = useState(''); const [openDrawer, setOpenDrawer] = useState(false); - const [shouldRefresh, setShouldRefresh] = useState(false); - - const refresh = () => { - setShouldRefresh(prev => !prev); - }; return (
@@ -23,14 +19,10 @@ const Home = ({ location, match }) => { textSearch={textSearch} setTextSearch={setTextSearch} setOpenDrawer={setOpenDrawer} - refresh={shouldRefresh} /> - } - /> + } /> ({ diff --git a/src/components/panel-body/queen-container/component.js b/src/components/panel-body/queen-container/component.js index 67203a70b..28e71fdab 100644 --- a/src/components/panel-body/queen-container/component.js +++ b/src/components/panel-body/queen-container/component.js @@ -1,6 +1,6 @@ -import { makeStyles } from '@material-ui/core'; -import listenQueen from 'utils/hooks/listenQueen'; import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import listenQueen from 'utils/hooks/listenQueen'; import { useHistory } from 'react-router-dom'; const useStyles = makeStyles(theme => ({ diff --git a/src/components/panel-body/resetData/index.js b/src/components/panel-body/resetData/index.js index f28702574..bc176a33e 100644 --- a/src/components/panel-body/resetData/index.js +++ b/src/components/panel-body/resetData/index.js @@ -1,8 +1,13 @@ -import { Button, makeStyles, Typography } from '@material-ui/core'; -import { Delete, Warning } from '@material-ui/icons'; +import React, { useState } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import Button from '@material-ui/core/Button'; +import Typography from '@material-ui/core/Typography'; + +import Delete from '@material-ui/icons/Delete'; +import Warning from '@material-ui/icons/Warning'; + import Dexie from 'dexie'; import D from 'i18n'; -import React, { useState } from 'react'; import { unregister } from 'serviceWorkerRegistration'; import { ResetDialog } from './resetDialog'; diff --git a/src/components/panel-body/resetData/resetDialog.js b/src/components/panel-body/resetData/resetDialog.js index a1fe1eef0..d8fc20372 100644 --- a/src/components/panel-body/resetData/resetDialog.js +++ b/src/components/panel-body/resetData/resetDialog.js @@ -1,17 +1,15 @@ /* eslint-disable jsx-a11y/no-autofocus */ -import { - Button, - Dialog, - DialogActions, - DialogContent, - DialogContentText, - DialogTitle, - makeStyles, - TextField, - Typography, -} from '@material-ui/core'; -import D from 'i18n'; import React, { useState } from 'react'; +import Button from '@material-ui/core/Button'; +import Dialog from '@material-ui/core/Dialog'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogContentText from '@material-ui/core/DialogContentText'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import TextField from '@material-ui/core/TextField'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; +import D from 'i18n'; import { PEARL_USER_KEY } from 'utils/constants'; const useStyles = makeStyles(theme => ({ diff --git a/src/components/sychronizeWrapper/index.js b/src/components/sychronizeWrapper/index.js index 828169173..2f2f60f32 100644 --- a/src/components/sychronizeWrapper/index.js +++ b/src/components/sychronizeWrapper/index.js @@ -1,12 +1,14 @@ -import notificationIdbService from 'indexedbb/services/notification-idb-service'; -import { synchronizePearl, useQueenSynchronisation } from 'utils/synchronize'; -import D from 'i18n'; import React, { useContext, useEffect, useState } from 'react'; -import { analyseResult, getNotifFromResult, saveSyncPearlData } from 'utils/synchronize/check'; import * as api from 'utils/api'; + +import { analyseResult, getNotifFromResult, saveSyncPearlData } from 'utils/synchronize/check'; +import { synchronizePearl, useQueenSynchronisation } from 'utils/synchronize'; + import { AppContext } from 'Root'; +import D from 'i18n'; import Preloader from 'components/common/loader'; import { SyncDialog } from './sychronizeDialog'; +import notificationIdbService from 'utils/indexeddb/services/notification-idb-service'; export const SynchronizeWrapperContext = React.createContext(); diff --git a/src/components/sychronizeWrapper/sychronizeDialog.js b/src/components/sychronizeWrapper/sychronizeDialog.js index 14e13bde7..1f736ea9d 100644 --- a/src/components/sychronizeWrapper/sychronizeDialog.js +++ b/src/components/sychronizeWrapper/sychronizeDialog.js @@ -1,20 +1,20 @@ -import { - Accordion, - AccordionDetails, - AccordionSummary, - Button, - Dialog, - DialogActions, - DialogContent, - DialogContentText, - DialogTitle, - Divider, - makeStyles, - Typography, -} from '@material-ui/core'; +import React from 'react'; + +import { makeStyles } from '@material-ui/core/styles'; +import Button from '@material-ui/core/Button'; +import Dialog from '@material-ui/core/Dialog'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import Accordion from '@material-ui/core/Accordion'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogContentText from '@material-ui/core/DialogContentText'; +import Divider from '@material-ui/core/Divider'; +import Typography from '@material-ui/core/Typography'; +import AccordionDetails from '@material-ui/core/AccordionDetails'; +import AccordionSummary from '@material-ui/core/AccordionSummary'; + import { ExpandMore, ThumbUpAlt } from '@material-ui/icons'; import { IconStatus } from 'components/common/IconStatus'; -import React from 'react'; import D from 'i18n'; const useStyles = makeStyles(theme => ({ diff --git a/src/indexedbb/idb-config.js b/src/indexedbb/idb-config.js deleted file mode 100644 index 73a38b82d..000000000 --- a/src/indexedbb/idb-config.js +++ /dev/null @@ -1,32 +0,0 @@ -import Dexie from 'dexie'; -import schema from './schema.json'; -import schema2 from './schema-2.json'; - -export class LocalDbFactory extends Dexie { - constructor(dataBaseName) { - super(dataBaseName); - this.version(1).stores(schema); - // upgrade dataBase (please see https://dexie.org/docs/Tutorial/Design#database-versioning) - this.version(2) - .stores(schema2) - .upgrade(tx => { - // An upgrade function for version 2 will upgrade data based on version 1. - // delete unused attribute - return tx - .table('notification') - .toCollection() - .modify(notif => { - // Modify each friend: - delete notif.time; - delete notif.message; - }); - }); - } - - getStore(name) { - const store = this[name]; - return store; - } -} - -export default new LocalDbFactory('Pearl'); diff --git a/src/indexedbb/services/allTables-idb-service.js b/src/indexedbb/services/allTables-idb-service.js deleted file mode 100644 index e020745d7..000000000 --- a/src/indexedbb/services/allTables-idb-service.js +++ /dev/null @@ -1,12 +0,0 @@ -import Dexie from 'dexie'; -import schema from '../schema.json'; - -const clearAllTables = async () => { - const db = new Dexie('Prisme'); - db.version(1).stores(schema); - await db.open(); - await Promise.all(Object.keys(schema).map(table => db.table(table).clear())); - await db.close(); -}; - -export default clearAllTables; diff --git a/src/utils/functions/surveyUnitFunctions.js b/src/utils/functions/surveyUnitFunctions.js index c0b91b3a9..fffd17d5f 100644 --- a/src/utils/functions/surveyUnitFunctions.js +++ b/src/utils/functions/surveyUnitFunctions.js @@ -4,7 +4,7 @@ import { differenceInYears, formatDistanceStrict } from 'date-fns'; import D from 'i18n'; import { contactOutcomeEnum } from 'utils/enum/ContactOutcomeEnum'; import { convertSUStateInToDo } from 'utils/functions/convertSUStateInToDo'; -import surveyUnitDBService from 'indexedbb/services/surveyUnit-idb-service'; +import surveyUnitDBService from 'utils/indexeddb/services/surveyUnit-idb-service'; import { surveyUnitStateEnum } from 'utils/enum/SUStateEnum'; export const getCommentByType = (type, su) => { diff --git a/src/utils/hooks/database.js b/src/utils/hooks/database.js new file mode 100644 index 000000000..103b778ee --- /dev/null +++ b/src/utils/hooks/database.js @@ -0,0 +1,10 @@ +import { db } from 'utils/indexeddb/idb-config'; +import { useLiveQuery } from 'dexie-react-hooks'; + +// prevent liveQuery from triggering on comments changes +export const useSurveyUnit = id => useLiveQuery(async () => await db.surveyUnit.get(id)); + +export const useSurveyUnits = () => useLiveQuery(() => db.surveyUnit.toArray(), [], []); + +export const useMissingSurveyUnits = () => + useLiveQuery(() => db.surveyUnitMissing.toArray(), [], []); diff --git a/src/utils/hooks/listenQueen.js b/src/utils/hooks/listenQueen.js index 315350be0..03054c53a 100644 --- a/src/utils/hooks/listenQueen.js +++ b/src/utils/hooks/listenQueen.js @@ -1,6 +1,6 @@ import { addNewState } from 'utils/functions/surveyUnitFunctions'; import questionnaireEnum from 'utils/enum/QuestionnaireStateEnum'; -import surveyUnitDBService from 'indexedbb/services/surveyUnit-idb-service'; +import surveyUnitDBService from 'utils/indexeddb/services/surveyUnit-idb-service'; import { surveyUnitStateEnum } from 'utils/enum/SUStateEnum'; import { useEffect } from 'react'; diff --git a/src/utils/indexeddb/idb-config.js b/src/utils/indexeddb/idb-config.js new file mode 100644 index 000000000..7cfd43bc4 --- /dev/null +++ b/src/utils/indexeddb/idb-config.js @@ -0,0 +1,22 @@ +import Dexie from 'dexie'; +import schema from './schema.json'; +import schema2 from './schema-2.json'; + +export const db = new Dexie('Pearl'); + +db.version(1).stores(schema); +// upgrade dataBase (please see https://dexie.org/docs/Tutorial/Design#database-versioning) +db.version(2) + .stores(schema2) + .upgrade(tx => { + // An upgrade function for version 2 will upgrade data based on version 1. + // delete unused attribute + return tx + .table('notification') + .toCollection() + .modify(notif => { + // Modify each friend: + delete notif.time; + delete notif.message; + }); + }); diff --git a/src/indexedbb/schema-2.json b/src/utils/indexeddb/schema-2.json similarity index 100% rename from src/indexedbb/schema-2.json rename to src/utils/indexeddb/schema-2.json diff --git a/src/indexedbb/schema.json b/src/utils/indexeddb/schema.json similarity index 100% rename from src/indexedbb/schema.json rename to src/utils/indexeddb/schema.json diff --git a/src/indexedbb/services/abstract-idb-service.js b/src/utils/indexeddb/services/abstract-idb-service.js similarity index 87% rename from src/indexedbb/services/abstract-idb-service.js rename to src/utils/indexeddb/services/abstract-idb-service.js index 8b6b26530..ecfb17355 100644 --- a/src/indexedbb/services/abstract-idb-service.js +++ b/src/utils/indexeddb/services/abstract-idb-service.js @@ -1,8 +1,8 @@ -import initIDB from '../idb-config'; +import { db } from '../idb-config'; export default class AbstractIdbService { constructor(store) { - this.store = initIDB.getStore(store); + this.store = db[store]; } get(id) { @@ -10,7 +10,7 @@ export default class AbstractIdbService { } getById(id) { - return this.store.get({ id: `${id}` }); + return this.store.get(id); } getAll() { diff --git a/src/indexedbb/services/notification-idb-service.js b/src/utils/indexeddb/services/notification-idb-service.js similarity index 100% rename from src/indexedbb/services/notification-idb-service.js rename to src/utils/indexeddb/services/notification-idb-service.js diff --git a/src/indexedbb/services/surveyUnit-idb-service.js b/src/utils/indexeddb/services/surveyUnit-idb-service.js similarity index 100% rename from src/indexedbb/services/surveyUnit-idb-service.js rename to src/utils/indexeddb/services/surveyUnit-idb-service.js diff --git a/src/indexedbb/services/surveyUnitMissing-idb-service.js b/src/utils/indexeddb/services/surveyUnitMissing-idb-service.js similarity index 100% rename from src/indexedbb/services/surveyUnitMissing-idb-service.js rename to src/utils/indexeddb/services/surveyUnitMissing-idb-service.js diff --git a/src/indexedbb/services/syncReport-idb-service.js b/src/utils/indexeddb/services/syncReport-idb-service.js similarity index 100% rename from src/indexedbb/services/syncReport-idb-service.js rename to src/utils/indexeddb/services/syncReport-idb-service.js diff --git a/src/utils/synchronize/check.js b/src/utils/synchronize/check.js index 0620088d5..93b7f558d 100644 --- a/src/utils/synchronize/check.js +++ b/src/utils/synchronize/check.js @@ -1,10 +1,12 @@ -import surveyUnitMissingIdbService from 'indexedbb/services/surveyUnitMissing-idb-service'; -import surveyUnitIdbService from 'indexedbb/services/surveyUnit-idb-service'; -import notificationIdbService from 'indexedbb/services/notification-idb-service'; -import syncReportIdbService from 'indexedbb/services/syncReport-idb-service'; -import { NOTIFICATION_TYPE_SYNC, PEARL_USER_KEY } from 'utils/constants'; import * as api from 'utils/api'; + +import { NOTIFICATION_TYPE_SYNC, PEARL_USER_KEY } from 'utils/constants'; + import D from 'i18n'; +import notificationIdbService from 'utils/indexeddb/services/notification-idb-service'; +import surveyUnitIdbService from 'utils/indexeddb/services/surveyUnit-idb-service'; +import surveyUnitMissingIdbService from 'utils/indexeddb/services/surveyUnitMissing-idb-service'; +import syncReportIdbService from 'utils/indexeddb/services/syncReport-idb-service'; export const checkSyncResult = (pearlSuccess, queenSuccess) => { if (pearlSuccess && queenSuccess) { diff --git a/src/utils/synchronize/index.js b/src/utils/synchronize/index.js index 0fb72d017..ac63aab8e 100644 --- a/src/utils/synchronize/index.js +++ b/src/utils/synchronize/index.js @@ -3,8 +3,8 @@ import * as api from 'utils/api'; import { useCallback, useState } from 'react'; import { getLastState } from 'utils/functions'; -import surveyUnitDBService from 'indexedbb/services/surveyUnit-idb-service'; -import surveyUnitMissingIdbService from 'indexedbb/services/surveyUnitMissing-idb-service'; +import surveyUnitDBService from 'utils/indexeddb/services/surveyUnit-idb-service'; +import surveyUnitMissingIdbService from 'utils/indexeddb/services/surveyUnitMissing-idb-service'; import { surveyUnitStateEnum } from 'utils/enum/SUStateEnum'; import { useHistory } from 'react-router-dom'; diff --git a/yarn.lock b/yarn.lock index 1e40ac639..7361c780c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3522,15 +3522,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001027: - version "1.0.30001028" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001028.tgz#f2241242ac70e0fa9cda55c2776d32a0867971c2" - integrity sha512-Vnrq+XMSHpT7E+LWoIYhs3Sne8h9lx9YJV3acH3THNCwU/9zV93/ta4xVfzTtnqd3rvnuVpVjE3DFqf56tr3aQ== - -caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001181: - version "1.0.30001205" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001205.tgz#d79bf6a6fb13196b4bb46e5143a22ca0242e0ef8" - integrity sha512-TL1GrS5V6LElbitPazidkBMD9sa448bQDDLrumDqaggmKFcuU2JW1wTOHJPukAcOMtEmLcmDJEzfRrf+GjM0Og== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001027, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001181: + version "1.0.30001320" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001320.tgz" + integrity sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA== capture-exit@^2.0.0: version "2.0.0" @@ -4548,10 +4543,20 @@ detect-port-alt@1.1.6: address "^1.0.1" debug "^2.6.0" -dexie@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/dexie/-/dexie-2.0.4.tgz#6027a5e05879424e8f9979d8c14e7420f27e3a11" - integrity sha512-aQ/s1U2wHxwBKRrt2Z/mwFNHMQWhESerFsMYzE+5P5OsIe5o1kgpFMWkzKTtkvkyyEni6mWr/T4HUJuY9xIHLA== +dexie-export-import@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/dexie-export-import/-/dexie-export-import-1.0.3.tgz#e93926a0a3939c68f5e2b80b48517ea4c6d88fde" + integrity sha512-oun27bUUEaeOfSZ8Cv3Nvj5s0LeANYBYQ7ROpF/3Zg1X/IALUnrX0hk5ZUMlYC3s99kFHimXX57ac5AlOdMzWw== + +dexie-react-hooks@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/dexie-react-hooks/-/dexie-react-hooks-1.1.1.tgz#ff405cc89e5d899ddbac5e40d593f83f9a74106a" + integrity sha512-Cam5JP6PxHN564RvWEoe8cqLhosW0O4CAZ9XEVYeGHJBa6KEJlOpd9CUpV3kmU9dm2MrW97/lk7qkf1xpij7gA== + +dexie@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/dexie/-/dexie-3.2.1.tgz#ef21456d725e700c1ab7ac4307896e4fdabaf753" + integrity sha512-Y8oz3t2XC9hvjkP35B5I8rUkKKwM36GGRjWQCMjzIYScg7W+GHKDXobSYswkisW7CxL1/tKQtggMDsiWqDUc1g== diff-sequences@^26.6.2: version "26.6.2" @@ -4727,6 +4732,11 @@ dotenv@8.2.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== +downloadjs@^1.4.7: + version "1.4.7" + resolved "https://registry.yarnpkg.com/downloadjs/-/downloadjs-1.4.7.tgz#f69f96f940e0d0553dac291139865a3cd0101e3c" + integrity sha1-9p+W+UDg0FU9rCkROYZaPNAQHjw= + duplexer@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"