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

Prod - Requested changes to the TTA Overview widgets - add non-grantees, tta hours, fix region order #486

Merged
merged 44 commits into from
Jun 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
9dd2284
Add links to TTAHUB System Operations wikie page.
dcloud Jun 8, 2021
d2362ef
Merge branch 'main' into NO-TICKET/link-to-TTAHUB-System-Operations
dcloud Jun 14, 2021
8be8e96
Merge pull request #325 from adhocteam/NO-TICKET/link-to-TTAHUB-Syste…
dcloud Jun 14, 2021
0e4fa94
Update the grant and grantee job (#331)
kryswisnaskas Jun 14, 2021
928fca5
Merge pull request #478 from adhocteam/main
PatricePascual-ACF Jun 15, 2021
6b48a0f
TTA overview widget (#316)
kryswisnaskas Jun 15, 2021
b8f662f
TTAHUB-138: WIP Added custom survey button.
AdamAdHocTeam Jun 15, 2021
4e489ec
Fix lint errors.
AdamAdHocTeam Jun 15, 2021
a59b6f5
CSS fix for modal
AdamAdHocTeam Jun 15, 2021
33c8924
Ignore vulnerabilities (#333)
kryswisnaskas Jun 15, 2021
985c102
added unit test
AdamAdHocTeam Jun 15, 2021
e410331
Merge branch 'HHS:main' into TTAHUB-138-AL-TP-Survey-On-AR-Landing
AdamAdHocTeam Jun 15, 2021
5ba493e
Merge branch 'main' into TTAHUB-138-AL-TP-Survey-On-AR-Landing
AdamAdHocTeam Jun 15, 2021
0cc41d1
change button name.
AdamAdHocTeam Jun 15, 2021
cce3076
Merge pull request #479 from adhocteam/main
PatricePascual-ACF Jun 15, 2021
0a5719f
TTAHUB-138: Fix survey button showing only on AR Landing.
AdamAdHocTeam Jun 16, 2021
4de8ef7
TTAHUB-138: Fix Z index of survey button.
AdamAdHocTeam Jun 16, 2021
8e0fd59
Merge pull request #334 from adhocteam/TTAHUB-138-AL-TP-Survey-On-AR-…
AdamAdHocTeam Jun 16, 2021
715a860
TTAHUB-138/al-fix-csp-for-script: Test possible fix for TP Script.
AdamAdHocTeam Jun 21, 2021
6b6440a
linter fix
AdamAdHocTeam Jun 21, 2021
104ba14
omit csp directive
AdamAdHocTeam Jun 21, 2021
05eb80e
fix lint
AdamAdHocTeam Jun 21, 2021
8d29e5f
add img src
AdamAdHocTeam Jun 21, 2021
06d6de8
attemp to fix img-src for csp
AdamAdHocTeam Jun 21, 2021
3e52a1a
more SCP testing with data
AdamAdHocTeam Jun 22, 2021
3730a00
fix lint
AdamAdHocTeam Jun 22, 2021
fc6ceb0
fix audit vul
AdamAdHocTeam Jun 22, 2021
6153edb
more fixes for scripts
AdamAdHocTeam Jun 22, 2021
6694aa2
more csp updates'
AdamAdHocTeam Jun 22, 2021
e3a41cc
fix wildcard
AdamAdHocTeam Jun 22, 2021
c71978e
remove comment
AdamAdHocTeam Jun 22, 2021
773c3ef
Merge pull request #336 from adhocteam/TTAHUB-138/al-fix-csp-for-script
AdamAdHocTeam Jun 22, 2021
2f527a1
Fix region order and add non-grantees. (#335)
kryswisnaskas Jun 24, 2021
a3be4d3
Merge branch 'main' of https://github.com/HHS/Head-Start-TTADP into main
kryswisnaskas Jun 24, 2021
0d213ee
Merge pull request #339 from adhocteam/kw-conflict
kryswisnaskas Jun 25, 2021
13ca480
Debug intermittent rendering issue
kryswisnaskas Jun 25, 2021
c95b183
Merge branch 'main' into kw-test
kryswisnaskas Jun 25, 2021
ce4ffb1
Debug intermittent rendering issue
kryswisnaskas Jun 25, 2021
b64ae0a
Reverting to the state at 6b48a0fdf7a35eb6d8cf6f427af0046ea022023c
kryswisnaskas Jun 25, 2021
abb0b2b
Revert and cherry pick
kryswisnaskas Jun 24, 2021
7e9d224
Ignore vulnerabilities (#333)
kryswisnaskas Jun 15, 2021
7c700ef
audit vulnerabilities
kryswisnaskas Jun 25, 2021
a256385
Merge pull request #340 from adhocteam/kw-test
kryswisnaskas Jun 25, 2021
608967f
Merge pull request #485 from adhocteam/main
PatricePascual-ACF Jun 25, 2021
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
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ parameters:
default: "main"
type: string
sandbox_git_branch: # change to feature branch to test deployment
default: "AL-MB-Fix-Sequelize-Join-Issue"
default: "kw-test"
type: string
prod_new_relic_app_id:
default: "877570491"
Expand Down
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ those services are already running on your machine.

1. Make sure Docker is installed. To check run `docker ps`.
2. Make sure you have Node 14.16.1 installed.
4. Copy `.env.example` to `.env`.
4. Copy `.env.example` to `.env`.
6. Change the `AUTH_CLIENT_ID` and `AUTH_CLIENT_SECRET` variables to to values found in the "Values for local development" section of the "Development Credentials" document. If you don't have access to this document, please ask in the hs-vendors-ohs-tta channel of the gsa-tts slack channel.
7. Optionally, set `CURRENT_USER` to your current user's uid:gid. This will cause files created by docker compose to be owned by your user instead of root.
3. Run `yarn docker:reset`. This builds the frontend and backend, installs dependencies, then runs database migrations and seeders. If this returns errors that the version of nodejs is incorrect, you may have older versions of the containers built. Delete those images and it should rebuild them.
Expand All @@ -57,9 +57,9 @@ You must also install and run minio locally to use the file upload functionality

#### Docker

If switching branches for code review, run `yarn docker:reset` before running your tests.
If switching branches for code review, run `yarn docker:reset` before running your tests.

Run `yarn docker:test` to run all tests for the frontend and backend.
Run `yarn docker:test` to run all tests for the frontend and backend.

To only run the frontend tests run `yarn docker:test frontend`.

Expand Down Expand Up @@ -258,6 +258,8 @@ If your env variable is secret or the value is dependent on the deployment envir

**Interacting with a deployed database**

Read [TTAHUB-System-Operations](https://github.com/HHS/Head-Start-TTADP/wiki/TTAHUB-System-Operations) for information on how production may be accessed.

Our project includes four deployed Postgres databases, one to interact with each application environment (sandbox, dev, staging, prod). For instructions on how to create and modify databases instances within the cloud.gov ecosystem see the [terraform/README.md](terraform/README.md).

You can run psql commands directly against a deployed database by following these directions.
Expand Down Expand Up @@ -312,7 +314,7 @@ The script takes two flags
- \-e | \-\-environment controls which environment you are targeting.
- Options are "sandbox", "dev", "staging", and "prod"

Ex.
Ex.
```
# Puts the dev environment into maintenance mode
./bin/maintenance -e dev -m on
Expand All @@ -324,6 +326,7 @@ If you are not logged into the cf cli, it will ask you for an sso temporary pass
<!-- Links -->

[adhoc-main]: https://github.com/adhocteam/Head-Start-TTADP/tree/main
[TTAHUB-System-Operations](https://github.com/HHS/Head-Start-TTADP/wiki/TTAHUB-System-Operations)
[circleci-envvar]: https://app.circleci.com/settings/project/github/adhocteam/Head-Start-TTADP/environment-variables?return-to=https%3A%2F%2Fcircleci.com%2Fdashboard
[cloudgov]: https://dashboard.fr.cloud.gov/home
[cloudgov-deployer]: https://cloud.gov/docs/services/cloud-gov-service-account/
Expand Down
1 change: 1 addition & 0 deletions frontend/.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ BACKEND_PROXY=http://localhost:8080
REACT_APP_INACTIVE_MODAL_TIMEOUT=1500000
REACT_APP_SESSION_TIMEOUT=1800000
REACT_APP_TTA_SMART_HUB_URI=http://localhost:3000
REACT_APP_ENABLE_WIDGETS=true
12 changes: 11 additions & 1 deletion frontend/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import Home from './pages/Home';
import Landing from './pages/Landing';
import ActivityReport from './pages/ActivityReport';
import LegacyReport from './pages/LegacyReport';
import Widgets from './pages/Widgets';

import isAdmin from './permissions';
import 'react-dates/initialize';
import 'react-dates/lib/css/_datepicker.css';
Expand Down Expand Up @@ -76,6 +78,7 @@ function App() {
}

const admin = isAdmin(user);
const enableWidgets = process.env.REACT_APP_ENABLE_WIDGETS === 'true';

const renderAuthenticatedRoutes = () => (
<div role="main" id="main-content">
Expand Down Expand Up @@ -113,7 +116,14 @@ function App() {
<ActivityReport location={location} match={match} user={user} />
)}
/>

{enableWidgets && (
<Route
path="/widgets"
render={() => (
<Widgets />
)}
/>
)}
{admin && (
<Route
path="/admin"
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/__tests__/permissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ describe('permissions', () => {
},
],
};
const regions = allRegionsUserHasPermissionTo(user);
const includeAdmin = true;
const regions = allRegionsUserHasPermissionTo(user, includeAdmin);
expect(regions).toEqual(expect.arrayContaining([14, 3, 4]));
});

Expand Down
24 changes: 24 additions & 0 deletions frontend/src/components/RegionDropdown.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.smart-hub--region-dropdown {
background-color: #0166AB;
border: none;
border-radius: 5px;
color: #FFFFFF;
padding-left: 18px;
font-weight: 700;
font-size: 17px;
display:inline-block;
background-image: url(../images/triange_down.png);
}

.smart-hub--region-dropdown option{
background-color: white;
border: none;
border-radius: 5px;
padding: 0px;
}

/* .arrow-down {
border-left:5px solid rgba(0,0,0,0);
border-right:5px solid rgba(0,0,0,0);
color: #FFFFFF;
} */
10 changes: 10 additions & 0 deletions frontend/src/fetchers/Widgets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import join from 'url-join';
import { get } from './index';

const fetchWidget = async (widgetId, region, query = '') => {
const queryStr = query ? `?${query}&` : '?&';
const res = await get(join('/', 'api', 'widgets', `${widgetId}${queryStr}region.in[]=${region}`));
return res.json();
};

export default fetchWidget;
1 change: 1 addition & 0 deletions frontend/src/images/check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/src/images/triange_down.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion frontend/src/pages/Landing/Filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
DATE_FMT,
QUERY_CONDITIONS,
} from './constants';
import { DECIMAL_BASE } from '../../Constants';
import './Filter.css';

const defaultFilter = () => (
Expand Down Expand Up @@ -186,7 +187,7 @@ Filter.defaultProps = {
forMyAlerts: false,
};

export function filtersToQueryString(filters) {
export function filtersToQueryString(filters, region) {
const filtersWithValues = filters.filter((f) => {
if (f.condition === WITHIN) {
const [startDate, endDate] = f.query.split('-');
Expand All @@ -198,6 +199,9 @@ export function filtersToQueryString(filters) {
const con = QUERY_CONDITIONS[filter.condition];
return `${filter.topic}.${con}=${filter.query}`;
});
if (region && (parseInt(region, DECIMAL_BASE) !== -1)) {
queryFragments.push(`region.in[]=${parseInt(region, DECIMAL_BASE)}`);
}
return queryFragments.join('&');
}

Expand Down
160 changes: 160 additions & 0 deletions frontend/src/pages/Landing/RegionalSelect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/* eslint-disable react/forbid-prop-types */
/* eslint-disable react/jsx-props-no-spreading */
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import Select, { components } from 'react-select';
import { Button } from '@trussworks/react-uswds';

import 'uswds/dist/css/uswds.css';
import '@trussworks/react-uswds/lib/index.css';
import './index.css';

import triangleDown from '../../images/triange_down.png';
import check from '../../images/check.svg';

const DropdownIndicator = (props) => (
<components.DropdownIndicator {...props}>
<img alt="" style={{ width: '22px' }} src={triangleDown} />
</components.DropdownIndicator>
);

const Placeholder = (props) => <components.Placeholder {...props} />;

export const getUserOptions = (regions) => regions.map((region) => ({ value: region, label: `Region ${region}` }));

const styles = {
container: (provided, state) => {
// To match the focus indicator provided by uswds
const outline = state.isFocused ? '0.25rem solid #2491ff;' : '';
return {
...provided,
outline,
};
},
input: () => ({ display: 'none' }),
control: (provided) => ({
...provided,
borderColor: '#0166AB',
backgroundColor: '#0166AB',
borderRadius: '5px',
paddingLeft: '5px',
paddingTop: '4px',
paddingBottom: '4px',
whiteSpace: 'nowrap',
color: 'white',
width: '120px',
}),
indicatorSeparator: () => ({ display: 'none' }),
menu: (provided) => ({
...provided,
width: '200px',
}),
option: (provided, state) => ({
...provided,
color: state.isSelected ? '#0166AB' : 'black',
fontWeight: state.isSelected ? '700' : 'normal',
backgroundColor: state.isSelected ? '#F8F8F8' : '#FFFFFF',
padding: 11,
}),
singleValue: (provided) => {
const single = { color: '#FFFFFF', fontWeight: 600 };

return {
...provided, ...single,
};
},
valueContainer: () => ({ padding: '10px 8px' }),
};

function RegionalSelect(props) {
const {
regions, onApply,
} = props;

const [selectedItem, setSelectedItem] = useState();
const [appliedItem, setAppliedItem] = useState();
const [menuIsOpen, setMenuIsOpen] = useState(false);

// const delayedCloseMenu = () => setTimeout(setMenuIsOpen(false), 1000);

const CustomOption = (customOptionProps) => {
const {
data, innerRef, innerProps, isSelected,
} = customOptionProps;
return data.custom ? (
<div ref={innerRef} {...innerProps}>
<Button
type="button"
className="float-left margin-2 smart-hub--filter-button"
onClick={() => {
onApply(selectedItem);
setAppliedItem(selectedItem);
setMenuIsOpen(false);
}}
>
Apply
</Button>
</div>
) : (
<components.Option {...customOptionProps}>
{data.label}
{isSelected && (
<img
className="tta-smarthub--check"
src={check}
style={{
width: 32,
float: 'right',
marginTop: '-9px ',
}}
alt={data.label}
/>
)}
</components.Option>
);
};

CustomOption.propTypes = {
data: PropTypes.shape({
value: PropTypes.number,
label: PropTypes.string,
}),
innerRef: PropTypes.func,
innerProps: PropTypes.object.isRequired,
};

CustomOption.defaultProps = {
data: {},
innerRef: () => 0,
};

const options = [...getUserOptions(regions), { custom: true }];
return (
<Select
options={options}
menuIsOpen={menuIsOpen}
onChange={(value) => { if (value && value.value) setSelectedItem(value); }}
onMenuOpen={() => setMenuIsOpen(true)}
onBlur={() => setMenuIsOpen(false)}
// onBlur={() => delayedCloseMenu()}
name="RegionalSelect"
defaultValue={options[0]}
value={{
value: selectedItem ? selectedItem.value : options[0].value,
label: appliedItem ? appliedItem.label : options[0].label,
}}
styles={styles}
components={{ Placeholder, DropdownIndicator, Option: CustomOption }}
placeholder="Select Region"
closeMenuOnSelect={false}
maxMenuHeight={600}
/>
);
}

RegionalSelect.propTypes = {
regions: PropTypes.arrayOf(PropTypes.number).isRequired,
onApply: PropTypes.func.isRequired,
};

export default RegionalSelect;
5 changes: 5 additions & 0 deletions frontend/src/pages/Landing/__tests__/MyAlerts.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ const renderMyAlerts = () => {
const alertsPerPage = ALERTS_PER_PAGE;
const alertsActivePage = 1;
const alertReportsCount = 10;
const updateReportAlerts = jest.fn();
const setAlertReportsCount = jest.fn();
const requestAlertsSort = jest.fn();

render(
<Router history={history}>
<MyAlerts
Expand All @@ -31,6 +34,8 @@ const renderMyAlerts = () => {
alertsActivePage={alertsActivePage}
alertReportsCount={alertReportsCount}
sortHandler={requestAlertsSort}
updateReportAlerts={updateReportAlerts}
setAlertReportsCount={setAlertReportsCount}
fetchReports={() => {}}
updateReportFilters={() => {}}
handleDownloadAllAlerts={() => {}}
Expand Down
44 changes: 44 additions & 0 deletions frontend/src/pages/Landing/__tests__/RegionalSelect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import '@testing-library/jest-dom';
import React from 'react';
import {
render, screen, fireEvent,
} from '@testing-library/react';
import { Router } from 'react-router';
import { createMemoryHistory } from 'history';

import selectEvent from 'react-select-event';
import RegionalSelect from '../RegionalSelect';

const renderRegionalSelect = () => {
const history = createMemoryHistory();
const onApplyRegion = jest.fn();

render(
<Router history={history}>
<RegionalSelect
regions={[1, 2]}
onApply={onApplyRegion}
/>
</Router>,
);
return history;
};

describe('Regional Select', () => {
test('displays correct region in input', async () => {
renderRegionalSelect();
const input = await screen.findByText(/region 1/i);
expect(input).toBeVisible();
});

test('changes input value on apply', async () => {
renderRegionalSelect();
let input = await screen.findByText(/region 1/i);
expect(input).toBeVisible();
await selectEvent.select(screen.getByText(/region 1/i), [/region 2/i]);
const applyButton = await screen.findByText(/apply/i);
fireEvent.click(applyButton);
input = await screen.findByText(/region 2/i);
expect(input).toBeVisible();
});
});
Loading