Skip to content

Commit

Permalink
UIU-2969: change user type confirmation modal
Browse files Browse the repository at this point in the history
  • Loading branch information
alisher-epam committed Feb 8, 2024
1 parent 3454583 commit bec610e
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* Enable effective call number column sorting in Open Loans screen. Refs UIU-3002.
* User Information in User Edit to display profile picture and update button set. Refs UIU-3005.
* Update request header for pay several Fees/fines. Refs UIU-3040.
* Changing user type confirmation modal. Refs UIU-2969.

## [10.0.4](https://github.com/folio-org/ui-users/tree/v10.0.4) (2023-11-10)
[Full Changelog](https://github.com/folio-org/ui-users/compare/v10.0.3...v10.0.4)
Expand Down
39 changes: 30 additions & 9 deletions src/components/EditSections/EditUserInfo/EditUserInfo.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import _ from 'lodash';
import React from 'react';
import get from 'lodash/get';
import moment from 'moment-timezone';
import PropTypes from 'prop-types';
import React from 'react';
import { Field } from 'react-final-form';
import { FormattedMessage, injectIntl } from 'react-intl';
import moment from 'moment-timezone';
import { OnChange } from 'react-final-form-listeners';
import { FormattedMessage, injectIntl } from 'react-intl';

import { ViewMetaData } from '@folio/stripes/smart-components';
import {
Button,
Select,
Expand All @@ -19,14 +18,16 @@ import {
Modal,
ModalFooter,
} from '@folio/stripes/components';
import { ViewMetaData } from '@folio/stripes/smart-components';

import { USER_TYPES, USER_TYPE_FIELD } from '../../../constants';
import { isConsortiumEnabled } from '../../util';
import asyncValidateField from '../../validators/asyncValidateField';
import validateMinDate from '../../validators/validateMinDate';

import { ChangeUserTypeModal, ProfilePicture } from './components';

import css from './EditUserInfo.css';
import ProfilePicture from './components/ProfilePicture';

class EditUserInfo extends React.Component {
static propTypes = {
Expand Down Expand Up @@ -56,6 +57,7 @@ class EditUserInfo extends React.Component {
const { initialValues: { patronGroup } } = props;
this.state = {
showRecalculateModal: false,
showUserTypeModal: false,
selectedPatronGroup: patronGroup,
};
}
Expand All @@ -78,6 +80,12 @@ class EditUserInfo extends React.Component {
this.setState({ showRecalculateModal: false });
}

setChangedUserType = (userType) => {
const { form: { change } } = this.props;
change(USER_TYPE_FIELD, userType);
this.setState({ showUserTypeModal: false });
}

calculateNewExpirationDate = (startCalcToday) => {
const { initialValues } = this.props;
const expirationDate = new Date(initialValues.expirationDate);
Expand All @@ -94,7 +102,7 @@ class EditUserInfo extends React.Component {

getPatronGroupOffset = () => {
const selectedPatronGroup = this.props.patronGroups.find(i => i.id === this.state.selectedPatronGroup);
return _.get(selectedPatronGroup, 'expirationOffsetInDays', '');
return get(selectedPatronGroup, 'expirationOffsetInDays', '');
};

parseExpirationDate = (expirationDate) => {
Expand Down Expand Up @@ -207,7 +215,7 @@ class EditUserInfo extends React.Component {
].filter(o => o.visible);

const offset = this.getPatronGroupOffset();
const group = _.get(this.props.patronGroups.find(i => i.id === this.state.selectedPatronGroup), 'group', '');
const group = get(this.props.patronGroups.find(i => i.id === this.state.selectedPatronGroup), 'group', '');
const date = moment(this.calculateNewExpirationDate(true)).format('LL');

const modalFooter = (
Expand Down Expand Up @@ -400,7 +408,15 @@ class EditUserInfo extends React.Component {
dataOptions={typeOptions}
aria-required={isConsortium}
required={isConsortium}
/>
>
<OnChange name={USER_TYPE_FIELD}>
{(selectedUserType) => {
if (initialValues.type === USER_TYPES.STAFF && selectedUserType === USER_TYPES.PATRON) {
this.setState({ showUserTypeModal: true });
}
}}
</OnChange>
</Field>
</Col>
</Row>

Expand All @@ -418,6 +434,11 @@ class EditUserInfo extends React.Component {
/>
</div>
</Modal>
<ChangeUserTypeModal
onChange={this.setChangedUserType}
initialUserType={initialValues.type}
open={this.state.showUserTypeModal}
/>
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';

import {
Button,
Modal,
ModalFooter,
} from '@folio/stripes/components';

import { USER_TYPES } from '../../../../../constants';

const ChangeUserTypeModal = ({ onChange, initialUserType, open }) => {
const userTypeModalFooter = (
<ModalFooter>
<Button
id="userType-modal-btn"
onClick={() => onChange(USER_TYPES.PATRON)}
>
<FormattedMessage id="ui-users.information.change.userType.modal.button" />
</Button>
<Button
id="userType-modal-cancel-btn"
onClick={() => onChange(initialUserType)}
>
<FormattedMessage id="ui-users.cancel" />
</Button>
</ModalFooter>
);

return (
<Modal
footer={userTypeModalFooter}
id="userType_confirmation_modal"
label={<FormattedMessage id="ui-users.information.change.userType.modal.label" />}
open={open}
>
<div>
<FormattedMessage
id="ui-users.information.change.userType.modal.text"
/>
</div>
</Modal>
);
};

ChangeUserTypeModal.propTypes = {
onChange: PropTypes.func.isRequired,
initialUserType: PropTypes.string.isRequired,
open: PropTypes.bool,
};

ChangeUserTypeModal.defaultProps = {
open: false,
};

export default ChangeUserTypeModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { render, screen } from '@folio/jest-config-stripes/testing-library/react';

import { USER_TYPES } from '../../../../../constants';
import ChangeUserTypeModal from './ChangeUserTypeModal';

describe('ChangeUserTypeModal', () => {
it('should render component', () => {
const onChange = jest.fn();
render(<ChangeUserTypeModal
open
onChange={onChange}
initialUserType={USER_TYPES.STAFF}
/>);

expect(screen.getByTestId('ui-users.information.change.userType.modal.label')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './ChangeUserTypeModal';
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/* eslint-disable import/prefer-default-export */
export { default as ProfilePicture } from './ProfilePicture';
export { default as ChangeUserTypeModal } from './ChangeUserTypeModal';
3 changes: 3 additions & 0 deletions translations/ui-users/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,9 @@
"information.recalculate.modal.button": "Set",
"information.recalculate.modal.text": "Library accounts with patron group <b>{group}</b> expire in <b>{offset} days</b>. Do you want to set this user’s account to expire on <b>{date}</b>?",
"information.recalculate.modal.label": "Set expiration date?",
"information.change.userType.modal.label": "Changing user type?",
"information.change.userType.modal.button": "Set",
"information.change.userType.modal.text": "Making this change will update the users affiliations and their the permissions they are granted for those affiliations when clicking Save & close. This action can not easily be reversed, you would need to manually update the user's affiliations and permissions to reverse the resulting changes. Would you like to proceed?",
"information.recalculate.will.reactivate.user": "User will reactivate after saving",
"lostItems.message.noAccessToActualCostPage": "User does not have permission to access \"Lost items needing actual cost\" processing page",

Expand Down

0 comments on commit bec610e

Please sign in to comment.