diff --git a/doc/release/RELEASE-NOTES.md b/doc/release/RELEASE-NOTES.md
index 79143dbd0..52059890e 100644
--- a/doc/release/RELEASE-NOTES.md
+++ b/doc/release/RELEASE-NOTES.md
@@ -3,6 +3,39 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). The format is based on the `RELEASE-NOTES-TEMPLATE.md` file.
+## Release 1.31.0
+
+## Introduction
+* Product name: Open Supply Hub
+* Release date: March 8, 2025
+
+### Database changes
+* *Describe high-level database changes.*
+
+#### Migrations:
+* *Describe migrations here.*
+
+#### Schema changes
+* *Describe schema changes here.*
+
+### Code/API changes
+* *Describe code/API changes here.*
+
+### Architecture/Environment changes
+* *Describe architecture/environment changes here.*
+
+### Bugfix
+* [OSDEV-1777](https://opensupplyhub.atlassian.net/browse/OSDEV-1777) - A consistent URL style was established across all pages of the SLC workflow. After the changes, the URL begins from `/contribute/single-location/`.
+
+### What's new
+* *Describe what's new here. The changes that can impact user experience should be listed in this section.*
+
+### Release instructions:
+* Ensure that the following commands are included in the `post_deployment` command:
+ * `migrate`
+ * `reindex_database`
+
+
## Release 1.30.0
## Introduction
diff --git a/src/react/src/__tests__/components/ContributeProductionLocation.test.js b/src/react/src/__tests__/components/ContributeProductionLocation.test.js
index 01273a0a9..e37373d9d 100644
--- a/src/react/src/__tests__/components/ContributeProductionLocation.test.js
+++ b/src/react/src/__tests__/components/ContributeProductionLocation.test.js
@@ -8,9 +8,9 @@ jest.mock('../../components/Contribute/SearchByOsIdTab', () => () =>
Mocked
jest.mock('../../components/Contribute/SearchByNameAndAddressTab', () => () =>
Mocked SearchByNameAndAddressTab
);
describe('ContributeProductionLocation component', () => {
- const renderComponent = (initialEntries = ['/']) =>
+ const renderComponent = (queryParams = '') =>
renderWithProviders(
-
+
);
@@ -33,7 +33,7 @@ describe('ContributeProductionLocation component', () => {
});
it('changes the tab when clicked and updates the URL', () => {
- const { getByRole, getByText } = renderComponent();
+ const { getByRole } = renderComponent();
const nameAddressTab = getByRole('tab', { name: /Search by name and address/i });
const osIdTab = getByRole('tab', { name: /Search by OS ID/i });
@@ -41,7 +41,6 @@ describe('ContributeProductionLocation component', () => {
fireEvent.click(osIdTab);
expect(osIdTab).toHaveAttribute('aria-selected', 'true');
expect(nameAddressTab).toHaveAttribute('aria-selected', 'false');
- expect(getByText('Search by OS ID')).toBeInTheDocument();
});
it('renders SearchByNameAndAddressTab when Name and Address tab is selected', () => {
@@ -58,9 +57,9 @@ describe('ContributeProductionLocation component', () => {
});
it('handles invalid tab and defaults to Name and Address tab', () => {
- const { getByRole } = renderComponent(['contribute/production-location?tab=invalid-tab']);
- const osIdTab = getByRole('tab', { name: /Search by name and address/i });
+ const { getByRole } = renderComponent('?tab=invalid-tab');
+ const nameAddressTab = getByRole('tab', { name: /Search by name and address/i });
- expect(osIdTab).toHaveAttribute('aria-selected', 'true');
+ expect(nameAddressTab).toHaveAttribute('aria-selected', 'true');
});
});
diff --git a/src/react/src/__tests__/components/ProductionLocationDetails.test.js b/src/react/src/__tests__/components/ProductionLocationDetails.test.js
index 92fecd8fe..082f0c1ec 100644
--- a/src/react/src/__tests__/components/ProductionLocationDetails.test.js
+++ b/src/react/src/__tests__/components/ProductionLocationDetails.test.js
@@ -30,7 +30,7 @@ describe('ProductionLocationDetails component', () => {
test('renders production location details correctly', () => {
useLocation.mockReturnValue({
- pathname: '/contribute/production-location/search/id/US2021250D1DTN7',
+ pathname: '/contribute/single-location/search/id/US2021250D1DTN7',
});
const { getByText } = renderWithProviders(
@@ -60,7 +60,7 @@ describe('ProductionLocationDetails component', () => {
test('renders previous OS IDs that match the search parameter', () => {
useLocation.mockReturnValue({
- pathname: '/contribute/production-location/search/id/US2020053ZH1RY5',
+ pathname: '/contribute/single-location/search/id/US2020053ZH1RY5',
});
const { getByText } = renderWithProviders(
@@ -73,7 +73,7 @@ describe('ProductionLocationDetails component', () => {
test('does not render previous OS IDs if they do not match the search parameter', () => {
useLocation.mockReturnValue({
- pathname: '/contribute/production-location/search/id/UNKNOWN_OS_ID',
+ pathname: '/contribute/single-location/search/id/UNKNOWN_OS_ID',
});
const { queryByText } = renderWithProviders(
@@ -85,7 +85,7 @@ describe('ProductionLocationDetails component', () => {
test('renders only "OS ID:" if there are no historical OS IDs', () => {
useLocation.mockReturnValue({
- pathname: '/contribute/production-location/search/id/US2021250D1DTN7',
+ pathname: '/contribute/single-location/search/id/US2021250D1DTN7',
});
const { getByText } = renderWithProviders(
diff --git a/src/react/src/__tests__/components/SearchByNameAndAddressSuccessResult.test.js b/src/react/src/__tests__/components/SearchByNameAndAddressSuccessResult.test.js
index f5389d125..e49d8da37 100644
--- a/src/react/src/__tests__/components/SearchByNameAndAddressSuccessResult.test.js
+++ b/src/react/src/__tests__/components/SearchByNameAndAddressSuccessResult.test.js
@@ -129,7 +129,7 @@ describe('SearchByNameAndAddressSuccessResult component', () => {
selectButtons.forEach((button, index) => {
fireEvent.click(button);
expect(mockHistoryPush).toHaveBeenCalledWith(
- `/contribute/production-location/${defaultProps.productionLocations[index].os_id}/info/`
+ `/contribute/single-location/${defaultProps.productionLocations[index].os_id}/info/`
);
});
});
diff --git a/src/react/src/__tests__/components/SearchByOsIdTab.test.js b/src/react/src/__tests__/components/SearchByOsIdTab.test.js
index a33d8d4e6..3d4789de3 100644
--- a/src/react/src/__tests__/components/SearchByOsIdTab.test.js
+++ b/src/react/src/__tests__/components/SearchByOsIdTab.test.js
@@ -64,7 +64,7 @@ describe('SearchByOsIdTab component', () => {
fireEvent.click(getByRole('button', { name: /Search by ID/i }));
expect(history.location.pathname).toBe(
- '/contribute/production-location/search/id/CN2021250D1DTN7'
+ '/contribute/single-location/search/id/CN2021250D1DTN7'
);
});
diff --git a/src/react/src/__tests__/utils.tests.js b/src/react/src/__tests__/utils.tests.js
index 34b17eae6..0806876b4 100644
--- a/src/react/src/__tests__/utils.tests.js
+++ b/src/react/src/__tests__/utils.tests.js
@@ -1877,27 +1877,27 @@ it('should not call setter when dataKey is null', () => {
});
it('extracts the ID from a valid URL without a trailing slash', () => {
- const url = '/contribute/production-location/search/id/BD202034606B9SA';
+ const url = '/contribute/single-location/search/id/BD202034606B9SA';
expect(getLastPathParameter(url)).toBe('BD202034606B9SA');
});
it('extracts the ID from a valid URL with a trailing slash', () => {
- const url = '/contribute/production-location/search/id/BD202034606B9SA/';
+ const url = '/contribute/single-location/search/id/BD202034606B9SA/';
expect(getLastPathParameter(url)).toBe('BD202034606B9SA');
});
it('returns id when the URL ends at "id/" with no ID', () => {
- const url = '/contribute/production-location/search/id/';
+ const url = '/contribute/single-location/search/id/';
expect(getLastPathParameter(url)).toBe('id');
});
it('returns the correct ID when the URL contains query parameters', () => {
- const url = '/contribute/production-location/search/id/BD202034606B9SA?foo=bar';
+ const url = '/contribute/single-location/search/id/BD202034606B9SA?foo=bar';
expect(getLastPathParameter(url)).toBe('BD202034606B9SA');
});
it('returns the correct ID when the URL has multiple segments after "id/"', () => {
- const url = '/contribute/production-location/search/id/BD202034606B9SA/extra';
+ const url = '/contribute/single-location/search/id/BD202034606B9SA/extra';
expect(getLastPathParameter(url)).toBe('extra');
});
diff --git a/src/react/src/components/Contribute/SearchByOsIdSuccessResult.jsx b/src/react/src/components/Contribute/SearchByOsIdSuccessResult.jsx
index 71b2b1f19..e471ec2d3 100644
--- a/src/react/src/components/Contribute/SearchByOsIdSuccessResult.jsx
+++ b/src/react/src/components/Contribute/SearchByOsIdSuccessResult.jsx
@@ -24,7 +24,7 @@ const SearchByOsIdSuccessResult = ({
const history = useHistory();
const handleGoToSelectedProductionLocationInfo = () =>
- history.push(`/contribute/production-location/${osId}/info/`);
+ history.push(`/contribute/single-location/${osId}/info/`);
return (
<>
diff --git a/src/react/src/components/Contribute/SearchByOsIdTab.jsx b/src/react/src/components/Contribute/SearchByOsIdTab.jsx
index 44c10298c..0262ca74d 100644
--- a/src/react/src/components/Contribute/SearchByOsIdTab.jsx
+++ b/src/react/src/components/Contribute/SearchByOsIdTab.jsx
@@ -31,7 +31,7 @@ const SearchByOsIdTab = ({ classes }) => {
};
const handleSearch = () => {
- history.push(`/contribute/production-location/search/id/${inputOsId}`);
+ history.push(`/contribute/single-location/search/id/${inputOsId}`);
};
return (
diff --git a/src/react/src/util/constants.jsx b/src/react/src/util/constants.jsx
index ef662b41d..acb4d32a4 100644
--- a/src/react/src/util/constants.jsx
+++ b/src/react/src/util/constants.jsx
@@ -353,15 +353,15 @@ export const dashboardClaimsDetailsRoute = '/dashboard/claims/:claimID';
export const aboutClaimedFacilitiesRoute = `${InfoLink}/${InfoPaths.claimedFacilities}`;
export const contributeProductionLocationRoute = '/contribute/single-location';
export const searchByOsIdResultRoute =
- '/contribute/production-location/search/id/:osID';
+ '/contribute/single-location/search/id/:osID';
export const searchByNameAndAddressResultRoute =
- '/contribute/production-location/search/';
+ '/contribute/single-location/search/';
export const productionLocationInfoRouteCommon =
- '/contribute/production-location/info/';
+ '/contribute/single-location/info/';
export const productionLocationInfoRouteCreate =
- '/contribute/production-location/info/:moderationID?';
+ '/contribute/single-location/info/:moderationID?';
export const productionLocationInfoRouteUpdate =
- '/contribute/production-location/:osID/info/:moderationID?';
+ '/contribute/single-location/:osID/info/:moderationID?';
export const contributeFieldsEnum = Object.freeze({
name: 'name',
diff --git a/src/react/src/util/util.js b/src/react/src/util/util.js
index 4620cddcc..b4da790e9 100644
--- a/src/react/src/util/util.js
+++ b/src/react/src/util/util.js
@@ -297,7 +297,7 @@ export const makeProductionLocationFromModerationEventURL = (
};
export const makeContributeProductionLocationUpdateURL = osID =>
- `/contribute/production-location/${osID}/info/`;
+ `/contribute/single-location/${osID}/info/`;
export const makeGetModerationEventsWithQueryString = (
qs,