From 206be77d1218a657d6e3cdb07f4101ca55388eba Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Fri, 3 Mar 2023 15:34:28 +0000 Subject: [PATCH 01/18] feat: Number Generator (Settings) Initial setup of number generator in inventory, package changes and settings page set up --- package.json | 10 ++ .../NumberGeneratorOptions.css | 5 + .../NumberGeneratorOptions.js | 61 +++++++ .../NumberGeneratorOptions.test.js | 24 +++ .../NumberGeneratorOptionsForm.js | 151 ++++++++++++++++++ src/settings/NumberGeneratorOptions/index.js | 1 + src/settings/index.js | 8 + translations/ui-inventory/en.json | 12 ++ 8 files changed, 272 insertions(+) create mode 100644 src/settings/NumberGeneratorOptions/NumberGeneratorOptions.css create mode 100644 src/settings/NumberGeneratorOptions/NumberGeneratorOptions.js create mode 100644 src/settings/NumberGeneratorOptions/NumberGeneratorOptions.test.js create mode 100644 src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js create mode 100644 src/settings/NumberGeneratorOptions/index.js diff --git a/package.json b/package.json index e901b2635..d8cab42c1 100644 --- a/package.json +++ b/package.json @@ -478,6 +478,14 @@ ], "visible": true }, + { + "permissionName": "ui-inventory.settings.numberGenerator.manage", + "displayName": "Settings (Inventory): Manage number generator options", + "subPermissions": [ + "settings.users.enabled" + ], + "visible": true + }, { "permissionName": "ui-inventory.instance.view", "displayName": "Inventory: View instances, holdings, and items", @@ -855,6 +863,7 @@ "@bigtest/mocha": "^0.5.1", "@bigtest/react": "^0.1.2", "@folio/eslint-config-stripes": "^6.0.0", + "@folio/service-interaction": "^1.0.0", "@folio/stripes": "^8.0.0", "@folio/stripes-cli": "^2.0.0", "@folio/stripes-components": "^11.0.0", @@ -912,6 +921,7 @@ "zustand": "^3.7.2" }, "peerDependencies": { + "@folio/service-interaction": "^1.0.0", "@folio/stripes": "^8.0.0", "react": "^17.0.2", "react-intl": "^5.8.0", diff --git a/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.css b/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.css new file mode 100644 index 000000000..ba4467baa --- /dev/null +++ b/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.css @@ -0,0 +1,5 @@ +@import '@folio/stripes-components/lib/variables'; + +.marginBottomGutter { + margin-bottom: var(--gutter); +} \ No newline at end of file diff --git a/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.js b/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.js new file mode 100644 index 000000000..3b6120897 --- /dev/null +++ b/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.js @@ -0,0 +1,61 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { FormattedMessage } from 'react-intl'; + +import { stripesConnect, withStripes } from '@folio/stripes/core'; +import { ConfigManager } from '@folio/stripes/smart-components'; + +import NumberGeneratorOptionsForm from './NumberGeneratorOptionsForm'; + +class NumberGeneratorOptions extends React.Component { + static propTypes = { + stripes: PropTypes.object, + }; + + constructor(props) { + super(props); + this.connectedConfigManager = stripesConnect(ConfigManager); + } + + defaultValues = { + barcodeGeneratorSetting: 'useTextField' + }; + + 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) { + // Make sure we return _something_ because ConfigManager no longer has a safety check here + return {}; + } + + return { + ...this.defaultValues, + ...loadedValues, + }; + } + + render() { + return ( + } + moduleName="INVENTORY" + onBeforeSave={this.beforeSave} + stripes={this.props.stripes} + formType="final-form" + > + + + ); + } +} + +export default withStripes(NumberGeneratorOptions); diff --git a/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.test.js b/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.test.js new file mode 100644 index 000000000..875725519 --- /dev/null +++ b/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.test.js @@ -0,0 +1,24 @@ +import React from 'react'; + +import { screen } from '@testing-library/react'; + +import '../../test/jest/__mock__'; + +import { + renderWithIntl, + translationsProperties +} from '../../test/jest/helpers'; + +import NumberGeneratorOptions from './NumberGeneratorOptions'; + +jest.unmock('@folio/stripes/components'); + +const renderNumberGeneratorSettings = (props) => renderWithIntl(, translationsProperties); + +describe('Number generator settings', () => { + it('renders', () => { + renderNumberGeneratorSettings(); + + expect(screen.getByTestId('config-manager')).toBeTruthy(); + }); +}); diff --git a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js new file mode 100644 index 000000000..9e2d805c0 --- /dev/null +++ b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js @@ -0,0 +1,151 @@ +import { FormattedMessage } from 'react-intl'; +import { Field, useFormState } from 'react-final-form'; + +import { Col, Label, MessageBanner, RadioButton, Row } from '@folio/stripes/components'; +import css from './NumberGeneratorOptions.css'; + +const NumberGeneratorOptionsForm = () => { + const { values } = useFormState(); + const disableCallNumberFields = values?.useAccessionNumberForCallNumber === 'yes'; + + return ( + <> + + +
+ + } + name="barcodeGeneratorSetting" + type="radio" + value="useGenerator" + /> + } + name="barcodeGeneratorSetting" + type="radio" + value="useTextField" + /> + } + name="barcodeGeneratorSetting" + type="radio" + value="useBoth" + /> +
+ +
+ + +
+ + } + name="accessionNumberGeneratorSetting" + type="radio" + value="useGenerator" + /> + } + name="accessionNumberGeneratorSetting" + type="radio" + value="useTextField" + /> + } + name="accessionNumberGeneratorSetting" + type="radio" + value="useBoth" + /> +
+ +
+ + +
+ + } + name="useAccessionNumberForCallNumber" + type="radio" + value="yes" + /> + } + name="useAccessionNumberForCallNumber" + type="radio" + value="no" + /> +
+ +
+ + +
+ {disableCallNumberFields && + + + + } + + } + name="callNumberGeneratorSetting" + type="radio" + value="useGenerator" + /> + } + name="callNumberGeneratorSetting" + type="radio" + value="useTextField" + /> + } + name="callNumberGeneratorSetting" + type="radio" + value="useBoth" + /> +
+ +
+ + ); +}; + +export default NumberGeneratorOptionsForm; diff --git a/src/settings/NumberGeneratorOptions/index.js b/src/settings/NumberGeneratorOptions/index.js new file mode 100644 index 000000000..34e593541 --- /dev/null +++ b/src/settings/NumberGeneratorOptions/index.js @@ -0,0 +1 @@ +export { default } from './NumberGeneratorOptions'; diff --git a/src/settings/index.js b/src/settings/index.js index 9cd98bb58..19284bd92 100644 --- a/src/settings/index.js +++ b/src/settings/index.js @@ -28,6 +28,7 @@ import ModesOfIssuanceSettings from './ModesOfIssuanceSettings'; import InstanceNoteTypesSettings from './InstanceNoteTypesSettings'; import NatureOfContentTermsSettings from './NatureOfContentTermsSettings'; import FastAddSettings from './FastAdd/FastAddSettings'; +import NumberGeneratorOptions from './NumberGeneratorOptions'; class InventorySettings extends React.Component { constructor(props) { @@ -149,6 +150,13 @@ class InventorySettings extends React.Component { component: MaterialTypesSettings, perm: this.addPerm('ui-inventory.settings.materialtypes'), }, + { + route: 'numbergeneratoroptions', + label: , + component: NumberGeneratorOptions, + interface: 'servint', + perm: 'ui-inventory.settings.numberGenerator.manage' + }, ] }, { diff --git a/translations/ui-inventory/en.json b/translations/ui-inventory/en.json index 244740030..d8a2e4ca6 100644 --- a/translations/ui-inventory/en.json +++ b/translations/ui-inventory/en.json @@ -162,6 +162,18 @@ "selectLocation": "Select location", "selectAlternativeTitleType": "Select alternative title type", "settings.goBack": "Go back to inventory settings", + "settings.numberGeneratorOptions": "Number generator options", + "settings.numberGeneratorOptions.useGeneratorForBarcode": "Number generator on, fixed: the barcode can be filled using the generator only.", + "settings.numberGeneratorOptions.useTextFieldForBarcode": "Number generator off: the barcode can be filled manually only.", + "settings.numberGeneratorOptions.useBothForBarcode": "Number generator on, editable: the barcode can be filled using the generator and be edited, or filled manually.", + "settings.numberGeneratorOptions.useGeneratorForAccessionNumber": "Number generator on, fixed: the accession number can be filled using the generator only.", + "settings.numberGeneratorOptions.useTextFieldForAccessionNumber": "Number generator off: the accession number can be filled manually only.", + "settings.numberGeneratorOptions.useBothForAccessionNumber": "Number generator on, editable: the accession number can be filled using the generator and be edited, or filled manually.", + "settings.numberGeneratorOptions.useAccessionNumberForCallNumber": "Autofill the call number field from the accession number generator.", + "settings.numberGeneratorOptions.callNumberGeneratorWarning": "When set to autofill from accession number generator, the call number generator will not be used.", + "settings.numberGeneratorOptions.useGeneratorForCallNumber": "Number generator on, fixed: the call number can be filled using the generator only.", + "settings.numberGeneratorOptions.useTextFieldForCallNumber": "Number generator off: the call number can be filled manually only.", + "settings.numberGeneratorOptions.useBothForCallNumber": "Number generator on, editable: the call number can be filled using the generator and be edited, or filled manually.", "hridHandling": "HRID handling", "hridHandling.checkbox.label": "Remove leading zeroes from HRID", "hridHandling.description.line1": "After initial data migration, new FOLIO HRIDs are assigned sequentially, based on the starting number in these settings", From e939a79172ef3e874804681087cb0947e4d0aac6 Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Fri, 10 Mar 2023 14:47:10 +0000 Subject: [PATCH 02/18] feat: Wired up settings to ItemForm Added useConfigurationQuery hook in the same style as other hooks in use already, and made use of this in EditItem and CreateItem to pass to ItemForm. Ideally this could just live in ItemForm, but that component is a class component and refactoring that to functional to use a hook is out of scope for this work. --- src/Item/CreateItem/CreateItem.js | 3 +++ src/Item/EditItem/EditItem.js | 3 +++ src/edit/items/ItemForm.js | 2 ++ src/hooks/index.js | 1 + src/hooks/useConfigurationQuery.js | 33 ++++++++++++++++++++++++++++++ 5 files changed, 42 insertions(+) create mode 100644 src/hooks/useConfigurationQuery.js diff --git a/src/Item/CreateItem/CreateItem.js b/src/Item/CreateItem/CreateItem.js index a2b1b965a..3a0ab6dac 100644 --- a/src/Item/CreateItem/CreateItem.js +++ b/src/Item/CreateItem/CreateItem.js @@ -21,6 +21,7 @@ import { import ItemForm from '../../edit/items/ItemForm'; import useCallout from '../../hooks/useCallout'; import { useItemMutation } from '../hooks'; +import { useConfigurationQuery } from '../../hooks'; const CreateItem = ({ referenceData, @@ -34,6 +35,7 @@ const CreateItem = ({ const { isLoading: isHoldingLoading, holding } = useHolding(holdingId); const callout = useCallout(); const stripes = useStripes(); + const { configs } = useConfigurationQuery('number_generator'); const initialValues = useMemo(() => ({ status: { name: 'Available' }, @@ -71,6 +73,7 @@ const CreateItem = ({ return ( { history.push({ @@ -106,6 +108,7 @@ const EditItem = ({ return ( <> { + const ky = useOkapiKy().extend({ timeout: false }); + const [namespace] = useNamespace(); + const query = `query=(module=INVENTORY and configName=${configName})`; + + const queryKey = [namespace, query, 'useConfigurationQuery']; + + + const queryFn = () => ky.get(`configurations/entries?${query}`).json(); + const { data: { configs: { 0: settings = {} } = [], totalRecords } = {}, isLoading, isFetching } = useQuery({ queryKey, queryFn }); + + let parsedSettings = {}; + if (settings.value) { + try { + parsedSettings = JSON.parse(settings.value); + } catch (error) { + // Error parsing settings JSON + console.error(error); // eslint-disable-line no-console + } + } + + return { + isFetching, + isLoading, + configs: parsedSettings, + totalRecords, + }; +}; + +export default useConfigurationQuery; From 575f064ba2c18d4f512f97dc4fdf07df500d3f29 Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Fri, 10 Mar 2023 17:40:35 +0000 Subject: [PATCH 03/18] feat: ItemForm Hooked up itemForm to the settings, small tweaks to settings to avoid softlocking user out of options, some translations --- src/edit/items/ItemForm.js | 109 ++++++++++++++++++ .../NumberGeneratorOptionsForm.js | 10 +- translations/ui-inventory/en.json | 8 +- 3 files changed, 125 insertions(+), 2 deletions(-) diff --git a/src/edit/items/ItemForm.js b/src/edit/items/ItemForm.js index ed8191254..d6e6cf00b 100644 --- a/src/edit/items/ItemForm.js +++ b/src/edit/items/ItemForm.js @@ -29,6 +29,7 @@ import { HasCommand, collapseAllSections, expandAllSections, + MessageBanner, } from '@folio/stripes/components'; import { AppIcon, @@ -39,6 +40,8 @@ import { } from '@folio/stripes/smart-components'; import { effectiveCallNumber } from '@folio/stripes/util'; +import { NumberGeneratorModalButton } from '@folio/service-interaction'; + import RepeatableField from '../../components/RepeatableField'; import OptimisticLockingBanner from '../../components/OptimisticLockingBanner'; import ElectronicAccessFields from '../electronicAccessFields'; @@ -179,6 +182,7 @@ class ItemForm extends React.Component { render() { const { configs, + form: { change }, onCancel, initialValues, instance, @@ -294,6 +298,94 @@ class ItemForm extends React.Component { }, ]; + const { + accessionNumberGeneratorSetting, + callNumberGeneratorSetting, + barcodeGeneratorSetting, + useAccessionNumberForCallNumber + } = configs; + + // TODO might need to neaten this code up significantly + const disableAccessionNumberField = accessionNumberGeneratorSetting === 'useGenerator'; + + // Call number field is disabled if Accession number generator is ON, used for call number and set to non-editable + // OR if that ISN'T true and call number is set to only use generator + const disableCallNumberField = (accessionNumberGeneratorSetting !== 'useTextField' && + useAccessionNumberForCallNumber === 'yes' && + accessionNumberGeneratorSetting === 'useGenerator') || + ((useAccessionNumberForCallNumber !== 'yes') && + callNumberGeneratorSetting === 'useGenerator'); + + const jointNumberGeneratorActive = (accessionNumberGeneratorSetting !== 'useTextField' && + useAccessionNumberForCallNumber === 'yes'); + + const accessionNumberGeneratorActive = !jointNumberGeneratorActive && + (accessionNumberGeneratorSetting === 'useGenerator' || + accessionNumberGeneratorSetting === 'useBoth'); + + const callNumberGeneratorActive = !jointNumberGeneratorActive && + (callNumberGeneratorSetting === 'useGenerator' || + callNumberGeneratorSetting === 'useBoth'); + + // Don't worry about calling logic in here, do that in renderAccession... and renderCall... + const renderJointNumberGenerator = () => ( + + + + } + callback={(generated) => { + change('accessionNumber', generated); + change('itemLevelCallNumber', generated); + }} + fullWidth + id="inventoryAccessionNumberAndCallNumber" + generator="inventory_accessionNumber" + renderTop={() => ( + + + + )} + /> + ); + + const renderAccessionNumberGenerator = () => { + if (jointNumberGeneratorActive) { + return renderJointNumberGenerator(); + } else if (accessionNumberGeneratorActive) { + return ( + } + callback={(generated) => change('accessionNumber', generated)} + fullWidth + id="inventoryAccessionNumber" + generator="inventory_accessionNumber" + /> + ); + } + + return null; + }; + + const renderCallNumberGenerator = () => { + if (jointNumberGeneratorActive) { + return renderJointNumberGenerator(); + } else if (callNumberGeneratorActive) { + return ( + } + callback={(generated) => change('itemLevelCallNumber', generated)} + fullWidth + id="inventoryCallNumber" + generator="inventory_callNumber" + /> + ); + } + + return null; + }; + return (
} name="barcode" id="additem_barcode" @@ -426,15 +519,29 @@ class ItemForm extends React.Component { component={TextField} fullWidth /> + { + (barcodeGeneratorSetting === 'useGenerator' || barcodeGeneratorSetting === 'useBoth') && + + } + callback={(generated) => change('barcode', generated)} + fullWidth + id="inventorybarcode" + generator="inventory_itemBarcode" + /> + } } name="accessionNumber" id="additem_accessionnumber" component={TextField} fullWidth /> + {renderAccessionNumberGenerator()} } name="itemLevelCallNumber" id="additem_callnumber" @@ -554,6 +662,7 @@ class ItemForm extends React.Component { rows={1} fullWidth /> + {renderCallNumberGenerator()} { const { values } = useFormState(); - const disableCallNumberFields = values?.useAccessionNumberForCallNumber === 'yes'; + const disableUseForBothFields = values?.accessionNumberGeneratorSetting === 'useTextField'; + const disableCallNumberFields = !disableUseForBothFields && values?.useAccessionNumberForCallNumber === 'yes'; return ( <> @@ -79,11 +80,17 @@ const NumberGeneratorOptionsForm = () => {
+ {disableUseForBothFields && + + + + } } @@ -93,6 +100,7 @@ const NumberGeneratorOptionsForm = () => { /> } diff --git a/translations/ui-inventory/en.json b/translations/ui-inventory/en.json index d8a2e4ca6..7616f97fa 100644 --- a/translations/ui-inventory/en.json +++ b/translations/ui-inventory/en.json @@ -170,10 +170,16 @@ "settings.numberGeneratorOptions.useTextFieldForAccessionNumber": "Number generator off: the accession number can be filled manually only.", "settings.numberGeneratorOptions.useBothForAccessionNumber": "Number generator on, editable: the accession number can be filled using the generator and be edited, or filled manually.", "settings.numberGeneratorOptions.useAccessionNumberForCallNumber": "Autofill the call number field from the accession number generator.", - "settings.numberGeneratorOptions.callNumberGeneratorWarning": "When set to autofill from accession number generator, the call number generator will not be used.", + "settings.numberGeneratorOptions.useAccessionNumberForCallNumberWarning": "When accession number is set to \"Number generator off\", the option to autofill call number from accession number cannot be used.", + "settings.numberGeneratorOptions.callNumberGeneratorWarning": "When set to autofill from accession number generator, the call number generator will not be used. Instead the generate button on the field will act the same as the accession number generate button, and using either of them will fill both fields.", "settings.numberGeneratorOptions.useGeneratorForCallNumber": "Number generator on, fixed: the call number can be filled using the generator only.", "settings.numberGeneratorOptions.useTextFieldForCallNumber": "Number generator off: the call number can be filled manually only.", "settings.numberGeneratorOptions.useBothForCallNumber": "Number generator on, editable: the call number can be filled using the generator and be edited, or filled manually.", + "numberGenerator.generateAccessionNumber": "Generate accession number", + "numberGenerator.generateCallNumber": "Generate call number", + "numberGenerator.generateAccessionAndCallNumber": "Generate accession number and call number", + "numberGenerator.generateAccessionAndCallNumberWarning": "Both accession number and call number will be filled from this action, using a sequence from the Inventory: Accession number generator.", + "numberGenerator.generateItemBarcode": "Generate item barcode", "hridHandling": "HRID handling", "hridHandling.checkbox.label": "Remove leading zeroes from HRID", "hridHandling.description.line1": "After initial data migration, new FOLIO HRIDs are assigned sequentially, based on the starting number in these settings", From f7e643a6ebc481fc78c3557f2d4dcaeb4f31ecd8 Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Thu, 23 Mar 2023 12:15:17 +0000 Subject: [PATCH 04/18] refactor: Tweaks Tweaked settings layouts and translations (WIP, missing a translation still), and refactored ItemForm implementation to make simpler. Also moved majority of render logic to a separate utility method to keep the changes to the actual form component to a minimum --- src/edit/items/ItemForm.js | 109 ++------------- src/edit/items/getNumberGeneratorModals.js | 116 +++++++++++++++ .../NumberGeneratorOptions.css | 4 + .../NumberGeneratorOptionsForm.js | 132 +++++++++--------- src/settings/index.js | 14 +- translations/ui-inventory/en.json | 8 +- 6 files changed, 208 insertions(+), 175 deletions(-) create mode 100644 src/edit/items/getNumberGeneratorModals.js diff --git a/src/edit/items/ItemForm.js b/src/edit/items/ItemForm.js index d6e6cf00b..ef7ba7af6 100644 --- a/src/edit/items/ItemForm.js +++ b/src/edit/items/ItemForm.js @@ -51,6 +51,7 @@ import { LocationSelectionWithCheck } from '../common'; import AdministrativeNoteFields from '../administrativeNoteFields'; import styles from './ItemForm.css'; import { RemoteStorageWarning } from './RemoteStorageWarning'; +import getNumberGeneratorModals from './getNumberGeneratorModals'; function validate(values) { @@ -299,92 +300,13 @@ class ItemForm extends React.Component { ]; const { - accessionNumberGeneratorSetting, - callNumberGeneratorSetting, - barcodeGeneratorSetting, - useAccessionNumberForCallNumber - } = configs; - - // TODO might need to neaten this code up significantly - const disableAccessionNumberField = accessionNumberGeneratorSetting === 'useGenerator'; - - // Call number field is disabled if Accession number generator is ON, used for call number and set to non-editable - // OR if that ISN'T true and call number is set to only use generator - const disableCallNumberField = (accessionNumberGeneratorSetting !== 'useTextField' && - useAccessionNumberForCallNumber === 'yes' && - accessionNumberGeneratorSetting === 'useGenerator') || - ((useAccessionNumberForCallNumber !== 'yes') && - callNumberGeneratorSetting === 'useGenerator'); - - const jointNumberGeneratorActive = (accessionNumberGeneratorSetting !== 'useTextField' && - useAccessionNumberForCallNumber === 'yes'); - - const accessionNumberGeneratorActive = !jointNumberGeneratorActive && - (accessionNumberGeneratorSetting === 'useGenerator' || - accessionNumberGeneratorSetting === 'useBoth'); - - const callNumberGeneratorActive = !jointNumberGeneratorActive && - (callNumberGeneratorSetting === 'useGenerator' || - callNumberGeneratorSetting === 'useBoth'); - - // Don't worry about calling logic in here, do that in renderAccession... and renderCall... - const renderJointNumberGenerator = () => ( - - - - } - callback={(generated) => { - change('accessionNumber', generated); - change('itemLevelCallNumber', generated); - }} - fullWidth - id="inventoryAccessionNumberAndCallNumber" - generator="inventory_accessionNumber" - renderTop={() => ( - - - - )} - /> - ); - - const renderAccessionNumberGenerator = () => { - if (jointNumberGeneratorActive) { - return renderJointNumberGenerator(); - } else if (accessionNumberGeneratorActive) { - return ( - } - callback={(generated) => change('accessionNumber', generated)} - fullWidth - id="inventoryAccessionNumber" - generator="inventory_accessionNumber" - /> - ); - } - - return null; - }; - - const renderCallNumberGenerator = () => { - if (jointNumberGeneratorActive) { - return renderJointNumberGenerator(); - } else if (callNumberGeneratorActive) { - return ( - } - callback={(generated) => change('itemLevelCallNumber', generated)} - fullWidth - id="inventoryCallNumber" - generator="inventory_callNumber" - /> - ); - } - - return null; - }; + disableAccessionNumberField, + disableBarcodeField, + disableCallNumberField, + renderAccessionNumberGenerator, + renderBarcodeGenerator, + renderCallNumberGenerator + } = getNumberGeneratorModals(configs, change); return ( } name="barcode" id="additem_barcode" @@ -519,18 +441,7 @@ class ItemForm extends React.Component { component={TextField} fullWidth /> - { - (barcodeGeneratorSetting === 'useGenerator' || barcodeGeneratorSetting === 'useBoth') && - - } - callback={(generated) => change('barcode', generated)} - fullWidth - id="inventorybarcode" - generator="inventory_itemBarcode" - /> - } + {renderBarcodeGenerator()} { + const { + accessionNumberGeneratorSetting, + barcodeGeneratorSetting, + callNumberGeneratorSetting, + useAccessionNumberForCallNumber + } = configs; + + const accessionNumberGeneratorActive = accessionNumberGeneratorSetting === 'useGenerator' || + accessionNumberGeneratorSetting === 'useBoth'; + + const barcodeGeneratorActive = barcodeGeneratorSetting === 'useGenerator' || + barcodeGeneratorSetting === 'useBoth'; + + const callNumberGeneratorActive = callNumberGeneratorSetting === 'useGenerator' || + callNumberGeneratorSetting === 'useBoth'; + + const disableAccessionNumberField = accessionNumberGeneratorSetting === 'useGenerator'; + const disableBarcodeField = barcodeGeneratorSetting === 'useGenerator'; + const disableCallNumberField = callNumberGeneratorSetting === 'useGenerator'; + + // Don't worry about calling logic in here, do that in renderAccession... and renderCall... + const renderJointNumberGenerator = () => ( + + + + } + callback={(generated) => { + change('accessionNumber', generated); + change('itemLevelCallNumber', generated); + }} + fullWidth + id="inventoryAccessionNumberAndCallNumber" + generator="inventory_accessionNumber" + renderTop={() => ( + + + + )} + /> + ); + + const renderAccessionNumberGenerator = () => { + if (useAccessionNumberForCallNumber) { + return renderJointNumberGenerator(); + } else if (accessionNumberGeneratorActive) { + return ( + } + callback={(generated) => change('accessionNumber', generated)} + fullWidth + id="inventoryAccessionNumber" + generator="inventory_accessionNumber" + /> + ); + } + + return null; + }; + + const renderCallNumberGenerator = () => { + if (useAccessionNumberForCallNumber) { + return renderJointNumberGenerator(); + } else if (callNumberGeneratorActive) { + return ( + } + callback={(generated) => change('itemLevelCallNumber', generated)} + fullWidth + id="inventoryCallNumber" + generator="inventory_callNumber" + /> + ); + } + + return null; + }; + + const renderBarcodeGenerator = () => { + if (barcodeGeneratorActive) { + return ( + + } + callback={(generated) => change('barcode', generated)} + fullWidth + id="inventorybarcode" + generator="inventory_itemBarcode" + /> + ); + } + return null; + }; + + return { + disableAccessionNumberField, + disableBarcodeField, + disableCallNumberField, + renderAccessionNumberGenerator, + renderCallNumberGenerator, + renderBarcodeGenerator + }; +}; + +export default getNumberGeneratorModals; diff --git a/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.css b/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.css index ba4467baa..6501c7205 100644 --- a/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.css +++ b/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.css @@ -2,4 +2,8 @@ .marginBottomGutter { margin-bottom: var(--gutter); +} + +.greyLabel { + color: var(--checkable-disabled-fill); } \ No newline at end of file diff --git a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js index 13d71c3b3..fc12ae803 100644 --- a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js +++ b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js @@ -1,30 +1,34 @@ import { FormattedMessage } from 'react-intl'; import { Field, useFormState } from 'react-final-form'; -import { Col, Label, MessageBanner, RadioButton, Row } from '@folio/stripes/components'; +import { Checkbox, Col, InfoPopover, Label, MessageBanner, RadioButton, Row } from '@folio/stripes/components'; import css from './NumberGeneratorOptions.css'; const NumberGeneratorOptionsForm = () => { const { values } = useFormState(); - const disableUseForBothFields = values?.accessionNumberGeneratorSetting === 'useTextField'; - const disableCallNumberFields = !disableUseForBothFields && values?.useAccessionNumberForCallNumber === 'yes'; + const disableUseForBothFields = + (values?.accessionNumberGeneratorSetting ?? 'useTextField') === 'useTextField' || + (values?.callNumberGeneratorSetting ?? 'useTextField') === 'useTextField'; + + const disableAccessionNumberAndCallNumberOffOptions = !!values?.useAccessionNumberForCallNumber return ( <> + + +
+ + + +
+ +
- } - name="barcodeGeneratorSetting" - type="radio" - value="useGenerator" - /> { type="radio" value="useBoth" /> + } + name="barcodeGeneratorSetting" + type="radio" + value="useGenerator" + />
@@ -52,14 +64,7 @@ const NumberGeneratorOptionsForm = () => { } - name="accessionNumberGeneratorSetting" - type="radio" - value="useGenerator" - /> - } name="accessionNumberGeneratorSetting" @@ -74,39 +79,13 @@ const NumberGeneratorOptionsForm = () => { type="radio" value="useBoth" /> -
- -
- - -
- {disableUseForBothFields && - - - - } - - } - name="useAccessionNumberForCallNumber" - type="radio" - value="yes" - /> } - name="useAccessionNumberForCallNumber" + id="useGeneratorAccessionNumber" + label={} + name="accessionNumberGeneratorSetting" type="radio" - value="no" + value="useGenerator" />
@@ -114,26 +93,12 @@ const NumberGeneratorOptionsForm = () => {
- {disableCallNumberFields && - - - - } } - name="callNumberGeneratorSetting" - type="radio" - value="useGenerator" - /> - } name="callNumberGeneratorSetting" @@ -142,13 +107,50 @@ const NumberGeneratorOptionsForm = () => { /> } name="callNumberGeneratorSetting" type="radio" value="useBoth" /> + } + name="callNumberGeneratorSetting" + type="radio" + value="useGenerator" + /> +
+ +
+ + +
+ +
+ +
+ + + } + name="useAccessionNumberForCallNumber" + type="checkbox" + /> + {disableUseForBothFields && + + + + }
diff --git a/src/settings/index.js b/src/settings/index.js index 19284bd92..3bed81802 100644 --- a/src/settings/index.js +++ b/src/settings/index.js @@ -150,13 +150,6 @@ class InventorySettings extends React.Component { component: MaterialTypesSettings, perm: this.addPerm('ui-inventory.settings.materialtypes'), }, - { - route: 'numbergeneratoroptions', - label: , - component: NumberGeneratorOptions, - interface: 'servint', - perm: 'ui-inventory.settings.numberGenerator.manage' - }, ] }, { @@ -192,6 +185,13 @@ class InventorySettings extends React.Component { component: URLRelationshipSettings, perm: this.addPerm('ui-inventory.settings.electronic-access-relationships'), }, + { + route: 'numbergeneratoroptions', + label: , + component: NumberGeneratorOptions, + interface: 'servint', + perm: 'ui-inventory.settings.numberGenerator.manage' + }, ] }, { diff --git a/translations/ui-inventory/en.json b/translations/ui-inventory/en.json index 7616f97fa..1a0c4f33d 100644 --- a/translations/ui-inventory/en.json +++ b/translations/ui-inventory/en.json @@ -163,21 +163,21 @@ "selectAlternativeTitleType": "Select alternative title type", "settings.goBack": "Go back to inventory settings", "settings.numberGeneratorOptions": "Number generator options", + "settings.numberGeneratorOptions.info": "Fields which are usually filled using a numeric sequence can use the number generator. When the generator is switched on the field can either be fixed to prevent manual update, or made fully editable. When switched off, the field must be filled manually.", "settings.numberGeneratorOptions.useGeneratorForBarcode": "Number generator on, fixed: the barcode can be filled using the generator only.", "settings.numberGeneratorOptions.useTextFieldForBarcode": "Number generator off: the barcode can be filled manually only.", "settings.numberGeneratorOptions.useBothForBarcode": "Number generator on, editable: the barcode can be filled using the generator and be edited, or filled manually.", "settings.numberGeneratorOptions.useGeneratorForAccessionNumber": "Number generator on, fixed: the accession number can be filled using the generator only.", "settings.numberGeneratorOptions.useTextFieldForAccessionNumber": "Number generator off: the accession number can be filled manually only.", "settings.numberGeneratorOptions.useBothForAccessionNumber": "Number generator on, editable: the accession number can be filled using the generator and be edited, or filled manually.", - "settings.numberGeneratorOptions.useAccessionNumberForCallNumber": "Autofill the call number field from the accession number generator.", - "settings.numberGeneratorOptions.useAccessionNumberForCallNumberWarning": "When accession number is set to \"Number generator off\", the option to autofill call number from accession number cannot be used.", - "settings.numberGeneratorOptions.callNumberGeneratorWarning": "When set to autofill from accession number generator, the call number generator will not be used. Instead the generate button on the field will act the same as the accession number generate button, and using either of them will fill both fields.", + "settings.numberGeneratorOptions.useAccessionNumberForCallNumber": "Use the same generated number for Accession number and Call number", + "settings.numberGeneratorOptions.useAccessionNumberForCallNumberWarning": "Warning: The checkbox has been disabled because the Accession number and/or Call number have been set to manual completion", "settings.numberGeneratorOptions.useGeneratorForCallNumber": "Number generator on, fixed: the call number can be filled using the generator only.", "settings.numberGeneratorOptions.useTextFieldForCallNumber": "Number generator off: the call number can be filled manually only.", "settings.numberGeneratorOptions.useBothForCallNumber": "Number generator on, editable: the call number can be filled using the generator and be edited, or filled manually.", "numberGenerator.generateAccessionNumber": "Generate accession number", "numberGenerator.generateCallNumber": "Generate call number", - "numberGenerator.generateAccessionAndCallNumber": "Generate accession number and call number", + "numberGenerator.generateAccessionAndCallNumber": "Generate accession and call number", "numberGenerator.generateAccessionAndCallNumberWarning": "Both accession number and call number will be filled from this action, using a sequence from the Inventory: Accession number generator.", "numberGenerator.generateItemBarcode": "Generate item barcode", "hridHandling": "HRID handling", From 5f33597662c28511614bdcb0fe805c673793dab9 Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Thu, 23 Mar 2023 13:07:08 +0000 Subject: [PATCH 05/18] chore: Translation Added translation to the inofPopover in settings and small linting changes --- src/edit/items/ItemForm.js | 3 --- .../NumberGeneratorOptions.test.js | 4 ++-- .../NumberGeneratorOptionsForm.js | 15 ++++++++++----- translations/ui-inventory/en.json | 1 + 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/edit/items/ItemForm.js b/src/edit/items/ItemForm.js index ef7ba7af6..5a102c6c2 100644 --- a/src/edit/items/ItemForm.js +++ b/src/edit/items/ItemForm.js @@ -29,7 +29,6 @@ import { HasCommand, collapseAllSections, expandAllSections, - MessageBanner, } from '@folio/stripes/components'; import { AppIcon, @@ -40,8 +39,6 @@ import { } from '@folio/stripes/smart-components'; import { effectiveCallNumber } from '@folio/stripes/util'; -import { NumberGeneratorModalButton } from '@folio/service-interaction'; - import RepeatableField from '../../components/RepeatableField'; import OptimisticLockingBanner from '../../components/OptimisticLockingBanner'; import ElectronicAccessFields from '../electronicAccessFields'; diff --git a/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.test.js b/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.test.js index 875725519..d953f781d 100644 --- a/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.test.js +++ b/src/settings/NumberGeneratorOptions/NumberGeneratorOptions.test.js @@ -2,12 +2,12 @@ import React from 'react'; import { screen } from '@testing-library/react'; -import '../../test/jest/__mock__'; +import '../../../test/jest/__mock__'; import { renderWithIntl, translationsProperties -} from '../../test/jest/helpers'; +} from '../../../test/jest/helpers'; import NumberGeneratorOptions from './NumberGeneratorOptions'; diff --git a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js index fc12ae803..261b78fc5 100644 --- a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js +++ b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js @@ -10,7 +10,7 @@ const NumberGeneratorOptionsForm = () => { (values?.accessionNumberGeneratorSetting ?? 'useTextField') === 'useTextField' || (values?.callNumberGeneratorSetting ?? 'useTextField') === 'useTextField'; - const disableAccessionNumberAndCallNumberOffOptions = !!values?.useAccessionNumberForCallNumber + const disableAccessionNumberAndCallNumberOffOptions = !!values?.useAccessionNumberForCallNumber; return ( <> @@ -133,12 +133,17 @@ const NumberGeneratorOptionsForm = () => { label={ <>
- +
+ }} + /> + } iconSize="medium" /> diff --git a/translations/ui-inventory/en.json b/translations/ui-inventory/en.json index 1a0c4f33d..bc7907d9c 100644 --- a/translations/ui-inventory/en.json +++ b/translations/ui-inventory/en.json @@ -172,6 +172,7 @@ "settings.numberGeneratorOptions.useBothForAccessionNumber": "Number generator on, editable: the accession number can be filled using the generator and be edited, or filled manually.", "settings.numberGeneratorOptions.useAccessionNumberForCallNumber": "Use the same generated number for Accession number and Call number", "settings.numberGeneratorOptions.useAccessionNumberForCallNumberWarning": "Warning: The checkbox has been disabled because the Accession number and/or Call number have been set to manual completion", + "settings.numberGeneratorOptions.useAccessionNumberForCallNumberInfo": "When this option is selected, the user will be able to use the same generated number in the Accession number and Call number fields on inventory Item records.{linebreak}{linebreak}This option is only available when the number generator is switched on in the above Accession number and Call number settings.", "settings.numberGeneratorOptions.useGeneratorForCallNumber": "Number generator on, fixed: the call number can be filled using the generator only.", "settings.numberGeneratorOptions.useTextFieldForCallNumber": "Number generator off: the call number can be filled manually only.", "settings.numberGeneratorOptions.useBothForCallNumber": "Number generator on, editable: the call number can be filled using the generator and be edited, or filled manually.", From 23f0456465fa604d68c576159135d162af767127 Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Thu, 23 Mar 2023 14:45:54 +0000 Subject: [PATCH 06/18] feat: Safety Added safety feature to ensure that if the "use the same generated number for accession number and call number" did get set by accident when accession number and/or call number were "off", then it would ignore that setting --- src/edit/items/getNumberGeneratorModals.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/edit/items/getNumberGeneratorModals.js b/src/edit/items/getNumberGeneratorModals.js index 50b4e686e..08a927c4a 100644 --- a/src/edit/items/getNumberGeneratorModals.js +++ b/src/edit/items/getNumberGeneratorModals.js @@ -27,6 +27,9 @@ const getNumberGeneratorModals = (configs, change) => { const disableBarcodeField = barcodeGeneratorSetting === 'useGenerator'; const disableCallNumberField = callNumberGeneratorSetting === 'useGenerator'; + // This is to ensure that if the field somehow _did_ get set when it's not supposed to, we ignore it + const useJointModal = useAccessionNumberForCallNumber && accessionNumberGeneratorActive && callNumberGeneratorActive; + // Don't worry about calling logic in here, do that in renderAccession... and renderCall... const renderJointNumberGenerator = () => ( { ); const renderAccessionNumberGenerator = () => { - if (useAccessionNumberForCallNumber) { + if (useJointModal) { return renderJointNumberGenerator(); } else if (accessionNumberGeneratorActive) { return ( @@ -69,7 +72,7 @@ const getNumberGeneratorModals = (configs, change) => { }; const renderCallNumberGenerator = () => { - if (useAccessionNumberForCallNumber) { + if (useJointModal) { return renderJointNumberGenerator(); } else if (callNumberGeneratorActive) { return ( From 8e7634063a0fd58ca5546a090bc78c999f68c3a0 Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Thu, 23 Mar 2023 17:15:06 +0000 Subject: [PATCH 07/18] style: Grey out disabled radio buttons Manually provide styling for disabling of radio buttons since that isn't set up by default in stripes --- .../NumberGeneratorOptionsForm.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js index 261b78fc5..ad0b09e61 100644 --- a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js +++ b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js @@ -66,7 +66,11 @@ const NumberGeneratorOptionsForm = () => { component={RadioButton} disabled={disableAccessionNumberAndCallNumberOffOptions} id="useTextFieldAccessionNumber" - label={} + label={ +
+ +
+ } name="accessionNumberGeneratorSetting" type="radio" value="useTextField" @@ -97,10 +101,15 @@ const NumberGeneratorOptionsForm = () => { } + label={ +
+ +
+ } name="callNumberGeneratorSetting" type="radio" value="useTextField" From e9024df2e6c54258000ea9609db6125d9d89ff08 Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Fri, 21 Apr 2023 10:53:54 +0100 Subject: [PATCH 08/18] chore: Slight tweaks Small tweaks to translations, added "learn more" button to link to documentation (when written) --- .../NumberGeneratorOptionsForm.js | 28 ++++++++++++++----- translations/ui-inventory/en.json | 4 +-- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js index ad0b09e61..e61e59d6c 100644 --- a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js +++ b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js @@ -1,7 +1,7 @@ import { FormattedMessage } from 'react-intl'; import { Field, useFormState } from 'react-final-form'; -import { Checkbox, Col, InfoPopover, Label, MessageBanner, RadioButton, Row } from '@folio/stripes/components'; +import { Button, Checkbox, Col, InfoPopover, Label, Layout, MessageBanner, RadioButton, Row } from '@folio/stripes/components'; import css from './NumberGeneratorOptions.css'; const NumberGeneratorOptionsForm = () => { @@ -146,12 +146,26 @@ const NumberGeneratorOptionsForm = () => { - }} - /> + + + + }} + /> + + + + + } iconSize="medium" /> diff --git a/translations/ui-inventory/en.json b/translations/ui-inventory/en.json index bc7907d9c..07b3d041c 100644 --- a/translations/ui-inventory/en.json +++ b/translations/ui-inventory/en.json @@ -161,6 +161,7 @@ "selectTemporaryLocation": "Select temporary location", "selectLocation": "Select location", "selectAlternativeTitleType": "Select alternative title type", + "settings.learnMore": "Learn more", "settings.goBack": "Go back to inventory settings", "settings.numberGeneratorOptions": "Number generator options", "settings.numberGeneratorOptions.info": "Fields which are usually filled using a numeric sequence can use the number generator. When the generator is switched on the field can either be fixed to prevent manual update, or made fully editable. When switched off, the field must be filled manually.", @@ -172,7 +173,7 @@ "settings.numberGeneratorOptions.useBothForAccessionNumber": "Number generator on, editable: the accession number can be filled using the generator and be edited, or filled manually.", "settings.numberGeneratorOptions.useAccessionNumberForCallNumber": "Use the same generated number for Accession number and Call number", "settings.numberGeneratorOptions.useAccessionNumberForCallNumberWarning": "Warning: The checkbox has been disabled because the Accession number and/or Call number have been set to manual completion", - "settings.numberGeneratorOptions.useAccessionNumberForCallNumberInfo": "When this option is selected, the user will be able to use the same generated number in the Accession number and Call number fields on inventory Item records.{linebreak}{linebreak}This option is only available when the number generator is switched on in the above Accession number and Call number settings.", + "settings.numberGeneratorOptions.useAccessionNumberForCallNumberInfo": "When this option is selected, the Accession and Call numbers in Inventory Item records will be generated using the same Accession Number sequence.{linebreak}{linebreak}This option is only available when the number generator is switched on in the above Accession number and Call number settings.", "settings.numberGeneratorOptions.useGeneratorForCallNumber": "Number generator on, fixed: the call number can be filled using the generator only.", "settings.numberGeneratorOptions.useTextFieldForCallNumber": "Number generator off: the call number can be filled manually only.", "settings.numberGeneratorOptions.useBothForCallNumber": "Number generator on, editable: the call number can be filled using the generator and be edited, or filled manually.", @@ -191,7 +192,6 @@ "hridHandling.sectionHeader3": "Inventory item records", "hridHandling.label.startWith": "Start with", "hridHandling.label.assignPrefix": "Assign prefix", - "hridHandling.validation.enterValue": "Please enter a value", "hridHandling.validation.maxLength": "Invalid value. Maximum {maxLength} characters allowed", "hridHandling.validation.startWithField": "Please enter a numeric value", "hridHandling.validation.assignPrefixField": "Please enter an alphanumeric value", From e5cebd64c88186bd79558a7e21bb85f4679aa313 Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Thu, 11 May 2023 15:36:12 +0100 Subject: [PATCH 09/18] feat: Styling tweaks Added labels to make modal implementation slightly nicer to view --- src/edit/items/getNumberGeneratorModals.js | 24 ++++++++++++++++++---- src/settings/index.js | 14 ++++++------- translations/ui-inventory/en.json | 6 +++++- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/edit/items/getNumberGeneratorModals.js b/src/edit/items/getNumberGeneratorModals.js index 08a927c4a..92434fe9e 100644 --- a/src/edit/items/getNumberGeneratorModals.js +++ b/src/edit/items/getNumberGeneratorModals.js @@ -43,8 +43,12 @@ const getNumberGeneratorModals = (configs, change) => { change('itemLevelCallNumber', generated); }} fullWidth - id="inventoryAccessionNumberAndCallNumber" + generateButtonLabel={} generator="inventory_accessionNumber" + id="inventoryAccessionNumberAndCallNumber" + modalProps={{ + label: + }} renderTop={() => ( @@ -62,8 +66,12 @@ const getNumberGeneratorModals = (configs, change) => { buttonLabel={} callback={(generated) => change('accessionNumber', generated)} fullWidth - id="inventoryAccessionNumber" + generateButtonLabel={} generator="inventory_accessionNumber" + id="inventoryAccessionNumber" + modalProps={{ + label: + }} /> ); } @@ -80,8 +88,12 @@ const getNumberGeneratorModals = (configs, change) => { buttonLabel={} callback={(generated) => change('itemLevelCallNumber', generated)} fullWidth - id="inventoryCallNumber" + generateButtonLabel={} generator="inventory_callNumber" + id="inventoryCallNumber" + modalProps={{ + label: + }} /> ); } @@ -98,8 +110,12 @@ const getNumberGeneratorModals = (configs, change) => { } callback={(generated) => change('barcode', generated)} fullWidth - id="inventorybarcode" + generateButtonLabel={} generator="inventory_itemBarcode" + id="inventorybarcode" + modalProps={{ + label: + }} /> ); } diff --git a/src/settings/index.js b/src/settings/index.js index 3bed81802..6638ae36b 100644 --- a/src/settings/index.js +++ b/src/settings/index.js @@ -185,13 +185,6 @@ class InventorySettings extends React.Component { component: URLRelationshipSettings, perm: this.addPerm('ui-inventory.settings.electronic-access-relationships'), }, - { - route: 'numbergeneratoroptions', - label: , - component: NumberGeneratorOptions, - interface: 'servint', - perm: 'ui-inventory.settings.numberGenerator.manage' - }, ] }, { @@ -203,6 +196,13 @@ class InventorySettings extends React.Component { component: CallNumberTypes, perm: this.addPerm('ui-inventory.settings.call-number-types'), }, + { + route: 'numbergeneratoroptions', + label: , + component: NumberGeneratorOptions, + interface: 'servint', + perm: 'ui-inventory.settings.numberGenerator.manage' + }, ] }, ]; diff --git a/translations/ui-inventory/en.json b/translations/ui-inventory/en.json index 07b3d041c..5944c7f3f 100644 --- a/translations/ui-inventory/en.json +++ b/translations/ui-inventory/en.json @@ -179,9 +179,13 @@ "settings.numberGeneratorOptions.useBothForCallNumber": "Number generator on, editable: the call number can be filled using the generator and be edited, or filled manually.", "numberGenerator.generateAccessionNumber": "Generate accession number", "numberGenerator.generateCallNumber": "Generate call number", - "numberGenerator.generateAccessionAndCallNumber": "Generate accession and call number", + "numberGenerator.generateAccessionAndCallNumber": "Generate accession and call numbers", "numberGenerator.generateAccessionAndCallNumberWarning": "Both accession number and call number will be filled from this action, using a sequence from the Inventory: Accession number generator.", "numberGenerator.generateItemBarcode": "Generate item barcode", + "numberGenerator.itemBarcodeGenerator": "Item barcode generator", + "numberGenerator.callNumberGenerator": "Call number generator", + "numberGenerator.accessionNumberGenerator": "Accession number generator", + "numberGenerator.accessionAndCallNumberGenerator": "Accession number and call number generator", "hridHandling": "HRID handling", "hridHandling.checkbox.label": "Remove leading zeroes from HRID", "hridHandling.description.line1": "After initial data migration, new FOLIO HRIDs are assigned sequentially, based on the starting number in these settings", From 685ebae7d6146bad577e485c9768cc6b275f569e Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Thu, 11 May 2023 16:11:14 +0100 Subject: [PATCH 10/18] style: Padding Added some padding to the text at the top of the joint accession/call number modal, and removed it from the MessageBanner --- src/edit/items/getNumberGeneratorModals.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/edit/items/getNumberGeneratorModals.js b/src/edit/items/getNumberGeneratorModals.js index 92434fe9e..317a25fc1 100644 --- a/src/edit/items/getNumberGeneratorModals.js +++ b/src/edit/items/getNumberGeneratorModals.js @@ -1,5 +1,5 @@ import { FormattedMessage } from 'react-intl'; -import { MessageBanner } from '@folio/stripes-components'; +import { Layout, MessageBanner } from '@folio/stripes-components'; import { NumberGeneratorModalButton } from '@folio/service-interaction'; // Moving this to a separate utility method so we can declutter this work @@ -50,9 +50,9 @@ const getNumberGeneratorModals = (configs, change) => { label: }} renderTop={() => ( - + - + )} /> ); From 9e202b8ce05fe1fcd3f12559964b30d037ff1bb4 Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Tue, 20 Jun 2023 09:26:58 +0100 Subject: [PATCH 11/18] build: OptionalOkapiInterfaces Update to use servint 3 --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index aeab0c833..76fe4ea8e 100644 --- a/package.json +++ b/package.json @@ -97,6 +97,7 @@ "order-lines": "2.0 3.0", "organizations.organizations": "1.0", "pieces": "2.0", + "servint": "2.0 3.0", "titles": "1.2" }, "permissionSets": [ From 3592bab20d656d7eaa76e004c26bc7da5d878e3b Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Fri, 1 Sep 2023 11:21:36 +0100 Subject: [PATCH 12/18] feat: Holdings Added call number generator button to Holdings form, tweaks to settings --- src/Holding/CreateHolding/CreateHolding.js | 4 + src/Holding/EditHolding/EditHolding.js | 4 + src/edit/holdings/HoldingsForm.js | 51 ++- src/edit/items/getNumberGeneratorModals.js | 30 +- .../NumberGeneratorOptionsForm.js | 398 +++++++++++------- 5 files changed, 305 insertions(+), 182 deletions(-) diff --git a/src/Holding/CreateHolding/CreateHolding.js b/src/Holding/CreateHolding/CreateHolding.js index c3b5b74e8..fe9d2e76d 100644 --- a/src/Holding/CreateHolding/CreateHolding.js +++ b/src/Holding/CreateHolding/CreateHolding.js @@ -19,6 +19,7 @@ import { } from '../../common/hooks'; import useCallout from '../../hooks/useCallout'; import HoldingsForm from '../../edit/holdings/HoldingsForm'; +import { useConfigurationQuery } from '../../hooks'; const CreateHolding = ({ history, @@ -29,6 +30,8 @@ const CreateHolding = ({ mutator, }) => { const callout = useCallout(); + const { configs } = useConfigurationQuery('number_generator'); + const { instance, isLoading: isInstanceLoading } = useInstance(instanceId, mutator.holdingInstance); const sourceId = referenceData.holdingsSourcesByName?.FOLIO?.id; @@ -62,6 +65,7 @@ const CreateHolding = ({ return ( { const callout = useCallout(); + const { configs } = useConfigurationQuery('number_generator'); + const { search, state: locationState } = location; const stripes = useStripes(); const [httpError, setHttpError] = useState(); @@ -82,6 +85,7 @@ const EditHolding = ({ return ( <> ({ label: it.name, @@ -538,15 +549,37 @@ class HoldingsForm extends React.Component { /> - } - name="callNumber" - id="additem_callnumber" - component={TextArea} - rows={1} - fullWidth - disabled={this.isFieldBlocked('callNumber')} - /> + + } + name="callNumber" + id="additem_callnumber" + component={TextArea} + rows={1} + fullWidth + disabled={this.isFieldBlocked('callNumber') || callNumberGeneratorSettingHoldings === 'useGenerator'} + /> + + + {( + callNumberGeneratorSettingHoldings === 'useGenerator' || + callNumberGeneratorSettingHoldings === 'useBoth' + ) && + + } + callback={(generated) => change('callNumber', generated)} + fullWidth + id="inventoryCallNumber" + generateButtonLabel={} + generator="inventory_callNumber" + modalProps={{ + label: + }} + /> + + } + { const { - accessionNumberGeneratorSetting, - barcodeGeneratorSetting, - callNumberGeneratorSetting, - useAccessionNumberForCallNumber + accessionNumberGeneratorSettingItems, + barcodeGeneratorSettingItems, + callNumberGeneratorSettingItems, + useAccessionNumberForCallNumberItems } = configs; - const accessionNumberGeneratorActive = accessionNumberGeneratorSetting === 'useGenerator' || - accessionNumberGeneratorSetting === 'useBoth'; + const accessionNumberGeneratorActive = accessionNumberGeneratorSettingItems === 'useGenerator' || + accessionNumberGeneratorSettingItems === 'useBoth'; - const barcodeGeneratorActive = barcodeGeneratorSetting === 'useGenerator' || - barcodeGeneratorSetting === 'useBoth'; + const barcodeGeneratorActive = barcodeGeneratorSettingItems === 'useGenerator' || + barcodeGeneratorSettingItems === 'useBoth'; - const callNumberGeneratorActive = callNumberGeneratorSetting === 'useGenerator' || - callNumberGeneratorSetting === 'useBoth'; + const callNumberGeneratorActive = callNumberGeneratorSettingItems === 'useGenerator' || + callNumberGeneratorSettingItems === 'useBoth'; - const disableAccessionNumberField = accessionNumberGeneratorSetting === 'useGenerator'; - const disableBarcodeField = barcodeGeneratorSetting === 'useGenerator'; - const disableCallNumberField = callNumberGeneratorSetting === 'useGenerator'; + const disableAccessionNumberField = accessionNumberGeneratorSettingItems === 'useGenerator'; + const disableBarcodeField = barcodeGeneratorSettingItems === 'useGenerator'; + const disableCallNumberField = callNumberGeneratorSettingItems === 'useGenerator'; // This is to ensure that if the field somehow _did_ get set when it's not supposed to, we ignore it - const useJointModal = useAccessionNumberForCallNumber && accessionNumberGeneratorActive && callNumberGeneratorActive; + const useJointModal = useAccessionNumberForCallNumberItems && accessionNumberGeneratorActive && callNumberGeneratorActive; // Don't worry about calling logic in here, do that in renderAccession... and renderCall... const renderJointNumberGenerator = () => ( diff --git a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js index e61e59d6c..1e0d4bb61 100644 --- a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js +++ b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js @@ -1,16 +1,34 @@ +import { useRef } from 'react'; + import { FormattedMessage } from 'react-intl'; import { Field, useFormState } from 'react-final-form'; -import { Button, Checkbox, Col, InfoPopover, Label, Layout, MessageBanner, RadioButton, Row } from '@folio/stripes/components'; +import { + Accordion, + AccordionSet, + AccordionStatus, + Button, + Checkbox, + Col, + ExpandAllButton, + InfoPopover, + Label, + Layout, + MessageBanner, + RadioButton, + Row, +} from '@folio/stripes/components'; + import css from './NumberGeneratorOptions.css'; const NumberGeneratorOptionsForm = () => { + const accordionStatusRef = useRef(); const { values } = useFormState(); const disableUseForBothFields = - (values?.accessionNumberGeneratorSetting ?? 'useTextField') === 'useTextField' || - (values?.callNumberGeneratorSetting ?? 'useTextField') === 'useTextField'; + (values?.accessionNumberGeneratorSettingItems ?? 'useTextField') === 'useTextField' || + (values?.callNumberGeneratorSettingItems ?? 'useTextField') === 'useTextField'; - const disableAccessionNumberAndCallNumberOffOptions = !!values?.useAccessionNumberForCallNumber; + const disableAccessionNumberAndCallNumberOffOptions = !!values?.useAccessionNumberForCallNumberItems; return ( <> @@ -23,165 +41,229 @@ const NumberGeneratorOptionsForm = () => {
- - -
- - } - name="barcodeGeneratorSetting" - type="radio" - value="useTextField" - /> - } - name="barcodeGeneratorSetting" - type="radio" - value="useBoth" - /> - } - name="barcodeGeneratorSetting" - type="radio" - value="useGenerator" - /> -
- -
- - -
- - - + + + + + + + + + + + } + id="number-generator-options-items" + > + + +
+ + } + name="barcodeGeneratorSettingItems" + type="radio" + value="useTextField" + /> + } + name="barcodeGeneratorSettingItems" + type="radio" + value="useBoth" + /> + } + name="barcodeGeneratorSettingItems" + type="radio" + value="useGenerator" + />
- } - name="accessionNumberGeneratorSetting" - type="radio" - value="useTextField" - /> - } - name="accessionNumberGeneratorSetting" - type="radio" - value="useBoth" - /> - } - name="accessionNumberGeneratorSetting" - type="radio" - value="useGenerator" - /> -
- -
- - -
- - - + + + + +
+ + + +
+ } + name="accessionNumberGeneratorSettingItems" + type="radio" + value="useTextField" + /> + } + name="accessionNumberGeneratorSettingItems" + type="radio" + value="useBoth" + /> + } + name="accessionNumberGeneratorSettingItems" + type="radio" + value="useGenerator" + />
- } - name="callNumberGeneratorSetting" - type="radio" - value="useTextField" - /> - } - name="callNumberGeneratorSetting" - type="radio" - value="useBoth" - /> - } - name="callNumberGeneratorSetting" - type="radio" - value="useGenerator" - /> - - -
- - -
- -
- -
- - - - }} - /> - - - - - + + + + +
+ + + +
+ } + name="callNumberGeneratorSettingItems" + type="radio" + value="useTextField" + /> + } + name="callNumberGeneratorSettingItems" + type="radio" + value="useBoth" + /> + } + name="callNumberGeneratorSettingItems" + type="radio" + value="useGenerator" + /> +
+ +
+ + +
+ +
+ +
+ + + + }} + /> + + + + + + } + iconSize="medium" + /> + } - iconSize="medium" + name="useAccessionNumberForCallNumberItems" + type="checkbox" /> - - } - name="useAccessionNumberForCallNumber" - type="checkbox" - /> - {disableUseForBothFields && - - - + {disableUseForBothFields && + + + + } +
+ +
+ + + + } - - - + id="number-generator-options-holdings" + > + + +
+ + + +
+ } + name="callNumberGeneratorSettingHoldings" + type="radio" + value="useTextField" + /> + } + name="callNumberGeneratorSettingHoldings" + type="radio" + value="useBoth" + /> + } + name="callNumberGeneratorSettingHoldings" + type="radio" + value="useGenerator" + /> + + +
+
+ + ); }; From d2728a446007cf298927e5a51af5d786db6a98cb Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Fri, 29 Sep 2023 12:43:03 +0100 Subject: [PATCH 13/18] chore: Button UX Changed Button from fullWidth to scale with text --- src/edit/holdings/HoldingsForm.js | 1 - src/edit/items/getNumberGeneratorModals.js | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/edit/holdings/HoldingsForm.js b/src/edit/holdings/HoldingsForm.js index ab46549a5..d48894e7b 100644 --- a/src/edit/holdings/HoldingsForm.js +++ b/src/edit/holdings/HoldingsForm.js @@ -569,7 +569,6 @@ class HoldingsForm extends React.Component { } callback={(generated) => change('callNumber', generated)} - fullWidth id="inventoryCallNumber" generateButtonLabel={} generator="inventory_callNumber" diff --git a/src/edit/items/getNumberGeneratorModals.js b/src/edit/items/getNumberGeneratorModals.js index 3410fabfe..e6a1d1496 100644 --- a/src/edit/items/getNumberGeneratorModals.js +++ b/src/edit/items/getNumberGeneratorModals.js @@ -42,7 +42,6 @@ const getNumberGeneratorModals = (configs, change) => { change('accessionNumber', generated); change('itemLevelCallNumber', generated); }} - fullWidth generateButtonLabel={} generator="inventory_accessionNumber" id="inventoryAccessionNumberAndCallNumber" @@ -65,7 +64,6 @@ const getNumberGeneratorModals = (configs, change) => { } callback={(generated) => change('accessionNumber', generated)} - fullWidth generateButtonLabel={} generator="inventory_accessionNumber" id="inventoryAccessionNumber" @@ -87,7 +85,6 @@ const getNumberGeneratorModals = (configs, change) => { } callback={(generated) => change('itemLevelCallNumber', generated)} - fullWidth generateButtonLabel={} generator="inventory_callNumber" id="inventoryCallNumber" @@ -109,7 +106,6 @@ const getNumberGeneratorModals = (configs, change) => { } callback={(generated) => change('barcode', generated)} - fullWidth generateButtonLabel={} generator="inventory_itemBarcode" id="inventorybarcode" From 2f1cab62ad687118cfe5de15e8856733560ed7a1 Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Fri, 1 Mar 2024 10:49:22 +0000 Subject: [PATCH 14/18] refactor: Settings order Change order of ui-inventory NumGen settings UIIN-2557 --- .../NumberGeneratorOptionsForm.js | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js index 1e0d4bb61..4e317497b 100644 --- a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js +++ b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js @@ -48,6 +48,52 @@ const NumberGeneratorOptionsForm = () => { + + + + } + id="number-generator-options-holdings" + > + + +
+ + + +
+ } + name="callNumberGeneratorSettingHoldings" + type="radio" + value="useTextField" + /> + } + name="callNumberGeneratorSettingHoldings" + type="radio" + value="useBoth" + /> + } + name="callNumberGeneratorSettingHoldings" + type="radio" + value="useGenerator" + /> + + +
+
@@ -216,52 +262,6 @@ const NumberGeneratorOptionsForm = () => { - - - - } - id="number-generator-options-holdings" - > - - -
- - - -
- } - name="callNumberGeneratorSettingHoldings" - type="radio" - value="useTextField" - /> - } - name="callNumberGeneratorSettingHoldings" - type="radio" - value="useBoth" - /> - } - name="callNumberGeneratorSettingHoldings" - type="radio" - value="useGenerator" - /> - - -
-
From 1eb29eb1bf1cd6dc6ba829aec7397ba55c8fba27 Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Fri, 1 Mar 2024 12:30:44 +0000 Subject: [PATCH 15/18] chore: Linting and test fixes --- src/Holding/CreateHolding/CreateHolding.js | 3 +-- .../CreateHolding/CreateHolding.test.js | 1 + src/Holding/EditHolding/EditHolding.test.js | 1 + src/Item/CreateItem/CreateItem.js | 3 +-- src/Item/CreateItem/CreateItem.test.js | 8 +++++- src/Item/EditItem/EditItem.js | 3 +-- src/Item/EditItem/EditItem.test.js | 7 ++++- src/edit/holdings/HoldingsForm.test.js | 1 + src/edit/items/ItemForm.test.js | 1 + .../NumberGeneratorOptions.test.js | 26 +++++++++++++++---- test/jest/helpers/index.js | 1 + 11 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/Holding/CreateHolding/CreateHolding.js b/src/Holding/CreateHolding/CreateHolding.js index 3e62c0fb8..05b490e4f 100644 --- a/src/Holding/CreateHolding/CreateHolding.js +++ b/src/Holding/CreateHolding/CreateHolding.js @@ -13,9 +13,8 @@ import { import { LoadingView } from '@folio/stripes/components'; import { useInstance } from '../../common/hooks'; -import { useCallout } from '../../hooks'; +import { useCallout, useConfigurationQuery } from '../../hooks'; import HoldingsForm from '../../edit/holdings/HoldingsForm'; -import { useConfigurationQuery } from '../../hooks'; import { switchAffiliation } from '../../utils'; const CreateHolding = ({ diff --git a/src/Holding/CreateHolding/CreateHolding.test.js b/src/Holding/CreateHolding/CreateHolding.test.js index 47f4824ca..8b582b20a 100644 --- a/src/Holding/CreateHolding/CreateHolding.test.js +++ b/src/Holding/CreateHolding/CreateHolding.test.js @@ -15,6 +15,7 @@ import CreateHolding from './CreateHolding'; jest.mock('../../hooks', () => ({ ...jest.requireActual('../../hooks'), useCallout: () => ({ sendCallout: jest.fn() }), + useConfigurationQuery: () => ({ configs: {} }) })); jest.mock('../../common/hooks', () => ({ diff --git a/src/Holding/EditHolding/EditHolding.test.js b/src/Holding/EditHolding/EditHolding.test.js index 34494fc91..993db9cdc 100644 --- a/src/Holding/EditHolding/EditHolding.test.js +++ b/src/Holding/EditHolding/EditHolding.test.js @@ -20,6 +20,7 @@ jest.mock('../../edit/holdings/HoldingsForm', () => jest.fn().mockReturnValue('H jest.mock('../../hooks', () => ({ ...jest.requireActual('../../hooks'), useCallout: () => jest.fn().mockReturnValue({ sendCallout: jest.fn() }), + useConfigurationQuery: () => ({ configs: {} }), useHoldingItemsQuery: jest.fn().mockReturnValue({ totalRecords: 1, isLoading: false }), useHoldingMutation: jest.fn().mockReturnValue({ mutateHolding: jest.fn() }), })); diff --git a/src/Item/CreateItem/CreateItem.js b/src/Item/CreateItem/CreateItem.js index 448b8d0de..4997497b1 100644 --- a/src/Item/CreateItem/CreateItem.js +++ b/src/Item/CreateItem/CreateItem.js @@ -14,9 +14,8 @@ import { useHolding, } from '../../common'; import ItemForm from '../../edit/items/ItemForm'; -import useCallout from '../../hooks/useCallout'; import { useItemMutation } from '../hooks'; -import { useConfigurationQuery } from '../../hooks'; +import { useCallout, useConfigurationQuery } from '../../hooks'; import { switchAffiliation } from '../../utils'; const CreateItem = ({ diff --git a/src/Item/CreateItem/CreateItem.test.js b/src/Item/CreateItem/CreateItem.test.js index f116a1b5d..6f535129b 100644 --- a/src/Item/CreateItem/CreateItem.test.js +++ b/src/Item/CreateItem/CreateItem.test.js @@ -13,7 +13,13 @@ import { import CreateItem from './CreateItem'; jest.mock('../../edit/items/ItemForm', () => jest.fn().mockReturnValue('ItemForm')); -jest.mock('../../hooks/useCallout', () => jest.fn().mockReturnValue({ sendCallout: jest.fn() })); + +jest.mock('../../hooks', () => ({ + ...jest.requireActual('../../hooks'), + useCallout: () => jest.fn().mockReturnValue({ sendCallout: jest.fn() }), + useConfigurationQuery: () => ({ configs: {} }), +})); + jest.mock('../../common/hooks', () => ({ ...jest.requireActual('../../common/hooks'), useInstanceQuery: jest.fn().mockReturnValue({ instance: {}, isLoading: false }), diff --git a/src/Item/EditItem/EditItem.js b/src/Item/EditItem/EditItem.js index 79275c81a..de57c9db8 100644 --- a/src/Item/EditItem/EditItem.js +++ b/src/Item/EditItem/EditItem.js @@ -17,14 +17,13 @@ import { useHolding, } from '../../common'; import ItemForm from '../../edit/items/ItemForm'; -import useCallout from '../../hooks/useCallout'; import { parseHttpError, switchAffiliation } from '../../utils'; import { useItem, useItemMutation, useBoundWithsMutation, } from '../hooks'; -import { useConfigurationQuery } from '../../hooks'; +import { useCallout, useConfigurationQuery } from '../../hooks'; const EditItem = ({ referenceData, diff --git a/src/Item/EditItem/EditItem.test.js b/src/Item/EditItem/EditItem.test.js index 0b1320585..b95b46d62 100644 --- a/src/Item/EditItem/EditItem.test.js +++ b/src/Item/EditItem/EditItem.test.js @@ -14,7 +14,12 @@ import EditItem from './EditItem'; import ItemForm from '../../edit/items/ItemForm'; jest.mock('../../edit/items/ItemForm', () => jest.fn().mockReturnValue('ItemForm')); -jest.mock('../../hooks/useCallout', () => jest.fn().mockReturnValue({ sendCallout: jest.fn() })); +jest.mock('../../hooks', () => ({ + ...jest.requireActual('../../hooks'), + useCallout: () => jest.fn().mockReturnValue({ sendCallout: jest.fn() }), + useConfigurationQuery: () => ({ configs: {} }), +})); + jest.mock('../../common/hooks', () => ({ ...jest.requireActual('../../common/hooks'), useInstanceQuery: jest.fn().mockReturnValue({ instance: {}, isLoading: false }), diff --git a/src/edit/holdings/HoldingsForm.test.js b/src/edit/holdings/HoldingsForm.test.js index bc683fb4b..43b89bf74 100644 --- a/src/edit/holdings/HoldingsForm.test.js +++ b/src/edit/holdings/HoldingsForm.test.js @@ -76,6 +76,7 @@ const HoldingsFormSetup = (props = {}) => ( > ( }} > renderWithIntl(, translationsProperties); +const Form = ({ handleSubmit, ...props }) => ( + + + +); + +const WrappedForm = stripesFinalForm({ + navigationCheck: true, + enableReinitialize: false, +})(Form); + +const renderNumberGeneratorOptions = () => renderWithIntl( + renderWithRouter(), + translationsProperties, +); describe('Number generator settings', () => { it('renders', () => { - renderNumberGeneratorSettings(); + renderNumberGeneratorOptions(); - expect(screen.getByTestId('config-manager')).toBeTruthy(); + expect(screen.getByText('ConfigManager')).toBeInTheDocument(); }); }); diff --git a/test/jest/helpers/index.js b/test/jest/helpers/index.js index b9c939cf3..d30c8043c 100644 --- a/test/jest/helpers/index.js +++ b/test/jest/helpers/index.js @@ -2,3 +2,4 @@ export { default as stripesStub } from './stripesStub'; export { default as translationsProperties } from './translationsProperties'; export { default as renderWithFinalForm } from './renderWithFinalForm'; export { default as renderWithIntl } from './renderWithIntl'; +export { default as renderWithRouter } from './renderWithRouter'; From 83819573e6e523838e480b1a249437bc42fca9ec Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Fri, 1 Mar 2024 13:55:50 +0000 Subject: [PATCH 16/18] test: More tests and mocks to try and push PR through --- src/edit/holdings/HoldingsForm.test.js | 4 ++++ src/edit/items/ItemForm.test.js | 4 ++++ src/index.test.js | 4 ++++ src/routes/CreateItemRoute.test.js | 4 ++++ src/routes/DuplicateHoldingRoute.test.js | 4 ++++ src/routes/DuplicateItemRoute.test.js | 4 ++++ src/routes/EditHoldingRoute.test.js | 4 ++++ src/routes/EditItemRoute.test.js | 4 ++++ 8 files changed, 32 insertions(+) diff --git a/src/edit/holdings/HoldingsForm.test.js b/src/edit/holdings/HoldingsForm.test.js index 43b89bf74..d4e8bf2bb 100644 --- a/src/edit/holdings/HoldingsForm.test.js +++ b/src/edit/holdings/HoldingsForm.test.js @@ -19,6 +19,10 @@ import { DataContext } from '../../contexts'; import HoldingsForm from './HoldingsForm'; +jest.mock('@folio/service-interaction', () => ({ + NumberGeneratorModalButton: () =>
NumberGeneratorModalButton
+})); + jest.mock('../common', () => ({ LocationSelectionWithCheck: () =>
LocationSelection
, })); diff --git a/src/edit/items/ItemForm.test.js b/src/edit/items/ItemForm.test.js index 4e36f437e..26f01d626 100644 --- a/src/edit/items/ItemForm.test.js +++ b/src/edit/items/ItemForm.test.js @@ -18,6 +18,10 @@ import { DataContext } from '../../contexts'; import ItemForm from './ItemForm'; +jest.mock('@folio/service-interaction', () => ({ + NumberGeneratorModalButton: () =>
NumberGeneratorModalButton
+})); + jest.mock('../common', () => ({ LocationSelectionWithCheck: () =>
LocationSelection
, })); diff --git a/src/index.test.js b/src/index.test.js index 1a4f59666..6e0298972 100644 --- a/src/index.test.js +++ b/src/index.test.js @@ -6,6 +6,10 @@ import { EVENTS } from './constants'; jest.mock('./storage'); +jest.mock('@folio/service-interaction', () => ({ + NumberGeneratorModalButton: () =>
NumberGeneratorModalButton
+})); + const searchTermsExpectations = () => { expect(removeItem).toHaveBeenNthCalledWith(1, '@folio/inventory/search.instances.lastSearch'); expect(removeItem).toHaveBeenNthCalledWith(2, '@folio/inventory/search.holdings.lastSearch'); diff --git a/src/routes/CreateItemRoute.test.js b/src/routes/CreateItemRoute.test.js index 53c0e59d1..2d4ec0829 100644 --- a/src/routes/CreateItemRoute.test.js +++ b/src/routes/CreateItemRoute.test.js @@ -5,6 +5,10 @@ import { render, screen } from '@folio/jest-config-stripes/testing-library/react import CreateItemRoute from './CreateItemRoute'; +jest.mock('@folio/service-interaction', () => ({ + NumberGeneratorModalButton: () =>
NumberGeneratorModalButton
+})); + jest.mock('../Item', () => ({ ...jest.requireActual('../Item'), CreateItem: jest.fn().mockReturnValue('CreateItem') diff --git a/src/routes/DuplicateHoldingRoute.test.js b/src/routes/DuplicateHoldingRoute.test.js index 0994d43cc..de5107db5 100644 --- a/src/routes/DuplicateHoldingRoute.test.js +++ b/src/routes/DuplicateHoldingRoute.test.js @@ -5,6 +5,10 @@ import { render, screen } from '@folio/jest-config-stripes/testing-library/react import DuplicateHoldingRoute from './DuplicateHoldingRoute'; +jest.mock('@folio/service-interaction', () => ({ + NumberGeneratorModalButton: () =>
NumberGeneratorModalButton
+})); + jest.mock('../Holding', () => ({ ...jest.requireActual('../Holding'), DuplicateHolding: jest.fn().mockReturnValue('DuplicateHolding') diff --git a/src/routes/DuplicateItemRoute.test.js b/src/routes/DuplicateItemRoute.test.js index d604e25bb..0c4ef4b77 100644 --- a/src/routes/DuplicateItemRoute.test.js +++ b/src/routes/DuplicateItemRoute.test.js @@ -5,6 +5,10 @@ import { render, screen } from '@folio/jest-config-stripes/testing-library/react import DuplicateItemRoute from './DuplicateItemRoute'; +jest.mock('@folio/service-interaction', () => ({ + NumberGeneratorModalButton: () =>
NumberGeneratorModalButton
+})); + jest.mock('../Item', () => ({ ...jest.requireActual('../Item'), DuplicateItem: jest.fn().mockReturnValue('DuplicateItem') diff --git a/src/routes/EditHoldingRoute.test.js b/src/routes/EditHoldingRoute.test.js index 6b60c7080..b204da925 100644 --- a/src/routes/EditHoldingRoute.test.js +++ b/src/routes/EditHoldingRoute.test.js @@ -5,6 +5,10 @@ import { render, screen } from '@folio/jest-config-stripes/testing-library/react import EditHoldingRoute from './EditHoldingRoute'; +jest.mock('@folio/service-interaction', () => ({ + NumberGeneratorModalButton: () =>
NumberGeneratorModalButton
+})); + jest.mock('../Holding', () => ({ ...jest.requireActual('../Holding'), EditHolding: jest.fn().mockReturnValue('EditHolding') diff --git a/src/routes/EditItemRoute.test.js b/src/routes/EditItemRoute.test.js index 52a036da1..a6d16cf58 100644 --- a/src/routes/EditItemRoute.test.js +++ b/src/routes/EditItemRoute.test.js @@ -5,6 +5,10 @@ import { render, screen } from '@folio/jest-config-stripes/testing-library/react import EditItemRoute from './EditItemRoute'; +jest.mock('@folio/service-interaction', () => ({ + NumberGeneratorModalButton: () =>
NumberGeneratorModalButton
+})); + jest.mock('../Item', () => ({ ...jest.requireActual('../Item'), EditItem: jest.fn().mockReturnValue('EditItem') From ea9eccf66e0ed49290bcf2d268df8c89f8c4761c Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Thu, 28 Mar 2024 10:37:12 +0000 Subject: [PATCH 17/18] build: Change service interaction dependency to ^3.0.0 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5c6f0e0cf..8778e01b9 100644 --- a/package.json +++ b/package.json @@ -877,7 +877,7 @@ "@babel/preset-react": "^7.9.0", "@folio/eslint-config-stripes": "^7.0.0", "@folio/jest-config-stripes": "^2.0.0", - "@folio/service-interaction": "^2.0.0", + "@folio/service-interaction": "^3.0.0", "@folio/stripes": "^9.0.0", "@folio/stripes-cli": "^3.0.0", "@folio/stripes-components": "^12.0.0", @@ -925,7 +925,7 @@ "use-session-storage-state": "^18.2.0" }, "peerDependencies": { - "@folio/service-interaction": "^2.0.0", + "@folio/service-interaction": "^3.0.0", "@folio/stripes": "^9.0.0", "@folio/stripes-marc-components": "^1.0.0", "react": "^18.2.0", From b0a16b667e11780bd9dca40b4cdbc95338d493fb Mon Sep 17 00:00:00 2001 From: Ethan Freestone Date: Tue, 18 Jun 2024 09:44:44 +0100 Subject: [PATCH 18/18] chore: Removed "Learn more" button --- .../NumberGeneratorOptionsForm.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js index 4e317497b..0f21da223 100644 --- a/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js +++ b/src/settings/NumberGeneratorOptions/NumberGeneratorOptionsForm.js @@ -234,16 +234,6 @@ const NumberGeneratorOptionsForm = () => { }} /> - - - } iconSize="medium"