Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UIORGS-336: Creating or changing a vendor code using number generator in Organizations App #536

Merged
merged 41 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
556ce31
feat: Number Generator
EthanFreestone Sep 15, 2022
7a04e05
chore: Interfaces
EthanFreestone Sep 16, 2022
515dfb7
Merge branch 'master' of github.com:folio-org/ui-organizations into f…
EthanFreestone Feb 3, 2023
b3d112e
chore: Tweaks
EthanFreestone Feb 3, 2023
2bdaba9
fix: Generator code
EthanFreestone Feb 16, 2023
0017207
feat: Permission
EthanFreestone Feb 16, 2023
6a1e4dc
Merge branch 'master' of github.com:folio-org/ui-organizations into f…
EthanFreestone Feb 22, 2023
03fe682
Merge branch 'master' of github.com:folio-org/ui-organizations into f…
EthanFreestone Jun 20, 2023
f9a299d
build: OptionalOkapiInterfaces
EthanFreestone Jun 20, 2023
ec4f60a
Merge branch 'master' of github.com:folio-org/ui-organizations into f…
EthanFreestone Aug 7, 2023
ce20f23
build: New service interaction
EthanFreestone Aug 7, 2023
b4c1a43
Merge branch 'master' of github.com:folio-org/ui-organizations into f…
EthanFreestone Aug 21, 2023
3305486
Merge branch 'master' of github.com:folio-org/ui-organizations into f…
EthanFreestone Sep 8, 2023
5366269
feat: Number generator
EthanFreestone Sep 8, 2023
dab366d
Merge branch 'master' of github.com:folio-org/ui-organizations into f…
EthanFreestone Sep 13, 2023
fbaabdf
chore: Button UX
EthanFreestone Sep 29, 2023
d79dcd9
Merge branch 'master' of github.com:folio-org/ui-organizations into f…
EthanFreestone Sep 29, 2023
5b3bde5
Merge branch 'master' of github.com:folio-org/ui-organizations into f…
EthanFreestone Oct 23, 2023
be51dbf
Merge branch 'master' of github.com:folio-org/ui-organizations into f…
EthanFreestone Dec 8, 2023
588afcf
Merge branch 'master' of github.com:folio-org/ui-organizations into f…
EthanFreestone Dec 8, 2023
68419c4
Merge branch 'feat/number_generator' of github.com:folio-org/ui-organ…
EthanFreestone Dec 8, 2023
d618b90
chore: Revert to state on master
EthanFreestone Dec 8, 2023
28d2d16
Merge branch 'master' of github.com:folio-org/ui-organizations into f…
EthanFreestone Mar 1, 2024
5724de3
test: mock useSettings
EthanFreestone Mar 1, 2024
e0f9cff
test: Updated jest snapshot
EthanFreestone Mar 1, 2024
2fdb4e7
test: Test fails on CI because of non mocked component -- easy fix
EthanFreestone Mar 1, 2024
79e4c34
build: Change service interaction dependency to ^3.0.0
EthanFreestone Mar 28, 2024
5e4e4c2
refactor: Refactor tweaks
EthanFreestone Apr 12, 2024
bae809d
chore: MessageBanner
EthanFreestone May 7, 2024
d9805f3
Merge branch 'master' into feat/number_generator
alb3rtino Nov 18, 2024
d78705c
Update dependencies
alb3rtino Nov 18, 2024
30ab158
Update implementation
alb3rtino Nov 18, 2024
1454363
Update CHANGELOG and version
alb3rtino Nov 20, 2024
0ced3e6
Ignore test until fixed
alb3rtino Nov 22, 2024
d195ed9
Merge branch 'master' into feat/number_generator
alb3rtino Nov 27, 2024
b398e75
Unignore test
alb3rtino Nov 27, 2024
d643304
Use organizations-storage settings api
alb3rtino Dec 9, 2024
e4c477f
Merge branch 'master' into feat/number_generator
alb3rtino Dec 9, 2024
043b6b9
Merge branch 'master' into feat/number_generator
alb3rtino Dec 9, 2024
51224b5
Add AbortSignal to queryFn
alb3rtino Dec 11, 2024
0ab159c
Merge branch 'master' into feat/number_generator
alb3rtino Dec 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Adapt organization metadata fields to version history mechanism. Refs UIORGS-359.
* Add claiming to organization integration details. Refs UIORGS-442.
* Add "Duplicate" integration action to organization integration view. Refs UIORGS-441.
* *BREAKING* Add number generator for vendor code including settings page. Refs UIORGS-336, UIORGS-337.

## [5.2.0](https://github.com/folio-org/ui-organizations/tree/v5.2.0) (2024-10-31)
[Full Changelog](https://github.com/folio-org/ui-organizations/compare/v5.1.1...v5.2.0)
Expand Down
24 changes: 22 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@
"organizations-storage.interfaces": "2.1",
"organizations-storage.phone-numbers": "2.0",
"organizations-storage.privileged-contacts": "1.0",
"organizations-storage.settings": "1.0",
"organizations-storage.settings": "1.1",
"organizations-storage.urls": "1.1",
"tags": "1.0",
"users": "15.1 16.0"
},
"optionalOkapiInterfaces": {
"servint": "4.0"
},
"queryResource": "query",
"icons": [
{
Expand All @@ -46,6 +49,7 @@
}
],
"stripesDeps": [
"@folio/service-interaction",
"@folio/stripes-acq-components"
],
"permissionSets": [
Expand All @@ -64,7 +68,9 @@
{
"permissionName": "ui-organizations.third-party-services.execute",
"displayName": "Organizations: Permissions required to call services apart from mod-organizations-storage",
"replaces": ["ui-organizations.third-party-services"],
"replaces": [
"ui-organizations.third-party-services"
],
"visible": false,
"subPermissions": [
"acquisition.organization.events.get",
Expand Down Expand Up @@ -297,6 +303,17 @@
"organizations-storage.banking-account-types.item.put",
"organizations-storage.banking-account-types.item.delete"
]
},
{
"permissionName": "ui-organizations.settings.numberGenerator.manage",
"displayName": "Settings (Organizations): Manage number generator options",
"subPermissions": [
"settings.organizations.enabled",
"organizations-storage.settings.collection.get",
"organizations-storage.settings.item.post",
"organizations-storage.settings.item.put"
],
"visible": true
}
]
},
Expand Down Expand Up @@ -327,8 +344,10 @@
"@bigtest/react": "^0.1.2",
"@folio/eslint-config-stripes": "^7.0.0",
"@folio/jest-config-stripes": "^2.0.0",
"@folio/service-interaction": "^3.1.0",
"@folio/stripes": "^9.0.0",
"@folio/stripes-cli": "^3.0.0",
"@folio/stripes-erm-components": "^9.2.0",
"@formatjs/cli": "^6.1.3",
"babel-jest": "^26.3.0",
"chai": "^4.2.0",
Expand Down Expand Up @@ -367,6 +386,7 @@
"redux-form": "^8.3.0"
},
"peerDependencies": {
"@folio/service-interaction": "^3.1.0",
"@folio/stripes": "^9.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,67 @@
import React, { useCallback } from 'react';
import { Field } from 'react-final-form';
import {
Field,
useForm,
} from 'react-final-form';
import { FormattedMessage } from 'react-intl';
import PropTypes from 'prop-types';

import { NumberGeneratorModalButton } from '@folio/service-interaction';
import { stripesConnect } from '@folio/stripes/core';
import { TextField } from '@folio/stripes/components';
import {
Col,
Row,
TextField,
} from '@folio/stripes/components';

import { VENDOR_CODE_GENERATOR_CODE } from '../../../../common/constants';
import { useVendorCodeGeneratorSettings } from '../../../../common/hooks';
import { fetchOrgsByParam } from '../../../../common/resources';
import { validateOrgCode } from './validateOrgCode';

const FieldCode = ({ orgId, mutator }) => {
const { change, resetFieldState } = useForm();
const { isUseGenerator, isUseBoth } = useVendorCodeGeneratorSettings();

const validate = useCallback(value => {
return validateOrgCode(mutator.fetchOrgByCode, orgId, value);
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[orgId]);

const handleGeneratedValue = useCallback((generatedValue) => {
change('code', generatedValue);
resetFieldState('code');
}, [change, resetFieldState]);

return (
<Field
component={TextField}
fullWidth
label={<FormattedMessage id="ui-organizations.summary.code" />}
name="code"
required
validate={validate}
/>
<Row>
<Col xs={12}>
<Field
component={TextField}
disabled={isUseGenerator}
fullWidth
label={<FormattedMessage id="ui-organizations.summary.code" />}
name="code"
required
validate={validate}
/>
</Col>
{(isUseGenerator || isUseBoth) && (
<Col xs={12}>
<NumberGeneratorModalButton
buttonLabel={<FormattedMessage id="ui-organizations.numberGenerator.generateVendorCode" />}
callback={handleGeneratedValue}
generateButtonLabel={<FormattedMessage id="ui-organizations.numberGenerator.generateVendorCode" />}
generator={VENDOR_CODE_GENERATOR_CODE}
id="vendor-code-generator"
modalProps={{
label: <FormattedMessage id="ui-organizations.numberGenerator.vendorCodeGenerator" />,
}}
/>
</Col>
)}
</Row>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import userEvent from '@folio/jest-config-stripes/testing-library/user-event';
import { render, screen } from '@folio/jest-config-stripes/testing-library/react';
import { MemoryRouter } from 'react-router-dom';

Expand All @@ -8,10 +9,25 @@ import { organization, organizationTypes } from 'fixtures';
import { QueryClient, QueryClientProvider } from 'react-query';
import OrganizationSummaryForm from './OrganizationSummaryForm';

import { useTypes } from '../../../common/hooks';
import {
useTypes,
useVendorCodeGeneratorSettings,
} from '../../../common/hooks';

jest.mock('../../../common/hooks', () => ({
useTypes: jest.fn(),
useVendorCodeGeneratorSettings: jest.fn(),
}));

jest.mock('@folio/service-interaction', () => ({
NumberGeneratorModalButton: ({ callback }) => (
<button
onClick={() => callback('abc123')}
type="button"
>
NumberGeneratorModalButton
</button>
),
}));

const TestForm = stripesFinalForm({})(
Expand Down Expand Up @@ -44,6 +60,11 @@ describe('OrganizationSummaryForm', () => {
useTypes
.mockClear()
.mockReturnValue({ organizationTypes, totalRecords: organizationTypes.length });
useVendorCodeGeneratorSettings.mockReturnValue({
isUseGenerator: false,
isUseBoth: false,
isUseTextfield: false,
});
});

afterEach(() => {
Expand Down Expand Up @@ -73,4 +94,41 @@ describe('OrganizationSummaryForm', () => {

expect((selectedType).length).toEqual(1);
});

it('should not render the NumberGeneratorModalButton', async () => {
renderForm();

expect(screen.getByRole('textbox', { name: 'ui-organizations.summary.code' })).toBeEnabled();
expect(screen.queryByRole('button', { name: 'NumberGeneratorModalButton' })).not.toBeInTheDocument();
});

it('should render the NumberGeneratorModalButton when setting=isUseGenerator', async () => {
useVendorCodeGeneratorSettings.mockReturnValue({ isUseGenerator: true });

renderForm();

expect(screen.getByRole('textbox', { name: 'ui-organizations.summary.code' })).toBeDisabled();
expect(screen.getByRole('button', { name: 'NumberGeneratorModalButton' })).toBeInTheDocument();
});

it('should render the NumberGeneratorModalButton when setting=isUseBoth', async () => {
useVendorCodeGeneratorSettings.mockReturnValue({ isUseBoth: true });

renderForm();

expect(screen.getByRole('textbox', { name: 'ui-organizations.summary.code' })).toBeEnabled();
expect(screen.getByRole('button', { name: 'NumberGeneratorModalButton' })).toBeInTheDocument();
});

it('should update vendor code field value when NumberGeneratorModalButton is clicked', async () => {
useVendorCodeGeneratorSettings.mockReturnValue({ isUseBoth: true });

renderForm();
const button = screen.getByRole('button', { name: 'NumberGeneratorModalButton' });
const input = screen.getByRole('textbox', { name: 'ui-organizations.summary.code' });

expect(input).toHaveValue('');
await userEvent.click(button);
expect(input).toHaveValue('abc123');
});
});
52 changes: 52 additions & 0 deletions src/Settings/NumberGeneratorSettings/NumberGeneratorSettings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { FormattedMessage } from 'react-intl';

import { Loading } from '@folio/stripes/components';
import { useOkapiKy } from '@folio/stripes/core';
import { useShowCallout } from '@folio/stripes-acq-components';

import NumberGeneratorSettingsForm from './NumberGeneratorSettingsForm';
import { SETTINGS_API } from '../../common/constants/api';
import { VENDOR_CODE_GENERATOR_SETTINGS_KEY } from '../../common/constants/numberGenerator';
import { useVendorCodeGeneratorSettings } from '../../common/hooks/useVendorCodeGeneratorSettings';

const NumberGeneratorSettings = () => {
const { vendorCodeSetting, isLoading } = useVendorCodeGeneratorSettings();
const ky = useOkapiKy();
const sendCallout = useShowCallout();

const onSubmit = async ({ [VENDOR_CODE_GENERATOR_SETTINGS_KEY]: value }) => {
try {
if (vendorCodeSetting) {
await ky.put(`${SETTINGS_API}/${vendorCodeSetting.id}`, {
json: { ...vendorCodeSetting, value },
});
} else {
await ky.post(SETTINGS_API, {
json: { key: VENDOR_CODE_GENERATOR_SETTINGS_KEY, value },
});
}

sendCallout({
message: <FormattedMessage id="ui-organizations.settings.numberGeneratorOptions.save.success" />,
});
} catch (error) {
sendCallout({
type: 'error',
message: <FormattedMessage id="ui-organizations.settings.numberGeneratorOptions.save.error" />,
});
}
};

if (isLoading) {
return <Loading />;
}

return (
<NumberGeneratorSettingsForm
initialValues={{ [VENDOR_CODE_GENERATOR_SETTINGS_KEY]: vendorCodeSetting?.value }}
onSubmit={onSubmit}
/>
);
};

export default NumberGeneratorSettings;
Loading
Loading