Skip to content

Commit

Permalink
#1214 - use phone number library for number validation. user can ente…
Browse files Browse the repository at this point in the history
…r phone number in multiple formats as used in real world - hence removed message to enter in 10 digits etc.
  • Loading branch information
petmongrels committed May 23, 2024
1 parent 4807ad7 commit cfb60c1
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 349 deletions.
3 changes: 0 additions & 3 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,3 @@ max_line_length = 140

[Makefile]
indent_style = tab

[*.js]
spaces_around_brackets = both
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@
"redux-saga": "0.16.2",
"redux-thunk": "^2.3.0",
"rules-config": "github:avniproject/rules-config#fe552da405368bfd138e2f38e605c1d307e3ebe4",
"uuid": "^3.3.2"
"uuid": "^3.3.2",
"libphonenumber-js": "^1.11.1"
},
"scripts": {
"analyze": "source-map-explorer 'build/static/js/*.js'",
Expand Down
18 changes: 5 additions & 13 deletions src/adminApp/Account.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
import React from "react";
import {
Create,
Datagrid,
Edit,
List,
Show,
SimpleForm,
SimpleShowLayout,
TextField,
TextInput,
Toolbar,
SaveButton
} from "react-admin";
import { Create, Datagrid, Edit, List, Show, SimpleForm, SimpleShowLayout, TextField, TextInput, Toolbar, SaveButton } from "react-admin";
import { Title } from "./components/Title";

//To remove delete button from the toolbar
Expand All @@ -25,6 +13,7 @@ export const AccountList = props => (
<List {...props} bulkActions={false} filter={{ searchURI: "findAll" }}>
<Datagrid rowClick="show">
<TextField label="Name" source="name" />
<TextField label="Region" source="region" />
</Datagrid>
</List>
);
Expand All @@ -33,6 +22,7 @@ export const AccountDetails = props => (
<Show title={<Title title={"Account"} />} {...props}>
<SimpleShowLayout>
<TextField source="name" label="Name" />
<TextField source="region" label="Region" />
</SimpleShowLayout>
</Show>
);
Expand All @@ -41,6 +31,7 @@ export const AccountCreate = props => (
<Create title="Add a new Account" {...props}>
<SimpleForm redirect="list">
<TextInput source="name" />
<TextInput source="region" />
</SimpleForm>
</Create>
);
Expand All @@ -49,6 +40,7 @@ export const AccountEdit = props => (
<Edit undoable={false} title={<Title title={"Edit account"} />} {...props}>
<SimpleForm toolbar={<CustomToolbar />} redirect="list">
<TextInput source="name" />
<TextInput source="region" />
</SimpleForm>
</Edit>
);
25 changes: 8 additions & 17 deletions src/adminApp/AccountOrgAdminUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,25 @@ import EnableDisableButton from "./components/EnableDisableButton";
import {
CustomToolbar,
formatRoles,
getPhoneValidator,
isRequired,
mobileNumberFormatter,
mobileNumberParser,
PasswordTextField,
UserFilter,
UserTitle,
validateEmail,
validatePhone
validateEmail
} from "./UserHelper";
import { TitleChip } from "./components/TitleChip";
import OrganisationService from "../common/service/OrganisationService";

export const AccountOrgAdminUserCreate = ({ user, ...props }) => (
export const AccountOrgAdminUserCreate = ({ user, region, ...props }) => (
<Create {...props}>
<UserForm user={user} />
<UserForm user={user} region={region} />
</Create>
);

export const AccountOrgAdminUserEdit = ({ user, ...props }) => (
export const AccountOrgAdminUserEdit = ({ user, region, ...props }) => (
<Edit {...props} title={<UserTitle titlePrefix="Edit" />} undoable={false} filter={{ searchURI: "orgAdmin" }}>
<UserForm edit user={user} />
<UserForm edit user={user} region={region} />
</Edit>
);

Expand Down Expand Up @@ -99,7 +97,7 @@ export const AccountOrgAdminUserDetail = ({ user, ...props }) => (
</Show>
);

const UserForm = ({ edit, user, ...props }) => {
const UserForm = ({ edit, user, region, ...props }) => {
const [nameSuffix, setNameSuffix] = useState("");
const getOrgData = id => id && OrganisationService.getOrganisation(id).then(data => setNameSuffix(data.usernameSuffix));

Expand Down Expand Up @@ -155,14 +153,7 @@ const UserForm = ({ edit, user, ...props }) => {
{!edit && <PasswordTextField />}
<TextInput source="name" label="Name of the Person" validate={isRequired} autoComplete="off" />
<TextInput source="email" label="Email Address" validate={validateEmail} autoComplete="off" />
<TextInput
source="phoneNumber"
label="10 digit mobile number"
validate={validatePhone}
format={mobileNumberFormatter}
parse={mobileNumberParser}
autoComplete="off"
/>
<TextInput source="phoneNumber" validate={getPhoneValidator(region)} autoComplete="off" />
</SimpleForm>
);
};
23 changes: 7 additions & 16 deletions src/adminApp/DeploymentManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,8 @@ import {
AccountOrgAdminUserEdit,
AccountOrgAdminUserList
} from "./AccountOrgAdminUser";
import {
OrganisationCreate,
OrganisationDetails,
OrganisationEdit,
OrganisationList
} from "./Organisation";
import {
organisationGroupCreate,
organisationGroupEdit,
OrganisationGroupList,
OrganisationGroupShow
} from "./OrganisationGroup";
import { OrganisationCreate, OrganisationDetails, OrganisationEdit, OrganisationList } from "./Organisation";
import { organisationGroupCreate, organisationGroupEdit, OrganisationGroupList, OrganisationGroupShow } from "./OrganisationGroup";

class DeploymentManager extends Component {
static childContextTypes = {
Expand All @@ -39,7 +29,7 @@ class DeploymentManager extends Component {
}

render() {
const { user } = this.props;
const { user, userInfo } = this.props;

return (
<Admin
Expand All @@ -62,9 +52,9 @@ class DeploymentManager extends Component {
name="accountOrgAdmin"
options={{ label: "Admins" }}
list={AccountOrgAdminUserList}
create={WithProps({ user }, AccountOrgAdminUserCreate)}
show={WithProps({ user }, AccountOrgAdminUserDetail)}
edit={WithProps({ user }, AccountOrgAdminUserEdit)}
create={WithProps({ user, region: userInfo.region }, AccountOrgAdminUserCreate)}
show={WithProps({ user, region: userInfo.region }, AccountOrgAdminUserDetail)}
edit={WithProps({ user, region: userInfo.region }, AccountOrgAdminUserEdit)}
/>
<Resource
name="organisation"
Expand All @@ -89,6 +79,7 @@ class DeploymentManager extends Component {

const mapStateToProps = state => ({
user: state.app.authSession,
userInfo: state.app.userInfo,
organisations: state.app.organisations
});

Expand Down
40 changes: 8 additions & 32 deletions src/adminApp/OrgManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,9 @@ import { authProvider, LogoutButton } from "./react-admin-config";
import { adminHistory, store } from "../common/store";
import { UserCreate, UserDetail, UserEdit, UserList } from "./user";
import { CatchmentCreate, CatchmentDetail, CatchmentEdit, CatchmentList } from "./catchment";
import {
LocationTypeCreate,
LocationTypeDetail,
LocationTypeEdit,
LocationTypeList
} from "./addressLevelType";
import { LocationTypeCreate, LocationTypeDetail, LocationTypeEdit, LocationTypeList } from "./addressLevelType";
import { LocationCreate, LocationDetail, LocationEdit, LocationList } from "./locations";
import {
IdentifierSourceCreate,
IdentifierSourceDetail,
IdentifierSourceEdit,
IdentifierSourceList
} from "./IdentifierSource";
import { IdentifierSourceCreate, IdentifierSourceDetail, IdentifierSourceEdit, IdentifierSourceList } from "./IdentifierSource";
import {
IdentifierUserAssignmentCreate,
IdentifierUserAssignmentDetail,
Expand Down Expand Up @@ -120,15 +110,9 @@ class OrgManager extends Component {
<Resource
name="user"
list={UserList}
create={
hasPrivilege(userInfo, EditUserConfiguration) &&
WithProps({ organisation, userInfo }, UserCreate)
}
show={WithProps(
{ user, hasEditUserPrivilege: hasPrivilege(userInfo, EditUserConfiguration) },
UserDetail
)}
edit={hasPrivilege(userInfo, EditUserConfiguration) && UserEdit}
create={hasPrivilege(userInfo, EditUserConfiguration) && WithProps({ organisation, userInfo }, UserCreate)}
show={WithProps({ user, hasEditUserPrivilege: hasPrivilege(userInfo, EditUserConfiguration) }, UserDetail)}
edit={hasPrivilege(userInfo, EditUserConfiguration) && WithProps({ organisation }, UserEdit)}
/>
) : (
<div />
Expand Down Expand Up @@ -158,12 +142,8 @@ class OrgManager extends Component {
options={{ label: "Identifier User Assignment" }}
list={IdentifierUserAssignmentList}
show={IdentifierUserAssignmentDetail}
create={
hasPrivilege(userInfo, EditIdentifierUserAssignment) && IdentifierUserAssignmentCreate
}
edit={
hasPrivilege(userInfo, EditIdentifierUserAssignment) && IdentifierUserAssignmentEdit
}
create={hasPrivilege(userInfo, EditIdentifierUserAssignment) && IdentifierUserAssignmentCreate}
edit={hasPrivilege(userInfo, EditIdentifierUserAssignment) && IdentifierUserAssignmentEdit}
/>
<Resource
name="organisationDetails"
Expand All @@ -177,11 +157,7 @@ class OrgManager extends Component {
)}
/>
{hasPrivilege(userInfo, PhoneVerification) ? (
<Resource
name="phoneNumberVerification"
options={{ label: "Phone Verification" }}
list={Msg91Config}
/>
<Resource name="phoneNumberVerification" options={{ label: "Phone Verification" }} list={Msg91Config} />
) : (
<div />
)}
Expand Down
41 changes: 16 additions & 25 deletions src/adminApp/UserHelper.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
import React from "react";
import { isEmpty, isEqual, isNil } from "lodash";
import { phoneCountryPrefix } from "../common/constants";
import {
email,
Filter,
regex,
required,
SaveButton,
TextInput,
Toolbar,
minLength
} from "react-admin";
import { isEmpty, isEqual } from "lodash";
import { email, Filter, minLength, required, SaveButton, TextInput, Toolbar } from "react-admin";
import { isValidPhoneNumber } from "libphonenumber-js";

export const UserTitle = ({ record, titlePrefix }) => {
return (
Expand Down Expand Up @@ -57,21 +48,21 @@ export const PasswordTextField = props => (
</sub>
);

export const mobileNumberFormatter = (v = "") =>
isNil(v) ? v : v.substring(phoneCountryPrefix.length);
export const mobileNumberParser = v =>
v.startsWith(phoneCountryPrefix) ? v : phoneCountryPrefix.concat(v);

export const isRequired = required("This field is required");
export const validateEmail = [isRequired, email("Please enter a valid email address")];
export const validatePhone = [
isRequired,
regex(/[0-9]{12}/, "Enter a 10 digit number (eg. 9820324567)")
];
export const validatePassword = [
isRequired,
minLength(8, "Password too small, enter at least 8 characters.")
];

const getValidatePhoneValidator = function(region) {
return value => {
const isValid = isValidPhoneNumber(value, region);
return isValid ? undefined : "Invalid phone number";
};
};

export const getPhoneValidator = function(region) {
return [isRequired, getValidatePhoneValidator(region)];
};

export const validatePassword = [isRequired, minLength(8, "Password too small, enter at least 8 characters.")];
export const validatePasswords = ({ password, confirmPassword }) => {
const errors = {};
if (!isEqual(password, confirmPassword)) {
Expand Down
Loading

0 comments on commit cfb60c1

Please sign in to comment.