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
12 changes: 11 additions & 1 deletion src/app/api/flag-wrapper.jsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
import React, { useEffect, useState } from 'react';
import { element } from 'prop-types';

import useFetchFlags from 'api/flags';
import { useFetchEnvironment, useFetchFlags } from 'api/flags';
import { FlagContext } from 'shared/contexts';

function FlagWrapper({ children }) {
const { data } = useFetchFlags();
const { data: isProductionData, isLoading, isSuccess } = useFetchEnvironment();
const [isProduction, setIsProduction] = useState(true);
const [flags, setFlags] = useState({});

useEffect(() => {
setFlags(data);
}, [data]);

useEffect(() => {
if (isLoading || !isSuccess) { return; }
setIsProduction(isProductionData.headers.environment.toUpperCase() === 'PRODUCTION');
}, [isProductionData, isLoading, isSuccess]);

const isOn = (flag) => flags?.length > 0 && flags.find((f) => f.key === flag)?.active;

const demographicChangeRequestIsOn = isOn('demographic-change-request');
const domainIsOn = isOn('domain');
const insightsConnectionIsOn = isOn('insights-connection');
const insightsDisplayIsOn = isOn('insights-display');
const rwtAiIntegrationIsOn = isOn('rwt-ai-integration');
const rwtChangeRequestIsOn = isOn('rwt-change-request');
const sbulChangeRequestIsOn = isOn('sbul-change-request');

const flagState = {
isProduction,
demographicChangeRequestIsOn,
domainIsOn,
insightsConnectionIsOn,
insightsDisplayIsOn,
rwtAiIntegrationIsOn,
rwtChangeRequestIsOn,
sbulChangeRequestIsOn,
};
Expand Down
13 changes: 12 additions & 1 deletion src/app/api/flags.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ import { useQuery } from '@tanstack/react-query';

import { useAxios } from './axios';

const useFetchEnvironment = () => {
const axios = useAxios();
return useQuery(['system-status'], async () => {
const response = await axios.get('system-status');
return response;
});
};

const useFetchFlags = () => {
const axios = useAxios();
return useQuery(['feature-flags'], async () => {
Expand All @@ -10,4 +18,7 @@ const useFetchFlags = () => {
});
};

export default useFetchFlags;
export {
useFetchEnvironment,
useFetchFlags,
};
10 changes: 9 additions & 1 deletion src/app/api/url-checker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,12 @@ const usePostUrlChecker = () => {
return useMutation(async (data) => axios.post('urls/validate', data));
};

export default usePostUrlChecker;
const usePostRwtResultsChecker = () => {
const axios = useAxios();
return useMutation(async (data) => axios.post('real-world-testing/validate-results-url', data));
};

export {
usePostUrlChecker,
usePostRwtResultsChecker,
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { useFormik } from 'formik';
import * as yup from 'yup';

import { usePostChangeRequest } from 'api/change-requests';
import usePostUrlChecker from 'api/url-checker';
import { usePostUrlChecker } from 'api/url-checker';
import { ChplActionBar } from 'components/action-bar';
import { ChplLink, ChplTextField } from 'components/util';
import { ListingContext, UserContext } from 'shared/contexts';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { useFormik } from 'formik';
import * as yup from 'yup';

import { usePostChangeRequest } from 'api/change-requests';
import usePostUrlChecker from 'api/url-checker';
import { usePostUrlChecker } from 'api/url-checker';
import { ChplActionBar } from 'components/action-bar';
import { ChplLink, ChplTextField } from 'components/util';
import { ListingContext, UserContext } from 'shared/contexts';
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/change-request/types/listing-sbul.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { useFormik } from 'formik';
import * as yup from 'yup';

import { usePostChangeRequest } from 'api/change-requests';
import usePostUrlChecker from 'api/url-checker';
import { usePostUrlChecker } from 'api/url-checker';
import { ChplActionBar } from 'components/action-bar';
import { ChplLink, ChplTextField } from 'components/util';
import { ListingContext, UserContext } from 'shared/contexts';
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/components.module.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import ChplUsersWrapper from './user/users-wrapper';
import {
ChplConfirmation,
ChplEllipsis,
ChplNonProdIndicator,
ChplNonProdIndicatorWrapper,
} from './util';

import { reactToAngularComponent } from 'services/angular-react-helper';
Expand Down Expand Up @@ -49,7 +49,7 @@ angular
.component('chplCriteriaBridge', reactToAngularComponent(ChplCriteriaWrapper))
.component('chplEllipsisBridge', reactToAngularComponent(ChplEllipsis))
.component('chplListingViewBridge', reactToAngularComponent(ChplListingView))
.component('chplNonProdIndicatorBridge', reactToAngularComponent(ChplNonProdIndicator))
.component('chplNonProdIndicatorBridge', reactToAngularComponent(ChplNonProdIndicatorWrapper))
.component('chplRealWorldTestingViewBridge', reactToAngularComponent(ChplRealWorldTestingViewWrapper))
.component('chplUsersBridge', reactToAngularComponent(ChplUsersWrapper))
.component('indexWrapperBridge', reactToAngularComponent(IndexWrapper));
91 changes: 67 additions & 24 deletions src/app/components/listing/listing-edit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ import {
makeStyles,
} from '@material-ui/core';
import DeleteIcon from '@material-ui/icons/Delete';
import VerifiedUserIcon from '@material-ui/icons/VerifiedUser';
import {
arrayOf,
bool,
func,
string,
} from 'prop-types';
import { useSnackbar } from 'notistack';
import { useFormik } from 'formik';
import * as yup from 'yup';
import {
Expand All @@ -31,10 +33,11 @@ import {
import { useFetchAcbs } from 'api/acbs';
import { useFetchAtls } from 'api/atls';
import { useFetchCertificationStatuses } from 'api/data';
import { usePostRwtResultsChecker } from 'api/url-checker';
import { ChplActionBar } from 'components/action-bar';
import { ChplTextField } from 'components/util';
import { getDisplayDateFormat } from 'services/date-util';
import { ListingContext, UserContext } from 'shared/contexts';
import { FlagContext, ListingContext, UserContext } from 'shared/contexts';

const validationSchema = yup.object({
acbCertificationId: yup.string()
Expand Down Expand Up @@ -91,8 +94,10 @@ function ChplListingEdit({
warnings = [],
isProcessing = false,
}) {
const { isProduction, rwtAiIntegrationIsOn } = useContext(FlagContext);
const { listing } = useContext(ListingContext);
const { hasAnyRole } = useContext(UserContext);
const { enqueueSnackbar } = useSnackbar();
const [statuses, setStatuses] = useState([]);
const [addingStatus, setAddingStatus] = useState(false);
const [statusToAdd, setStatusToAdd] = useState('');
Expand All @@ -109,6 +114,7 @@ function ChplListingEdit({
const { data: statusesData, isLoading: statusesIsLoading, isSuccess: statusesIsSuccess } = useFetchCertificationStatuses();
const { data: acbsData, isLoading: acbsIsLoading, isSuccess: acbsIsSuccess } = useFetchAcbs();
const { data: atlsData, isLoading: atlsIsLoading, isSuccess: atlsIsSuccess } = useFetchAtls();
const { mutate } = usePostRwtResultsChecker();
const classes = useStyles();
let formik;

Expand Down Expand Up @@ -199,6 +205,25 @@ function ChplListingEdit({
});
};

const validate = () => {
mutate({
listingId: listing.id,
url: formik.values.rwtResultsUrl,
}, {
onSuccess: (response) => {
console.log(response);
enqueueSnackbar(`Your request has been submitted and you'll get an email at ${response.data.job.jobDataMap.user.email} when it's done`, {
variant: 'success',
});
},
onError: () => {
enqueueSnackbar('There was an error attempting to check the RWT Results.', {
variant: 'error',
});
},
});
};

formik = useFormik({
initialValues: {
acbCertificationId: listing.acbCertificationId ?? '',
Expand Down Expand Up @@ -538,32 +563,50 @@ function ChplListingEdit({

{ /* Real-World Testing */}
<Box display="flex" pt={4} gridGap={8} flexDirection="column">
<Typography variant="h6">
<Typography gutterBottom variant="h6">
Real World Testing
</Typography>
<Box display="flex" pt={2} justifyContent="space-around" gridGap={32} flexDirection="row">
<ChplTextField
id="rwt-plans-url"
name="rwtPlansUrl"
label="Real-World Testing Plans URL"
value={formik.values.rwtPlansUrl}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.touched.rwtPlansUrl && !!formik.errors.rwtPlansUrl}
helperText={formik.touched.rwtPlansUrl && formik.errors.rwtPlansUrl}
/>
<ChplTextField
id="rwt-results-url"
name="rwtResultsUrl"
label="Real-World Testing Results URL"
value={formik.values.rwtResultsUrl}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.touched.rwtResultsUrl && !!formik.errors.rwtResultsUrl}
helperText={formik.touched.rwtResultsUrl && formik.errors.rwtResultsUrl}
/>
<Box display="flex" justifyContent="space-around" gridGap={16} flexDirection="row">
<Box display="flex" justifyContent="space-around" gridGap={16} width={rwtAiIntegrationIsOn ? '90%' : '100%'} flexDirection="row">
<ChplTextField
id="rwt-plans-url"
name="rwtPlansUrl"
label="Real-World Testing Plans URL"
value={formik.values.rwtPlansUrl}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.touched.rwtPlansUrl && !!formik.errors.rwtPlansUrl}
helperText={formik.touched.rwtPlansUrl && formik.errors.rwtPlansUrl}
/>
<ChplTextField
id="rwt-results-url"
name="rwtResultsUrl"
label="Real-World Testing Results URL"
value={formik.values.rwtResultsUrl}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.touched.rwtResultsUrl && !!formik.errors.rwtResultsUrl}
helperText={formik.touched.rwtResultsUrl && formik.errors.rwtResultsUrl}
/>
</Box>
{ rwtAiIntegrationIsOn && !isProduction
&& (
<Button
id="validate-url"
aria-label="Validate RWT Results URL"
color="primary"
variant="contained"
onClick={validate}
size="small"
disabled={formik.values.rwtResultsUrl.length === 0}
endIcon={<VerifiedUserIcon />}
style={{ padding: '8px !important' }}
>
Validate
</Button>
)}
</Box>
<Box display="flex" pt={4} justifyContent="space-around" gridGap={32} flexDirection="row">
<Box display="flex" pt={4} justifyContent="space-around" gridGap={16} flexDirection="row">
<ChplTextField
id="rwt-plans-check-date"
name="rwtPlansCheckDate"
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/util/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ChplCriterionTitle from './criterion-title';
import ChplDialogTitle from './chpl-dialog-title';
import ChplEllipsis from './chpl-ellipsis';
import ChplLink from './chpl-link';
import ChplNonProdIndicator from './non-prod-indicator';
import ChplNonProdIndicatorWrapper from './non-prod-indicator-wrapper';
import ChplPagination from './pagination';
import ChplProgress from './progress';
import ChplLoadingTable from './loading-table';
Expand All @@ -25,7 +25,7 @@ export {
ChplEllipsis,
ChplLink,
ChplLoadingTable,
ChplNonProdIndicator,
ChplNonProdIndicatorWrapper,
ChplPagination,
ChplProgress,
ChplSearchResultCard,
Expand Down
18 changes: 18 additions & 0 deletions src/app/components/util/non-prod-indicator-wrapper.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';

import ChplNonProdIndicator from './non-prod-indicator';

import AppWrapper from 'app-wrapper';

function ChplNonProdIndicatorWrapper() {
return (
<AppWrapper>
<ChplNonProdIndicator />
</AppWrapper>
);
}

export default ChplNonProdIndicatorWrapper;

ChplNonProdIndicatorWrapper.propTypes = {
};
65 changes: 23 additions & 42 deletions src/app/components/util/non-prod-indicator.jsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,42 @@
import React, { useEffect, useState } from 'react';
import { Toolbar } from '@material-ui/core';
import { makeStyles, ThemeProvider } from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';
import React, { useContext } from 'react';
import {
Toolbar,
Typography,
makeStyles,
} from '@material-ui/core';

import theme from '../../themes/theme';
import { getAngularService } from '../../services/angular-react-helper';
import { FlagContext } from 'shared/contexts';

const useStyles = makeStyles(() => ({
const useStyles = makeStyles({
toolBar: {
minHeight: '25px',
backgroundColor: '#c44f65',
width: '100%',
color: '#ffffff',
},
}));
});

function ChplNonProdIndicator() {
const networkService = getAngularService('networkService');
// eslint-disable-next-line react/destructuring-assignment
const [production, setProduction] = useState(true);
const { isProduction } = useContext(FlagContext);
const classes = useStyles();

useEffect(() => {
networkService.getSystemStatus()
.then((response) => {
let headerValue = '';
// Local environments send the header key in all lower case
// but other environments send the header key capitalized
if (response.headers('Environment')) {
headerValue = response.headers('Environment');
} else if (response.headers('environment')) {
headerValue = response.headers('environment');
}
setProduction(headerValue.toUpperCase() === 'PRODUCTION');
});
}, []);

// This will prevent the component from rendering in PROD env
if (production) {
if (isProduction) {
return null;
}

return (
<ThemeProvider theme={theme}>
<Toolbar className={classes.toolBar} id="non-prod-indicator">
<Typography variant="body2" noWrap>
{
Array.from({ length: 15 }, (_, idx) => (
<span key={idx}>
TEST ENVIRONMENT – DO NOT USE
<b> | </b>
</span>
))
}
</Typography>
</Toolbar>
</ThemeProvider>
<Toolbar className={classes.toolBar} id="non-prod-indicator">
<Typography variant="body2" noWrap>
{
Array.from({ length: 15 }, (_, idx) => (
<span key={idx}>
TEST ENVIRONMENT – DO NOT USE
<b> | </b>
</span>
))
}
</Typography>
</Toolbar>
);
}

Expand Down
Loading
Loading