Skip to content

Commit

Permalink
UIU-2936: Add dropdown to specify user type: Patron or Staff (#2546)
Browse files Browse the repository at this point in the history
* UIU-2936: add user types for dropdown selection

* refactor: create const for disabling userType field remove test case

* refactor: improve code quality

* refactor: remove unused constants file

* refactor: change filed initial value from `defaultValue` to `initialValue`

* refactor: remove not required code

* refactor: code quality

* tests: add test cases

* tests: add stripes props
  • Loading branch information
alisher-epam authored Sep 2, 2023
1 parent c52c318 commit 2231b86
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
* ECS - Do not display shadow users in search results. Refs UIU-2933.
* User can't pay the fee/fine. Refs UIU-2930.
* Sort proxies and sponsors by user display name. Refs UIU-2799.
* Add dropdown to specify user type: Patron or Staff. Refs UIU-2936.

## [9.0.0](https://github.com/folio-org/ui-users/tree/v9.0.0) (2023-02-20)
[Full Changelog](https://github.com/folio-org/ui-users/compare/v8.1.0...v9.0.0)
Expand Down
41 changes: 41 additions & 0 deletions src/components/EditSections/EditUserInfo/EditUserInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
ModalFooter,
} from '@folio/stripes/components';

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

Expand Down Expand Up @@ -111,9 +113,11 @@ class EditUserInfo extends React.Component {
onToggle,
accordionId,
intl,
stripes,
uniquenessValidator,
} = this.props;

const isConsortium = isConsortiumEnabled(stripes);
const { barcode } = initialValues;

const isUserExpired = () => {
Expand Down Expand Up @@ -164,6 +168,30 @@ class EditUserInfo extends React.Component {
}
];

const isShadowUser = initialValues.type === USER_TYPES.SHADOW;
const typeOptions = [
{
value: '',
label: intl.formatMessage({ id: 'ui-users.information.selectUserType' }),
visible: true,
},
{
value: USER_TYPES.PATRON,
label: intl.formatMessage({ id: 'ui-users.information.type.patron' }),
visible: !isShadowUser,
},
{
value: USER_TYPES.STAFF,
label: intl.formatMessage({ id: 'ui-users.information.type.staff' }),
visible: !isShadowUser,
},
{
value: USER_TYPES.SHADOW,
label: intl.formatMessage({ id: 'ui-users.information.type.shadow' }),
visible: isShadowUser,
}
].filter(o => o.visible);

const offset = this.getPatronGroupOffset();
const group = _.get(this.props.patronGroups.find(i => i.id === this.state.selectedPatronGroup), 'group', '');
const date = moment(this.calculateNewExpirationDate(true)).format('LL');
Expand Down Expand Up @@ -316,6 +344,19 @@ class EditUserInfo extends React.Component {
fullWidth
/>
</Col>
<Col xs={12} md={3}>
<Field
label={<FormattedMessage id="ui-users.information.type" />}
name="type"
id="type"
component={Select}
fullWidth
disabled={isShadowUser}
dataOptions={typeOptions}
aria-required={isConsortium}
required={isConsortium}
/>
</Col>
</Row>
</Accordion>
<Modal
Expand Down
57 changes: 55 additions & 2 deletions src/components/EditSections/EditUserInfo/EditUserInfo.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,33 @@ import { Form } from 'react-final-form';
import '__mock__/stripesComponents.mock';

import renderWithRouter from 'helpers/renderWithRouter';

import EditUserInfo from './EditUserInfo';
import { isConsortiumEnabled } from '../../util';
import { USER_TYPES } from '../../../constants';

jest.mock('@folio/stripes/components', () => ({
...jest.requireActual('@folio/stripes/components'),
Modal: jest.fn(({ children, label, footer, ...rest }) => {
return (
<div
{...rest}
>
<h1>{label}</h1>
{children}
{footer}
</div>
);
}),
ModalFooter: jest.fn((props) => (
<div>{props.children}</div>
)),
}));

jest.mock('../../util', () => ({
...jest.requireActual('../../util'),
isConsortiumEnabled: jest.fn(() => true),
}));

const onSubmit = jest.fn();

Expand All @@ -29,7 +55,7 @@ const renderEditUserInfo = (props) => {
<EditUserInfo {...props} />
</>
);
renderWithRouter(
return renderWithRouter(
<Form
id="form-user"
mutators={{
Expand Down Expand Up @@ -58,7 +84,8 @@ const props = {
accordionId: 'editUserInfo',
stripes: {
connect: (Component) => Component,
timezone: 'USA/TestTimeZone'
timezone: 'USA/TestTimeZone',
hasInterface: () => true,
},
patronGroups: [{
desc: 'Staff Member',
Expand Down Expand Up @@ -98,6 +125,10 @@ const props = {
};

describe('Render Edit User Information component', () => {
beforeEach(() => {
isConsortiumEnabled.mockClear().mockReturnValue(false);
});

it('Must be rendered', () => {
renderEditUserInfo(props);
expect(screen.getByText('ui-users.information.recalculate.will.reactivate.user')).toBeInTheDocument();
Expand All @@ -119,4 +150,26 @@ describe('Render Edit User Information component', () => {
await userEvent.click(screen.getByText('ui-users.cancel'));
expect(screen.getByText('ui-users.information.recalculate.expirationDate'));
});

it.each`
type
${USER_TYPES.PATRON}
${USER_TYPES.SHADOW}
`('Should have user type $type', async ({ type }) => {
const isShadowUser = type === USER_TYPES.SHADOW;
isConsortiumEnabled.mockClear().mockReturnValue(isShadowUser);
renderEditUserInfo({ ...props, initialValues: { ...props.initialValues, type } });

const selectElement = screen.getByRole('combobox', { name: /ui-users.information.type/i });
expect(selectElement).toBeInTheDocument();

if (type !== USER_TYPES.SHADOW) {
expect(selectElement).toBeEnabled();
}

if (isShadowUser) {
expect(selectElement).toBeDisabled();
}
expect(screen.getByRole('option', { name: `ui-users.information.type.${type}` })).toHaveValue(type);
});
});
4 changes: 4 additions & 0 deletions src/components/util/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,7 @@ export const getContributors = (account, instance) => {

return contributors && contributors.map(({ name }) => name);
};

export const isConsortiumEnabled = stripes => {
return stripes.hasInterface('consortia');
};
2 changes: 2 additions & 0 deletions src/views/UserEdit/UserEdit.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { toUserAddresses, getFormAddressList } from '../../components/data/conve
import contactTypes from '../../components/data/static/contactTypes';
import {
OKAPI_TENANT_HEADER,
USER_TYPES,
deliveryFulfillmentValues,
} from '../../constants';
import { resourcesLoaded, showErrorCallout } from './UserEditHelpers';
Expand Down Expand Up @@ -83,6 +84,7 @@ class UserEdit extends React.Component {
defaultDeliveryAddressTypeId: null,
},
username: '',
type: USER_TYPES.PATRON,
};

if (!match.params.id) return initialFormValues;
Expand Down
5 changes: 5 additions & 0 deletions translations/ui-users/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,11 @@
"information.firstName": "First name",
"information.middleName": "Middle name",
"information.barcode": "Barcode",
"information.selectUserType": "Select user type",
"information.type": "User type",
"information.type.patron": "Patron",
"information.type.staff": "Staff",
"information.type.shadow": "Shadow",
"information.patronGroup": "Patron group",
"information.patronGroups": "Patron groups",
"information.status": "Status",
Expand Down

0 comments on commit 2231b86

Please sign in to comment.