From a697e6d4b03be50eb6e88d3451376b70348b737d Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Thu, 20 May 2021 15:10:15 -0300 Subject: [PATCH 01/14] Button on admin page brings users to CreateOrganizationPage.js --- frontend/src/AdminPage.js | 16 +- frontend/src/App.js | 8 + frontend/src/CreateOrganizationPage.js | 321 +++++++++++++++++++++++++ frontend/src/graphql/mutations.js | 48 ++++ 4 files changed, 391 insertions(+), 2 deletions(-) create mode 100644 frontend/src/CreateOrganizationPage.js diff --git a/frontend/src/AdminPage.js b/frontend/src/AdminPage.js index 2d66adb463..6f34d5452c 100644 --- a/frontend/src/AdminPage.js +++ b/frontend/src/AdminPage.js @@ -1,5 +1,5 @@ import React, { useState } from 'react' -import { Stack, Text, Select, useToast } from '@chakra-ui/core' +import { Stack, Text, Select, useToast, Icon } from '@chakra-ui/core' import { Trans, t } from '@lingui/macro' import { Layout } from './Layout' import AdminPanel from './AdminPanel' @@ -8,6 +8,8 @@ import { useQuery } from '@apollo/client' import { useUserState } from './UserState' import { ErrorFallbackMessage } from './ErrorFallbackMessage' import { LoadingMessage } from './LoadingMessage' +import { TrackerButton } from './TrackerButton' +import { Link as RouteLink } from 'react-router-dom' export default function AdminPage() { const { currentUser } = useUserState() @@ -86,7 +88,7 @@ export default function AdminPage() { Welcome, Admin - + Organization: @@ -101,6 +103,16 @@ export default function AdminPage() { > {options} + + + Create Organization + {options.length > 1 && orgDetails ? ( diff --git a/frontend/src/App.js b/frontend/src/App.js index 02fa6e4d3f..26f03577d3 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -36,6 +36,7 @@ const TwoFactorAuthenticatePage = lazy(() => import('./TwoFactorAuthenticatePage'), ) const EmailValidationPage = lazy(() => import('./EmailValidationPage')) +const CreateOrganizationPage = lazy(() => import('./CreateOrganizationPage')) export default function App() { // Hooks to be used with this functional component @@ -203,6 +204,13 @@ export default function App() { + + + + diff --git a/frontend/src/CreateOrganizationPage.js b/frontend/src/CreateOrganizationPage.js new file mode 100644 index 0000000000..2ba47dfba8 --- /dev/null +++ b/frontend/src/CreateOrganizationPage.js @@ -0,0 +1,321 @@ +import React from 'react' +import { + Stack, + useToast, + Box, + Button, + Heading, + Input, + Text, +} from '@chakra-ui/core' +import { Trans, t } from '@lingui/macro' +import { Layout } from './Layout' +import { CREATE_ORGANIZATION } from './graphql/mutations' +import { useMutation } from '@apollo/client' +import { useUserState } from './UserState' +import { LoadingMessage } from './LoadingMessage' +import { Formik } from 'formik' +import { useHistory, Link as RouteLink } from 'react-router-dom' +import { TrackerButton } from './TrackerButton' +import { object, string } from 'yup' +import { i18n } from '@lingui/core' + +export default function CreateOrganizationPage() { + const { currentUser } = useUserState() + const toast = useToast() + const history = useHistory() + + const validationSchema = object().shape({ + nameEN: string(), + }) + + const [createOrganization, { loading }] = useMutation(CREATE_ORGANIZATION, { + context: { + headers: { + authorization: currentUser.jwt, + }, + }, + onError(error) { + toast({ + title: t`An error occurred.`, + description: error.message, + status: 'error', + duration: 9000, + isClosable: true, + position: 'top-left', + }) + }, + onCompleted({ createOrganization }) { + if (createOrganization.result.__typename === 'Organization') { + toast({ + title: t`Organization created`, + description: t`${createOrganization.result.slug} was created`, + status: 'success', + duration: 9000, + isClosable: true, + position: 'top-left', + }) + history.push('/admin') + } else if (createOrganization.result.__typename === 'OrganizationError') { + toast({ + title: t`Unable to create new organization.`, + description: createOrganization.result.description, + status: 'error', + duration: 9000, + isClosable: true, + position: 'top-left', + }) + } else { + toast({ + title: t`Incorrect send method received.`, + description: t`Incorrect createOrganization.result typename.`, + status: 'error', + duration: 9000, + isClosable: true, + position: 'top-left', + }) + console.log('Incorrect createOrganization.result typename.') + } + }, + }) + + if (loading) return + + return ( + + + { + // createOrganization({ + // variables: { + // acronymEN: values.acronymEN, + // acronymFR: values.acronymFR, + // nameEN: values.nameEN, + // nameFR: values.nameFR, + // zoneEN: values.zoneEN, + // zoneFR: values.zoneFR, + // sectorEN: values.sectorEN, + // sectorFR: values.sectorFR, + // countryEN: values.countryEN, + // countryFR: values.countryFR, + // provinceEN: values.provinceEN, + // provinceFR: values.provinceFR, + // cityEN: values.cityEN, + // cityFR: values.cityFR, + // }, + // }) + window.alert(JSON.stringify(values)) + }} + > + {({ + handleSubmit, + handleBlur, + handleChange, + values, + isSubmitting, + }) => ( +
+ + + Create an account by entering an email and password. + + + + + + Name: + + + + + + + + Acronym: + + + + + + + + Zone: + + + + + + + + Sector: + + + + + + + + City: + + + + + + + + Province: + + + + + + + + Country: + + + + + + + + Create Organization + + + + +
+ )} +
+
+
+ ) +} diff --git a/frontend/src/graphql/mutations.js b/frontend/src/graphql/mutations.js index c277ef3053..6553fa050e 100644 --- a/frontend/src/graphql/mutations.js +++ b/frontend/src/graphql/mutations.js @@ -372,4 +372,52 @@ export const VERIFY_ACCOUNT = gql` } ` +export const CREATE_ORGANIZATION = gql` + mutation CreateOrganization( + $acronymEN: Acronym! + $acronymFR: Acronym! + $nameEN: String! + $nameFR: String! + $zoneEN: String! + $zoneFR: String! + $sectorEN: String! + $sectorFR: String! + $countryEN: String! + $countryFR: String! + $provinceEN: String! + $provinceFR: String! + $cityEN: String! + $cityFR: String! + ) { + createOrganization( + input: { + acronymEN: $acronymEN + acronymFR: $acronymFR + nameEN: $nameEN + nameFR: $nameFR + zoneEN: $zoneEN + zoneFR: $zoneFR + sectorEN: $sectorEN + sectorFR: $sectorFR + countryEN: $countryEN + countryFR: $countryFR + provinceEN: $provinceEN + provinceFR: $provinceFR + cityEN: $cityEN + cityFR: $cityFR + } + ) { + result { + ... on Organization { + slug + } + ... on OrganizationError { + code + description + } + } + } + } +` + export default '' From 2c82b45b00f0ebe60c6ce9b7962c53704c8c939e Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Fri, 21 May 2021 13:42:35 -0300 Subject: [PATCH 02/14] Added FormControl to all input fields, added validation schema for acronyms --- frontend/src/AdminPage.js | 17 +- frontend/src/CreateOrganizationPage.js | 297 +++++++++++++++---------- frontend/src/fieldRequirements.js | 10 + 3 files changed, 206 insertions(+), 118 deletions(-) diff --git a/frontend/src/AdminPage.js b/frontend/src/AdminPage.js index 6f34d5452c..1fa5cb0df1 100644 --- a/frontend/src/AdminPage.js +++ b/frontend/src/AdminPage.js @@ -133,9 +133,20 @@ export default function AdminPage() { ) } else { return ( - - You do not have admin permissions in any organization - + + + You do not have admin permissions in any organization + + + + Create Organization + + ) } } diff --git a/frontend/src/CreateOrganizationPage.js b/frontend/src/CreateOrganizationPage.js index 2ba47dfba8..19b244ff09 100644 --- a/frontend/src/CreateOrganizationPage.js +++ b/frontend/src/CreateOrganizationPage.js @@ -7,6 +7,9 @@ import { Heading, Input, Text, + // FormLabel, + FormControl, + FormErrorMessage, } from '@chakra-ui/core' import { Trans, t } from '@lingui/macro' import { Layout } from './Layout' @@ -19,6 +22,7 @@ import { useHistory, Link as RouteLink } from 'react-router-dom' import { TrackerButton } from './TrackerButton' import { object, string } from 'yup' import { i18n } from '@lingui/core' +import { fieldRequirements } from './fieldRequirements' export default function CreateOrganizationPage() { const { currentUser } = useUserState() @@ -26,7 +30,24 @@ export default function CreateOrganizationPage() { const history = useHistory() const validationSchema = object().shape({ - nameEN: string(), + acronymEN: string() + .matches( + fieldRequirements.acronym.matches.regex, + i18n._(fieldRequirements.acronym.matches.message), + ) + .max( + fieldRequirements.acronym.max.maxLength, + i18n._(fieldRequirements.acronym.max.message), + ), + acronymFR: string() + .matches( + fieldRequirements.acronym.matches.regex, + i18n._(fieldRequirements.acronym.matches.message), + ) + .max( + fieldRequirements.acronym.max.maxLength, + i18n._(fieldRequirements.acronym.max.message), + ), }) const [createOrganization, { loading }] = useMutation(CREATE_ORGANIZATION, { @@ -85,6 +106,7 @@ export default function CreateOrganizationPage() { - Create an account by entering an email and password. + Create an organization by filling out the following info in + both English and French - Name: + Name - - + + + Error! + + + + Error! + Acronym: - - + + + Error! + + + + Error! + Zone: - - + + + Error! + + + + Error! + Sector: - - + + + Error! + + + + Error! + City: - - + + + Error! + + + + Error! + Province: - - + + + Error! + + + + Error! + Country: - - + + + Error! + + + + Error! + diff --git a/frontend/src/fieldRequirements.js b/frontend/src/fieldRequirements.js index 4ca8195f07..a9402aaf08 100644 --- a/frontend/src/fieldRequirements.js +++ b/frontend/src/fieldRequirements.js @@ -35,4 +35,14 @@ export const fieldRequirements = { }, required: { message: t`Phone number field must not be empty` }, }, + acronym: { + matches: { + regex: /^[A-Z]+(?:_[A-Z]+)*$/g, + message: t`Acronyms can only use upper case letters and underscores`, + }, + max: { + maxLength: 50, + message: t`Acronyms must be max 50 characters`, + }, + }, } From 93b866257ea56cf63b019854487c04f0ed18eb80 Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Fri, 21 May 2021 14:00:48 -0300 Subject: [PATCH 03/14] Centered "No admin orgs" screen --- frontend/src/AdminPage.js | 33 ++++++++++++----------- frontend/src/CreateOrganizationPage.js | 37 +++++++++++++------------- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/frontend/src/AdminPage.js b/frontend/src/AdminPage.js index 1fa5cb0df1..808e5fc3cd 100644 --- a/frontend/src/AdminPage.js +++ b/frontend/src/AdminPage.js @@ -1,5 +1,5 @@ import React, { useState } from 'react' -import { Stack, Text, Select, useToast, Icon } from '@chakra-ui/core' +import { Stack, Text, Select, useToast, Icon, Divider } from '@chakra-ui/core' import { Trans, t } from '@lingui/macro' import { Layout } from './Layout' import AdminPanel from './AdminPanel' @@ -133,20 +133,23 @@ export default function AdminPage() { ) } else { return ( - - - You do not have admin permissions in any organization - - - - Create Organization - - + + + + You do not have admin permissions in any organization + + + + + Create Organization + + + ) } } diff --git a/frontend/src/CreateOrganizationPage.js b/frontend/src/CreateOrganizationPage.js index 19b244ff09..b6556b7c23 100644 --- a/frontend/src/CreateOrganizationPage.js +++ b/frontend/src/CreateOrganizationPage.js @@ -124,25 +124,24 @@ export default function CreateOrganizationPage() { countryFR: '', }} onSubmit={async (values) => { - // createOrganization({ - // variables: { - // acronymEN: values.acronymEN, - // acronymFR: values.acronymFR, - // nameEN: values.nameEN, - // nameFR: values.nameFR, - // zoneEN: values.zoneEN, - // zoneFR: values.zoneFR, - // sectorEN: values.sectorEN, - // sectorFR: values.sectorFR, - // countryEN: values.countryEN, - // countryFR: values.countryFR, - // provinceEN: values.provinceEN, - // provinceFR: values.provinceFR, - // cityEN: values.cityEN, - // cityFR: values.cityFR, - // }, - // }) - window.alert(JSON.stringify(values)) + createOrganization({ + variables: { + acronymEN: values.acronymEN, + acronymFR: values.acronymFR, + nameEN: values.nameEN, + nameFR: values.nameFR, + zoneEN: values.zoneEN, + zoneFR: values.zoneFR, + sectorEN: values.sectorEN, + sectorFR: values.sectorFR, + countryEN: values.countryEN, + countryFR: values.countryFR, + provinceEN: values.provinceEN, + provinceFR: values.provinceFR, + cityEN: values.cityEN, + cityFR: values.cityFR, + }, + }) }} > {({ From 18221fe33b41c7680f9ec4e655b61ab54236f80f Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Tue, 25 May 2021 08:37:19 -0300 Subject: [PATCH 04/14] translations --- frontend/src/CreateOrganizationPage.js | 532 ++++++++++++------------- frontend/src/fieldRequirements.js | 2 +- frontend/src/locales/en.po | 60 +++ frontend/src/locales/fr.po | 58 +++ 4 files changed, 373 insertions(+), 279 deletions(-) diff --git a/frontend/src/CreateOrganizationPage.js b/frontend/src/CreateOrganizationPage.js index b6556b7c23..1cddf2d1e5 100644 --- a/frontend/src/CreateOrganizationPage.js +++ b/frontend/src/CreateOrganizationPage.js @@ -7,12 +7,10 @@ import { Heading, Input, Text, - // FormLabel, FormControl, FormErrorMessage, } from '@chakra-ui/core' import { Trans, t } from '@lingui/macro' -import { Layout } from './Layout' import { CREATE_ORGANIZATION } from './graphql/mutations' import { useMutation } from '@apollo/client' import { useUserState } from './UserState' @@ -21,7 +19,6 @@ import { Formik } from 'formik' import { useHistory, Link as RouteLink } from 'react-router-dom' import { TrackerButton } from './TrackerButton' import { object, string } from 'yup' -import { i18n } from '@lingui/core' import { fieldRequirements } from './fieldRequirements' export default function CreateOrganizationPage() { @@ -33,20 +30,20 @@ export default function CreateOrganizationPage() { acronymEN: string() .matches( fieldRequirements.acronym.matches.regex, - i18n._(fieldRequirements.acronym.matches.message), + fieldRequirements.acronym.matches.message, ) .max( fieldRequirements.acronym.max.maxLength, - i18n._(fieldRequirements.acronym.max.message), + fieldRequirements.acronym.max.message, ), acronymFR: string() .matches( fieldRequirements.acronym.matches.regex, - i18n._(fieldRequirements.acronym.matches.message), + fieldRequirements.acronym.matches.message, ) .max( fieldRequirements.acronym.max.maxLength, - i18n._(fieldRequirements.acronym.max.message), + fieldRequirements.acronym.max.message, ), }) @@ -103,285 +100,264 @@ export default function CreateOrganizationPage() { if (loading) return return ( - - - { - createOrganization({ - variables: { - acronymEN: values.acronymEN, - acronymFR: values.acronymFR, - nameEN: values.nameEN, - nameFR: values.nameFR, - zoneEN: values.zoneEN, - zoneFR: values.zoneFR, - sectorEN: values.sectorEN, - sectorFR: values.sectorFR, - countryEN: values.countryEN, - countryFR: values.countryFR, - provinceEN: values.provinceEN, - provinceFR: values.provinceFR, - cityEN: values.cityEN, - cityFR: values.cityFR, - }, - }) - }} - > - {({ - handleSubmit, - handleBlur, - handleChange, - values, - isSubmitting, - }) => ( -
- - - Create an organization by filling out the following info in - both English and French - - + + { + createOrganization({ + variables: { + acronymEN: values.acronymEN, + acronymFR: values.acronymFR, + nameEN: values.nameEN, + nameFR: values.nameFR, + zoneEN: values.zoneEN, + zoneFR: values.zoneFR, + sectorEN: values.sectorEN, + sectorFR: values.sectorFR, + countryEN: values.countryEN, + countryFR: values.countryFR, + provinceEN: values.provinceEN, + provinceFR: values.provinceFR, + cityEN: values.cityEN, + cityFR: values.cityFR, + }, + }) + }} + > + {({ handleSubmit, handleChange, values, isSubmitting }) => ( + + + + Create an organization by filling out the following info in both + English and French + + - - - Name - - - - Error! - - - - Error! - - + + + Name: + + + + Error! + + + + Error! + + - - - Acronym: - - - - Error! - - - - Error! - - + + + Acronym: + + + + Error! + + + + Error! + + - - - Zone: - - - - Error! - - - - Error! - - + + + Zone: + + + + Error! + + + + Error! + + - - - Sector: - - - - Error! - - - - Error! - - + + + Sector: + + + + Error! + + + + Error! + + - - - City: - - - - Error! - - - - Error! - - + + + City: + + + + Error! + + + + Error! + + - - - Province: - - - - Error! - - - - Error! - - + + + Province: + + + + Error! + + + + Error! + + - - - Country: - - - - Error! - - - - Error! - - + + + Country: + + + + Error! + + + + Error! + + - - - Create Organization - + + + Create Organization + - - - - )} - -
-
+ +
+ + )} +
+
) } diff --git a/frontend/src/fieldRequirements.js b/frontend/src/fieldRequirements.js index a9402aaf08..b924923246 100644 --- a/frontend/src/fieldRequirements.js +++ b/frontend/src/fieldRequirements.js @@ -42,7 +42,7 @@ export const fieldRequirements = { }, max: { maxLength: 50, - message: t`Acronyms must be max 50 characters`, + message: t`Acronyms must be at most 50 characters`, }, }, } diff --git a/frontend/src/locales/en.po b/frontend/src/locales/en.po index e627d13e20..42a4d583f9 100644 --- a/frontend/src/locales/en.po +++ b/frontend/src/locales/en.po @@ -168,6 +168,7 @@ msgstr "An error occurred while verifying your phone number." #: src/UserList.js:136 #: src/UserList.js:184 #: src/UserList.js:237 +#: src/CreateOrganizationPage.js:61 msgid "An error occurred." msgstr "An error occurred." @@ -970,6 +971,7 @@ msgstr "Incorrect resetPassword.result typename." #: src/TwoFactorAuthenticatePage.js:80 #: src/UserList.js:114 #: src/UserList.js:165 +#: src/CreateOrganizationPage.js: msgid "Incorrect send method received." msgstr "Incorrect send method received." @@ -2432,3 +2434,61 @@ msgstr "New user email" msgid "Edit Role" msgstr "Edit Role" +#: src/AdminPage.js:114 +#: src/AdminPage.js:149 +#: src/CreateOrganizationPage.js:367 +msgid "Create Organization" +msgstr "Create Organization" + +#: src/fieldRequirements.js:41 +msgid "Acronyms can only use upper case letters and underscores" +msgstr "Acronyms can only use upper case letters and underscores" + +#: src/fieldRequirements.js:45 +msgid "Acronyms must be at most 50 characters" +msgstr "Acronyms must be at most 50 characters" + +#: src/CreateOrganizationPage.js:72 +msgid "Organization created" +msgstr "Organization created" + +#: src/CreateOrganizationPage.js:82 +msgid "Unable to create new organization." +msgstr "Unable to create new organization." + +#: src/CreateOrganizationPage.js:92 +msgid "Incorrect createOrganization.result typename." +msgstr "Incorrect createOrganization.result typename." + +#: src/CreateOrganizationPage.js:157 +msgid "Create an organization by filling out the following info in both English and French" +msgstr "Create an organization by filling out the following info in both English and French" + +#: src/CreateOrganizationPage.js:164 +msgid "Name:" +msgstr "Name:" + +#: src/CreateOrganizationPage.js:192 +msgid "Acronym:" +msgstr "Acronym:" + +#: src/CreateOrganizationPage.js:222 +msgid "Zone:" +msgstr "Zone:" + +#: src/CreateOrganizationPage.js:250 +msgid "Sector:" +msgstr "Sector:" + +#: src/CreateOrganizationPage.js:278 +msgid "City:" +msgstr "City:" + +#: src/CreateOrganizationPage.js:306 +msgid "Province:" +msgstr "Province:" + +#: src/CreateOrganizationPage.js:334 +msgid "Country:" +msgstr "Country:" + diff --git a/frontend/src/locales/fr.po b/frontend/src/locales/fr.po index 603ecc3f1f..3a5eda9a19 100644 --- a/frontend/src/locales/fr.po +++ b/frontend/src/locales/fr.po @@ -2423,3 +2423,61 @@ msgstr "Courriel du nouvel utilisateur" #: src/UserList.js:261 msgid "Edit Role" msgstr "Rôle d'édition" + +#: src/AdminPage.js:114 +#: src/AdminPage.js:149 +#: src/CreateOrganizationPage.js:367 +msgid "Create Organization" +msgstr "Créer une organisation" + +#: src/fieldRequirements.js:41 +msgid "Acronyms can only use upper case letters and underscores" +msgstr "Les acronymes ne peuvent utiliser que des lettres majuscules et des caractères de soulignement." + +#: src/fieldRequirements.js:45 +msgid "Acronyms must be at most 50 characters" +msgstr "Les acronymes doivent comporter au maximum 50 caractères." + +#: src/CreateOrganizationPage.js:72 +msgid "Organization created" +msgstr "Organisation créée" + +#: src/CreateOrganizationPage.js:82 +msgid "Unable to create new organization." +msgstr "Impossible de créer une nouvelle organisation." + +#: src/CreateOrganizationPage.js:92 +msgid "Incorrect createOrganization.result typename." +msgstr "createOrganization.result incorrecte typename." + +#: src/CreateOrganizationPage.js:157 +msgid "Create an organization by filling out the following info in both English and French" +msgstr "Créez une organisation en remplissant les informations suivantes en anglais et en français" + +#: src/CreateOrganizationPage.js:164 +msgid "Name:" +msgstr "Nom:" + +#: src/CreateOrganizationPage.js:192 +msgid "Acronym:" +msgstr "Acronyme:" + +#: src/CreateOrganizationPage.js:222 +msgid "Zone:" +msgstr "Zone:" + +#: src/CreateOrganizationPage.js:250 +msgid "Sector:" +msgstr "Secteur:" + +#: src/CreateOrganizationPage.js:278 +msgid "City:" +msgstr "Ville:" + +#: src/CreateOrganizationPage.js:306 +msgid "Province:" +msgstr "Province:" + +#: src/CreateOrganizationPage.js:334 +msgid "Country:" +msgstr "Pays:" From facc862c96397db6efc27866f626d4429b37ec62 Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Wed, 26 May 2021 10:41:59 -0300 Subject: [PATCH 05/14] added AcronymField.js and validation errors appear --- frontend/src/AcronymField.js | 40 ++++++++++ frontend/src/CreateOrganizationPage.js | 82 ++++++++------------- frontend/src/__tests__/AcronymField.test.js | 51 +++++++++++++ 3 files changed, 123 insertions(+), 50 deletions(-) create mode 100644 frontend/src/AcronymField.js create mode 100644 frontend/src/__tests__/AcronymField.test.js diff --git a/frontend/src/AcronymField.js b/frontend/src/AcronymField.js new file mode 100644 index 0000000000..4440dbece7 --- /dev/null +++ b/frontend/src/AcronymField.js @@ -0,0 +1,40 @@ +import React from 'react' +import { elementType, func, oneOfType, shape, string } from 'prop-types' +import { FormControl, FormErrorMessage, Input } from '@chakra-ui/core' +import { useField } from 'formik' +import WithPseudoBox from './withPseudoBox' + +const AcronymField = WithPseudoBox(function AcronymField({ + name, + placeholder, + forwardedRef, + ...props +}) { + const [field, meta] = useField(name) + + return ( + + + {meta.error} + + ) +}) + +AcronymField.propTypes = { + name: string.isRequired, + forwardedRef: oneOfType([func, shape({ current: elementType })]), +} + +const withForwardedRef = React.forwardRef((props, ref) => { + return +}) +withForwardedRef.displayName = 'AcronymField' + +export default withForwardedRef diff --git a/frontend/src/CreateOrganizationPage.js b/frontend/src/CreateOrganizationPage.js index 1cddf2d1e5..cce89c5ee2 100644 --- a/frontend/src/CreateOrganizationPage.js +++ b/frontend/src/CreateOrganizationPage.js @@ -20,6 +20,8 @@ import { useHistory, Link as RouteLink } from 'react-router-dom' import { TrackerButton } from './TrackerButton' import { object, string } from 'yup' import { fieldRequirements } from './fieldRequirements' +import AcronymField from './AcronymField' +import { i18n } from '@lingui/core' export default function CreateOrganizationPage() { const { currentUser } = useUserState() @@ -30,20 +32,20 @@ export default function CreateOrganizationPage() { acronymEN: string() .matches( fieldRequirements.acronym.matches.regex, - fieldRequirements.acronym.matches.message, + i18n._(fieldRequirements.acronym.matches.message), ) .max( fieldRequirements.acronym.max.maxLength, - fieldRequirements.acronym.max.message, + i18n._(fieldRequirements.acronym.max.message), ), acronymFR: string() .matches( fieldRequirements.acronym.matches.regex, - fieldRequirements.acronym.matches.message, + i18n._(fieldRequirements.acronym.matches.message), ) .max( fieldRequirements.acronym.max.maxLength, - fieldRequirements.acronym.max.message, + i18n._(fieldRequirements.acronym.max.message), ), }) @@ -104,20 +106,20 @@ export default function CreateOrganizationPage() { { createOrganization({ @@ -155,7 +157,7 @@ export default function CreateOrganizationPage() { Acronym: - - - Error! - - - - Error! - + +
@@ -209,7 +191,7 @@ export default function CreateOrganizationPage() { ', () => { + describe('when validation fails', () => { + it('displays an error message', async () => { + const validationSchema = object().shape({ + acronym: string().required('sadness'), + }) + + const { getByTestId, getByText } = render( + + + + {() => } + + + , + ) + + const input = getByTestId('AcronymField') + fireEvent.blur(input) + + await waitFor(() => { + expect(getByText(/sadness/)).toBeInTheDocument() + }) + }) + }) +}) From 203d4373d9004ef14b8e26c2ac3ff320e0d75df8 Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Wed, 26 May 2021 13:38:26 -0300 Subject: [PATCH 06/14] Removed unneeded Form Error Messages --- frontend/src/CreateOrganizationPage.js | 41 +++++++++----------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/frontend/src/CreateOrganizationPage.js b/frontend/src/CreateOrganizationPage.js index cce89c5ee2..edb30c67b8 100644 --- a/frontend/src/CreateOrganizationPage.js +++ b/frontend/src/CreateOrganizationPage.js @@ -8,7 +8,6 @@ import { Input, Text, FormControl, - FormErrorMessage, } from '@chakra-ui/core' import { Trans, t } from '@lingui/macro' import { CREATE_ORGANIZATION } from './graphql/mutations' @@ -106,28 +105,28 @@ export default function CreateOrganizationPage() { { createOrganization({ variables: { - acronymEN: values.acronymEN, - acronymFR: values.acronymFR, nameEN: values.nameEN, nameFR: values.nameFR, + acronymEN: values.acronymEN, + acronymFR: values.acronymFR, zoneEN: values.zoneEN, zoneFR: values.zoneFR, sectorEN: values.sectorEN, @@ -163,7 +162,6 @@ export default function CreateOrganizationPage() { value={values.nameEN} placeholder={t`Name EN`} /> - Error! - Error! @@ -197,7 +194,6 @@ export default function CreateOrganizationPage() { value={values.zoneEN} placeholder={t`Zone EN`} /> - Error! - Error!
@@ -223,7 +218,6 @@ export default function CreateOrganizationPage() { value={values.sectorEN} placeholder={t`Sector EN`} /> - Error! - Error! @@ -249,7 +242,6 @@ export default function CreateOrganizationPage() { value={values.cityEN} placeholder={t`City EN`} /> - Error! - Error! @@ -276,7 +267,6 @@ export default function CreateOrganizationPage() { value={values.provinceEN} placeholder={t`Province EN`} /> - Error! - Error! @@ -302,7 +291,6 @@ export default function CreateOrganizationPage() { value={values.countryEN} placeholder={t`Country EN`} /> - Error! - Error! From 1a2d510f29390905d76fc30639a5d4a9119af5c3 Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Wed, 26 May 2021 13:48:43 -0300 Subject: [PATCH 07/14] Add tests --- .../__tests__/CreateOrganizationPage.test.js | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 frontend/src/__tests__/CreateOrganizationPage.test.js diff --git a/frontend/src/__tests__/CreateOrganizationPage.test.js b/frontend/src/__tests__/CreateOrganizationPage.test.js new file mode 100644 index 0000000000..49fb321025 --- /dev/null +++ b/frontend/src/__tests__/CreateOrganizationPage.test.js @@ -0,0 +1,92 @@ +import React from 'react' +import { ThemeProvider, theme } from '@chakra-ui/core' +import { MemoryRouter } from 'react-router-dom' +import { fireEvent, render, waitFor } from '@testing-library/react' +import { MockedProvider } from '@apollo/client/testing' +import CreateOrganizationPage from '../CreateOrganizationPage' +import { CREATE_ORGANIZATION } from '../graphql/mutations' +import { I18nProvider } from '@lingui/react' +import { setupI18n } from '@lingui/core' +import { UserStateProvider } from '../UserState' + +const i18n = setupI18n({ + locale: 'en', + messages: { + en: {}, + }, + localeData: { + en: {}, + }, +}) + +const mocks = [ + { + request: { + query: CREATE_ORGANIZATION, + }, + result: { + data: { + organization: { + slug: 'new-org-slug', + }, + }, + }, + }, +] + +describe('', () => { + it('renders', async () => { + const { getByText } = render( + + + + + + + + + + + , + ) + + const welcomeMessage = /Create an organization by filling out the following info in both English and French/i + + await waitFor(() => expect(getByText(welcomeMessage)).toBeInTheDocument()) + }) + + describe('acronym fields', () => { + it('displays an error message when incorrect format is used', async () => { + const { container, getByText } = render( + + + + + + + + + + + , + ) + + const acronymEN = container.querySelector('#acronymEN') + const errorMessage = /Acronyms can only use upper case letters and underscores/i + + await waitFor(() => { + fireEvent.change(acronymEN, { target: { value: 'test' } }) + }) + + await waitFor(() => { + fireEvent.blur(acronymEN) + }) + + await waitFor(() => expect(getByText(errorMessage)).toBeInTheDocument()) + }) + }) +}) From 2525e182bff4a964525c9d66a94b43bbddb0802a Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Wed, 26 May 2021 14:47:03 -0300 Subject: [PATCH 08/14] input placeholders --- frontend/src/CreateOrganizationPage.js | 29 +++++++++++++------------- frontend/src/locales/en.po | 7 +++++++ frontend/src/locales/fr.po | 8 +++++++ 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/frontend/src/CreateOrganizationPage.js b/frontend/src/CreateOrganizationPage.js index edb30c67b8..e7567d3649 100644 --- a/frontend/src/CreateOrganizationPage.js +++ b/frontend/src/CreateOrganizationPage.js @@ -160,7 +160,7 @@ export default function CreateOrganizationPage() { name="nameEN" onChange={handleChange} value={values.nameEN} - placeholder={t`Name EN`} + placeholder={t`English`} /> @@ -169,7 +169,7 @@ export default function CreateOrganizationPage() { name="nameFR" onChange={handleChange} value={values.nameFR} - placeholder={t`Name FR`} + placeholder={t`French`} /> @@ -178,8 +178,8 @@ export default function CreateOrganizationPage() { Acronym: - - + + @@ -192,7 +192,7 @@ export default function CreateOrganizationPage() { name="zoneEN" onChange={handleChange} value={values.zoneEN} - placeholder={t`Zone EN`} + placeholder={t`English`} /> @@ -201,7 +201,7 @@ export default function CreateOrganizationPage() { name="zoneFR" onChange={handleChange} value={values.zoneFR} - placeholder={t`Zone FR`} + placeholder={t`French`} /> @@ -216,7 +216,7 @@ export default function CreateOrganizationPage() { name="sectorEN" onChange={handleChange} value={values.sectorEN} - placeholder={t`Sector EN`} + placeholder={t`English`} /> @@ -225,7 +225,7 @@ export default function CreateOrganizationPage() { name="sectorFR" onChange={handleChange} value={values.sectorFR} - placeholder={t`Sector FR`} + placeholder={t`French`} /> @@ -240,7 +240,7 @@ export default function CreateOrganizationPage() { name="cityEN" onChange={handleChange} value={values.cityEN} - placeholder={t`City EN`} + placeholder={t`English`} /> @@ -249,7 +249,7 @@ export default function CreateOrganizationPage() { name="cityFR" onChange={handleChange} value={values.cityFR} - placeholder={t`City FR`} + placeholder={t`French`} /> @@ -263,9 +263,8 @@ export default function CreateOrganizationPage() { id="provinceEN" name="provinceEN" onChange={handleChange} - // value={values.provinceEN} - placeholder={t`Province EN`} + placeholder={t`English`} /> @@ -274,7 +273,7 @@ export default function CreateOrganizationPage() { name="provinceFR" onChange={handleChange} value={values.provinceFR} - placeholder={t`Province FR`} + placeholder={t`French`} /> @@ -289,7 +288,7 @@ export default function CreateOrganizationPage() { name="countryEN" onChange={handleChange} value={values.countryEN} - placeholder={t`Country EN`} + placeholder={t`English`} /> @@ -298,7 +297,7 @@ export default function CreateOrganizationPage() { name="countryFR" onChange={handleChange} value={values.countryFR} - placeholder={t`Country FR`} + placeholder={t`French`} /> diff --git a/frontend/src/locales/en.po b/frontend/src/locales/en.po index 42a4d583f9..15407bb2c8 100644 --- a/frontend/src/locales/en.po +++ b/frontend/src/locales/en.po @@ -2492,3 +2492,10 @@ msgstr "Province:" msgid "Country:" msgstr "Country:" +#: src/CreateOrganizationPage.js:163 +msgid "English" +msgstr "English" + +#: src/CreateOrganizationPage.js:172 +msgid "French" +msgstr "French" diff --git a/frontend/src/locales/fr.po b/frontend/src/locales/fr.po index 3a5eda9a19..53ce3c99d2 100644 --- a/frontend/src/locales/fr.po +++ b/frontend/src/locales/fr.po @@ -2481,3 +2481,11 @@ msgstr "Province:" #: src/CreateOrganizationPage.js:334 msgid "Country:" msgstr "Pays:" + +#: src/CreateOrganizationPage.js:163 +msgid "English" +msgstr "Anglais" + +#: src/CreateOrganizationPage.js:172 +msgid "French" +msgstr "Français" From a4989c89cade0666f920fccc00695f29be868d63 Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Wed, 26 May 2021 15:13:28 -0300 Subject: [PATCH 09/14] changed toast to display org name instead of slug --- frontend/src/CreateOrganizationPage.js | 2 +- frontend/src/__tests__/CreateOrganizationPage.test.js | 2 +- frontend/src/graphql/mutations.js | 2 +- frontend/src/locales/en.po | 4 ++++ frontend/src/locales/fr.po | 4 ++++ 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/frontend/src/CreateOrganizationPage.js b/frontend/src/CreateOrganizationPage.js index e7567d3649..af0e8f8886 100644 --- a/frontend/src/CreateOrganizationPage.js +++ b/frontend/src/CreateOrganizationPage.js @@ -68,7 +68,7 @@ export default function CreateOrganizationPage() { if (createOrganization.result.__typename === 'Organization') { toast({ title: t`Organization created`, - description: t`${createOrganization.result.slug} was created`, + description: t`${createOrganization.result.name} was created`, status: 'success', duration: 9000, isClosable: true, diff --git a/frontend/src/__tests__/CreateOrganizationPage.test.js b/frontend/src/__tests__/CreateOrganizationPage.test.js index 49fb321025..fedb3c5f25 100644 --- a/frontend/src/__tests__/CreateOrganizationPage.test.js +++ b/frontend/src/__tests__/CreateOrganizationPage.test.js @@ -27,7 +27,7 @@ const mocks = [ result: { data: { organization: { - slug: 'new-org-slug', + name: 'New Test Org', }, }, }, diff --git a/frontend/src/graphql/mutations.js b/frontend/src/graphql/mutations.js index 6553fa050e..8fd649b7e1 100644 --- a/frontend/src/graphql/mutations.js +++ b/frontend/src/graphql/mutations.js @@ -409,7 +409,7 @@ export const CREATE_ORGANIZATION = gql` ) { result { ... on Organization { - slug + name } ... on OrganizationError { code diff --git a/frontend/src/locales/en.po b/frontend/src/locales/en.po index 15407bb2c8..cfe956d524 100644 --- a/frontend/src/locales/en.po +++ b/frontend/src/locales/en.po @@ -2452,6 +2452,10 @@ msgstr "Acronyms must be at most 50 characters" msgid "Organization created" msgstr "Organization created" +#: src/CreateOrganizationPage.js:73 +msgid "{0} was created" +msgstr "{0} was created" + #: src/CreateOrganizationPage.js:82 msgid "Unable to create new organization." msgstr "Unable to create new organization." diff --git a/frontend/src/locales/fr.po b/frontend/src/locales/fr.po index 53ce3c99d2..d913e8cb58 100644 --- a/frontend/src/locales/fr.po +++ b/frontend/src/locales/fr.po @@ -2442,6 +2442,10 @@ msgstr "Les acronymes doivent comporter au maximum 50 caractères." msgid "Organization created" msgstr "Organisation créée" +#: src/CreateOrganizationPage.js:73 +msgid "{0} was created" +msgstr "{0} a été créée" + #: src/CreateOrganizationPage.js:82 msgid "Unable to create new organization." msgstr "Impossible de créer une nouvelle organisation." From ac28294c4ff1edecc4725fc4825ac839fa6048e6 Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Thu, 27 May 2021 10:17:21 -0300 Subject: [PATCH 10/14] more tests --- .../__tests__/CreateOrganizationPage.test.js | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/frontend/src/__tests__/CreateOrganizationPage.test.js b/frontend/src/__tests__/CreateOrganizationPage.test.js index fedb3c5f25..5e5da9c7b7 100644 --- a/frontend/src/__tests__/CreateOrganizationPage.test.js +++ b/frontend/src/__tests__/CreateOrganizationPage.test.js @@ -89,4 +89,39 @@ describe('', () => { await waitFor(() => expect(getByText(errorMessage)).toBeInTheDocument()) }) }) + + it('displays an error message when input is too large', async () => { + const { container, getByText } = render( + + + + + + + + + + + , + ) + + const acronymEN = container.querySelector('#acronymEN') + const errorMessage = /Acronyms must be at most 50 characters/i + + await waitFor(() => { + fireEvent.change(acronymEN, { + target: { + value: 'THIS_ACRONYM_IS_OVER_FIFTY_CHARACTERS_WHICH_MAKES_IT_INVALID', + }, + }) + }) + + await waitFor(() => { + fireEvent.blur(acronymEN) + }) + + await waitFor(() => expect(getByText(errorMessage)).toBeInTheDocument()) + }) }) From 3e9560b28f0900155185e4e9b9732907ea428cf0 Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Thu, 27 May 2021 11:08:30 -0300 Subject: [PATCH 11/14] move test into proper describe --- .../__tests__/CreateOrganizationPage.test.js | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/frontend/src/__tests__/CreateOrganizationPage.test.js b/frontend/src/__tests__/CreateOrganizationPage.test.js index 5e5da9c7b7..98185584e4 100644 --- a/frontend/src/__tests__/CreateOrganizationPage.test.js +++ b/frontend/src/__tests__/CreateOrganizationPage.test.js @@ -88,40 +88,41 @@ describe('', () => { await waitFor(() => expect(getByText(errorMessage)).toBeInTheDocument()) }) - }) - it('displays an error message when input is too large', async () => { - const { container, getByText } = render( - - - - - - - - - - - , - ) + it('displays an error message when input is too large', async () => { + const { container, getByText } = render( + + + + + + + + + + + , + ) - const acronymEN = container.querySelector('#acronymEN') - const errorMessage = /Acronyms must be at most 50 characters/i + const acronymEN = container.querySelector('#acronymEN') + const errorMessage = /Acronyms must be at most 50 characters/i - await waitFor(() => { - fireEvent.change(acronymEN, { - target: { - value: 'THIS_ACRONYM_IS_OVER_FIFTY_CHARACTERS_WHICH_MAKES_IT_INVALID', - }, + await waitFor(() => { + fireEvent.change(acronymEN, { + target: { + value: + 'THIS_ACRONYM_IS_OVER_FIFTY_CHARACTERS_WHICH_MAKES_IT_INVALID', + }, + }) }) - }) - await waitFor(() => { - fireEvent.blur(acronymEN) - }) + await waitFor(() => { + fireEvent.blur(acronymEN) + }) - await waitFor(() => expect(getByText(errorMessage)).toBeInTheDocument()) + await waitFor(() => expect(getByText(errorMessage)).toBeInTheDocument()) + }) }) }) From 69ca3186e4f8c67691b00f32fb87a908115627ab Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Thu, 27 May 2021 15:47:00 -0300 Subject: [PATCH 12/14] All fields now have labels and validation schema --- ...nymField.js => CreateOrganizationField.js} | 25 +- frontend/src/CreateOrganizationPage.js | 247 ++++++++---------- ...est.js => CreateOrganizationField.test.js} | 13 +- frontend/src/fieldRequirements.js | 3 + frontend/src/locales/en.po | 30 +-- frontend/src/locales/fr.po | 28 +- 6 files changed, 160 insertions(+), 186 deletions(-) rename frontend/src/{AcronymField.js => CreateOrganizationField.js} (55%) rename frontend/src/__tests__/{AcronymField.test.js => CreateOrganizationField.test.js} (76%) diff --git a/frontend/src/AcronymField.js b/frontend/src/CreateOrganizationField.js similarity index 55% rename from frontend/src/AcronymField.js rename to frontend/src/CreateOrganizationField.js index 4440dbece7..945c9d0481 100644 --- a/frontend/src/AcronymField.js +++ b/frontend/src/CreateOrganizationField.js @@ -1,40 +1,49 @@ import React from 'react' import { elementType, func, oneOfType, shape, string } from 'prop-types' -import { FormControl, FormErrorMessage, Input } from '@chakra-ui/core' +import { + FormControl, + FormErrorMessage, + FormLabel, + Input, +} from '@chakra-ui/core' import { useField } from 'formik' import WithPseudoBox from './withPseudoBox' -const AcronymField = WithPseudoBox(function AcronymField({ +const OrganizationCreateField = WithPseudoBox(function OrganizationCreateField({ name, - placeholder, + label, + language, forwardedRef, ...props }) { const [field, meta] = useField(name) return ( - + + + {label} ({language}) + {meta.error} ) }) -AcronymField.propTypes = { +OrganizationCreateField.propTypes = { name: string.isRequired, forwardedRef: oneOfType([func, shape({ current: elementType })]), } const withForwardedRef = React.forwardRef((props, ref) => { - return + return }) -withForwardedRef.displayName = 'AcronymField' +withForwardedRef.displayName = 'OrganizationCreateField' export default withForwardedRef diff --git a/frontend/src/CreateOrganizationPage.js b/frontend/src/CreateOrganizationPage.js index af0e8f8886..61c076a993 100644 --- a/frontend/src/CreateOrganizationPage.js +++ b/frontend/src/CreateOrganizationPage.js @@ -1,14 +1,5 @@ import React from 'react' -import { - Stack, - useToast, - Box, - Button, - Heading, - Input, - Text, - FormControl, -} from '@chakra-ui/core' +import { Stack, useToast, Box, Button, Heading } from '@chakra-ui/core' import { Trans, t } from '@lingui/macro' import { CREATE_ORGANIZATION } from './graphql/mutations' import { useMutation } from '@apollo/client' @@ -19,7 +10,7 @@ import { useHistory, Link as RouteLink } from 'react-router-dom' import { TrackerButton } from './TrackerButton' import { object, string } from 'yup' import { fieldRequirements } from './fieldRequirements' -import AcronymField from './AcronymField' +import CreateOrganizationField from './CreateOrganizationField' import { i18n } from '@lingui/core' export default function CreateOrganizationPage() { @@ -28,6 +19,8 @@ export default function CreateOrganizationPage() { const history = useHistory() const validationSchema = object().shape({ + nameEN: string().required(i18n._(fieldRequirements.field.required.message)), + nameFR: string().required(i18n._(fieldRequirements.field.required.message)), acronymEN: string() .matches( fieldRequirements.acronym.matches.regex, @@ -36,7 +29,8 @@ export default function CreateOrganizationPage() { .max( fieldRequirements.acronym.max.maxLength, i18n._(fieldRequirements.acronym.max.message), - ), + ) + .required(i18n._(fieldRequirements.field.required.message)), acronymFR: string() .matches( fieldRequirements.acronym.matches.regex, @@ -45,7 +39,30 @@ export default function CreateOrganizationPage() { .max( fieldRequirements.acronym.max.maxLength, i18n._(fieldRequirements.acronym.max.message), - ), + ) + .required(i18n._(fieldRequirements.field.required.message)), + zoneEN: string().required(i18n._(fieldRequirements.field.required.message)), + zoneFR: string().required(i18n._(fieldRequirements.field.required.message)), + sectorEN: string().required( + i18n._(fieldRequirements.field.required.message), + ), + sectorFR: string().required( + i18n._(fieldRequirements.field.required.message), + ), + cityEN: string().required(i18n._(fieldRequirements.field.required.message)), + cityFR: string().required(i18n._(fieldRequirements.field.required.message)), + provinceEN: string().required( + i18n._(fieldRequirements.field.required.message), + ), + provinceFR: string().required( + i18n._(fieldRequirements.field.required.message), + ), + countryEN: string().required( + i18n._(fieldRequirements.field.required.message), + ), + countryFR: string().required( + i18n._(fieldRequirements.field.required.message), + ), }) const [createOrganization, { loading }] = useMutation(CREATE_ORGANIZATION, { @@ -139,9 +156,10 @@ export default function CreateOrganizationPage() { cityFR: values.cityFR, }, }) + // window.alert(JSON.stringify(values)) }} > - {({ handleSubmit, handleChange, values, isSubmitting }) => ( + {({ handleSubmit, isSubmitting }) => (
@@ -151,155 +169,94 @@ export default function CreateOrganizationPage() { - - Name: - - - - - - - + + - - Acronym: - - - + + - - Zone: - - - - - - - + + - - Sector: - - - - - - - + + - - City: - - - - - - - + + - - Province: - - - - - - - + + - - Country: - - - - - - - + + diff --git a/frontend/src/__tests__/AcronymField.test.js b/frontend/src/__tests__/CreateOrganizationField.test.js similarity index 76% rename from frontend/src/__tests__/AcronymField.test.js rename to frontend/src/__tests__/CreateOrganizationField.test.js index bfb0975b10..4463864023 100644 --- a/frontend/src/__tests__/AcronymField.test.js +++ b/frontend/src/__tests__/CreateOrganizationField.test.js @@ -2,7 +2,7 @@ import React from 'react' import { object, string } from 'yup' import { waitFor, render, fireEvent } from '@testing-library/react' import { ThemeProvider, theme } from '@chakra-ui/core' -import AcronymField from '../AcronymField' +import CreateOrganizationField from '../CreateOrganizationField' import { Formik } from 'formik' import { I18nProvider } from '@lingui/react' import { setupI18n } from '@lingui/core' @@ -17,7 +17,7 @@ const i18n = setupI18n({ }, }) -describe('', () => { +describe('', () => { describe('when validation fails', () => { it('displays an error message', async () => { const validationSchema = object().shape({ @@ -34,13 +34,18 @@ describe('', () => { email: '', }} > - {() => } + {() => ( + + )} , ) - const input = getByTestId('AcronymField') + const input = getByTestId('CreateOrganizationField') fireEvent.blur(input) await waitFor(() => { diff --git a/frontend/src/fieldRequirements.js b/frontend/src/fieldRequirements.js index b924923246..3e82b541d1 100644 --- a/frontend/src/fieldRequirements.js +++ b/frontend/src/fieldRequirements.js @@ -45,4 +45,7 @@ export const fieldRequirements = { message: t`Acronyms must be at most 50 characters`, }, }, + field: { + required: { message: t`This field cannot be empty` }, + }, } diff --git a/frontend/src/locales/en.po b/frontend/src/locales/en.po index 2ec4bf831c..cd861e3444 100644 --- a/frontend/src/locales/en.po +++ b/frontend/src/locales/en.po @@ -2492,32 +2492,32 @@ msgid "Create an organization by filling out the following info in both English msgstr "Create an organization by filling out the following info in both English and French" #: src/CreateOrganizationPage.js:164 -msgid "Name:" -msgstr "Name:" +msgid "Name" +msgstr "Name" #: src/CreateOrganizationPage.js:192 -msgid "Acronym:" -msgstr "Acronym:" +msgid "Acronym" +msgstr "Acronym" #: src/CreateOrganizationPage.js:222 -msgid "Zone:" -msgstr "Zone:" +msgid "Zone" +msgstr "Zone" #: src/CreateOrganizationPage.js:250 -msgid "Sector:" -msgstr "Sector:" +msgid "Sector" +msgstr "Sector" #: src/CreateOrganizationPage.js:278 -msgid "City:" -msgstr "City:" +msgid "City" +msgstr "City" #: src/CreateOrganizationPage.js:306 -msgid "Province:" -msgstr "Province:" +msgid "Province" +msgstr "Province" #: src/CreateOrganizationPage.js:334 -msgid "Country:" -msgstr "Country:" +msgid "Country" +msgstr "Country" #: src/CreateOrganizationPage.js:163 msgid "English" @@ -2593,4 +2593,4 @@ msgstr "Web Guidance" #: src/DmarcGuidancePage.js:84 msgid "Email Guidance" -msgstr "Email Guidance" \ No newline at end of file +msgstr "Email Guidance" diff --git a/frontend/src/locales/fr.po b/frontend/src/locales/fr.po index 2d62f01d73..cf802ac165 100644 --- a/frontend/src/locales/fr.po +++ b/frontend/src/locales/fr.po @@ -2482,32 +2482,32 @@ msgid "Create an organization by filling out the following info in both English msgstr "Créez une organisation en remplissant les informations suivantes en anglais et en français" #: src/CreateOrganizationPage.js:164 -msgid "Name:" -msgstr "Nom:" +msgid "Name" +msgstr "Nom" #: src/CreateOrganizationPage.js:192 -msgid "Acronym:" -msgstr "Acronyme:" +msgid "Acronym" +msgstr "Acronyme" #: src/CreateOrganizationPage.js:222 -msgid "Zone:" -msgstr "Zone:" +msgid "Zone" +msgstr "Zone" #: src/CreateOrganizationPage.js:250 -msgid "Sector:" -msgstr "Secteur:" +msgid "Sector" +msgstr "Secteur" #: src/CreateOrganizationPage.js:278 -msgid "City:" -msgstr "Ville:" +msgid "City" +msgstr "Ville" #: src/CreateOrganizationPage.js:306 -msgid "Province:" -msgstr "Province:" +msgid "Province" +msgstr "Province" #: src/CreateOrganizationPage.js:334 -msgid "Country:" -msgstr "Pays:" +msgid "Country" +msgstr "Pays" #: src/CreateOrganizationPage.js:163 msgid "English" From 07aadd9356ac7acb658da988fef8caa5240d8678 Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Thu, 27 May 2021 15:50:22 -0300 Subject: [PATCH 13/14] translation for required field --- frontend/src/CreateOrganizationPage.js | 1 - frontend/src/locales/en.po | 4 ++++ frontend/src/locales/fr.po | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/frontend/src/CreateOrganizationPage.js b/frontend/src/CreateOrganizationPage.js index 61c076a993..b828a33d9b 100644 --- a/frontend/src/CreateOrganizationPage.js +++ b/frontend/src/CreateOrganizationPage.js @@ -156,7 +156,6 @@ export default function CreateOrganizationPage() { cityFR: values.cityFR, }, }) - // window.alert(JSON.stringify(values)) }} > {({ handleSubmit, isSubmitting }) => ( diff --git a/frontend/src/locales/en.po b/frontend/src/locales/en.po index cd861e3444..8025c92334 100644 --- a/frontend/src/locales/en.po +++ b/frontend/src/locales/en.po @@ -2471,6 +2471,10 @@ msgstr "Acronyms can only use upper case letters and underscores" msgid "Acronyms must be at most 50 characters" msgstr "Acronyms must be at most 50 characters" +#: src/fieldRequirements.js:49 +msgid "This field cannot be empty" +msgstr "This field cannot be empty" + #: src/CreateOrganizationPage.js:72 msgid "Organization created" msgstr "Organization created" diff --git a/frontend/src/locales/fr.po b/frontend/src/locales/fr.po index cf802ac165..aa9173a221 100644 --- a/frontend/src/locales/fr.po +++ b/frontend/src/locales/fr.po @@ -2461,6 +2461,10 @@ msgstr "Les acronymes ne peuvent utiliser que des lettres majuscules et des cara msgid "Acronyms must be at most 50 characters" msgstr "Les acronymes doivent comporter au maximum 50 caractères." +#: src/fieldRequirements.js:49 +msgid "This field cannot be empty" +msgstr "Ce champ ne peut pas être vide" + #: src/CreateOrganizationPage.js:72 msgid "Organization created" msgstr "Organisation créée" From ef5f08b4742576a17acf24f23ac37854ac2fb90b Mon Sep 17 00:00:00 2001 From: lcampbell2 Date: Fri, 28 May 2021 08:10:01 -0300 Subject: [PATCH 14/14] htmlFor={name} added to CreateOrganizationField.js --- frontend/src/CreateOrganizationField.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/CreateOrganizationField.js b/frontend/src/CreateOrganizationField.js index 945c9d0481..f3111d43d9 100644 --- a/frontend/src/CreateOrganizationField.js +++ b/frontend/src/CreateOrganizationField.js @@ -20,7 +20,7 @@ const OrganizationCreateField = WithPseudoBox(function OrganizationCreateField({ return ( - + {label} ({language})