Skip to content

Commit

Permalink
Merge pull request #2318 from HHS/main
Browse files Browse the repository at this point in the history
[Prod] Show session status on "view training report" page, migration to remove duplicate Activity Report Objectives
  • Loading branch information
Jones-QuarteyDana authored Aug 19, 2024
2 parents 30e3596 + 58d85eb commit 8c6744d
Show file tree
Hide file tree
Showing 15 changed files with 809 additions and 66 deletions.
29 changes: 10 additions & 19 deletions frontend/src/components/GoalCards/GoalsCardsHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import colors from '../../colors';
import SelectPagination from '../SelectPagination';
import { similarity } from '../../fetchers/goals';
import { markSimilarGoals } from '../../fetchers/recipient';
import { getFeatureFlags } from '../../fetchers/users';
import FeatureFlag from '../FeatureFlag';

export default function GoalCardsHeader({
title,
Expand Down Expand Up @@ -45,7 +45,6 @@ export default function GoalCardsHeader({
}) {
const [retrieveSimilarGoals, setRetrieveSimilarGoals] = useState(false);
const [goalMergeGroups, setGoalMergeGroups] = useState([]);
const [hasManualMarkGoalsSimilar, setHasManualMarkGoalsSimilar] = useState(false);
const history = useHistory();
const { user } = useContext(UserContext);
const hasButtonPermissions = canEditOrCreateGoals(user, parseInt(regionId, DECIMAL_BASE));
Expand Down Expand Up @@ -75,15 +74,6 @@ export default function GoalCardsHeader({
}
}, [canMergeGoals, recipientId, regionId, retrieveSimilarGoals]);

useEffect(() => {
async function checkFeatureFlags() {
const flags = await getFeatureFlags();
setHasManualMarkGoalsSimilar(flags.includes('manual_mark_goals_similar'));
}

checkFeatureFlags();
}, []);

const showAddNewButton = hasActiveGrants && hasButtonPermissions;
const onPrint = () => {
// See if we have goals selected.
Expand Down Expand Up @@ -253,15 +243,16 @@ export default function GoalCardsHeader({
{`Preview and print ${hasGoalsSelected ? 'selected' : ''}`}
</Button>
{ numberOfSelectedGoals > 1
&& hasManualMarkGoalsSimilar
&& (
<Button
unstyled
className="display-flex flex-align-center margin-left-3 margin-y-0"
onClick={onMarkSimilarGoals}
>
Mark goals as similar
</Button>
<FeatureFlag flag="manual_mark_goals_similar">
<Button
unstyled
className="display-flex flex-align-center margin-left-3 margin-y-0"
onClick={onMarkSimilarGoals}
>
Mark goals as similar
</Button>
</FeatureFlag>
)}
</div>
<div>
Expand Down
10 changes: 0 additions & 10 deletions frontend/src/components/GoalCards/__tests__/GoalCards.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,6 @@ describe('Goals Table', () => {
...oldWindowLocation,
assign: jest.fn(),
};
fetchMock.get('/api/users/feature-flags', []);
});
afterAll(() => {
window.location = oldWindowLocation;
Expand All @@ -278,7 +277,6 @@ describe('Goals Table', () => {
describe('Table displays data', () => {
beforeEach(() => {
fetchMock.restore();
fetchMock.get('/api/users/feature-flags', []);
});
afterEach(() => {
window.location.assign.mockReset();
Expand Down Expand Up @@ -316,9 +314,6 @@ describe('Goals Table', () => {
});

describe('Table displays objective data', () => {
beforeEach(() => {
fetchMock.get('/api/users/feature-flags', []);
});
afterEach(() => {
window.location.assign.mockReset();
fetchMock.restore();
Expand Down Expand Up @@ -415,7 +410,6 @@ describe('Goals Table', () => {

describe('Table sorting', () => {
beforeEach(async () => {
fetchMock.get('/api/users/feature-flags', []);
renderTable({ goals: baseGoals, goalsCount: 6 }, defaultUser);
await screen.findByText('TTA goals and objectives');
});
Expand All @@ -441,7 +435,6 @@ describe('Goals Table', () => {

describe('Paging', () => {
beforeEach(async () => {
fetchMock.get('/api/users/feature-flags', []);
renderTable({ goals: baseGoals, goalsCount: 6 }, defaultUser);
await screen.findByText('TTA goals and objectives');
});
Expand Down Expand Up @@ -481,7 +474,6 @@ describe('Goals Table', () => {
beforeEach(async () => {
const allGoalIds = baseGoals.map((g) => g.id);
allGoalIds.push(23);
fetchMock.get('/api/users/feature-flags', []);
renderTable({ goals: baseGoals, goalsCount: 7, allGoalIds }, defaultUser);
await screen.findByText('TTA goals and objectives');
});
Expand Down Expand Up @@ -558,7 +550,6 @@ describe('Goals Table', () => {
describe('Context Menu', () => {
beforeEach(async () => {
fetchMock.restore();
fetchMock.get('/api/users/feature-flags', []);
renderTable({ goals: [baseGoals[0], baseGoals[3]], goalsCount: 1 }, defaultUser);
await screen.findByText('TTA goals and objectives');
});
Expand Down Expand Up @@ -676,7 +667,6 @@ describe('Goals Table', () => {
describe('Context Menu with Different User Permissions', () => {
beforeAll(() => {
fetchMock.restore();
fetchMock.get('/api/users/feature-flags', []);
});
afterAll(() => {
fetchMock.restore();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ describe('GoalDataController', () => {
},
);
fetchMock.get(`/api/goals/similar/region/${REGION_ID}/recipient/${RECIPIENT_ID}?cluster=true`, []);
fetchMock.get('/api/users/feature-flags', []);
});

afterEach(async () => {
Expand Down
20 changes: 11 additions & 9 deletions frontend/src/components/GoalCards/__tests__/GoalsCardsHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ describe('GoalCardsHeader', () => {
const DEFAULT_USER = {
name: '',
id: 1,
flags: [],
};

const REGION_ID = 1;
Expand All @@ -19,7 +20,6 @@ describe('GoalCardsHeader', () => {
beforeEach(() => {
const url = `/api/goals/similar/region/${REGION_ID}/recipient/${RECIPIENT_ID}?cluster=true`;
fetchMock.get(url, [{ ids: [1], goals: [2] }]);
fetchMock.get('/api/users/feature-flags', ['manual_mark_goals_similar']);
fetchMock.put(`/api/recipient/${RECIPIENT_ID}/mark-similar-goals`, {});
});

Expand Down Expand Up @@ -66,11 +66,17 @@ describe('GoalCardsHeader', () => {

const history = createMemoryHistory();

const renderTest = (props = {}, locationState = undefined) => {
const renderTest = (props = {}, locationState = undefined, userFlags = []) => {
history.location.state = locationState;

render(
<UserContext.Provider value={{ user: DEFAULT_USER }}>
<UserContext.Provider value={{
user: {
...DEFAULT_USER,
flags: userFlags,
},
}}
>
<Router history={history}>
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<GoalCardsHeader {...defaultProps} {...props} />
Expand Down Expand Up @@ -123,7 +129,7 @@ describe('GoalCardsHeader', () => {
};

act(() => {
renderTest(props);
renderTest(props, {}, ['manual_mark_goals_similar']);
});

const markSimilarButton = await screen.findByRole('button', { name: /mark goals as similar/i });
Expand Down Expand Up @@ -156,10 +162,6 @@ describe('GoalCardsHeader', () => {
hasManualMarkGoalsSimilar: false,
};

fetchMock.config.overwriteRoutes = true;
fetchMock.get('/api/users/feature-flags', []);
fetchMock.config.overwriteRoutes = false;

await act(async () => {
renderTest(props);
});
Expand All @@ -175,7 +177,7 @@ describe('GoalCardsHeader', () => {
};

await act(async () => {
renderTest(props);
renderTest(props, {}, ['manual_mark_goals_similar']);
});

const markSimilarButton = screen.queryByText(/Mark goals as similar/i);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable react/jsx-props-no-spreading */
import React from 'react';
import colors from '../../../colors';
import {
Expand All @@ -10,46 +11,60 @@ import {
} from '../../icons';

const STATUSES = {
'In progress': {
display: 'In progress',
color: colors.ttahubMediumBlue,
icon: <InProgress />,
IconWithProps: (props) => <InProgress {...props} />,
},
'In Progress': {
display: 'In progress',
color: colors.ttahubMediumBlue,
icon: <InProgress />,
IconWithProps: (props) => <InProgress {...props} />,
},
Closed: {
display: 'Closed',
color: colors.success,
icon: <Closed />,
IconWithProps: (props) => <Closed {...props} />,
},
// my database has "completed" goals in it, not sure why so leaving it in case of breakage
Completed: {
display: 'Closed',
color: colors.success,
icon: <Closed />,
IconWithProps: (props) => <Closed {...props} />,
},
Complete: {
display: 'Complete',
color: colors.success,
icon: <Closed />,
IconWithProps: (props) => <Closed {...props} />,
},
Draft: {
display: 'Draft',
color: colors.ttahubBlue,
icon: <Draft />,
IconWithProps: (props) => <Draft {...props} />,
},
'Not Started': {
display: 'Not started',
color: colors.warning,
icon: <NotStarted />,
IconWithProps: (props) => <NotStarted {...props} />,
},
Suspended: {
display: 'Suspended',
color: colors.errorDark,
icon: <Ceased />,
IconWithProps: (props) => <Ceased {...props} />,
},
'Needs Status': {
display: 'Needs status',
color: colors.baseLighter,
icon: <NoStatus />,
IconWithProps: (props) => <NoStatus {...props} />,
},
};

Expand Down
34 changes: 33 additions & 1 deletion frontend/src/components/ReadOnlyContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,46 @@ import React from 'react';
import PropTypes from 'prop-types';
import { v4 as uuidv4 } from 'uuid';
import renderData from './renderReadOnlyContentData';
import STATUSES from './GoalCards/components/StatusDropdownStatuses';
import './ReadOnlyContent.scss';

const Status = ({ statusKey }) => {
const statusData = STATUSES[statusKey];
const defaultData = STATUSES['Not Started'];

let data = defaultData;

if (statusData) {
data = statusData;
}

const { IconWithProps } = data;
return (
<div className="ttahub-read-only-content-section--heading--section-row-status display-flex flex-align-center margin-left-4">
<IconWithProps size="xl" />
<p className="ttahub-read-only-content-section--heading--section-row-status-text margin-0 text-bold font-sans-md">{data.display}</p>
</div>
);
};

Status.propTypes = {
statusKey: PropTypes.string.isRequired,
};

export default function ReadOnlyContent({
title,
sections,
className,
displayStatus,
}) {
return (
<div className={`ttahub-read-only-content-section-container ${className}`}>
<h2 className="font-serif-xl margin-y-3">{title}</h2>
<div className="display-flex">
<h2 className="font-serif-xl margin-y-3">{title}</h2>
{displayStatus && (
<Status statusKey={displayStatus} />
)}
</div>
{sections.map((section) => {
const subheadings = Object.keys(section.data);
return (
Expand Down Expand Up @@ -42,8 +72,10 @@ ReadOnlyContent.propTypes = {
data: PropTypes.object.isRequired, // we are using an object here since we don't know the keys
striped: PropTypes.bool,
})).isRequired,
displayStatus: PropTypes.string,
};

ReadOnlyContent.defaultProps = {
className: '',
displayStatus: '',
};
Loading

0 comments on commit 8c6744d

Please sign in to comment.