From 671d1c841adbae5dc622b395adfcfb206b80ef48 Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Fri, 15 Jul 2022 11:29:54 +0100 Subject: [PATCH 01/21] feat: Number Generator Barcode Added a setting "use number generator for user barcode", which disables the user input field "Barcode" on user create. Offered instead is a button to select from a list of Number Generator Sequences under the Generator "Patron", set up in the ui-service-interaction settings page. Linting --- package.json | 6 +- .../EditSections/EditUserInfo/EditUserInfo.js | 38 ++++++++--- src/routes/UserRecordContainer.js | 2 +- src/settings/NumberGeneratorOptions.js | 68 +++++++++++++++++++ src/settings/sections.js | 6 ++ src/views/Notes/NoteViewPage.test.js | 8 +-- src/views/UserEdit/UserEdit.js | 1 + src/views/UserEdit/UserForm.js | 1 + translations/ui-users/en.json | 2 + 9 files changed, 117 insertions(+), 15 deletions(-) create mode 100644 src/settings/NumberGeneratorOptions.js diff --git a/package.json b/package.json index 92817e8f7..657e7aefa 100644 --- a/package.json +++ b/package.json @@ -894,7 +894,8 @@ "react-router-dom": "^5.2.0", "redux": "^4.0.0", "regenerator-runtime": "^0.13.9", - "sinon": "^7.1.1" + "sinon": "^7.1.1", + "@folio/service-interaction": "^1.0.0" }, "dependencies": { "final-form-set-field-data": "^1.0.2", @@ -917,7 +918,8 @@ "react": "^17.0.2", "react-intl": "^5.8.0", "react-router": "^5.2.0", - "react-router-dom": "^5.2.0" + "react-router-dom": "^5.2.0", + "@folio/service-interaction": "^1.0.0" }, "optionalDependencies": { "@folio/plugin-find-user": "^6.0.0" diff --git a/src/components/EditSections/EditUserInfo/EditUserInfo.js b/src/components/EditSections/EditUserInfo/EditUserInfo.js index f0b91d46d..60304161a 100644 --- a/src/components/EditSections/EditUserInfo/EditUserInfo.js +++ b/src/components/EditSections/EditUserInfo/EditUserInfo.js @@ -7,6 +7,8 @@ import moment from 'moment-timezone'; import { OnChange } from 'react-final-form-listeners'; import { ViewMetaData } from '@folio/stripes/smart-components'; +import { NumberGeneratorModalButton } from '@folio/service-interaction'; + import { Button, Select, @@ -32,6 +34,7 @@ class EditUserInfo extends React.Component { intl: PropTypes.object.isRequired, onToggle: PropTypes.func, patronGroups: PropTypes.arrayOf(PropTypes.object), + settings: PropTypes.arrayOf(PropTypes.object), stripes: PropTypes.shape({ timezone: PropTypes.string.isRequired, store: PropTypes.shape({ @@ -111,8 +114,14 @@ class EditUserInfo extends React.Component { accordionId, intl, uniquenessValidator, + form: { change }, + settings } = this.props; + const useGeneratorForBarcode = JSON.parse( + (settings.find(sett => sett.configName === 'number_generator') ?? { value: '{}' }).value + )?.useGeneratorForBarcode ?? true; + const { barcode } = initialValues; const isUserExpired = () => { @@ -305,14 +314,27 @@ class EditUserInfo extends React.Component { )} - } - name="barcode" - id="adduser_barcode" - component={TextField} - validate={asyncValidateField('barcode', barcode, uniquenessValidator)} - fullWidth - /> + + + } + name="barcode" + id="adduser_barcode" + component={TextField} + validate={asyncValidateField('barcode', barcode, uniquenessValidator)} + fullWidth + /> + + {useGeneratorForBarcode && + + change('barcode', generated)} + generator="Patron" + /> + + } + diff --git a/src/routes/UserRecordContainer.js b/src/routes/UserRecordContainer.js index bda59bec3..94245a738 100644 --- a/src/routes/UserRecordContainer.js +++ b/src/routes/UserRecordContainer.js @@ -159,7 +159,7 @@ class UserRecordContainer extends React.Component { settings: { type: 'okapi', records: 'configs', - path: 'configurations/entries?query=(module==USERS and configName==profile_pictures)', + path: 'configurations/entries?query=(module==USERS and (configName==profile_pictures or configName==number_generator))', }, requestPreferences: { type: 'okapi', diff --git a/src/settings/NumberGeneratorOptions.js b/src/settings/NumberGeneratorOptions.js new file mode 100644 index 000000000..951589611 --- /dev/null +++ b/src/settings/NumberGeneratorOptions.js @@ -0,0 +1,68 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { FormattedMessage } from 'react-intl'; +import { Field } from 'react-final-form'; + +import { stripesConnect, withStripes } from '@folio/stripes/core'; +import { ConfigManager } from '@folio/stripes/smart-components'; + +import { Checkbox, Col, Row } from '@folio/stripes-components'; + +class NumberGeneratorOptions extends React.Component { + static propTypes = { + stripes: PropTypes.object, + }; + + constructor(props) { + super(props); + this.connectedConfigManager = stripesConnect(ConfigManager); + } + + defaultValues = { + useGeneratorForBarcode: true + }; + + beforeSave(data) { + return JSON.stringify(data); + } + + getInitialValues = (settings) => { + let loadedValues = {}; + try { + const value = settings.length === 0 ? '' : settings[0].value; + loadedValues = JSON.parse(value); + } catch (e) { } // eslint-disable-line no-empty + return { + ...this.defaultValues, + ...loadedValues, + }; + } + + render() { + return ( + } + moduleName="USERS" + onBeforeSave={this.beforeSave} + stripes={this.props.stripes} + formType="final-form" + > + + + } + /> + + + + ); + } +} + +export default withStripes(NumberGeneratorOptions); diff --git a/src/settings/sections.js b/src/settings/sections.js index beaef9de1..f486832af 100644 --- a/src/settings/sections.js +++ b/src/settings/sections.js @@ -18,6 +18,7 @@ import LimitsSettings from './LimitsSettings'; import DepartmentsSettings from './DepartmentsSettings'; import BlockTemplates from './patronBlocks/BlockTemplates'; import TransferCriteriaSettings from './TransferCriteriaSettings'; +import NumberGeneratorOptions from './NumberGeneratorOptions'; const settingsGeneral = [ { @@ -44,6 +45,11 @@ const settingsGeneral = [ component: DepartmentsSettings, perm: 'ui-users.settings.departments.view' }, + { + route: 'numbergeneratoroptions', + label: , + component: NumberGeneratorOptions + }, // Profile pictures are currently unsupported in Folio and the existence of this setting has // confused implementers. Commenting out for now as opposed to deleting it so the existing // files and components aren't orphaned. diff --git a/src/views/Notes/NoteViewPage.test.js b/src/views/Notes/NoteViewPage.test.js index 8695217ba..362d13f7a 100644 --- a/src/views/Notes/NoteViewPage.test.js +++ b/src/views/Notes/NoteViewPage.test.js @@ -1,8 +1,8 @@ -import { fireEvent } from '@testing-library/react'; -import { createMemoryHistory } from 'history'; import { - render, + fireEvent, + render } from '@testing-library/react'; +import { createMemoryHistory } from 'history'; import NoteViewPage from './NoteViewPage'; @@ -13,7 +13,7 @@ jest.mock('@folio/stripes/smart-components', () => ({ onEdit, }) => ( <> -