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 @@ -38,6 +38,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
* [OSDEV-2356](https://opensupplyhub.atlassian.net/browse/OSDEV-2356) - Added `GET api/partner-field-groups/` endpoint to retrieve partner field groups with pagination support and CDN caching for the endpoint (and additional endpoints for partner fields and contributors).
* [OSDEV-2369](https://opensupplyhub.atlassian.net/browse/OSDEV-2369) - As part of the Production Location page redesign, implemented the "Contribute to this profile" section in the sidebar. The section includes: Suggest Correction (link to the contribute flow), Report Duplicate and Dispute Claim (mailto links; Dispute Claim is shown only when the facility is claimed by someone else), and Report Closed / Report Reopened. Report Closed/Reopened opens a dialog where logged-in users can submit a reason; anonymous users see a prompt to log in.
* [OSDEV-2375](https://opensupplyhub.atlassian.net/browse/OSDEV-2375) - Created UI for the location name, OS ID, and "Understanding Data Sources" sections. Introduced `doc/frontend.md` with UI development considerations.
* [OSDEV-2366](https://opensupplyhub.atlassian.net/browse/OSDEV-2366) - Added "Jump to" section to the sidebar with links to the different sections of the Production Location page.

### Release instructions
* Ensure that the following commands are included in the `post_deployment` command:
Expand Down
55 changes: 55 additions & 0 deletions src/react/src/__tests__/components/NavBar.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { screen, fireEvent } from '@testing-library/react';
import renderWithProviders from '../../util/testUtils/renderWithProviders';
import NavBar from '../../components/ProductionLocation/Sidebar/NavBar/NavBar';

const renderNavBar = () =>
renderWithProviders(
<MemoryRouter>
<NavBar />
</MemoryRouter>,
);

describe('NavBar', () => {
test('renders the "Jump to" heading', () => {
renderNavBar();

expect(screen.getByText('Jump to')).toBeInTheDocument();
});

test('renders all three navigation items', () => {
renderNavBar();

expect(screen.getByText('Overview')).toBeInTheDocument();
expect(screen.getByText('General Information')).toBeInTheDocument();
expect(screen.getByText('Operational Details')).toBeInTheDocument();
});

test('clicking a link scrolls to the matching section', () => {
renderNavBar();

const scrollIntoView = jest.fn();
const target = document.createElement('div');
target.id = 'overview';
target.scrollIntoView = scrollIntoView;
document.body.appendChild(target);

fireEvent.click(screen.getByText('Overview'));

expect(scrollIntoView).toHaveBeenCalledWith({
behavior: 'smooth',
block: 'start',
});

document.body.removeChild(target);

Check warning on line 45 in src/react/src/__tests__/components/NavBar.test.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `childNode.remove()` over `parentNode.removeChild(childNode)`.

See more on https://sonarcloud.io/project/issues?id=opensupplyhub_open-supply-hub&issues=AZy5YSb6T-rdYsTwfp05&open=AZy5YSb6T-rdYsTwfp05&pullRequest=900
});

test('clicking a link does nothing when the target element is missing', () => {
renderNavBar();

expect(() => {
fireEvent.click(screen.getByText('General Information'));
}).not.toThrow();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';
import { fireEvent } from '@testing-library/react';
import ProductionLocationDetailsBackToSearch from '../../components/ProductionLocation/Sidebar/BackToSearch/BackToSearch';
import renderWithProviders from '../../util/testUtils/renderWithProviders';
import { setupStore } from '../../configureStore';

describe('ProductionLocationDetailsBackToSearch component', () => {
const mockPush = jest.fn();

beforeEach(() => {
jest.clearAllMocks();
});

it('renders the back to search link', () => {
const { getByText } = renderWithProviders(
<ProductionLocationDetailsBackToSearch
history={{ push: mockPush }}
/>,
);

expect(getByText('Back to search results')).toBeInTheDocument();
});

it('renders a link pointing to the facilities route', () => {
const { container } = renderWithProviders(
<ProductionLocationDetailsBackToSearch
history={{ push: mockPush }}
/>,
);

const link = container.querySelector('a');
expect(link).toHaveAttribute('href', '/facilities');
});

it('renders the back arrow icon', () => {
const { container } = renderWithProviders(
<ProductionLocationDetailsBackToSearch
history={{ push: mockPush }}
/>,
);

const svg = container.querySelector('svg');
expect(svg).toBeInTheDocument();
});

it('dispatches resetSingleFacility when clicked', () => {
const reduxStore = setupStore({});
const dispatchSpy = jest.spyOn(reduxStore, 'dispatch');

const { getByText } = renderWithProviders(
<ProductionLocationDetailsBackToSearch
history={{ push: mockPush }}
/>,
{ reduxStore },
);

fireEvent.click(getByText('Back to search results'));

expect(dispatchSpy).toHaveBeenCalledWith(
expect.objectContaining({ type: 'RESET_SINGLE_FACILITY' }),
);
});
});
22 changes: 22 additions & 0 deletions src/react/src/components/Icons/GeneralInformation.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';

export default function GeneralInformation(props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={props.width || '24'}

Check warning on line 7 in src/react/src/components/Icons/GeneralInformation.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'width' is missing in props validation

See more on https://sonarcloud.io/project/issues?id=opensupplyhub_open-supply-hub&issues=AZy5YSbwT-rdYsTwfp02&open=AZy5YSbwT-rdYsTwfp02&pullRequest=900
height={props.height || '24'}

Check warning on line 8 in src/react/src/components/Icons/GeneralInformation.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'height' is missing in props validation

See more on https://sonarcloud.io/project/issues?id=opensupplyhub_open-supply-hub&issues=AZy5YSbwT-rdYsTwfp03&open=AZy5YSbwT-rdYsTwfp03&pullRequest=900
viewBox={props.viewBox || '0 0 24 24'}

Check warning on line 9 in src/react/src/components/Icons/GeneralInformation.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'viewBox' is missing in props validation

See more on https://sonarcloud.io/project/issues?id=opensupplyhub_open-supply-hub&issues=AZy5YSbwT-rdYsTwfp04&open=AZy5YSbwT-rdYsTwfp04&pullRequest=900
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="lucide lucide-map-pin w-4 h-4"
{...props}
>
<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0" />
<circle cx="12" cy="10" r="3" />
</svg>
);
}
22 changes: 22 additions & 0 deletions src/react/src/components/Icons/OperationalDetails.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';

export default function OperationalDetails(props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={props.width || '24'}

Check warning on line 7 in src/react/src/components/Icons/OperationalDetails.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'width' is missing in props validation

See more on https://sonarcloud.io/project/issues?id=opensupplyhub_open-supply-hub&issues=AZy5YSbcT-rdYsTwfp0w&open=AZy5YSbcT-rdYsTwfp0w&pullRequest=900
height={props.height || '24'}

Check warning on line 8 in src/react/src/components/Icons/OperationalDetails.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'height' is missing in props validation

See more on https://sonarcloud.io/project/issues?id=opensupplyhub_open-supply-hub&issues=AZy5YSbcT-rdYsTwfp0x&open=AZy5YSbcT-rdYsTwfp0x&pullRequest=900
viewBox={props.viewBox || '0 0 24 24'}

Check warning on line 9 in src/react/src/components/Icons/OperationalDetails.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'viewBox' is missing in props validation

See more on https://sonarcloud.io/project/issues?id=opensupplyhub_open-supply-hub&issues=AZy5YSbcT-rdYsTwfp0y&open=AZy5YSbcT-rdYsTwfp0y&pullRequest=900
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="lucide lucide-shield-check w-5 h-5 text-verified"
{...props}
>
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
<path d="m9 12 2 2 4-4" />
</svg>
);
}
27 changes: 27 additions & 0 deletions src/react/src/components/Icons/Overview.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';

export default function Overview(props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={props.width || '24'}

Check warning on line 7 in src/react/src/components/Icons/Overview.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'width' is missing in props validation

See more on https://sonarcloud.io/project/issues?id=opensupplyhub_open-supply-hub&issues=AZy5YSbmT-rdYsTwfp0z&open=AZy5YSbmT-rdYsTwfp0z&pullRequest=900
height={props.height || '24'}

Check warning on line 8 in src/react/src/components/Icons/Overview.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'height' is missing in props validation

See more on https://sonarcloud.io/project/issues?id=opensupplyhub_open-supply-hub&issues=AZy5YSbmT-rdYsTwfp00&open=AZy5YSbmT-rdYsTwfp00&pullRequest=900
viewBox={props.viewBox || '0 0 24 24'}

Check warning on line 9 in src/react/src/components/Icons/Overview.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'viewBox' is missing in props validation

See more on https://sonarcloud.io/project/issues?id=opensupplyhub_open-supply-hub&issues=AZy5YSbmT-rdYsTwfp01&open=AZy5YSbmT-rdYsTwfp01&pullRequest=900
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="lucide lucide-building2 w-5 h-5"
{...props}
>
<path d="M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z" />
<path d="M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2" />
<path d="M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2" />
<path d="M10 6h4" />
<path d="M10 10h4" />
<path d="M10 14h4" />
<path d="M10 18h4" />
</svg>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,11 @@
<Grid container className={classes.root}>
<Grid item xs={12} md={2}>
<BackToSearch history={history} />
<NavBar />
<ContributeFields osId={osID} />
<SupplyChain />
<Grid className={classes.sidebar}>

Check warning on line 94 in src/react/src/components/ProductionLocation/ProductionLocationDetailsContainer/ProductionLocationDetailsContainer.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'classes.sidebar' is missing in props validation

See more on https://sonarcloud.io/project/issues?id=opensupplyhub_open-supply-hub&issues=AZy5b0Vk-VAN26XkvkA_&open=AZy5b0Vk-VAN26XkvkA_&pullRequest=900
<NavBar />
<ContributeFields osId={osID} />
<SupplyChain />
</Grid>
</Grid>
<Grid item xs={12} md={10}>
<ProductionLocationDetailsContent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,14 @@ export default theme =>
color: theme.palette.error.main,
marginBottom: theme.spacing.unit,
}),
sidebar: {
[theme.breakpoints.up('md')]: {
position: 'sticky',
top: '10px',
alignSelf: 'flex-start',
},
[theme.breakpoints.up('lg')]: {
top: '120px',
},
},
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React from 'react';
import { connect } from 'react-redux';
import { withStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import ArrowBack from '@material-ui/icons/ArrowBackIos';
import ArrowRightAlt from '@material-ui/icons/ArrowRightAlt';

import { resetSingleFacility } from '../../../../actions/facilities';
import { facilitiesRoute } from '../../../../util/constants';
Expand All @@ -14,19 +13,22 @@
clearFacility,
history: { push },
}) {
const onClick = event => {
event.preventDefault();
clearFacility();
push(facilitiesRoute);
};

return (
<div className={classes.buttonContainer}>
<Button
color="primary"
className={classes.backButton}
onClick={() => {
clearFacility();
push(facilitiesRoute);
}}
<a
href={facilitiesRoute}
className={classes.backLink}

Check warning on line 26 in src/react/src/components/ProductionLocation/Sidebar/BackToSearch/BackToSearch.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'classes.backLink' is missing in props validation

See more on https://sonarcloud.io/project/issues?id=opensupplyhub_open-supply-hub&issues=AZy4-uxJ7AKibpF0EqSO&open=AZy4-uxJ7AKibpF0EqSO&pullRequest=900
onClick={onClick}
>
<ArrowBack />
Back to search results
</Button>
<ArrowRightAlt style={{ transform: 'rotate(180deg)' }} />
<span className={classes.text}>Back to search results</span>

Check warning on line 30 in src/react/src/components/ProductionLocation/Sidebar/BackToSearch/BackToSearch.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'classes.text' is missing in props validation

See more on https://sonarcloud.io/project/issues?id=opensupplyhub_open-supply-hub&issues=AZy4-uxJ7AKibpF0EqSP&open=AZy4-uxJ7AKibpF0EqSP&pullRequest=900
</a>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
export default theme => ({
buttonContainer: {
alignItems: 'center',
backgroundColor: 'white',
marginBottom: theme.spacing.unit,
marginBottom: theme.spacing.unit * 2,
},
backButton: {
backLink: {
fontSize: `1.25rem`,
textTransform: 'none',
width: '100%',
fontWeight: 700,
display: 'flex',
alignItems: 'center',
textDecoration: 'none',
},
icon: {
transform: 'rotate(180deg)',
fontSize: `1.75rem`,
},
text: {
fontSize: `1.25rem`,
fontWeight: 700,
display: 'inline-block',
marginBottom: theme.spacing.unit / 2,
marginLeft: theme.spacing.unit / 2,
},
});
Loading