From 18ed87ab44a04665600732b504135a6430cac899 Mon Sep 17 00:00:00 2001 From: olewandowski1 Date: Thu, 4 Jan 2024 11:06:53 +0100 Subject: [PATCH 1/9] OP-1723: fix form reload and eslint errors --- src/components/UserForm.js | 87 ++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/src/components/UserForm.js b/src/components/UserForm.js index 8a21ba0..6748632 100644 --- a/src/components/UserForm.js +++ b/src/components/UserForm.js @@ -41,11 +41,12 @@ const USER_OVERVIEW_MUTATIONS_KEY = "user.UserOverview.mutations"; const setupState = (props) => ({ isLocked: false, - user: !props.userId + user: !props?.userId ? { userTypes: [INTERACTIVE_USER_TYPE], } : props.user, + isSaved: false, }); class UserForm extends Component { @@ -74,18 +75,20 @@ class UserForm extends Component { } componentDidUpdate(prevProps) { - if (prevProps.region_districts != this.props.region_districts) { - if (!!this.props.region_districts) { + if (prevProps.region_districts !== this.props.region_districts) { + if (this.props.region_districts) { const combined = [ - ...(!!this.state.user.districts ? this.state.user.districts : []), + ...(this.state.user.districts ? this.state.user.districts : []), ...this.props.region_districts, ]; - const no_duplicates = [...new Map(combined.map((x) => [x.uuid, x])).values()]; - this.state.user.districts = no_duplicates; - this.state.user.region = []; - this.setState((state, props) => ({ + + const noDuplicates = [...new Map(combined.map((x) => [x.uuid, x])).values()]; + + this.setState((prevState) => ({ user: { - ...state.user, + ...prevState.user, + districts: noDuplicates, + region: [], }, })); } @@ -108,25 +111,37 @@ class UserForm extends Component { } } - reload = () => { - const { clientMutationId } = this.props.mutation; - if (clientMutationId) { - this.props.fetchUserMutation(this.props.modulesManager, clientMutationId).then((res) => { - const mutationLogs = parseData(res.payload.data.mutationLogs); - if ( - mutationLogs && - mutationLogs[0] && - mutationLogs[0].users && - mutationLogs[0].users[0] && - mutationLogs[0].users[0].coreUser - ) { - const { id } = parseData(res.payload.data.mutationLogs)[0].users[0].coreUser; - if (id) { - historyPush(this.props.modulesManager, this.props.history, "admin.userOverview", [id]); - } - } - }); + reload = async () => { + const { isSaved } = this.state; + // eslint-disable-next-line no-shadow + const { modulesManager, history, mutation, fetchUserMutation, userId, fetchUser } = this.props; + + if (userId) { + try { + await fetchUser(modulesManager, userId); + } catch (error) { + // eslint-disable-next-line no-console + console.error(`[RELOAD_USER]: Fetching user details failed. ${error}`); + } + return; + } + + if (isSaved) { + try { + const { clientMutationId } = mutation; + const response = await fetchUserMutation(modulesManager, clientMutationId); + const createdUserId = parseData(response.payload.data.mutationLogs)[0].users[0].coreUser.id; + + await fetchUser(modulesManager, createdUserId); + historyPush(modulesManager, history, "admin.userOverview", [createdUserId]); + } catch (error) { + // eslint-disable-next-line no-console + console.error(`[RELOAD_USER]: Fetching user details failed. ${error}`); + } + return; } + + this.setState(setupState(this.props)); }; canSave = () => { @@ -152,8 +167,8 @@ class UserForm extends Component { if (user.userTypes?.includes(CLAIM_ADMIN_USER_TYPE) && !user.healthFacility) return false; if (user.userTypes?.includes(ENROLMENT_OFFICER_USER_TYPE) && !user.officerVillages) return false; if ( - (this.props.obligatory_user_fields?.phone == "M" || - (user.userTypes?.includes(ENROLMENT_OFFICER_USER_TYPE) && this.props.obligatory_eo_fields?.phone == "M")) && + (this.props.obligatory_user_fields?.phone === "M" || + (user.userTypes?.includes(ENROLMENT_OFFICER_USER_TYPE) && this.props.obligatory_eo_fields?.phone === "M")) && !user.phoneNumber ) return false; @@ -162,12 +177,11 @@ class UserForm extends Component { }; save = (user) => { - this.setState({ isLocked: true }); - this.props.save(user); + this.setState({ isLocked: !user?.id, isSaved: true }, this.props.save(user)); }; onEditedChanged = (user) => { - if (!!user.region) { + if (user.region) { user.region.forEach((region) => { this.props.fetchRegionDistricts(region); }); @@ -196,7 +210,7 @@ class UserForm extends Component { obligatoryEoFields, usernameLength, } = this.props; - const { user } = this.state; + const { user, isSaved } = this.state; if (!rights.includes(RIGHT_USERS)) return null; @@ -205,12 +219,13 @@ class UserForm extends Component { modulesManager.getContribs(USER_OVERVIEW_MUTATIONS_KEY).some((mutation) => mutation(state)); const actions = [ - !userId && { + { doIt: this.reload, icon: , - onlyIfDirty: !readOnly && !isInMutation, + onlyIfDirty: !readOnly && !isInMutation && !isSaved, }, - ].filter(Boolean); + ]; + return (
From c245a6bd0b6e310698d1cc7f39d0faa8ccd3facb Mon Sep 17 00:00:00 2001 From: olewandowski1 Date: Mon, 8 Jan 2024 16:27:40 +0100 Subject: [PATCH 2/9] OP-1725: remove null options --- src/components/UserMasterPanel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/UserMasterPanel.js b/src/components/UserMasterPanel.js index 41377a1..5cb1c25 100644 --- a/src/components/UserMasterPanel.js +++ b/src/components/UserMasterPanel.js @@ -264,7 +264,7 @@ const UserMasterPanel = (props) => { label="user.language" readOnly={readOnly} required - withNull + withNull={false} nullLabel={formatMessage("UserMasterPanel.language.null")} value={edited.language ?? ""} onChange={(language) => onEditedChanged({ ...edited, language })} From ad0c66c077fbb36d36b768265077b838c0d9d721 Mon Sep 17 00:00:00 2001 From: olewandowski1 Date: Thu, 8 Feb 2024 13:16:56 +0100 Subject: [PATCH 3/9] ONI-164: add setting to enable displaying first name before second name --- src/components/UserFilter.js | 127 ++++++++++-------- src/components/UserMasterPanel.js | 66 ++++++--- src/components/UserSearcher.js | 78 ++++++----- .../pickers/EnrolmentOfficerPicker.js | 27 +++- .../SubstitutionEnrolmentOfficerPicker.js | 27 +++- src/components/pickers/UserPicker.js | 23 +++- src/constants.js | 4 + 7 files changed, 221 insertions(+), 131 deletions(-) diff --git a/src/components/UserFilter.js b/src/components/UserFilter.js index 6ab85f6..b852fee 100644 --- a/src/components/UserFilter.js +++ b/src/components/UserFilter.js @@ -13,6 +13,7 @@ import { TextInput, formatMessage, } from "@openimis/fe-core"; +import { DEFAULT } from "../constants"; const styles = (theme) => ({ dialogTitle: theme.dialog.title, @@ -35,7 +36,6 @@ const extractLocations = (locations) => { const village = municipality && locationsArray.find((l) => l.parent && l.parent.id === municipality.id); return { region, district, municipality, village }; - }; const getParentLocation = (locations) => { @@ -71,10 +71,18 @@ const getParentLocation = (locations) => { }; } return newLocation; - }; class UserFilter extends Component { + constructor(props) { + super(props); + this.renderLastNameFirst = props.modulesManager.getConf( + "fe-insuree", + "renderLastNameFirst", + DEFAULT.RENDER_LAST_NAME_FIRST, + ); + } + state = { locationFilters: {}, selectedDistrict: {}, @@ -90,7 +98,6 @@ class UserFilter extends Component { return !!filters && !!filters[k] ? filters[k].value : null; }; - filterTextFieldValue = (k) => { const { filters } = this.props; return !!filters && !!filters[k] ? filters[k].value : ""; @@ -103,7 +110,6 @@ class UserFilter extends Component { return district; }; - onChangeCheckbox = (key, value) => { const filters = [ { @@ -163,8 +169,60 @@ class UserFilter extends Component { onChangeFilters(filters); }; + renderLastNameField = (classes) => ( + + + this.debouncedOnChangeFilter([ + { + id: "lastName", + value: v, + filter: `lastName: "${v}"`, + }, + ]) + } + /> + + } + /> + ); + + renderGivenNameField = (classes) => ( + + + this.debouncedOnChangeFilter([ + { + id: "otherNames", + value: v, + filter: `otherNames: "${v}"`, + }, + ]) + } + /> + + } + /> + ); + render() { - const { classes, filters, onChangeFilters , intl} = this.props; + const { classes, filters, onChangeFilters, intl } = this.props; const { locationFilters, currentUserType, currentUserRoles, selectedDistrict } = this.state; return (
@@ -204,7 +262,6 @@ class UserFilter extends Component { pubRef="location.HealthFacilityPicker" withNull={true} value={this.filterValue("healthFacilityId") || ""} - district={selectedDistrict} onChange={(v) => { onChangeFilters([ @@ -255,52 +312,17 @@ class UserFilter extends Component { } /> - - - this.debouncedOnChangeFilter([ - { - id: "lastName", - value: v, - filter: `lastName: "${v}"`, - }, - ]) - } - /> - - } - /> - - - this.debouncedOnChangeFilter([ - { - id: "otherNames", - value: v, - filter: `otherNames: "${v}"`, - }, - ]) - } - /> - - } - /> + {this.renderLastNameFirst ? ( + <> + {this.renderLastNameField(classes)} + {this.renderGivenNameField(classes)} + + ) : ( + <> + {this.renderGivenNameField(classes)} + {this.renderLastNameField(classes)} + + )} } label={formatMessage(intl, "admin", "UserFilter.showDeleted")} - /> } diff --git a/src/components/UserMasterPanel.js b/src/components/UserMasterPanel.js index 5cb1c25..00c7b3b 100644 --- a/src/components/UserMasterPanel.js +++ b/src/components/UserMasterPanel.js @@ -1,3 +1,4 @@ +/* eslint-disable no-shadow */ import React, { useEffect, useState } from "react"; import { connect, useDispatch } from "react-redux"; @@ -13,7 +14,7 @@ import { PublishedComponent, ValidatedTextInput, } from "@openimis/fe-core"; -import { CLAIM_ADMIN_USER_TYPE, ENROLMENT_OFFICER_USER_TYPE, EMAIL_REGEX_PATTERN } from "../constants"; +import { CLAIM_ADMIN_USER_TYPE, ENROLMENT_OFFICER_USER_TYPE, EMAIL_REGEX_PATTERN, DEFAULT } from "../constants"; import { usernameValidationCheck, usernameValidationClear, @@ -61,6 +62,11 @@ const UserMasterPanel = (props) => { } = props; const { formatMessage } = useTranslations("admin", modulesManager); const dispatch = useDispatch(); + const renderLastNameFirst = modulesManager.getConf( + "fe-insuree", + "renderLastNameFirst", + DEFAULT.RENDER_LAST_NAME_FIRST, + ); const shouldValidateUsername = (inputValue) => { const shouldBeValidated = inputValue !== savedUsername; @@ -91,7 +97,6 @@ const UserMasterPanel = (props) => { handleEmailChange(edited?.email); }, []); - const [showPassword, setShowPassword] = useState(false); const handleClickShowPassword = () => setShowPassword((show) => !show); @@ -111,6 +116,32 @@ const UserMasterPanel = (props) => { onEditedChanged({ ...edited, password: generatedPassword, confirmPassword: generatedPassword }); }; + const renderLastNameField = (edited, classes, readOnly) => ( + + onEditedChanged({ ...edited, lastName })} + /> + + ); + + const renderGivenNameField = (edited, classes, readOnly) => ( + + onEditedChanged({ ...edited, otherNames })} + /> + + ); + return ( @@ -135,26 +166,17 @@ const UserMasterPanel = (props) => { }} /> - - onEditedChanged({ ...edited, otherNames })} - /> - - - onEditedChanged({ ...edited, lastName })} - /> - + {renderLastNameFirst ? ( + <> + {renderLastNameField(edited, classes, readOnly)} + {renderGivenNameField(edited, classes, readOnly)} + + ) : ( + <> + {renderGivenNameField(edited, classes, readOnly)} + {renderLastNameField(edited, classes, readOnly)} + + )} {!( obligatoryUserFields?.email == "H" || (edited.userTypes?.includes(ENROLMENT_OFFICER_USER_TYPE) && obligatoryEOFields?.email == "H") diff --git a/src/components/UserSearcher.js b/src/components/UserSearcher.js index a2c2338..71f75dd 100644 --- a/src/components/UserSearcher.js +++ b/src/components/UserSearcher.js @@ -17,47 +17,56 @@ import { decodeId, } from "@openimis/fe-core"; import { fetchUsersSummaries, deleteUser } from "../actions"; -import { RIGHT_USER_DELETE } from "../constants"; +import { DEFAULT, RIGHT_USER_DELETE } from "../constants"; import UserFilter from "./UserFilter"; const USER_SEARCHER_CONTRIBUTION_KEY = "user.UserSearcher"; -const getHeaders = () => [ - "admin.user.username", - "admin.user.lastName", - "admin.user.otherNames", - "admin.user.email", - "admin.user.phone", - "admin.user.dob", - "", -]; - -const getSorts = () => [ - ["username", true], - ["iUser_LastName", true], - ["iUser_OtherNames", true], - ["iUser_Email", true], - ["iUser_Phone", true], - ["officer__dob", false], -]; - -const getAligns = () => { - const aligns = getHeaders().map(() => null); - aligns.splice(-1, 1, "right"); - return aligns; -}; - const styles = (theme) => ({ horizontalButtonContainer: theme.buttonContainer.horizontal, }); class UserSearcher extends Component { + constructor(props) { + super(props); + this.renderLastNameFirst = props.modulesManager.getConf( + "fe-insuree", + "renderLastNameFirst", + DEFAULT.RENDER_LAST_NAME_FIRST, + ); + } + state = { deleteUser: null, params: {}, defaultParams: {}, }; + getHeaders = () => [ + "admin.user.username", + this.renderLastNameFirst ? "admin.user.lastName" : "admin.user.otherNames", + !this.renderLastNameFirst ? "admin.user.lastName" : "admin.user.otherNames", + "admin.user.email", + "admin.user.phone", + "admin.user.dob", + "", + ]; + + getSorts = () => [ + ["username", true], + this.renderLastNameFirst ? ["iUser_LastName", true] : ["iUser_OtherNames", true], + !this.renderLastNameFirst ? ["iUser_LastName", true] : ["iUser_OtherNames", true], + ["iUser_Email", true], + ["iUser_Phone", true], + ["officer__dob", false], + ]; + + getAligns = () => { + const aligns = this.getHeaders().map(() => null); + aligns.splice(-1, 1, "right"); + return aligns; + }; + fetch = (params) => { this.setState({ params }); if (this.props.fetchedUserLocation) { @@ -128,8 +137,8 @@ class UserSearcher extends Component { itemFormatters = () => { const formatters = [ (u) => u.username, - (u) => this.getUserItem(u, "lastName"), - (u) => this.getUserItem(u, "otherNames"), + (u) => (this.renderLastNameFirst ? this.getUserItem(u, "lastName") : this.getUserItem(u, "otherNames")), + (u) => (!this.renderLastNameFirst ? this.getUserItem(u, "lastName") : this.getUserItem(u, "otherNames")), (u) => this.getUserItem(u, "email") || this.getUserItem(u, "emailId"), (u) => this.getUserItem(u, "phone"), (u) => @@ -145,15 +154,11 @@ class UserSearcher extends Component { {this.props.rights.includes(RIGHT_USER_DELETE) && u.validityTo ? null : ( - this.setState({ deleteUser: u })} - disabled={u.validityTo} - > + this.setState({ deleteUser: u })} disabled={u.validityTo}> )} -
), ]; @@ -187,16 +192,15 @@ class UserSearcher extends Component { contributionKey={USER_SEARCHER_CONTRIBUTION_KEY} tableTitle={formatMessageWithValues(intl, "admin.user", "userSummaries", { count: usersPageInfo.totalCount?.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,"), - })} fetch={this.fetch} rowIdentifier={(r) => r.uuid} filtersToQueryParams={this.filtersToQueryParams} defaultOrderBy="-username" - headers={getHeaders} - aligns={getAligns} + headers={this.getHeaders} + aligns={this.getAligns} itemFormatters={this.itemFormatters} - sorts={getSorts} + sorts={this.getSorts} rowDisabled={(_, i) => i.validityTo || i.clientMutationId} rowLocked={(_, i) => i.clientMutationId} onDoubleClick={onDoubleClick} diff --git a/src/components/pickers/EnrolmentOfficerPicker.js b/src/components/pickers/EnrolmentOfficerPicker.js index dd25a8a..5d484e2 100644 --- a/src/components/pickers/EnrolmentOfficerPicker.js +++ b/src/components/pickers/EnrolmentOfficerPicker.js @@ -1,12 +1,8 @@ import React, { useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; -import { Autocomplete } from "@openimis/fe-core"; +import { Autocomplete, withModulesManager } from "@openimis/fe-core"; import { fetchEnrolmentOfficers } from "../../actions"; - -const formatSuggestion = (p) => { - if (!p) return "?"; - return [p.code, p.lastName, p.otherNames].filter(Boolean).join(" "); -}; +import { DEFAULT } from "../../constants"; const EnrolmentOfficerPicker = (props) => { const { @@ -37,6 +33,23 @@ const EnrolmentOfficerPicker = (props) => { ); }, [searchString]); + const formatSuggestion = (p) => { + const renderLastNameFirst = modulesManager.getConf( + "fe-insuree", + "renderLastNameFirst", + DEFAULT.RENDER_LAST_NAME_FIRST, + ); + + if (!p) return "?"; + return [ + p.username, + renderLastNameFirst ? p.lastName : p.otherNames, + !renderLastNameFirst ? p.lastName : p.otherNames, + ] + .filter(Boolean) + .join(" "); + }; + return ( { ); }; -export default EnrolmentOfficerPicker; +export default withModulesManager(EnrolmentOfficerPicker); diff --git a/src/components/pickers/SubstitutionEnrolmentOfficerPicker.js b/src/components/pickers/SubstitutionEnrolmentOfficerPicker.js index 8d8fc7a..47a6838 100644 --- a/src/components/pickers/SubstitutionEnrolmentOfficerPicker.js +++ b/src/components/pickers/SubstitutionEnrolmentOfficerPicker.js @@ -3,13 +3,9 @@ import { useDispatch, useSelector } from "react-redux"; import { TextField } from "@material-ui/core"; -import { Autocomplete, useTranslations } from "@openimis/fe-core"; +import { withModulesManager, Autocomplete, useTranslations } from "@openimis/fe-core"; import { fetchSubstitutionEOs } from "../../utils"; - -const formatSuggestion = (p) => { - if (!p) return "?"; - return [p.code, p.lastName, p.otherNames].filter(Boolean).join(" "); -}; +import { DEFAULT } from "../../constants"; const SubstitutionEnrolmentOfficerPicker = (props) => { const { @@ -38,6 +34,23 @@ const SubstitutionEnrolmentOfficerPicker = (props) => { fetchSubstitutionEOs(dispatch, modulesManager, officerUuid, searchString, villages); }; + const formatSuggestion = (p) => { + const renderLastNameFirst = modulesManager.getConf( + "fe-insuree", + "renderLastNameFirst", + DEFAULT.RENDER_LAST_NAME_FIRST, + ); + + if (!p) return "?"; + return [ + p.username, + renderLastNameFirst ? p.lastName : p.otherNames, + !renderLastNameFirst ? p.lastName : p.otherNames, + ] + .filter(Boolean) + .join(" "); + }; + return ( { ); }; -export default SubstitutionEnrolmentOfficerPicker; +export default withModulesManager(SubstitutionEnrolmentOfficerPicker); diff --git a/src/components/pickers/UserPicker.js b/src/components/pickers/UserPicker.js index 8b07073..28b5174 100644 --- a/src/components/pickers/UserPicker.js +++ b/src/components/pickers/UserPicker.js @@ -5,6 +5,7 @@ import { Autocomplete } from "@material-ui/lab"; import { TextField } from "@material-ui/core"; import { withModulesManager, useDebounceCb, useTranslations } from "@openimis/fe-core"; import { fetchUsers } from "../../actions"; +import { DEFAULT } from "../../constants"; const styles = (theme) => ({ label: { @@ -12,11 +13,6 @@ const styles = (theme) => ({ }, }); -const formatSuggestion = (p) => { - if (!p) return "?"; - return [p.username, p.iUser?.lastName, p.iUser?.otherNames].filter(Boolean).join(" "); -}; - const UserPicker = (props) => { const { onChange, @@ -48,6 +44,23 @@ const UserPicker = (props) => { if (!multiple) setOpen(false); }; + const formatSuggestion = (p) => { + const renderLastNameFirst = modulesManager.getConf( + "fe-insuree", + "renderLastNameFirst", + DEFAULT.RENDER_LAST_NAME_FIRST, + ); + + if (!p) return "?"; + return [ + p.username, + renderLastNameFirst ? p.iUser?.lastName : p.iUser?.otherNames, + !renderLastNameFirst ? p.iUser?.lastName : p.iUser?.otherNames, + ] + .filter(Boolean) + .join(" "); + }; + useEffect(() => { if (searchString?.length > minCharLookup) { dispatch( diff --git a/src/constants.js b/src/constants.js index 47d66b4..1203861 100644 --- a/src/constants.js +++ b/src/constants.js @@ -22,6 +22,10 @@ export const CLAIM_ADMIN_USER_TYPE = "CLAIM_ADMIN"; export const CLAIM_ADMIN_IS_SYSTEM = 256; export const MODULE_NAME = "user"; +export const DEFAULT = { + RENDER_LAST_NAME_FIRST: true, +}; + // https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address export const EMAIL_REGEX_PATTERN = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; From f4bdfd53f3249bcdab8e3bc9697013884c485aa1 Mon Sep 17 00:00:00 2001 From: olewandowski1 Date: Thu, 29 Feb 2024 16:11:41 +0100 Subject: [PATCH 4/9] OM-131: if isWorker, display users as an only entry --- src/components/AdminMainMenu.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/components/AdminMainMenu.js b/src/components/AdminMainMenu.js index d260147..f43fb71 100644 --- a/src/components/AdminMainMenu.js +++ b/src/components/AdminMainMenu.js @@ -30,10 +30,36 @@ import { const ADMIN_MAIN_MENU_CONTRIBUTION_KEY = "admin.MainMenu"; class AdminMainMenu extends Component { + constructor(props) { + super(props); + this.isWorker = props.modulesManager.getConf("fe-core", "isWorker", false); + } + render() { const { rights } = this.props; const entries = []; + if (this.isWorker) { + if (rights.includes(RIGHT_USERS)) { + entries.push({ + text: formatMessage(this.props.intl, "admin", "menu.users"), + icon: , + route: "/admin/users", + }); + } + + if (!entries.length) return null; + + return ( + } + entries={entries} + /> + ); + } + if (rights.includes(RIGHT_PRODUCTS)) { entries.push({ text: formatMessage(this.props.intl, "admin", "menu.products"), From 29ea6f93cce4e4b9620221f3b0272de3648fe760 Mon Sep 17 00:00:00 2001 From: olewandowski1 Date: Thu, 29 Feb 2024 16:25:05 +0100 Subject: [PATCH 5/9] OM-131: fix condition --- src/components/AdminMainMenu.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/components/AdminMainMenu.js b/src/components/AdminMainMenu.js index f43fb71..e8efc55 100644 --- a/src/components/AdminMainMenu.js +++ b/src/components/AdminMainMenu.js @@ -39,14 +39,12 @@ class AdminMainMenu extends Component { const { rights } = this.props; const entries = []; - if (this.isWorker) { - if (rights.includes(RIGHT_USERS)) { - entries.push({ - text: formatMessage(this.props.intl, "admin", "menu.users"), - icon: , - route: "/admin/users", - }); - } + if (this.isWorker && rights.includes(RIGHT_USERS)) { + entries.push({ + text: formatMessage(this.props.intl, "admin", "menu.users"), + icon: , + route: "/admin/users", + }); if (!entries.length) return null; From 34d49e4d22b809bf3fb15f2091736d60e7df9cde Mon Sep 17 00:00:00 2001 From: olewandowski1 Date: Fri, 1 Mar 2024 16:02:09 +0100 Subject: [PATCH 6/9] hotfix: change condition --- src/components/AdminMainMenu.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/AdminMainMenu.js b/src/components/AdminMainMenu.js index e8efc55..f43fb71 100644 --- a/src/components/AdminMainMenu.js +++ b/src/components/AdminMainMenu.js @@ -39,12 +39,14 @@ class AdminMainMenu extends Component { const { rights } = this.props; const entries = []; - if (this.isWorker && rights.includes(RIGHT_USERS)) { - entries.push({ - text: formatMessage(this.props.intl, "admin", "menu.users"), - icon: , - route: "/admin/users", - }); + if (this.isWorker) { + if (rights.includes(RIGHT_USERS)) { + entries.push({ + text: formatMessage(this.props.intl, "admin", "menu.users"), + icon: , + route: "/admin/users", + }); + } if (!entries.length) return null; From 9dfe7ff1f4cb53584f7df8cb02390c508155eb86 Mon Sep 17 00:00:00 2001 From: olewandowski1 Date: Thu, 14 Mar 2024 10:17:30 +0100 Subject: [PATCH 7/9] hotfix: add contribution filter --- src/components/AdminMainMenu.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/AdminMainMenu.js b/src/components/AdminMainMenu.js index f43fb71..3ba80db 100644 --- a/src/components/AdminMainMenu.js +++ b/src/components/AdminMainMenu.js @@ -48,6 +48,12 @@ class AdminMainMenu extends Component { }); } + entries.push( + ...this.props.modulesManager + .getContribs(ADMIN_MAIN_MENU_CONTRIBUTION_KEY) + .filter((c) => !c.filter || c.filter(rights)), + ); + if (!entries.length) return null; return ( From 4d08466998d52130c4719cba815e271d1824e6d7 Mon Sep 17 00:00:00 2001 From: olewandowski1 Date: Wed, 27 Mar 2024 15:37:46 +0100 Subject: [PATCH 8/9] OM-131: create new contribution point --- src/components/AdminMainMenu.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/AdminMainMenu.js b/src/components/AdminMainMenu.js index 3ba80db..7e7d36f 100644 --- a/src/components/AdminMainMenu.js +++ b/src/components/AdminMainMenu.js @@ -28,6 +28,7 @@ import { } from "../constants"; const ADMIN_MAIN_MENU_CONTRIBUTION_KEY = "admin.MainMenu"; +const ADMIN_VOUCHER_MAIN_MENU_CONTRIBUTION_KEY = "admin.voucher.MainMenu"; class AdminMainMenu extends Component { constructor(props) { @@ -50,7 +51,7 @@ class AdminMainMenu extends Component { entries.push( ...this.props.modulesManager - .getContribs(ADMIN_MAIN_MENU_CONTRIBUTION_KEY) + .getContribs(ADMIN_VOUCHER_MAIN_MENU_CONTRIBUTION_KEY) .filter((c) => !c.filter || c.filter(rights)), ); From 9205c844189c95f2fd67f0ccf1d9beda220b9ce1 Mon Sep 17 00:00:00 2001 From: olewandowski1 Date: Thu, 11 Apr 2024 12:08:24 +0200 Subject: [PATCH 9/9] OP-1771: fix user form reload --- src/components/UserForm.js | 6 +++++- src/components/UserMasterPanel.js | 8 ++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/UserForm.js b/src/components/UserForm.js index 6748632..a313c64 100644 --- a/src/components/UserForm.js +++ b/src/components/UserForm.js @@ -47,6 +47,7 @@ const setupState = (props) => ({ } : props.user, isSaved: false, + reset: 0, }); class UserForm extends Component { @@ -123,6 +124,7 @@ class UserForm extends Component { // eslint-disable-next-line no-console console.error(`[RELOAD_USER]: Fetching user details failed. ${error}`); } + this.setState((state) => ({ ...state, reset: state.reset + 1 })); return; } @@ -138,6 +140,7 @@ class UserForm extends Component { // eslint-disable-next-line no-console console.error(`[RELOAD_USER]: Fetching user details failed. ${error}`); } + this.setState((state) => ({ ...state, reset: state.reset + 1 })); return; } @@ -210,7 +213,7 @@ class UserForm extends Component { obligatoryEoFields, usernameLength, } = this.props; - const { user, isSaved } = this.state; + const { user, isSaved, reset } = this.state; if (!rights.includes(RIGHT_USERS)) return null; @@ -236,6 +239,7 @@ class UserForm extends Component { title={userId ? "admin.user.UserOverview.title" : "admin.user.UserOverview.newTitle"} edited_id={userId} edited={user} + reset={reset} back={back} add={add} openDirty={save} diff --git a/src/components/UserMasterPanel.js b/src/components/UserMasterPanel.js index 00c7b3b..2d2fef8 100644 --- a/src/components/UserMasterPanel.js +++ b/src/components/UserMasterPanel.js @@ -229,11 +229,7 @@ const UserMasterPanel = (props) => { district={edited.districts} module="admin" readOnly={readOnly} - required={ - edited.userTypes.includes( - CLAIM_ADMIN_USER_TYPE, - ) /* This field is also present in the claim administrator panel */ - } + required={edited.userTypes.includes(CLAIM_ADMIN_USER_TYPE)} onChange={(healthFacility) => onEditedChanged({ ...edited, healthFacility })} /> @@ -264,7 +260,7 @@ const UserMasterPanel = (props) => { onEditedChanged({ ...edited, districts })} readOnly={readOnly} required