diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c0ddd3da..836c3fcfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [11.8.0](https://github.com/hopetambala/puente-reactnative-collect/compare/v11.7.12...v11.8.0) (2021-07-05) + + +### Bug fixes + +* keyboard automatically dismissing when entering ([b763f2a](https://github.com/hopetambala/puente-reactnative-collect/commit/b763f2a7ca9ea5d86d0e44ab94af6427cb147fd4)) +* Pinned Form Translation bug fix ([746de57](https://github.com/hopetambala/puente-reactnative-collect/commit/746de577589d315b472b81c3ee04d800d3833127)) +* user not switching when entering data collection epic ([3ba829b](https://github.com/hopetambala/puente-reactnative-collect/commit/3ba829ba1f41e92a74e54c5df646d3656aad1e3b)) + +### [11.7.12](https://github.com/hopetambala/puente-reactnative-collect/compare/v11.7.11...v11.7.12) (2021-07-03) + + +### Bug fixes + +* logging of session for user and refactor of custom forms function ([b52e7b2](https://github.com/hopetambala/puente-reactnative-collect/commit/b52e7b26c75d1c801349ce72f2f6a5b6eb69a3cd)) + +### [11.7.11](https://github.com/hopetambala/puente-reactnative-collect/compare/v11.7.10...v11.7.11) (2021-07-03) + + +### Bug fixes + +* forms not changing when user switch organizations or users ([3fa581b](https://github.com/hopetambala/puente-reactnative-collect/commit/3fa581b3a540a23a41356665385eaf5ff0b772d4)) + +### [11.7.10](https://github.com/hopetambala/puente-reactnative-collect/compare/v11.7.9...v11.7.10) (2021-07-01) + ### [11.7.9](https://github.com/hopetambala/puente-reactnative-collect/compare/v11.7.8...v11.7.9) (2021-06-13) ### [11.7.8](https://github.com/hopetambala/puente-reactnative-collect/compare/v11.7.7...v11.7.8) (2021-06-12) diff --git a/app.json b/app.json index 682e029a0..97bd6df49 100644 --- a/app.json +++ b/app.json @@ -7,7 +7,7 @@ "android", "web" ], - "version": "11.7.9", + "version": "11.8.2", "orientation": "portrait", "icon": "./assets/images/icon.png", "scheme": "myapp", @@ -23,7 +23,7 @@ ], "ios": { "supportsTablet": true, - "buildNumber": "11.7.9", + "buildNumber": "11.8.2", "infoPlist": { "NSLocationWhenInUseUsageDescription": "This app uses your location to geo-tag surveys accurately." }, @@ -34,7 +34,7 @@ "favicon": "./assets/images/favicon.png" }, "android": { - "versionCode": 410110709, + "versionCode": 410110802, "permissions": [ "ACCESS_COARSE_LOCATION", "ACCESS_FINE_LOCATION", diff --git a/components/Cards/SmallCardsCarousel/index.js b/components/Cards/SmallCardsCarousel/index.js index afcff3169..b3d53b756 100644 --- a/components/Cards/SmallCardsCarousel/index.js +++ b/components/Cards/SmallCardsCarousel/index.js @@ -7,9 +7,6 @@ import { Card, Text } from 'react-native-paper'; -import MedEvalSVG from '../../../assets/icons/Heart-Icon.svg'; -import EnvSVG from '../../../assets/icons/Home-icon.svg'; -import NewRecordSVG from '../../../assets/icons/New-Record-icon.svg'; import I18n from '../../../modules/i18n'; import { theme } from '../../../modules/theme'; @@ -49,47 +46,15 @@ const SmallCardsCarousel = ({ }} onLongPress={pinForm ? () => pinForm(form) : null} > - {form.tag === 'id' && ( - - - - - {I18n.t('cards.smallCards.residentID')} - - + + + + + {I18n.t(form.name)} + - )} + - {form.tag === 'env' && ( - - - - - {`${I18n.t('cards.smallCards.environmental')} ${I18n.t('cards.smallCards.history')}`} - - - - )} - {form.tag === 'med-eval' && ( - - - - - {`${I18n.t('cards.smallCards.medical')} ${I18n.t('cards.smallCards.evaluation')}`} - - - - )} - {form.tag === 'vitals' && ( - - - - - {I18n.t('cards.smallCards.vitals')} - - - - )} ))} diff --git a/components/Text/index.js b/components/Text/index.js index 8ec0df469..3c958a89c 100644 --- a/components/Text/index.js +++ b/components/Text/index.js @@ -6,4 +6,4 @@ import { Text } from 'react-native'; export default function MonoText(props) { const { style } = props; return ; -} +} \ No newline at end of file diff --git a/domains/Auth/SignIn/index.js b/domains/Auth/SignIn/index.js index 0de3012d1..45da285a5 100644 --- a/domains/Auth/SignIn/index.js +++ b/domains/Auth/SignIn/index.js @@ -92,9 +92,10 @@ const SignIn = ({ navigation }) => { navigation.navigate('Sign Up'); }; - const handleSignIn = async () => { + const handleSignIn = async (values, callback) => { + if (callback) callback(); Keyboard.dismiss(); - navigation.navigate('Root'); + navigation.navigate('Root', values); }; const handleSaveCredentials = (currentUser, values) => { @@ -119,7 +120,7 @@ const SignIn = ({ navigation }) => { text: 'No', style: 'cancel', onPress: () => { - navigation.navigate('Root'); + handleSignIn(values); } }, ], @@ -165,19 +166,17 @@ const SignIn = ({ navigation }) => { retrieveSignInFunction(values.username, values.password) .then((currentUser) => { storeUserInformation(currentUser, values); - getData('currentUser').then((userCreds) => { + getData('currentUser').then(async (userCreds) => { // credentials stored do not match those entered through sign-in, overwrite if (userCreds === null || userCreds.store === 'No' || values.username !== userCreds.username || values.password !== userCreds.password) { // Store user organization - storeUserInformation(currentUser, values); handleSaveCredentials(currentUser, values); } else { storeUserInformation(currentUser); - handleSignIn(values, actions.resetForm()); + await handleSignIn(values, actions.resetForm); } }, () => { - storeUserInformation(currentUser, values); handleSaveCredentials(currentUser, values); }); }, (err) => { @@ -185,12 +184,12 @@ const SignIn = ({ navigation }) => { }); } else { // offline - getData('currentUser').then((userCreds) => { + getData('currentUser').then(async (userCreds) => { // username and password entered (or saved in creds) match the saved cred if (values.username === userCreds.username && values.password === userCreds.password) { // need some pincode verification - handleSignIn(values, actions.resetForm()); + await handleSignIn(values, actions.resetForm); } else { // incorrect usernmae/password offline handleFailedAttempt(); diff --git a/domains/DataCollection/FormGallery/index.js b/domains/DataCollection/FormGallery/index.js index 7c1d7ab45..c2606c2c4 100644 --- a/domains/DataCollection/FormGallery/index.js +++ b/domains/DataCollection/FormGallery/index.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { ScrollView, View @@ -11,16 +11,45 @@ import { import ComingSoonSVG from '../../../assets/graphics/static/Adventurer.svg'; import SmallCardsCarousel from '../../../components/Cards/SmallCardsCarousel'; +import { getData, storeData } from '../../../modules/async-storage'; +import { customFormsQuery } from '../../../modules/cached-resources'; import I18n from '../../../modules/i18n'; import { layout, theme } from '../../../modules/theme'; import styles from './index.styles'; -const FormGallery = (props) => { - const { - navigateToNewRecord, puenteForms, - navigateToCustomForm, customForms, refreshCustomForms, - pinnedForms, pinForm, removePinnedForm - } = props; +const FormGallery = ({ + navigateToNewRecord, navigateToCustomForm, + puenteForms, + pinnedForms, setPinnedForms, + setLoading, surveyingOrganization +}) => { + const [customForms, setCustomForms] = useState([]); + + useEffect(() => { + getData('customForms').then((forms) => { + setCustomForms(forms); + }); + }, [customForms]); + + const refreshCustomForms = () => { + setLoading(true); + customFormsQuery(surveyingOrganization).then((forms) => { + setCustomForms(forms); + setLoading(false); + }); + }; + + const pinForm = async (form) => { + setPinnedForms([...pinnedForms, form]); + storeData(pinnedForms, 'pinnedForms'); + }; + + const removePinnedForm = async (form) => { + const filteredPinnedForms = pinnedForms.filter((pinnedForm) => pinnedForm !== form); + setPinnedForms(filteredPinnedForms); + storeData(filteredPinnedForms, 'pinnedForms'); + }; + return ( @@ -36,10 +65,14 @@ const FormGallery = (props) => { }} onLongPress={() => removePinnedForm(form)} > + + {form.image !== undefined && ( + + )} - {form.name} + { form.customForm === false ? I18n.t(form.name) : form.name} diff --git a/domains/DataCollection/Forms/IdentificationForm/index.js b/domains/DataCollection/Forms/IdentificationForm/index.js index 4b87120bb..08b234678 100644 --- a/domains/DataCollection/Forms/IdentificationForm/index.js +++ b/domains/DataCollection/Forms/IdentificationForm/index.js @@ -38,7 +38,7 @@ const IdentificationForm = ({ return ( - + { @@ -48,7 +48,7 @@ const IdentificationForm = ({ const formObject = values; const user = await getData('currentUser'); - formObject.surveyingOrganization = surveyingOrganization; + formObject.surveyingOrganization = surveyingOrganization || user.organization; formObject.surveyingUser = await surveyingUserFailsafe(user, surveyingUser, isEmpty); formObject.appVersion = await getData('appVersion'); diff --git a/domains/DataCollection/Forms/SupplementaryForm/index.js b/domains/DataCollection/Forms/SupplementaryForm/index.js index fd5b10b45..ef4cd7105 100644 --- a/domains/DataCollection/Forms/SupplementaryForm/index.js +++ b/domains/DataCollection/Forms/SupplementaryForm/index.js @@ -61,7 +61,7 @@ const SupplementaryForm = ({ const user = await getData('currentUser'); formObject.surveyingUser = await surveyingUserFailsafe(user, surveyingUser, isEmpty); - formObject.surveyingOrganization = surveyingOrganization; + formObject.surveyingOrganization = surveyingOrganization || user.organization; formObject.appVersion = await getData('appVersion'); let formObjectUpdated = addSelectTextInputs(values, formObject); diff --git a/domains/DataCollection/Forms/index.js b/domains/DataCollection/Forms/index.js index 7ef2e9b18..7b2157704 100644 --- a/domains/DataCollection/Forms/index.js +++ b/domains/DataCollection/Forms/index.js @@ -43,7 +43,7 @@ const Forms = (props) => { )} {consent === true && selectedForm !== 'id' && selectedForm !== '' && ( - + { const [scrollViewScroll, setScrollViewScroll] = useState(); - const [view, setView] = useState('Root'); + const [loading, setLoading] = useState(false); const [settings, setSettings] = useState(false); + + const [view, setView] = useState('Root'); + const [selectedForm, setSelectedForm] = useState('id'); const [selectedAsset, setSelectedAsset] = useState(null); - const [customForms, setCustomForms] = useState([]); - const [pinnedForms, setPinnedForms] = useState([]); const [customForm, setCustomForm] = useState(); + const [pinnedForms, setPinnedForms] = useState([]); const [selectPerson, setSelectPerson] = useState(); const [surveyee, setSurveyee] = useState({}); @@ -50,98 +63,58 @@ const DataCollection = ({ navigation }) => { const [surveyingOrganization, setSurveyingOrganization] = useState(''); const [surveyingUser, setSurveyingUser] = useState(); - useEffect(() => { - getData('currentUser').then((user) => { - setSurveyingUser(`${user.firstname || ''} ${user.lastname || ''}`); - }); - getData('organization').then((org) => { - setSurveyingOrganization(org || surveyingOrganization); - }).catch(() => { - setSurveyingOrganization(surveyingOrganization || ''); - }); - getData('customForms').then((forms) => { - setCustomForms(forms); - }); - getData('pinnedForms').then((forms) => { - if (forms) setPinnedForms(forms); - }); - }, [surveyingUser, surveyingOrganization]); + useFocusEffect( + useCallback(() => { + const fetchData = async () => { + getData('currentUser').then((user) => { + setSurveyingUser(`${user.firstname || ''} ${user.lastname || ''}`); + setSurveyingOrganization(user.organization || surveyingOrganization); + }); + getData('pinnedForms').then((forms) => { + if (forms) setPinnedForms(forms); + }); + }; + + fetchData(); + }, [surveyingUser, surveyingOrganization]) + ); const navigateToRoot = async () => { setView('Root'); }; const navigateToNewRecord = async (formTag, surveyeePerson) => { - await getData('organization').then((org) => { - setSurveyingOrganization(org || surveyingOrganization || ''); - setView('Forms'); - setSurveyee(surveyeePerson || surveyee); - setSelectedForm(formTag || 'id'); - }); + setView('Forms'); + setSurveyee(surveyeePerson || surveyee); + setSelectedForm(formTag || 'id'); }; const navigateToGallery = async () => { - await getData('organization').then((org) => { - setSurveyingOrganization(org || surveyingOrganization || ''); - setView('Gallery'); - }); + setView('Gallery'); }; const navigateToNewAssets = async () => { - await getData('organization').then((org) => { - setSurveyingOrganization(org || surveyingOrganization || ''); - setView('Assets'); - setSelectedAsset({}); - }); + setView('Assets'); + setSelectedAsset({}); }; const navigateToViewAllAssets = async () => { - await getData('organization').then((org) => { - setSurveyingOrganization(org || surveyingOrganization || ''); - setView('Assets'); - setSelectedAsset(null); - }); + setView('Assets'); + setSelectedAsset(null); }; const navigateToCustomForm = async (form, surveyeePerson) => { - await getData('organization').then((org) => { - setSurveyingOrganization(org || surveyingOrganization || ''); - setView('Forms'); - setSurveyee(surveyeePerson || surveyee); - setSelectedForm('custom'); - setCustomForm(form || ''); - }); + setView('Forms'); + setSurveyee(surveyeePerson || surveyee); + setSelectedForm('custom'); + setCustomForm(form || ''); }; const navigateToFindRecords = async () => { - await getData('organization').then((org) => { - setSurveyingOrganization(org || surveyingOrganization || ''); - setView('Find Records'); - }); + setView('Find Records'); }; - const refreshCustomForms = async () => { - customFormsQuery(surveyingOrganization).then((forms) => { - setCustomForms(forms); - }); - }; - - const pinForm = async (form) => { - setPinnedForms([...pinnedForms, form]); - storeData(pinnedForms, 'pinnedForms'); - }; - - const removePinnedForm = async (form) => { - const filteredPinnedForms = pinnedForms.filter((pinnedForm) => pinnedForm !== form); - setPinnedForms(filteredPinnedForms); - storeData(filteredPinnedForms, 'pinnedForms'); - }; - - const logOut = () => { - retrieveSignOutFunction().then(() => { - navigation.navigate('Sign In'); - }); - }; + const logOut = () => retrieveSignOutFunction().then(() => navigation.navigate('Sign In')); return ( { }} >
{ behavior={Platform.OS === 'ios' ? 'padding' : 'height'} style={{ flex: 1 }} > + {loading === true + && } {settings === true ? ( { navigateToNewRecord={navigateToNewRecord} puenteForms={puenteForms} navigateToCustomForm={navigateToCustomForm} - customForms={customForms} - refreshCustomForms={refreshCustomForms} + setLoading={setLoading} + surveyingOrganization={surveyingOrganization} pinnedForms={pinnedForms} - removePinnedForm={removePinnedForm} - pinForm={pinForm} + setPinnedForms={setPinnedForms} /> )} diff --git a/domains/HomeScreen/index.js b/domains/HomeScreen/index.js index 5d5ae82af..8961a67ab 100644 --- a/domains/HomeScreen/index.js +++ b/domains/HomeScreen/index.js @@ -9,15 +9,13 @@ import { import ComingSoonSVG from '../../assets/graphics/static/Adventurer.svg'; import Header from '../../components/Header'; -import { deleteData } from '../../modules/async-storage'; import { getTasksAsync } from '../../modules/cached-resources'; import I18n from '../../modules/i18n'; import { layout } from '../../modules/theme'; -import { retrieveSignOutFunction } from '../../services/parse/auth'; -const HomeScreen = (props) => { +const HomeScreen = () => { const [tasks, setTasks] = useState(null); - const { navigation } = props; + // const { navigation } = props; const showTasks = async () => { await getTasksAsync().then((result) => { @@ -25,18 +23,9 @@ const HomeScreen = (props) => { }); }; - const logOut = () => { - retrieveSignOutFunction().then(() => { - deleteData('pincode'); - deleteData('organization'); - deleteData('currentUser'); - navigation.navigate('Sign In'); - }); - }; - return ( -
+
{I18n.t('home.myTasks')} @@ -69,9 +58,6 @@ const HomeScreen = (props) => { */} - ); diff --git a/modules/cached-resources/populate-cache.js b/modules/cached-resources/populate-cache.js index 8a2181d14..36dde252a 100644 --- a/modules/cached-resources/populate-cache.js +++ b/modules/cached-resources/populate-cache.js @@ -12,7 +12,7 @@ export default function populateCache(user, expoToken) { cacheAutofillData('Communities') .then(async () => { const currentUserAsync = await getData('currentUser'); - const currentOrgAsync = await getData('organization'); + const currentOrgAsync = await getData('currentUser').then((currentUser) => currentUser.organization); // store information after sign up/sign in if (user) { if (user !== currentUserAsync) { diff --git a/modules/cached-resources/read.js b/modules/cached-resources/read.js index cfe85a49f..a6f37f7bb 100644 --- a/modules/cached-resources/read.js +++ b/modules/cached-resources/read.js @@ -57,37 +57,24 @@ async function cacheAutofillData(parameter) { } function customFormsQuery(surveyingOrganization) { - return new Promise((resolve, reject) => { - checkOnlineStatus().then((online) => { - if (online) { - const parseParams = { - typeOfForm: 'Custom', - organizations: surveyingOrganization - }; - customMultiParamQueryService(5000, 'FormSpecificationsV2', parseParams).then(async (forms) => { - if (forms !== null && forms !== undefined && forms !== '') { - await storeData(forms, 'customForms'); - resolve(JSON.parse(JSON.stringify(forms))); - } else { - getData('customForms').then((customForms) => { - resolve(customForms); - }, (error) => { - reject(error); - }); - } - }, (error) => { - reject(error); - }); - } else { - getData('customForms').then((forms) => { - resolve(forms); - }, (error) => { - reject(error); - }); - } - }, (error) => { - reject(error); - }); + return checkOnlineStatus().then((online) => { + if (online) { + const parseParams = { + typeOfForm: 'Custom', + organizations: surveyingOrganization + }; + + return customMultiParamQueryService(5000, 'FormSpecificationsV2', parseParams).then(async (forms) => { + if (forms !== null && forms !== undefined && forms !== '') { + await storeData(forms, 'customForms'); + return JSON.parse(JSON.stringify(forms)); + } + return getData('customForms').then((customForms) => customForms); + }, (error) => { + console.log(error); //eslint-disable-line + }); + } + return getData('customForms').then((forms) => forms, (error) => console.log(error)); // eslint-disable-line }); } diff --git a/modules/i18n/english/en.json b/modules/i18n/english/en.json index 1a5bf250e..944e7bf55 100644 --- a/modules/i18n/english/en.json +++ b/modules/i18n/english/en.json @@ -519,5 +519,11 @@ }, "assetFormSelect": { "supAssetForms": "Supplementary Asset Forms" + }, + "puenteForms":{ + "ResidentID": "Resident ID", + "EnvironmentalHealth": "Environmental Health", + "MedicalEvaluation": "Medical Evaluation", + "Vitals": "Vitals" } } \ No newline at end of file diff --git a/modules/i18n/spanish/es.json b/modules/i18n/spanish/es.json index 1e1a31cad..f54f1fb24 100644 --- a/modules/i18n/spanish/es.json +++ b/modules/i18n/spanish/es.json @@ -519,5 +519,11 @@ }, "assetFormSelect": { "supAssetForms": "Formularios de activos suplementarios" + }, + "puenteForms":{ + "ResidentID": "Identificación de residente", + "EnvironmentalHealth": "Salud Ambiental", + "MedicalEvaluation": "Evaluación Médica", + "Vitals": "Partes vitales" } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 88a12cd14..413f96253 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40913,4 +40913,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index f82bdfe2e..5b90ffa66 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "puente-reactnative", - "version": "11.7.9", + "version": "11.8.2", "main": "node_modules/expo/AppEntry.js", "scripts": { "start": "expo start", diff --git a/services/parse/auth/index.js b/services/parse/auth/index.js index c91edbe73..d43448fd4 100644 --- a/services/parse/auth/index.js +++ b/services/parse/auth/index.js @@ -35,14 +35,11 @@ function retrieveSignInFunction(username, password) { }); } -function retrieveSignOutFunction() { - return new Promise((resolve, reject) => { - Parse.User.logOut().then((result) => { - resolve(result); - }, (error) => { - reject(error); +async function retrieveSignOutFunction() { + return Parse.User.logOut() + .catch((error) => { + console.log(error.message); //eslint-disable-line }); - }); } function retrieveForgotPasswordFunction(params) {