From 75d5039e68f986bf0413a52f4b889c738614a39f Mon Sep 17 00:00:00 2001 From: Thomas Zemp Date: Thu, 14 Sep 2023 11:09:18 +0200 Subject: [PATCH] fix: update successful save redirects [DHIS2-15431] (#1218) --- src/AppWrapper.js | 7 +++++-- src/components/Form.js | 8 +++----- src/components/GroupForm/GroupForm.js | 14 ++++++++++++-- src/components/RoleForm/RoleForm.js | 14 ++++++++++++-- src/components/UserForm/UserForm.js | 14 ++++++++++++-- src/pages/GroupList/ContextMenu/ContextMenu.js | 7 +++++-- src/pages/GroupList/GroupTable.js | 3 +++ src/pages/RoleList/ContextMenu/ContextMenu.js | 7 +++++-- src/pages/RoleList/RoleTable.js | 3 +++ src/pages/UserList/ContextMenu/ContextMenu.js | 7 +++++-- src/pages/UserList/UserTable.js | 3 +++ src/providers/ReferrerContext.js | 6 ++++++ src/providers/ReferrerProvider.js | 17 +++++++++++++++++ src/providers/index.js | 2 ++ src/providers/useReferrer.js | 4 ++++ src/utils/navigateTo.js | 3 ++- 16 files changed, 99 insertions(+), 20 deletions(-) create mode 100644 src/providers/ReferrerContext.js create mode 100644 src/providers/ReferrerProvider.js create mode 100644 src/providers/index.js create mode 100644 src/providers/useReferrer.js diff --git a/src/AppWrapper.js b/src/AppWrapper.js index 979a417c9..00760477a 100644 --- a/src/AppWrapper.js +++ b/src/AppWrapper.js @@ -4,11 +4,14 @@ import { CssVariables } from '@dhis2/ui' import React from 'react' import App from './App.js' import { CurrentUserProvider } from './components/CurrentUserProvider.js' +import { ReferrerProvider } from './providers/index.js' const AppWrapper = () => ( - - + + + + ) diff --git a/src/components/Form.js b/src/components/Form.js index 6e672f656..f890e2fd0 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -19,7 +19,6 @@ import { import cx from 'classnames' import PropTypes from 'prop-types' import React, { useState, useCallback, useMemo } from 'react' -import { useHistory } from 'react-router-dom' import styles from './Form.module.css' import SearchableOrgUnitTree from './SearchableOrgUnitTree/index.js' @@ -288,10 +287,8 @@ const Form = ({ submitButtonLabel, cancelButtonLabel, onSubmit, + onCancel, }) => { - const history = useHistory() - const handleCancel = () => history.goBack() - if (loading) { return ( @@ -337,7 +334,7 @@ const Form = ({ > {submitButtonLabel} - @@ -354,6 +351,7 @@ Form.defaultProps = { Form.propTypes = { children: PropTypes.func.isRequired, submitButtonLabel: PropTypes.string.isRequired, + onCancel: PropTypes.func.isRequired, onSubmit: PropTypes.func.isRequired, cancelButtonLabel: PropTypes.string, error: PropTypes.instanceOf(Error), diff --git a/src/components/GroupForm/GroupForm.js b/src/components/GroupForm/GroupForm.js index 9cef93e31..de7aa23e9 100644 --- a/src/components/GroupForm/GroupForm.js +++ b/src/components/GroupForm/GroupForm.js @@ -5,6 +5,8 @@ import PropTypes from 'prop-types' import React from 'react' import { useHistory } from 'react-router-dom' import { useCurrentUser } from '../../hooks/useCurrentUser.js' +import { useReferrerInfo } from '../../providers/index.js' +import navigateTo from '../../utils/navigateTo.js' import Attributes from '../Attributes/index.js' import Form, { FormSection } from '../Form.js' import BasicInformationSection from './BasicInformationSection.js' @@ -18,10 +20,11 @@ import UserGroupManagementSection from './UserGroupManagementSection.js' import UserManagementSection from './UserManagementSection.js' const GroupForm = ({ submitButtonLabel, group }) => { - const history = useHistory() const engine = useDataEngine() const { loading, error, userGroupOptions, attributes } = useFormData() const currentUser = useCurrentUser() + const { referrer } = useReferrerInfo() + const history = useHistory() const handleSubmit = async (values, form) => { try { if (group) { @@ -43,7 +46,7 @@ const GroupForm = ({ submitButtonLabel, group }) => { }) } - history.goBack() + navigateTo('/user-groups') if (group && currentUser.userGroupIds.includes(group.id)) { currentUser.refresh() } @@ -68,6 +71,13 @@ const GroupForm = ({ submitButtonLabel, group }) => { error={error} submitButtonLabel={submitButtonLabel} onSubmit={handleSubmit} + onCancel={() => { + if (referrer === 'user-groups') { + history.goBack() + } else { + navigateTo('/user-groups') + } + }} > {({ submitError }) => ( <> diff --git a/src/components/RoleForm/RoleForm.js b/src/components/RoleForm/RoleForm.js index ca6dada7f..a62d61e85 100644 --- a/src/components/RoleForm/RoleForm.js +++ b/src/components/RoleForm/RoleForm.js @@ -6,6 +6,8 @@ import PropTypes from 'prop-types' import React from 'react' import { useHistory } from 'react-router-dom' import { useCurrentUser } from '../../hooks/useCurrentUser.js' +import { useReferrerInfo } from '../../providers/index.js' +import navigateTo from '../../utils/navigateTo.js' import Form, { FormSection, TextField, TransferField } from '../Form.js' import { getJsonPatch } from './getJsonPatch.js' import { getRoleData } from './getRoleData.js' @@ -49,7 +51,6 @@ const getRoleAuthorityIDs = ({ } const RoleForm = ({ submitButtonLabel, role }) => { - const history = useHistory() const engine = useDataEngine() const debouncedUniqueRoleNameValidator = useDebouncedUniqueRoleNameValidator({ engine, roleName: role?.name }) @@ -75,6 +76,8 @@ const RoleForm = ({ submitButtonLabel, role }) => { systemAuthorityOptions, }) const currentUser = useCurrentUser() + const { referrer } = useReferrerInfo() + const history = useHistory() const handleSubmit = async (values, form) => { const roleData = getRoleData({ values }) @@ -100,7 +103,7 @@ const RoleForm = ({ submitButtonLabel, role }) => { }) } - history.goBack() + navigateTo('/user-roles') if (role && currentUser.userRoleIds.includes(role.id)) { currentUser.refresh() } @@ -125,6 +128,13 @@ const RoleForm = ({ submitButtonLabel, role }) => { error={error} submitButtonLabel={submitButtonLabel} onSubmit={handleSubmit} + onCancel={() => { + if (referrer === 'user-roles') { + history.goBack() + } else { + navigateTo('/user-roles') + } + }} > {({ submitError }) => ( <> diff --git a/src/components/UserForm/UserForm.js b/src/components/UserForm/UserForm.js index 118f2fc6c..e5fd7cf1e 100644 --- a/src/components/UserForm/UserForm.js +++ b/src/components/UserForm/UserForm.js @@ -6,6 +6,8 @@ import PropTypes from 'prop-types' import React, { useState } from 'react' import { useHistory } from 'react-router-dom' import { useCurrentUser } from '../../hooks/useCurrentUser.js' +import { useReferrerInfo } from '../../providers/index.js' +import navigateTo from '../../utils/navigateTo.js' import Attributes from '../Attributes/index.js' import Form, { FormSection } from '../Form.js' import AnalyticsDimensionsRestrictionsSection from './AnalyticsDimensionRestrictionsSection.js' @@ -30,7 +32,6 @@ const UserForm = ({ systemInfo: { emailConfigured }, } = useConfig() const [isInvite, setIsInvite] = useState(false) - const history = useHistory() const engine = useDataEngine() const { loading, @@ -45,6 +46,8 @@ const UserForm = ({ attributes, } = useFormData() const currentUser = useCurrentUser() + const { referrer } = useReferrerInfo() + const history = useHistory() const handleSubmit = async (values, form) => { const userData = getUserData({ values, @@ -107,7 +110,7 @@ const UserForm = ({ } } - history.goBack() + navigateTo('/users') if (user && user.id === currentUser.id) { currentUser.refresh() } @@ -151,6 +154,13 @@ const UserForm = ({ : i18n.t('Cancel without saving') } onSubmit={handleSubmit} + onCancel={() => { + if (referrer === 'users') { + history.goBack() + } else { + navigateTo('/users') + } + }} > {({ values, submitError }) => ( <> diff --git a/src/pages/GroupList/ContextMenu/ContextMenu.js b/src/pages/GroupList/ContextMenu/ContextMenu.js index 410cd58d6..e08809744 100644 --- a/src/pages/GroupList/ContextMenu/ContextMenu.js +++ b/src/pages/GroupList/ContextMenu/ContextMenu.js @@ -13,6 +13,7 @@ import { import PropTypes from 'prop-types' import React, { useState } from 'react' import { useCurrentUser } from '../../../hooks/useCurrentUser.js' +import { useReferrerInfo } from '../../../providers/index.js' import navigateTo from '../../../utils/navigateTo.js' import DeleteModal from './Modals/DeleteModal.js' import JoinModal from './Modals/JoinModal.js' @@ -37,6 +38,7 @@ const ContextMenu = ({ group, anchorRef, refetchGroups, onClose }) => { const currentUserIsMember = currentUser.userGroupIds.includes(group.id) const [CurrentModal, setCurrentModal] = useCurrentModal() const { access } = group + const { setReferrer } = useReferrerInfo() return ( <> @@ -67,9 +69,10 @@ const ContextMenu = ({ group, anchorRef, refetchGroups, onClose }) => { } - onClick={() => + onClick={() => { + setReferrer('user-groups') navigateTo(`/user-groups/edit/${group.id}`) - } + }} dense /> )} diff --git a/src/pages/GroupList/GroupTable.js b/src/pages/GroupList/GroupTable.js index 86fbc6871..e791ee694 100644 --- a/src/pages/GroupList/GroupTable.js +++ b/src/pages/GroupList/GroupTable.js @@ -16,6 +16,7 @@ import React from 'react' import DataTableInfoWrapper from '../../components/DataTableInfoWrapper.js' import EmptyTableInfo from '../../components/EmptyTableInfo.js' import { useCurrentUser } from '../../hooks/useCurrentUser.js' +import { useReferrerInfo } from '../../providers/useReferrer.js' import navigateTo from '../../utils/navigateTo.js' import ContextMenuButton from './ContextMenu/ContextMenuButton.js' @@ -28,6 +29,7 @@ const GroupTable = ({ onNameSortDirectionToggle, }) => { const currentUser = useCurrentUser() + const { setReferrer } = useReferrerInfo() if (loading && !groups) { return ( @@ -93,6 +95,7 @@ const GroupTable = ({ {groups.map((group) => { const { id, displayName, access } = group const handleClick = () => { + setReferrer('user-groups') if (access.update) { navigateTo(`/user-groups/edit/${id}`) } else if (access.read) { diff --git a/src/pages/RoleList/ContextMenu/ContextMenu.js b/src/pages/RoleList/ContextMenu/ContextMenu.js index 5ca85a9a7..e6ff9889a 100644 --- a/src/pages/RoleList/ContextMenu/ContextMenu.js +++ b/src/pages/RoleList/ContextMenu/ContextMenu.js @@ -12,6 +12,7 @@ import { } from '@dhis2/ui' import PropTypes from 'prop-types' import React, { useState } from 'react' +import { useReferrerInfo } from '../../../providers/index.js' import navigateTo from '../../../utils/navigateTo.js' import DeleteModal from './Modals/DeleteModal.js' import SharingSettingsModal from './Modals/SharingSettingsModal.js' @@ -32,6 +33,7 @@ const useCurrentModal = () => { const ContextMenu = ({ role, anchorRef, refetchRoles, onClose }) => { const [CurrentModal, setCurrentModal] = useCurrentModal() const { access } = role + const { setReferrer } = useReferrerInfo() return ( <> @@ -62,9 +64,10 @@ const ContextMenu = ({ role, anchorRef, refetchRoles, onClose }) => { } - onClick={() => + onClick={() => { + setReferrer('user-roles') navigateTo(`/user-roles/edit/${role.id}`) - } + }} dense /> )} diff --git a/src/pages/RoleList/RoleTable.js b/src/pages/RoleList/RoleTable.js index a587d1f01..00af930ee 100644 --- a/src/pages/RoleList/RoleTable.js +++ b/src/pages/RoleList/RoleTable.js @@ -15,6 +15,7 @@ import PropTypes from 'prop-types' import React from 'react' import DataTableInfoWrapper from '../../components/DataTableInfoWrapper.js' import EmptyTableInfo from '../../components/EmptyTableInfo.js' +import { useReferrerInfo } from '../../providers/useReferrer.js' import navigateTo from '../../utils/navigateTo.js' import ContextMenuButton from './ContextMenu/ContextMenuButton.js' @@ -26,6 +27,7 @@ const RoleTable = ({ nameSortDirection, onNameSortDirectionToggle, }) => { + const { setReferrer } = useReferrerInfo() if (loading && !roles) { return ( @@ -90,6 +92,7 @@ const RoleTable = ({ {roles.map((role) => { const { id, displayName, access, description } = role const handleClick = () => { + setReferrer('user-roles') if (access.update) { navigateTo(`/user-roles/edit/${id}`) } else if (access.read) { diff --git a/src/pages/UserList/ContextMenu/ContextMenu.js b/src/pages/UserList/ContextMenu/ContextMenu.js index d7c5832b8..6021695c8 100644 --- a/src/pages/UserList/ContextMenu/ContextMenu.js +++ b/src/pages/UserList/ContextMenu/ContextMenu.js @@ -18,6 +18,7 @@ import { import PropTypes from 'prop-types' import React, { useState } from 'react' import { useCurrentUser } from '../../../hooks/useCurrentUser.js' +import { useReferrerInfo } from '../../../providers/useReferrer.js' import navigateTo from '../../../utils/navigateTo.js' import DeleteModal from './Modals/DeleteModal.js' import Disable2FaModal from './Modals/Disable2FaModal.js' @@ -67,6 +68,7 @@ const ContextMenu = ({ user, anchorRef, refetchUsers, onClose }) => { ) const canDisable = currentUser.id !== user.id && access.update && !disabled const canDelete = currentUser.id !== user.id && access.delete + const { setReferrer } = useReferrerInfo() return ( <> @@ -87,9 +89,10 @@ const ContextMenu = ({ user, anchorRef, refetchUsers, onClose }) => { } - onClick={() => + onClick={() => { + setReferrer('users') navigateTo(`/users/edit/${user.id}`) - } + }} dense /> )} diff --git a/src/pages/UserList/UserTable.js b/src/pages/UserList/UserTable.js index cf7a4b862..3a856dc3a 100644 --- a/src/pages/UserList/UserTable.js +++ b/src/pages/UserList/UserTable.js @@ -17,6 +17,7 @@ import PropTypes from 'prop-types' import React from 'react' import DataTableInfoWrapper from '../../components/DataTableInfoWrapper.js' import EmptyTableInfo from '../../components/EmptyTableInfo.js' +import { useReferrerInfo } from '../../providers/useReferrer.js' import navigateTo from '../../utils/navigateTo.js' import ContextMenuButton from './ContextMenu/ContextMenuButton.js' @@ -29,6 +30,7 @@ const UserTable = ({ onNameSortDirectionToggle, }) => { const { fromServerDate } = useTimeZoneConversion() + const { setReferrer } = useReferrerInfo() if (loading && !users) { return ( @@ -102,6 +104,7 @@ const UserTable = ({ const lastLoginClient = fromServerDate(lastLogin) const handleClick = () => { + setReferrer('users') if (access.update) { navigateTo(`/users/edit/${id}`) } else if (access.read) { diff --git a/src/providers/ReferrerContext.js b/src/providers/ReferrerContext.js new file mode 100644 index 000000000..0b99669e6 --- /dev/null +++ b/src/providers/ReferrerContext.js @@ -0,0 +1,6 @@ +import React from 'react' + +export const ReferrerContext = React.createContext({ + referrer: '', + setReferrer: () => {}, +}) diff --git a/src/providers/ReferrerProvider.js b/src/providers/ReferrerProvider.js new file mode 100644 index 000000000..f2c5deb41 --- /dev/null +++ b/src/providers/ReferrerProvider.js @@ -0,0 +1,17 @@ +import PropTypes from 'prop-types' +import React, { useState } from 'react' +import { ReferrerContext } from './ReferrerContext.js' + +export const ReferrerProvider = ({ children }) => { + const [referrer, setReferrer] = useState('') + const providerValue = { referrer, setReferrer } + return ( + + {children} + + ) +} + +ReferrerProvider.propTypes = { + children: PropTypes.node.isRequired, +} diff --git a/src/providers/index.js b/src/providers/index.js new file mode 100644 index 000000000..2fa0c475c --- /dev/null +++ b/src/providers/index.js @@ -0,0 +1,2 @@ +export { useReferrerInfo } from './useReferrer.js' +export { ReferrerProvider } from './ReferrerProvider.js' diff --git a/src/providers/useReferrer.js b/src/providers/useReferrer.js new file mode 100644 index 000000000..72f45ff86 --- /dev/null +++ b/src/providers/useReferrer.js @@ -0,0 +1,4 @@ +import { useContext } from 'react' +import { ReferrerContext } from './ReferrerContext.js' + +export const useReferrerInfo = () => useContext(ReferrerContext) diff --git a/src/utils/navigateTo.js b/src/utils/navigateTo.js index b5a4c744d..2e44c8e21 100644 --- a/src/utils/navigateTo.js +++ b/src/utils/navigateTo.js @@ -7,7 +7,8 @@ import history from './history.js' * @function */ const navigateTo = (path) => { - history.push(path) + // window.history.pushState({ prevUrl: window.location.href },null) + history.push(path, { search: 'bAH!' }) } export default navigateTo