· 6 years ago · Dec 17, 2019, 09:56 PM
1diff --git a/package.json b/package.json
2index 5e5432f..f837379 100644
3--- a/package.json
4+++ b/package.json
5@@ -10,7 +10,6 @@
6 "@material-ui/lab": "^4.0.0-alpha.35",
7 "@material-ui/pickers": "^3.2.8",
8 "axios": "^0.19.0",
9- "clsx": "^1.0.4",
10 "date-fns": "^2.0.0-beta.5",
11 "formik": "^2.0.7",
12 "jwt-decode": "^2.2.0",
13diff --git a/src/Actions/Application/ApplicationSaga.js b/src/Actions/Application/ApplicationSaga.js
14index 56a13c1..af71253 100644
15--- a/src/Actions/Application/ApplicationSaga.js
16+++ b/src/Actions/Application/ApplicationSaga.js
17@@ -17,23 +17,6 @@ function* applicationSummarySaga({payload}) {
18 }
19 }
20
21-function* applicationSaveSaga({payload}) {
22- try {
23- const res = yield call(() => { return axios.post(SERVER_ROUTES.APPLICATION.SAVE, {payload}) });
24- yield put({type: ACTIONS.APPLICATION.FORM.SAVE.SUCCESS, payload: res.data});
25- } catch (e) {
26- if (e.response){
27- yield put({type: ACTIONS.APPLICATION.FORM.SAVE.FAIL, payload: e.response.data.message});
28- } else {
29- yield put({type: ACTIONS.APPLICATION.FORM.SAVE.FAIL, payload: e.message});
30- }
31- }
32-}
33-
34 export function* fetchApplicationSummary() {
35 yield takeEvery(ACTIONS.APPLICATION.SUMMARY.FETCH, applicationSummarySaga);
36-}
37-
38-export function* startApplicationSave(){
39- yield takeEvery(ACTIONS.APPLICATION.FORM.SAVE.START, applicationSaveSaga);
40 }
41\ No newline at end of file
42diff --git a/src/Actions/Types.js b/src/Actions/Types.js
43index 045dcf0..6d248d4 100644
44--- a/src/Actions/Types.js
45+++ b/src/Actions/Types.js
46@@ -37,13 +37,6 @@ export const ACTIONS = {
47 SUCCESS: "APPLICATION_SUMMARY_SUCCESS",
48 FAIL: "APPLICATION_SUMMARY_FAIL"
49 },
50- FORM: {
51- SAVE: {
52- START: "APPLICATION_FORM_SAVE_START",
53- SUCCESS: "APPLICATION_FORM_SAVE_SUCCESS",
54- FAIL: "APPLICATION_FORM_SAVE_FAIL"
55- },
56- },
57 FILTER: {
58 UPDATE: "APPLICATION_FILTER_UPDATE",
59 CLEAR: "APPLICATION_FILTER_CLEAR"
60diff --git a/src/Actions/index.js b/src/Actions/index.js
61index ee859f5..5af545c 100644
62--- a/src/Actions/index.js
63+++ b/src/Actions/index.js
64@@ -1,5 +1,5 @@
65 import {all} from "redux-saga/effects";
66-import {fetchApplicationSummary, startApplicationSave} from "./Application/ApplicationSaga";
67+import {fetchApplicationSummary} from "./Application/ApplicationSaga";
68 import {checkAuthentication, requestAuthentication} from "./AuthenticationSaga";
69 import {
70 fetchApplicationRegions,
71@@ -18,7 +18,6 @@ export default function* rootSaga(){
72 fetchApplicationRegions(),
73 fetchApplicationStatuses(),
74 fetchApplicationAssetCodes(),
75- startApplicationSave(),
76 fetchApplicationAssetDetails()
77 ]);
78 };
79\ No newline at end of file
80diff --git a/src/App.js b/src/App.js
81index e047390..c704948 100644
82--- a/src/App.js
83+++ b/src/App.js
84@@ -1,4 +1,4 @@
85-import React, {useEffect, useState} from 'react';
86+import React, {useEffect} from 'react';
87 import {BrowserRouter, Switch, Route} from "react-router-dom";
88 import {useDispatch, useSelector} from "react-redux";
89 import ApplicationSummary from "./Components/Pages/ApplicationSummary";
90@@ -11,7 +11,6 @@ import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles';
91 import Login from "./Components/Pages/Login";
92 import {ACTIONS} from "./Actions/Types";
93 import CssBaseline from '@material-ui/core/CssBaseline';
94-import SnackbarAlert from "./Components/Common/Display/SnackbarAlert";
95
96 const useStyles = makeStyles(theme => ({
97 root: {
98@@ -72,7 +71,6 @@ export const theme = createMuiTheme({
99 });
100
101 function App() {
102- const [offline, setOffline] = useState(false);
103 const {authenticated} = useSelector(state => state.Authentication);
104 const dispatch = useDispatch();
105
106@@ -80,18 +78,9 @@ function App() {
107 dispatch({type: ACTIONS.AUTHENTICATION.CHECK})
108 }, [dispatch]);
109
110- window.onoffline = () => {
111- setOffline(true);
112- };
113-
114- window.ononline = () => {
115- setOffline(false);
116- };
117-
118 return (
119 <div className="ana">
120 <CssBaseline />
121- {offline && <SnackbarAlert message="You Are Currently Offline" variant="error" />}
122 <ThemeProvider theme={theme}>
123 {authenticated ? <AuthenticatedApp/> : <UnauthenticatedApp/>}
124 </ThemeProvider>
125diff --git a/src/Assets/index.scss b/src/Assets/index.scss
126index 9c1e582..3d5d5f6 100644
127--- a/src/Assets/index.scss
128+++ b/src/Assets/index.scss
129@@ -7,9 +7,8 @@ body {
130 }
131 }
132
133-.input-date-range {
134- padding: 10px 20px;
135- width: 100%;
136+#application-filter-date-controls {
137+ padding: 0 20px 10px;
138 }
139
140
141diff --git a/src/Components/Application/Edit/ApplicationEditContainer.js b/src/Components/Application/Edit/ApplicationEditContainer.js
142index aeab8f3..d7a2119 100644
143--- a/src/Components/Application/Edit/ApplicationEditContainer.js
144+++ b/src/Components/Application/Edit/ApplicationEditContainer.js
145@@ -1,4 +1,4 @@
146-import React, {useEffect, useState} from "react";
147+import React from "react";
148 import { Formik } from "formik";
149 import { Link } from "react-router-dom";
150 import { Box, Button, Grid, Typography } from "@material-ui/core";
151@@ -20,9 +20,6 @@ import {
152 } from "./";
153 import ApplicationEditAdditionalInformation from "./ApplicationEditAdditionalInformation";
154 import ApplicationEditCustomerNotifications from "./ApplicationEditCustomerNotifications";
155-import SnackbarAlert from "../../Common/Display/SnackbarAlert";
156-import {useDispatch, useSelector} from "react-redux";
157-import {ACTIONS} from "../../../Actions/Types";
158
159 const PageNav = ({ handleCancel }) => (
160 <Grid container spacing={2}>
161@@ -85,9 +82,6 @@ const Title = ({ title, subtitle }) => (
162 );
163
164 const ApplicationEditContainer = ({ title, id }) => {
165- const dispatch = useDispatch();
166- const {saved, error} = useSelector(state => state.Application.Form.Save);
167-
168 const sections = [
169 {
170 title: "Location of works",
171@@ -117,19 +111,11 @@ const ApplicationEditContainer = ({ title, id }) => {
172 // @param actions is a formik {}
173 //
174 const onSave = (values, actions) => {
175- console.log(JSON.stringify(values));
176 // TODO: Add redux Save
177 // TODO: Trigger toast feedback on success / fail.
178 // dispatch({type: ACTIONS.APPLICATION.FILTER.UPDATE, payload: {view: viewType}});
179 Logger.log("Saving Application...", values, actions);
180 Logger.warn("TODO");
181- let transformedValues = {...values};
182- transformedValues.applicant = {
183- //TODO: This should be pulled from the JWT
184- id: 1,
185- title: "ANNA"
186- };
187- dispatch({type: ACTIONS.APPLICATION.FORM.SAVE.START, payload: transformedValues});
188 };
189 const handleApplicationSubmit = () => {
190 Logger.log("Submitting Application...");
191@@ -151,13 +137,11 @@ const ApplicationEditContainer = ({ title, id }) => {
192 const { workLocation, assetCode, description } = formikProps.values;
193
194 const subtitle = `${
195- assetCode.length ? assetCode[0].AssetCode : ""
196+ assetCode && assetCode.length ? assetCode[0].AssetCode : ""
197 } ${workLocation} ${description}`;
198
199 return (
200 <Box mt={5} mb={5}>
201- {saved && <SnackbarAlert message="Application Saved Successfully" variant="success" />}
202- {error && <SnackbarAlert message="Application Failed To Save" variant="error" />}
203 <PageNav handleCancel={handleCancel} />
204 <Grid container spacing={2}>
205 <Title title={title} subtitle={subtitle} />
206@@ -180,7 +164,7 @@ const ApplicationEditContainer = ({ title, id }) => {
207 </Box>
208
209 <Grid container spacing={2}>
210- <Grid item xs={6} />
211+ <Grid item xs={6}></Grid>
212 <FormActions
213 submitForm={formikProps.submitForm}
214 handleApplicationSubmit={handleApplicationSubmit}
215diff --git a/src/Components/Application/Edit/ApplicationEditCustomerNotifications.js b/src/Components/Application/Edit/ApplicationEditCustomerNotifications.js
216index bf44172..48ea84a 100644
217--- a/src/Components/Application/Edit/ApplicationEditCustomerNotifications.js
218+++ b/src/Components/Application/Edit/ApplicationEditCustomerNotifications.js
219@@ -1,5 +1,5 @@
220 import React from "react";
221-import {Autocomplete, ButtonGroup} from "../../Common/Form/Formik";
222+import {ButtonGroup} from "../../Common/Form/Formik";
223 import {Grid, Typography} from "@material-ui/core";
224 import {useFormikContext} from "formik";
225
226@@ -14,11 +14,10 @@ export default function ApplicationEditCustomerNotifications() {
227 <ButtonGroup name="cardingRequired" label="Is Carding Required?" options={['Yes', 'No']} fullWidth/>
228 </Grid>
229 <Grid item xs={4}>
230- {/*TODO: Options should be what the user types*/}
231- <Autocomplete name="meterNumbers" label="Meter Numbers For Carding (Optional)" options={[]}/>
232+ <Typography>Something will go here eventually</Typography>
233 </Grid>
234- <Grid item xs={12}>
235- <ButtonGroup name="tfbAllocation" label="TFB (Total Fire Ban) Allocation" options={['Proceed – Risk Assess', 'Proceed – Non Risk Assess', 'Cancel - REFCL', 'Cancel']} fullWidth/>
236+ <Grid item xs={6}>
237+ <ButtonGroup name="tfbAllocation" label="TFB (Total Fire Ban) Allocation" options={['Risk Assess', 'Non Risk Assess', 'Cancel']} fullWidth/>
238 </Grid>
239 <Grid item xs={4}>
240 <ButtonGroup name="handCardingRequired" label="Is Hand Carding Required?" options={['Yes', 'No']} fullWidth/>
241diff --git a/src/Components/Application/Edit/ApplicationEditSchema.js b/src/Components/Application/Edit/ApplicationEditSchema.js
242index c5fb51f..a5fd959 100644
243--- a/src/Components/Application/Edit/ApplicationEditSchema.js
244+++ b/src/Components/Application/Edit/ApplicationEditSchema.js
245@@ -12,8 +12,8 @@ const schema = Yup.object().shape({
246 workLocation: Yup.string().max(40, "Max length is 40 characters").required("Work location is required"),
247 description: Yup.string().max(30, "Max length is 30 characters"),
248
249- dayJob: Yup.string().oneOf(["Yes", "No"]),
250- workType: Yup.string().oneOf(["Planned", "Emergency"]),
251+ dayJob: Yup.string().required("Please pick an option").oneOf(["Yes", "No"]),
252+ workType: Yup.string().required("Please pick an option").oneOf(["Planned", "Emergency"]),
253 interruptionStartDate: Yup.date().min(moment().toDate(), 'Start date cannot be in the past').required("Please specify interruption start date"),
254 interruptionEndDate: Yup.date()
255 .when(
256@@ -26,21 +26,24 @@ const schema = Yup.object().shape({
257 ),
258 interruptionStartTime: Yup.date().min(moment().toDate(), 'Start time cannot be in the past').required("Please specify interruption start time"),
259 interruptionEndTime: Yup.date().required("Please specify interruption end time"),
260- estimatedRecall: Yup.string(),
261+ estimatedRecall: Yup.string().required("Please specify estimated recall time"),
262 wcaNumber: Yup.string(),
263 workOrderNumber: Yup.string(),
264
265- approvalToProceed: Yup.string().oneOf(["Yes", "No"]),
266- cardingRequired: Yup.string().oneOf(["Yes", "No"]),
267- meterNumbers: Yup.array(),
268- tfbAllocation: Yup.string().oneOf(['TFB – Proceed – Risk Assess', 'TFB – Proceed – Non Risk Assess', 'TFB – Cancel - REFCL', 'TFB - Cancel']),
269- handCardingRequired: Yup.string().oneOf(["Yes", "No"]),
270-
271 contactPerson: Yup.string(),
272+ //TODO: This should be validating the string based on a regex value for Australian mobile numbers
273 contactPersonPhone: Yup.string(),
274 notes: Yup.string(),
275+ approvalToProceed: Yup.string().required("Please pick an option").oneOf(["Yes", "No"]),
276+ cardingRequired: Yup.string().required("Please pick an option").oneOf(["Yes", "No"]),
277+ tfbAllocation: Yup.string().required("Please pick an option").oneOf(["Risk Assess", "Non Risk Assess", "Cancel"]),
278+ handCardingRequired: Yup.string().required("Please pick an option").oneOf(["Yes", "No"]),
279 });
280
281+//
282+// The initialValues key needs to match its asssociated field name.
283+// TODO: Populate initialValues from the backend API / DB.
284+//
285 const locationOfWorks = {
286 assetCode: "",
287 region: "",
288@@ -61,29 +64,18 @@ const typeAndSchedule = {
289 workOrderNumber: ""
290 };
291
292-const customerNotification = {
293- approvalToProceed: "",
294- cardingRequired: "",
295- meterNumbers: [],
296- tfbAllocation: "",
297- handCardingRequired: ""
298-};
299+const initialValues = {
300+ ...locationOfWorks,
301+ ...typeAndSchedule,
302
303-const additionalInformation = {
304+ //Todo: Determine where these properties should live
305 contactPerson: "",
306 contactPersonPhone: "",
307 notes: "",
308-};
309-
310-//
311-// The initialValues key needs to match its asssociated field name.
312-// TODO: Populate initialValues from the backend API / DB.
313-//
314-const initialValues = {
315- ...locationOfWorks,
316- ...typeAndSchedule,
317- ...customerNotification,
318- ...additionalInformation
319+ approvalToProceed: "",
320+ cardingRequired: "",
321+ tfbAllocation: "",
322+ handCardingRequired: ""
323 };
324
325 export {schema, initialValues};
326diff --git a/src/Components/Application/Edit/ApplicationEditSection.js b/src/Components/Application/Edit/ApplicationEditSection.js
327index 0c4de0a..0d9c62b 100644
328--- a/src/Components/Application/Edit/ApplicationEditSection.js
329+++ b/src/Components/Application/Edit/ApplicationEditSection.js
330@@ -10,7 +10,7 @@ import Typography from "@material-ui/core/Typography";
331
332 const ApplicationEditSection = ({ title, children, icon }) => {
333 return (
334- <ExpansionPanel defaultExpanded={true}>
335+ <ExpansionPanel>
336 <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
337 <Grid container spacing={2} alignItems="center">
338 <Grid item>
339diff --git a/src/Components/Application/Edit/ApplicationEditTypeAndSchedule.js b/src/Components/Application/Edit/ApplicationEditTypeAndSchedule.js
340index f4616ed..fe820aa 100644
341--- a/src/Components/Application/Edit/ApplicationEditTypeAndSchedule.js
342+++ b/src/Components/Application/Edit/ApplicationEditTypeAndSchedule.js
343@@ -5,7 +5,6 @@ import {useFormikContext} from "formik";
344 import {Autocomplete} from "../../Common/Form/Formik";
345 import {useDispatch, useSelector} from "react-redux";
346 import {ACTIONS} from "../../../Actions/Types";
347-import moment from "moment";
348
349 export default function ApplicationEditTypeAndSchedule() {
350 const {values} = useFormikContext();
351@@ -27,7 +26,7 @@ export default function ApplicationEditTypeAndSchedule() {
352 return (
353 <Grid container spacing={6}>
354 <Grid item xs={4}>
355- <Autocomplete name="applicationTypes" label="Application Types" options={applicationTypes} onTextChange={() => {}}/>
356+ <Autocomplete name="applicationTypes" label="Application Types" options={applicationTypes}/>
357 </Grid>
358 <Grid item xs={4}>
359 <ButtonGroup name="dayJob" label="Is This a One Day Job?" options={['Yes', 'No']} fullWidth/>
360@@ -55,7 +54,7 @@ export default function ApplicationEditTypeAndSchedule() {
361 :
362 <>
363 <Grid item xs={4}>
364- <InputDate name="interruptionStartDate" label="Interruption Start Date (Proposed)" disablePast={true} minDate={moment().toDate()}/>
365+ <InputDate name="interruptionStartDate" label="Interruption Start Date (Proposed)"/>
366 </Grid>
367 <Grid item xs={4}>
368 <InputTime name="interruptionStartTime" label="Interruption Start Time"/>
369@@ -74,19 +73,20 @@ export default function ApplicationEditTypeAndSchedule() {
370 <Grid item xs={4}>
371 <InputText name="workOrderNumber" label="Header Work Order Number (Optional)"/>
372 </Grid>
373- {(values.applicationTypes !== undefined && values.applicationTypes.length > 1) &&
374+ {values.applicationTypes !== undefined &&
375 values.applicationTypes.map(type => {
376 return (
377 <React.Fragment key={type.id}>
378 <Grid item xs={4}>
379- <InputDate name={`permitStartDate_${type.title}`} label={`${type.title} - Start Date`} />
380+ <InputDate name={`permitStartDate_${type.title}`} label={`${type.title} - Start Date`}/>
381 </Grid>
382 <Grid item xs={4}>
383- <InputTime name={`permitStartTime_${type.title}`} label={`${type.title} - Start Time`} />
384+ <InputTime name={`permitStartTime_${type.title}`} label={`${type.title} - Start Time`}/>
385 </Grid>
386 <Grid item xs={4}/>
387 </React.Fragment>
388- )})}
389+ )
390+ })}
391 </Grid>
392 );
393 }
394diff --git a/src/Components/Application/Summary/ApplicationSummaryFilters.js b/src/Components/Application/Summary/ApplicationSummaryFilters.js
395index 42c6473..2b77af7 100644
396--- a/src/Components/Application/Summary/ApplicationSummaryFilters.js
397+++ b/src/Components/Application/Summary/ApplicationSummaryFilters.js
398@@ -95,7 +95,9 @@ export default function ApplicationSummaryFilters({filterCount}) {
399
400 function handleDateChange(start, end) {
401 setDate({startDate: start, endDate: end});
402- dispatch({type: ACTIONS.APPLICATION.FILTER.UPDATE, payload: {date: {from: start, to: end}}});
403+ if (start && end) {
404+ dispatch({type: ACTIONS.APPLICATION.FILTER.UPDATE, payload: {date: {from: start, to: end}}});
405+ }
406 }
407
408 const dateObj = new Helper.Date();
409diff --git a/src/Components/Common/Display/SnackbarAlert.js b/src/Components/Common/Display/SnackbarAlert.js
410deleted file mode 100644
411index ea39e43..0000000
412--- a/src/Components/Common/Display/SnackbarAlert.js
413+++ /dev/null
414@@ -1,121 +0,0 @@
415-import React, {useState} from 'react';
416-import PropTypes from 'prop-types';
417-import clsx from 'clsx';
418-import CheckCircleIcon from '@material-ui/icons/CheckCircle';
419-import ErrorIcon from '@material-ui/icons/Error';
420-import InfoIcon from '@material-ui/icons/Info';
421-import CloseIcon from '@material-ui/icons/Close';
422-import { amber, green } from '@material-ui/core/colors';
423-import IconButton from '@material-ui/core/IconButton';
424-import Snackbar from '@material-ui/core/Snackbar';
425-import SnackbarContent from '@material-ui/core/SnackbarContent';
426-import WarningIcon from '@material-ui/icons/Warning';
427-import { makeStyles } from '@material-ui/core/styles';
428-
429-const variantIcon = {
430- success: CheckCircleIcon,
431- warning: WarningIcon,
432- error: ErrorIcon,
433- info: InfoIcon,
434-};
435-
436-const useStyles1 = makeStyles(theme => ({
437- success: {
438- backgroundColor: green[600],
439- },
440- error: {
441- backgroundColor: theme.palette.error.dark,
442- },
443- info: {
444- backgroundColor: theme.palette.primary.main,
445- },
446- warning: {
447- backgroundColor: amber[700],
448- },
449- icon: {
450- fontSize: 20,
451- },
452- iconVariant: {
453- opacity: 0.9,
454- marginRight: theme.spacing(1),
455- },
456- message: {
457- display: 'flex',
458- alignItems: 'center',
459- },
460-}));
461-
462-function SnackBarWrapper(props) {
463- const classes = useStyles1();
464- const { className, message, onClose, variant, ...other } = props;
465- const Icon = variantIcon[variant];
466-
467- return (
468- <SnackbarContent
469- className={clsx(classes[variant], className)}
470- aria-describedby="client-snackbar"
471- message={
472- <span id="client-snackbar" className={classes.message}>
473- <Icon className={clsx(classes.icon, classes.iconVariant)} />
474- {message}
475- </span>
476- }
477- action={[
478- <IconButton key="close" aria-label="close" color="inherit" onClick={onClose}>
479- <CloseIcon className={classes.icon} />
480- </IconButton>,
481- ]}
482- {...other}
483- />
484- );
485-}
486-
487-SnackBarWrapper.propTypes = {
488- className: PropTypes.string,
489- message: PropTypes.string,
490- onClose: PropTypes.func,
491- variant: PropTypes.oneOf(['error', 'info', 'success', 'warning']).isRequired,
492-};
493-
494-export default function SnackbarAlert({open, variant, message, closeAfter}) {
495- const [shouldOpen, setShouldOpen] = useState(open ? open : true);
496-
497- const handleClose = (event, reason) => {
498- if (reason === 'clickaway') {
499- return;
500- }
501-
502- setShouldOpen(false);
503- };
504-
505- setTimeout(() => {
506- setShouldOpen(false);
507- }, closeAfter ? closeAfter : 5000);
508-
509- return (
510- <div>
511- <Snackbar
512- anchorOrigin={{
513- vertical: 'bottom',
514- horizontal: 'right',
515- }}
516- open={shouldOpen}
517- autoHideDuration={6000}
518- onClose={handleClose}
519- >
520- <SnackBarWrapper
521- onClose={handleClose}
522- variant={variant}
523- message={message}
524- />
525- </Snackbar>
526- </div>
527- );
528-}
529-
530-SnackbarAlert.propTypes = {
531- variant: PropTypes.oneOf(["success", "info", "warning", "error"]).isRequired,
532- message: PropTypes.string.isRequired,
533- open: PropTypes.bool,
534- closeAfter: PropTypes.number
535-};
536\ No newline at end of file
537diff --git a/src/Components/Common/Form/Formik/Autocomplete.js b/src/Components/Common/Form/Formik/Autocomplete.js
538index 88fd152..fbf7c74 100644
539--- a/src/Components/Common/Form/Formik/Autocomplete.js
540+++ b/src/Components/Common/Form/Formik/Autocomplete.js
541@@ -4,18 +4,11 @@ import {
542 TextField,
543 FormGroup,
544 FormControl,
545- FormHelperText, FormLabel, makeStyles
546+ FormHelperText
547 } from "@material-ui/core";
548 import Autocomplete from "@material-ui/lab/Autocomplete";
549
550-const useStyles = makeStyles(theme => ({
551- label: {
552- marginBottom: theme.spacing(1)
553- },
554-}));
555-
556 const FormikAutocomplete = ({ label, onTextChange, onChange, ...props }) => {
557- const classes = useStyles();
558 const { options } = props;
559
560 return (
561@@ -23,7 +16,6 @@ const FormikAutocomplete = ({ label, onTextChange, onChange, ...props }) => {
562 {({ field, meta, form }) => (
563 <FormGroup>
564 <FormControl error={!!meta.error}>
565- <FormLabel className={classes.label} label={label}>{label}</FormLabel>
566 <Autocomplete
567 multiple
568 id="tags-outlined"
569@@ -38,7 +30,8 @@ const FormikAutocomplete = ({ label, onTextChange, onChange, ...props }) => {
570 <TextField
571 {...params}
572 variant="outlined"
573- placeholder="Start Typing..."
574+ label={label}
575+ placeholder={label}
576 onChange={(event) => {
577 onTextChange && onTextChange(event.target.value);
578 }}
579diff --git a/src/Components/Common/Form/Formik/ButtonGroup.js b/src/Components/Common/Form/Formik/ButtonGroup.js
580index cf08bd0..20cdd1a 100644
581--- a/src/Components/Common/Form/Formik/ButtonGroup.js
582+++ b/src/Components/Common/Form/Formik/ButtonGroup.js
583@@ -6,22 +6,10 @@ import {
584 FormGroup,
585 FormLabel,
586 FormHelperText,
587- Box, makeStyles
588+ Box
589 } from "@material-ui/core";
590 import { Field } from "formik";
591
592-const useStyles = makeStyles(theme => ({
593- label: {
594- marginBottom: theme.spacing(1)
595- },
596- formControl: {
597- width: '100%'
598- },
599- buttonGroup: {
600- height: '100%'
601- }
602-}));
603-
604 //
605 // This component uses formik to manage its state.
606 // OnClick for each button calls the form.setFieldValue which then
607@@ -29,24 +17,25 @@ const useStyles = makeStyles(theme => ({
608 // Formik then handes the passing down of props so only this component
609 // is re-rendered when its value changes.
610 //
611-export default function FormikButtonGroup({ label, options, size, ...props }) {
612- const classes = useStyles();
613-
614+export default function FormikButtonGroup({ label, options, ...props }) {
615 return (
616 <Field {...props}>
617- {({ field, meta, form }) => (
618- <FormControl className={classes.formControl} error={!!meta.error}>
619- <FormLabel className={classes.label} component="legend">{label}</FormLabel>
620- <ButtonGroup
621- className={classes.buttonGroup}
622+ {({ field, meta, form }) => {
623+ return (
624+ <FormGroup>
625+ <FormControl error={meta.touched && !!meta.error}>
626+ <Box m={-1}></Box>
627+ <FormLabel component="legend">{label}</FormLabel>
628+ <Box m={0.5}></Box>
629+ <ButtonGroup
630 disabled={props.disabled}
631 aria-label="outlined button group"
632 variant="contained"
633 size="large"
634 fullWidth
635 {...props}
636- >
637- {options.map((b, index) => {
638+ >
639+ {options.map((b, index) => {
640 const isSelected = b === field.value || (b.id && b.id === field.value.id);
641 return (
642 <Button
643@@ -59,13 +48,15 @@ export default function FormikButtonGroup({ label, options, size, ...props }) {
644 </Button>
645 );
646 })}
647- </ButtonGroup>
648+ </ButtonGroup>
649
650- {!!meta.error && (
651+ {meta.touched && !!meta.error && (
652 <FormHelperText>{meta.error}</FormHelperText>
653- )}
654- </FormControl>
655- )}
656+ )}
657+ </FormControl>
658+ </FormGroup>
659+ );
660+ }}
661 </Field>
662 );
663 }
664diff --git a/src/Components/Common/Form/Formik/InputDate.js b/src/Components/Common/Form/Formik/InputDate.js
665index 4564e72..1279108 100644
666--- a/src/Components/Common/Form/Formik/InputDate.js
667+++ b/src/Components/Common/Form/Formik/InputDate.js
668@@ -11,33 +11,27 @@ const useStyles = makeStyles(theme => ({
669 root: {
670 width: '100%'
671 },
672- label: {
673- marginBottom: theme.spacing(1)
674- }
675 }));
676
677-const FormikInputDate = ({label, disablePast, minDate, maxDate, ...props}) => {
678+const FormikInputDate = ({label, ...props}) => {
679 const classes = useStyles();
680 return (
681 <Field {...props}>
682 {({field, meta, form}) => (
683 <FormControl className={classes.root} error={meta.touched && !!meta.error}>
684- <FormLabel className={classes.label} label={label}>{label}</FormLabel>
685+ <FormLabel label={label}>{label}</FormLabel>
686 <MuiPickersUtilsProvider utils={DateFnsUtils}>
687 <KeyboardDatePicker
688+ margin="normal"
689 onChange={date => form.setFieldValue(field.name, date)}
690 onBlur={field.onBlur}
691 value={field.value}
692 inputVariant="outlined"
693 {...props}
694 fullWidth
695- disablePast={disablePast ? disablePast : false}
696- minDate={minDate ? minDate : null}
697- maxDate={maxDate ? maxDate : null}
698 KeyboardButtonProps={{
699 'aria-label': 'change date',
700 }}
701- format="dd/MM/yyyy"
702 />
703 </MuiPickersUtilsProvider>
704 {(meta.touched && !!meta.error) && (
705diff --git a/src/Components/Common/Form/Formik/InputText.js b/src/Components/Common/Form/Formik/InputText.js
706index 6e9fd99..c19e3d8 100644
707--- a/src/Components/Common/Form/Formik/InputText.js
708+++ b/src/Components/Common/Form/Formik/InputText.js
709@@ -1,55 +1,39 @@
710-import React, {useState} from "react";
711-import {useField} from "formik";
712-import {FormControl, FormHelperText, FormLabel, InputAdornment, makeStyles, TextField} from "@material-ui/core";
713-import {KeyboardDatePicker, MuiPickersUtilsProvider} from "@material-ui/pickers";
714-import DateFnsUtils from "@date-io/date-fns";
715+import React, { useState } from "react";
716+import { useField } from "formik";
717+import { InputAdornment, TextField } from "@material-ui/core";
718
719-const useStyles = makeStyles(theme => ({
720- root: {
721- width: '100%'
722- },
723- label: {
724- marginBottom: theme.spacing(1)
725- }
726-}));
727+const FormikInputText = ({ label, rows, multiline, ...props }) => {
728+ const [field, meta] = useField(props);
729+ const [val, setVal] = useState("");
730+ let InputProps = {};
731
732-const FormikInputText = ({label, rows, multiline, ...props}) => {
733- const classes = useStyles();
734- const [field, meta] = useField(props);
735- const [val, setVal] = useState("");
736- let InputProps = {};
737+ if (props.showcharcount) {
738+ InputProps = {
739+ endAdornment: (
740+ <InputAdornment position="end">{`${val.length}`}</InputAdornment>
741+ )
742+ };
743+ }
744
745- if (props.showcharcount) {
746- InputProps = {
747- endAdornment: (
748- <InputAdornment position="end">{`${val.length}`}</InputAdornment>
749- )
750- };
751- }
752-
753- return (
754- <FormControl className={classes.root} error={meta.touched && !!meta.error}>
755- <FormLabel className={classes.label} label={label}>{label}</FormLabel>
756- <TextField
757- variant="outlined"
758- error={meta.touched && !!meta.error}
759- multiline={multiline ? multiline : false}
760- rows={rows ? rows : 1}
761- rowsMax={6}
762- fullWidth
763- InputProps={InputProps}
764- {...field}
765- {...props}
766- onChange={event => {
767- field.onChange(event);
768- if (props.showcharcount) setVal(event.target.value);
769- }}
770- />
771- {(meta.touched && !!meta.error) && (
772- <FormHelperText>{meta.error}</FormHelperText>
773- )}
774- </FormControl>
775- );
776+ return (
777+ <TextField
778+ label={label}
779+ variant="outlined"
780+ error={meta.touched && !!meta.error}
781+ helperText={meta.error}
782+ multiline={multiline ? multiline : false}
783+ rows={rows ? rows : 1}
784+ rowsMax={6}
785+ fullWidth
786+ InputProps={InputProps}
787+ {...field}
788+ {...props}
789+ onChange={event => {
790+ field.onChange(event);
791+ if (props.showcharcount) setVal(event.target.value);
792+ }}
793+ />
794+ );
795 };
796
797 export default FormikInputText;
798diff --git a/src/Components/Common/Form/Formik/InputTime.js b/src/Components/Common/Form/Formik/InputTime.js
799index dcd8fc6..09050ef 100644
800--- a/src/Components/Common/Form/Formik/InputTime.js
801+++ b/src/Components/Common/Form/Formik/InputTime.js
802@@ -10,9 +10,6 @@ const useStyles = makeStyles(theme => ({
803 root: {
804 width: '100%'
805 },
806- label: {
807- marginBottom: theme.spacing(1)
808- }
809 }));
810
811 const FormikInputTime = ({ id, label, ...props }) => {
812@@ -21,9 +18,10 @@ const FormikInputTime = ({ id, label, ...props }) => {
813 <Field {...props}>
814 {({field, meta, form}) => (
815 <FormControl className={classes.root} error={meta.touched && !!meta.error}>
816- <FormLabel className={classes.label} label={label}>{label}</FormLabel>
817+ <FormLabel label={label}>{label}</FormLabel>
818 <MuiPickersUtilsProvider utils={DateFnsUtils}>
819 <KeyboardTimePicker
820+ margin="normal"
821 onChange={time => form.setFieldValue(field.name, time)}
822 onBlur={field.onBlur}
823 value={field.value}
824diff --git a/src/Components/Common/Form/InputDateRange.js b/src/Components/Common/Form/InputDateRange.js
825index 2351962..cc88c62 100644
826--- a/src/Components/Common/Form/InputDateRange.js
827+++ b/src/Components/Common/Form/InputDateRange.js
828@@ -7,14 +7,9 @@ import {Helper} from "../../../Util/Helper";
829 export default function InputDateRange({id, onChange, value, presets}) {
830 const [focusedDateInput, setFocusedDateInput] = useState(null);
831
832- function handleChange(start, end){
833- setFocusedDateInput(null);
834- onChange({startDate: start, endDate: end});
835- }
836-
837 function renderPresets() {
838 return (
839- <div id={id} className="input-date-range">
840+ <div id="application-filter-date-controls">
841 <ButtonGroup size="small">
842 {presets.map(({text, start, end}) => {
843 const isSelected = Helper.Date.isSameDay(start, value.startDate) && Helper.Date.isSameDay(end, value.endDate);
844@@ -24,7 +19,7 @@ export default function InputDateRange({id, onChange, value, presets}) {
845 variant={isSelected ? "contained" : "outlined"}
846 color="primary"
847 size="small"
848- onClick={() => handleChange(start, end)}
849+ onClick={() => onChange({startDate: start, endDate: end})}
850 >
851 {text}
852 </Button>
853@@ -44,9 +39,8 @@ export default function InputDateRange({id, onChange, value, presets}) {
854 endDate={value.endDate}
855 endDateId="date-filter-to"
856 onDatesChange={({startDate, endDate}) => {
857- handleChange(startDate, endDate);
858+ onChange({startDate, endDate});
859 }}
860- showClearDates={true}
861 focusedInput={focusedDateInput}
862 onFocusChange={focusedInput => setFocusedDateInput(focusedInput)}
863 noBorder={true}
864diff --git a/src/Reducers/Application/ApplicationFormReducer.js b/src/Reducers/Application/ApplicationFormReducer.js
865deleted file mode 100644
866index 45f3058..0000000
867--- a/src/Reducers/Application/ApplicationFormReducer.js
868+++ /dev/null
869@@ -1,43 +0,0 @@
870-import {ACTIONS} from "../../Actions/Types";
871-import {combineReducers} from "redux";
872-
873-const initialState = {
874- loading: false,
875- saved: false,
876- data: [],
877- error: null
878-};
879-
880-function ApplicationFormSaveReducer(state = initialState, action){
881- switch (action.type) {
882- case ACTIONS.APPLICATION.FORM.SAVE.START:
883- return {
884- ...state,
885- loading: true,
886- saved: false,
887- data: [],
888- error: null
889- };
890- case ACTIONS.APPLICATION.FORM.SAVE.SUCCESS:
891- return {
892- ...state,
893- loading: false,
894- saved: true,
895- data: action.payload.data
896- };
897- case ACTIONS.APPLICATION.FORM.SAVE.FAIL:
898- return {
899- ...state,
900- loading: false,
901- saved: false,
902- data: [],
903- error: action.payload
904- };
905- default:
906- return state;
907- }
908-}
909-
910-export default combineReducers({
911- Save: ApplicationFormSaveReducer
912-})
913\ No newline at end of file
914diff --git a/src/Reducers/Application/ApplicationReducer.js b/src/Reducers/Application/ApplicationReducer.js
915index d2a03c7..97d7b2c 100644
916--- a/src/Reducers/Application/ApplicationReducer.js
917+++ b/src/Reducers/Application/ApplicationReducer.js
918@@ -2,11 +2,9 @@ import ApplicationSummaryReducer from "./ApplicationSummaryReducer";
919 import {combineReducers} from "redux";
920 import ApplicationFilterReducer from "./ApplicationFilterReducer";
921 import ApplicationEnumReducer from "./Enums/ApplicationEnumReducer";
922-import ApplicationFormReducer from "./ApplicationFormReducer";
923
924 export default combineReducers({
925 Summary: ApplicationSummaryReducer,
926 Filters: ApplicationFilterReducer,
927- Enumerated: ApplicationEnumReducer,
928- Form: ApplicationFormReducer
929+ Enumerated: ApplicationEnumReducer
930 });
931\ No newline at end of file
932diff --git a/src/routes.js b/src/routes.js
933index 47d0703..305f686 100644
934--- a/src/routes.js
935+++ b/src/routes.js
936@@ -25,7 +25,6 @@ export const SERVER_ROUTES = {
937 APPLICATION: {
938 SUMMARY: "/allApplicationSummary",
939 CREATE: "/api/application/create",
940- SAVE: "/application/save",
941 ENUMERATED: {
942 STATUSES: "/applicationStatus",
943 TYPES: "/applicationTypes",