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 @@ -106,6 +106,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
* [OSDEV-1589](https://opensupplyhub.atlassian.net/browse/OSDEV-1589) - Fixed layout issue on new `contribute` page.
* [OSDEV-1739](https://opensupplyhub.atlassian.net/browse/OSDEV-1739) - Applied state cleanup on modal unmount to prevent the same dialog from appearing when clicking on a different production location.
* [OSDEV-1744](https://opensupplyhub.atlassian.net/browse/OSDEV-1744) - Fixed the issue where the text `by user ID:` appeared even when `user_id` was `null` in Contribution Record page.
* [OSDEV-1779](https://opensupplyhub.atlassian.net/browse/OSDEV-1779) - SLC. Made Parent Company field as regular text field and apply snake_case keys to standard keys (e.g. `location_type`, `number_of_workers`, `parent_company`, `processing_type` and `product_type`) in request payload from production location info page to conform API specs.

### What's new
* [OSDEV-1662](https://opensupplyhub.atlassian.net/browse/OSDEV-1662) - Added a new field, `action_perform_by`, to the moderation event. This data appears on the Contribution Record page when a moderator perform any actions like `APPROVED` or `REJECTED`.
Expand Down
118 changes: 108 additions & 10 deletions src/react/src/__tests__/utils.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -1973,8 +1973,8 @@ it('should process array fields and keep non-empty values', () => {
address: '710 AUZERAIS AVE, SAN JOSE, CA, 95126',
country: { value: 'US' },
sector: ['Waste Management'],
parent_company: ['ParentCompanySingle'],
product_type: ['Shirts', 'Pants'],
parentCompany: 'ParentCompanySingle',
productType: ['Shirts', 'Pants'],
};

const expectedOutput = {
Expand All @@ -1983,7 +1983,7 @@ it('should process array fields and keep non-empty values', () => {
address: '710 AUZERAIS AVE, SAN JOSE, CA, 95126',
country: 'US',
sector: ['Waste Management'],
parent_company: ['ParentCompanySingle'],
parent_company: 'ParentCompanySingle',
product_type: ['Shirts', 'Pants'],
};

Expand Down Expand Up @@ -2033,9 +2033,9 @@ it('should remove empty fields while keeping valid ones', () => {
address: '710 AUZERAIS AVE, SAN JOSE, CA, 95126',
country: { value: 'US' },
sector: [],
parent_company: null,
product_type: undefined,
location_type: ['RCRAInfo subtitle C (Hazardous waste handlers)'],
parentCompany: null,
productType: undefined,
locationType: ['RCRAInfo subtitle C (Hazardous waste handlers)'],
};

const expectedOutput = {
Expand All @@ -2055,10 +2055,10 @@ it('should return only the source field if all other values are empty', () => {
address: '',
country: null,
sector: [],
parent_company: '',
product_type: undefined,
location_type: null,
processing_type: '',
parentCompany: '',
productType: undefined,
locationType: null,
processingType: '',
numberOfWorkers: null,
};

Expand All @@ -2068,3 +2068,101 @@ it('should return only the source field if all other values are empty', () => {

expect(parseContribData(input)).toEqual(expectedOutput);
});

it('should convert incoming object with camelCase keys into snake_case to conform request payload format', () => {
const input = {
name: 'AJAX AUTO DISMANTLERS INC',
address: '2895 3RD, SAN FRANCISCO, CA, 94107-0000',
country: {
value: 'US',
label: 'United States'
},
sector: [
{
value: 'Waste Management',
label: 'Waste Management'
},
{
value: 'Recycling',
label: 'Recycling'
}
],
productType: [
{
label: 'Bottles',
value: 'Bottles'
},
{
label: 'Pockets',
value: 'Pockets'
},
{
label: 'Domestic goods',
value: 'Domestic goods'
}
],
locationType: [
{
value: 'Warehousing / Distribution',
label: 'Warehousing / Distribution'
},
{
value: 'Final Product Assembly',
label: 'Final Product Assembly'
},
{
value: 'Office / HQ',
label: 'Office / HQ'
}
],
processingType: [
{
value: 'Assembly',
label: 'Assembly'
},
{
value: 'Cut & Sew',
label: 'Cut & Sew'
},
{
value: 'Warehousing / Distribution',
label: 'Warehousing / Distribution'
}
],
numberOfWorkers: "20-35",
parentCompany: "Ajax Parent Ltd."
};

const expectedOutput = {
name: 'AJAX AUTO DISMANTLERS INC',
address: '2895 3RD, SAN FRANCISCO, CA, 94107-0000',
sector: [
'Waste Management',
'Recycling'
],
product_type: [
'Bottles',
'Pockets',
'Domestic goods'
],
location_type: [
'Warehousing / Distribution',
'Final Product Assembly',
'Office / HQ'
],
processing_type: [
'Assembly',
'Cut & Sew',
'Warehousing / Distribution'
],
parent_company: 'Ajax Parent Ltd.',
number_of_workers: {
"min": 20,
"max": 35
},
country: 'US',
source: 'SLC'
};

expect(parseContribData(input)).toEqual(expectedOutput);
});
4 changes: 2 additions & 2 deletions src/react/src/actions/contributeProductionLocation.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export function createProductionLocation(contribData) {
const parsedContribData = parseContribData(contribData);

return async dispatch => {
dispatch(startCreateProductionLocation());
dispatch(startCreateProductionLocation(parsedContribData));

try {
const { data } = await apiRequest.post(
Expand All @@ -89,7 +89,7 @@ export function updateProductionLocation(contribData, osID) {
const parsedContribData = parseContribData(contribData);

return async dispatch => {
dispatch(startUpdateProductionLocation());
dispatch(startUpdateProductionLocation(parsedContribData));

try {
const { data } = await apiRequest.patch(
Expand Down
29 changes: 16 additions & 13 deletions src/react/src/components/Contribute/ProductionLocationInfo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ const ProductionLocationInfo = ({
const [locationType, setLocationType] = useState(null);
const [processingType, setProcessingType] = useState(null);
const [numberOfWorkers, setNumberOfWorkers] = useState('');
const [parentCompany, setParentCompany] = useState([]);
const [parentCompany, setParentCompany] = useState('');
const customSelectComponents = { DropdownIndicator: null };

useEffect(() => {
Expand Down Expand Up @@ -161,6 +161,9 @@ const ProductionLocationInfo = ({
setAddressTouched(true);
setInputAddress(event.target.value);
};
const handleParentCompanyChange = event => {
setParentCompany(event.target.value);
};

let handleProductionLocation;
switch (submitMethod) {
Expand Down Expand Up @@ -243,11 +246,7 @@ const ProductionLocationInfo = ({
'processing_type',
setProcessingType,
);
updateStateFromData(
singleProductionLocationData,
'parent_company',
setParentCompany,
);
setParentCompany(singleProductionLocationData.parent_company ?? '');
}
}, [singleProductionLocationData, osID]);

Expand Down Expand Up @@ -754,16 +753,20 @@ const ProductionLocationInfo = ({
Enter the company that holds majority
ownership for this production.
</Typography>
<StyledSelect
creatable
name="Parent company"
<TextField
id="parent_company"
className={classes.textInputStyles}
value={parentCompany}
onChange={setParentCompany}
onChange={handleParentCompanyChange}
placeholder="Enter the parent company"
variant="outlined"
aria-label="Parent company"
styles={selectStyles}
className={classes.selectStyles}
components={customSelectComponents}
InputProps={{
classes: {
notchedOutline:
classes.notchedOutlineStyles,
},
}}
/>
</div>
</>
Expand Down
21 changes: 13 additions & 8 deletions src/react/src/util/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import flatten from 'lodash/flatten';
import identity from 'lodash/identity';
import split from 'lodash/split';
import last from 'lodash/last';
import snakeCase from 'lodash/snakeCase';
import some from 'lodash/some';
import size from 'lodash/size';
import negate from 'lodash/negate';
Expand Down Expand Up @@ -34,6 +35,7 @@ import includes from 'lodash/includes';
import join from 'lodash/join';
import map from 'lodash/map';
import mapValues from 'lodash/mapValues';
import mapKeys from 'lodash/mapKeys';
import uniq from 'lodash/uniq';
import has from 'lodash/has';
import { isURL, isInt } from 'validator';
Expand Down Expand Up @@ -1454,20 +1456,23 @@ export const generateRangeField = value => {
return { min: Number(value), max: Number(value) };
};

export const parseContribData = contribData => {
// eslint-disable-next-line camelcase
const { numberOfWorkers, country, ...fields } = contribData;
const convertToSnakeFields = fields =>
mapKeys(fields, (value, key) => snakeCase(key));

const countryValue = country?.value;

const transformedFields = mapValues(
const filterNonEmptyFields = fields =>
mapValues(
pickBy(fields, value => !isEmpty(value)),
extractProductionLocationContributionValues,
);

export const parseContribData = contribData => {
const { numberOfWorkers, country, ...fields } = contribData;
const countryValue = country?.value;

const parsedFields = convertToSnakeFields(filterNonEmptyFields(fields));

return {
...transformedFields,
// eslint-disable-next-line camelcase
...parsedFields,
...(numberOfWorkers && {
number_of_workers: generateRangeField(numberOfWorkers),
}),
Expand Down