Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 doc/release/RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html

### Bugfix
* [OSDEV-1747](https://opensupplyhub.atlassian.net/browse/OSDEV-1747) - The pages `My Claimed Facilities`, `Claimed Facility Details`, `My Lists`, and `My Lists/id` are now accessible only to authorized users. Additionally, styles have been refactored, an `InputSelect` component has been moved to the separate file, and input styling on the `Claimed Facility Details` page has been fixed.
* [OSDEV-1830](https://opensupplyhub.atlassian.net/browse/OSDEV-1830) - Updated implementation for `Production Location Info` page to input any values for `Location Type` and `Processing Type`, except when the sector is `Apparel` — in that case, enforce taxonomy filters.

### What's new
* *Describe what's new here. The changes that can impact user experience should be listed in this section.*
Expand Down
37 changes: 28 additions & 9 deletions src/react/src/__tests__/components/ProductionLocationInfo.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@ jest.mock('@material-ui/core/Popper', () => ({ children }) => children);
jest.mock('@material-ui/core/Portal', () => ({ children }) => children);

jest.mock("../../components/Filters/StyledSelect", () => (props) => {
const { options = [], value, onChange, onBlur, placeholder } = props;
const { options = [], value, onChange, onBlur, placeholder, name } = props;

return (
<select
data-testid="mocked-select"
data-testid={`mocked-select-${name}`}
value={value ? value.value : ""}
onChange={(e) => {
const selectedOption = options.find(
(opt) => opt.value === e.target.value,
);
onChange(selectedOption);
onChange(
name === 'country' ? selectedOption : [selectedOption]
);
}}
onBlur={onBlur}
>
Expand Down Expand Up @@ -100,7 +103,7 @@ describe("ProductionLocationInfo component, test input fields for POST v1/produc
expect(addressInput).toBeInTheDocument();
expect(addressInput).toHaveValue("");

const countrySelect = getByTestId("mocked-select");
const countrySelect = getByTestId("mocked-select-country");
expect(countrySelect).toBeInTheDocument();
expect(countrySelect).toHaveValue("");

Expand All @@ -116,7 +119,7 @@ describe("ProductionLocationInfo component, test input fields for POST v1/produc

const nameInput = getByPlaceholderText("Enter the name");
const addressInput = getByPlaceholderText("Enter the full address");
const countrySelect = getByTestId("mocked-select");
const countrySelect = getByTestId("mocked-select-country");

fireEvent.blur(nameInput);
fireEvent.blur(addressInput);
Expand All @@ -137,7 +140,7 @@ describe("ProductionLocationInfo component, test input fields for POST v1/produc

const nameInput = getByPlaceholderText("Enter the name");
const addressInput = getByPlaceholderText("Enter the full address");
const countrySelect = getByTestId("mocked-select");
const countrySelect = getByTestId("mocked-select-country");

fireEvent.change(nameInput, { target: { value: "Test Name" } });
fireEvent.change(addressInput, { target: { value: "Test Address" } });
Expand All @@ -158,9 +161,9 @@ describe("ProductionLocationInfo component, test input fields for POST v1/produc
expect(getByText("Product Type(s)")).toBeInTheDocument();
expect(getByText("Enter the type of products produced at this location. For example: Shirts, Laptops, Solar Panels.")).toBeInTheDocument();
expect(getByText("Location Type(s)")).toBeInTheDocument();
expect(getByText("Select the location type(s) for this production location. For example: Final Product Assembly, Raw Materials Production or Processing, Office/HQ.")).toBeInTheDocument();
expect(getByText("Select or enter the location type(s) for this production location. For example: Final Product Assembly, Raw Materials Production or Processing, Office/HQ.")).toBeInTheDocument();
expect(getByText("Processing Type(s)")).toBeInTheDocument();
expect(getByText("Select the type of processing activities that take place at this location. For example: Printing, Tooling, Assembly.")).toBeInTheDocument();
expect(getByText("Select or enter the type of processing activities that take place at this location. For example: Printing, Tooling, Assembly.")).toBeInTheDocument();
expect(getByText("Number of Workers")).toBeInTheDocument();
expect(getByText("Enter a number or a range for the number of people employed at the location. For example: 100, 100-150.")).toBeInTheDocument();
expect(getByText("Parent Company")).toBeInTheDocument();
Expand All @@ -184,7 +187,7 @@ describe("ProductionLocationInfo component, test input fields for POST v1/produc

const nameInput = getByPlaceholderText("Enter the name");
const addressInput = getByPlaceholderText("Enter the full address");
const countrySelect = getByTestId("mocked-select");
const countrySelect = getByTestId("mocked-select-country");

fireEvent.change(nameInput, { target: { value: "Test Name" } });
fireEvent.change(addressInput, { target: { value: "Test Address" } });
Expand Down Expand Up @@ -268,6 +271,22 @@ describe("ProductionLocationInfo component, test input fields for POST v1/produc

expect(noTooltipElementAfter).toBeInTheDocument();
});

test("displays select or input for location and processing type fields", () => {
const { getByTestId, getByText } = renderComponent();

const switchButton = getByTestId("switch-additional-info-fields");
fireEvent.click(switchButton);

expect(getByText("Enter location type(s)")).toBeInTheDocument();
expect(getByText("Enter processing type(s)")).toBeInTheDocument();

const sectorSelect = getByTestId("mocked-select-sector");
fireEvent.change(sectorSelect, { target: { value: 'Apparel' } });

expect(getByText("Select location type(s)")).toBeInTheDocument();
expect(getByText("Select processing type(s)")).toBeInTheDocument();
});
});

describe("ProductionLocationInfo component, test invalid incoming data for UPDATE v1/production-locations", () => {
Expand Down
109 changes: 74 additions & 35 deletions src/react/src/components/Contribute/ProductionLocationInfo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ const ProductionLocationInfo = ({
const [nameTouched, setNameTouched] = useState(false);
const [addressTouched, setAddressTouched] = useState(false);
const [countryTouched, setCountryTouched] = useState(false);
const [enabledTaxonomy, setEnabledTaxonomy] = useState(false);
const [sector, setSector] = useState('');
const [productType, setProductType] = useState([]);
const [locationType, setLocationType] = useState(null);
Expand Down Expand Up @@ -400,6 +401,12 @@ const ProductionLocationInfo = ({
moderationID,
]);

useEffect(() => {
setEnabledTaxonomy(
sector.length === 1 && sector[0].value === 'Apparel',
);
}, [sector]);

useEffect(
() => () => {
handleCleanupContributionRecord();
Expand Down Expand Up @@ -595,7 +602,7 @@ const ProductionLocationInfo = ({
</Typography>
<StyledSelect
id="country"
name="Country"
name="country"
aria-label="Country"
options={countriesOptions || []}
value={inputCountry}
Expand Down Expand Up @@ -698,7 +705,7 @@ const ProductionLocationInfo = ({

<StyledSelect
creatable
name="Product Type"
name="product-type"
value={productType}
onChange={setProductType}
placeholder="Enter product type(s)"
Expand All @@ -721,25 +728,40 @@ const ProductionLocationInfo = ({
component="h4"
className={classes.subTitleStyles}
>
Select the location type(s) for this
production location. For example: Final
Product Assembly, Raw Materials
Select or enter the location type(s) for
this production location. For example:
Final Product Assembly, Raw Materials
Production or Processing, Office/HQ.
</Typography>
<StyledSelect
id="location_type"
name="Location type"
aria-label="Location type"
options={mapFacilityTypeOptions(
facilityProcessingTypeOptions || [],
processingType || [],
)}
value={locationType}
onChange={setLocationType}
styles={getSelectStyles()}
className={classes.selectStyles}
placeholder="Select location type(s)"
/>
{enabledTaxonomy ? (
<StyledSelect
id="location_type"
name="location-type"
aria-label="Location type"
options={mapFacilityTypeOptions(
facilityProcessingTypeOptions ||
[],
processingType || [],
)}
value={locationType}
onChange={setLocationType}
styles={getSelectStyles()}
className={classes.selectStyles}
placeholder="Select location type(s)"
/>
) : (
<StyledSelect
creatable
name="location-type"
value={locationType || []}
onChange={setLocationType}
placeholder="Enter location type(s)"
aria-label="Location type"
styles={getSelectStyles()}
className={classes.selectStyles}
components={customSelectComponents}
/>
)}
</div>
<div
className={`${classes.inputSectionWrapStyles} ${classes.wrapStyles}`}
Expand All @@ -754,23 +776,40 @@ const ProductionLocationInfo = ({
component="h4"
className={classes.subTitleStyles}
>
Select the type of processing activities
that take place at this location. For
example: Printing, Tooling, Assembly.
Select or enter the type of processing
activities that take place at this
location. For example: Printing,
Tooling, Assembly.
</Typography>
<StyledSelect
id="processing_type"
name="Processing Type"
aria-label="Processing Type"
options={mapProcessingTypeOptions(
facilityProcessingTypeOptions || [],
locationType || [],
)}
value={processingType}
onChange={setProcessingType}
styles={getSelectStyles()}
className={classes.selectStyles}
/>
{enabledTaxonomy ? (
<StyledSelect
id="processing_type"
name="processing-type"
aria-label="Processing Type"
options={mapProcessingTypeOptions(
facilityProcessingTypeOptions ||
[],
locationType || [],
)}
value={processingType}
onChange={setProcessingType}
styles={getSelectStyles()}
className={classes.selectStyles}
placeholder="Select processing type(s)"
/>
) : (
<StyledSelect
creatable
name="processing-type"
value={processingType || []}
onChange={setProcessingType}
placeholder="Enter processing type(s)"
aria-label="Processing Type"
styles={getSelectStyles()}
className={classes.selectStyles}
components={customSelectComponents}
/>
)}
</div>
<div
className={`${classes.inputSectionWrapStyles} ${classes.wrapStyles}`}
Expand Down
Loading