Compare commits

..

4 Commits

Author SHA1 Message Date
faab2fd921 Updated error handling 2021-01-19 01:25:01 -05:00
7aea3080b6 Cam did stuff 2021-01-19 01:24:51 -05:00
54eb79c738 added timeslots 2021-01-19 01:24:32 -05:00
2b778223e3 Updated error function 2021-01-19 01:24:22 -05:00
7 changed files with 107 additions and 191 deletions

View File

@ -16,13 +16,13 @@ export const Error = () => (
</div> </div>
); );
export function buildErrorStringFromArray(error) { export function builfArrayFromObject(error) {
let errors = [] let errors = [];
for (let key in error) { for (let key in error) {
errors.push(key + ": " + error[key]) errors.push(key + ": " + error[key]);
// console.log(key + ": " + error[key]) // console.log(key + ": " + error[key])
} }
return errors return errors;
} }
// export default Error; // export default Error;

View File

@ -3,21 +3,42 @@ import { UList } from "../root/common/Functionality/UnorderedList";
// // Generic Msgbox // // Generic Msgbox
function Msgbox(props) { function Msgbox(props) {
return <div> return (
<div className="card-panel grey darken-1"> <div>
<div className="card-content white-link"> <div className="card-panel grey darken-1">
<center> <div className="card-content white-link">
<span className="card-title"> <center>
{ props.error ? <span className="white-text"> { "Unable to update: " } <UList className="white-text" listItems={props.error}></UList> </span> <span className="card-title">
: props.msg ? <span className="white-text">{ "Updated migration details for: " + props.msg }</span> {props.error ? (
: props.linkid ? <a href={ process.env.REACT_APP_SITE_URL + "migrations/" + props.linkid } <span className="white-text">
className="white-link">{process.env.REACT_APP_SITE_URL + "migrations/" + props.linkid }</a> {" "}
: null} {"Error: "}{" "}
</span> <UList className="white-text" listItems={props.error}></UList>{" "}
</center> </span>
) : props.msg ? (
<span className="white-text">
{"Updated migration details for: " + props.msg}
</span>
) : props.linkid ? (
<a
href={
process.env.REACT_APP_SITE_URL +
"migrations/" +
props.linkid
}
className="white-link"
>
{process.env.REACT_APP_SITE_URL +
"migrations/" +
props.linkid}
</a>
) : null}
</span>
</center>
</div>
</div> </div>
</div> </div>
</div>; );
} }
export default Msgbox; export default Msgbox;

View File

@ -3,6 +3,8 @@ import React, { Component } from "react";
import { callAPI } from "../actions/API"; import { callAPI } from "../actions/API";
import Cards from "./Pages/Cards"; import Cards from "./Pages/Cards";
import GenericList from "../root/Pages/GenericList"; import GenericList from "../root/Pages/GenericList";
import { UList } from "../root/common/Functionality/UnorderedList";
import { builfArrayFromObject } from "../actions/Error";
// Homepage/Cards, first API call here to pass down to cards // Homepage/Cards, first API call here to pass down to cards
// and the pending migration list, if there's no data, nothing will show // and the pending migration list, if there's no data, nothing will show
@ -17,6 +19,7 @@ export class Home extends Component {
super(props); super(props);
this.state = { this.state = {
migs: [], migs: [],
timeslots: [],
}; };
} }
@ -33,6 +36,18 @@ export class Home extends Component {
error: error, error: error,
}); });
}); });
callAPI
.get("/timeslots")
.then((request) => {
this.setState({
timeslots: request.data,
});
})
.catch((error) => {
this.setState({
error: error,
});
});
} }
render() { render() {
@ -45,13 +60,13 @@ export class Home extends Component {
<Cards migs={this.state.migs} /> <Cards migs={this.state.migs} />
</div> </div>
<div className="col s5"> <div className="col s5">
<p>Migrations tracker</p> <p>Current availability for {Date()}</p>
{/* <Cards migs={this.state.migs} /> */} <UList listItems={builfArrayFromObject(this.state.timeslots)} />
</div> </div>
<div className="divider"></div> <div className="divider"></div>
<div className="section"> <div className="section">
<div className="col s12"> <div className="col s12">
<GenericList APILINK="/pending/"/> <GenericList APILINK="/pending/" />
</div> </div>
</div> </div>
<div className="divider"></div> <div className="divider"></div>
@ -61,4 +76,4 @@ export class Home extends Component {
} }
} }
export default Home; export default Home;

View File

@ -7,8 +7,7 @@ import * as Yup from "yup";
import { Input, Submit } from "formstrap"; import { Input, Submit } from "formstrap";
import { callAPI } from "../../../actions/API"; import { callAPI } from "../../../actions/API";
import Msgbox from "../../../actions/Msgbox"; import Msgbox from "../../../actions/Msgbox";
import { buildErrorStringFromArray } from "../../../actions/Error"; import { builfArrayFromObject } from "../../../actions/Error";
// import FormikFieldDateTimePicker from "./FormikFieldDateTimePicker";
// Main form and POST Request to add migrations // Main form and POST Request to add migrations
// found at /book under the web hosting migration tab // found at /book under the web hosting migration tab
@ -25,39 +24,39 @@ const timezoneList = {
}; };
const timezone = timezoneList.melbourne; const timezone = timezoneList.melbourne;
const InputValidation = Yup.object().shape({ const InputValidation = Yup.object().shape({
domain: Yup.string() domain: Yup.string()
.matches( .matches(
/^((https?):\/\/)?(www.)?[a-z0-9]+(\.[a-z]{2,}){1,3}(#?\/?[a-zA-Z0-9#]+)*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/, /^((https?):\/\/)?(www.)?[a-z0-9]+(\.[a-z]{2,}){1,3}(#?\/?[a-zA-Z0-9#]+)*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/i,
"Enter correct url!" "Enter correct url!"
) )
.required("Please enter a domain"), .required("Please enter a domain"),
username: Yup.string().min(2, "Too Short!").required("Required"), username: Yup.string().min(2, "Too Short!").required("Required"),
original_server: Yup.string() original_server: Yup.string()
.matches( .matches(
/^((([1-9]?\d|1\d\d|2[0-5][0-5]|2[0-4]\d)\.){3}([1-9]?\d|1\d\d|2[0-5][0-5]|2[0-4]\d))|(((https?):\/\/)?(www.)?[a-z0-9]+(\.[a-z]{2,}){1,3}(#?\/?[a-zA-Z0-9#]+)*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?)$/, /^((([1-9]?\d|1\d\d|2[0-5][0-5]|2[0-4]\d)\.){3}([1-9]?\d|1\d\d|2[0-5][0-5]|2[0-4]\d))|(((https?):\/\/)?(www.)?[a-z0-9]+(\.[a-z]{2,}){1,3}(#?\/?[a-zA-Z0-9#]+)*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?)|([a-z0-9]{0,4}-[a-z0-9]{0,2}-[a-z0-9]{0,3})$/i,
"Please enter a valid IPv4 Address or domain" "Please enter a valid IPv4 Address or domain"
) )
.required("Please enter a valid IPv4 or domain"), .required("Please enter a valid IPv4 or domain"),
new_server: Yup.string() new_server: Yup.string()
.matches( .matches(
/^((([1-9]?\d|1\d\d|2[0-5][0-5]|2[0-4]\d)\.){3}([1-9]?\d|1\d\d|2[0-5][0-5]|2[0-4]\d))|(((https?):\/\/)?(www.)?[a-z0-9]+(\.[a-z]{2,}){1,3}(#?\/?[a-zA-Z0-9#]+)*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?)$/, /^((([1-9]?\d|1\d\d|2[0-5][0-5]|2[0-4]\d)\.){3}([1-9]?\d|1\d\d|2[0-5][0-5]|2[0-4]\d))|(((https?):\/\/)?(www.)?[a-z0-9]+(\.[a-z]{2,}){1,3}(#?\/?[a-zA-Z0-9#]+)*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?)|([a-z0-9]{0,4}-[a-z0-9]{0,2}-[a-z0-9]{0,3})$/i,
"Please enter a valid IPv4 Address or domain" "Please enter a valid IPv4 Address or domain"
) )
.required("Please enter a valid IPv4 or domain"), .required("Please enter a valid IPv4 or domain"),
agent_booked: Yup.string().min(2, "Too short!").required("Requried"), agent_booked: Yup.string()
booked_time: Yup.string().required("Requried"), .min(2, "Too short!")
ticket_id: Yup.string().required("Requried"), .required("Please enter your name!"),
brand: Yup.string().required("Requried"), booked_time: Yup.string().required("Time is needed!"),
migration_type: Yup.string().required("Requried"), ticket_id: Yup.string().required("Please add a ticket ID!"),
booked_date: Yup.date().required("Required") brand: Yup.string().required("Bush Did 911"),
migration_type: Yup.string().required("Type is required!"),
booked_date: Yup.date().required("Please enter a date!"),
}); });
export const CPanelBooking = () => { export const CPanelBooking = () => {
const [respID, setRespID] = useState(0) const [respID, setRespID] = useState(0);
const [error, setError] = useState(0) const [error, setError] = useState(0);
const initialValues = { const initialValues = {
submit_time: moment().format("YYYY-MM-DD"), submit_time: moment().format("YYYY-MM-DD"),
@ -70,15 +69,15 @@ export const CPanelBooking = () => {
.then(function (response) { .then(function (response) {
// console.log(response); // console.log(response);
// add function here // add function here
setRespID(response.data.id) setRespID(response.data.id);
setError(0) setError(0);
resetForm({ values: "" });
}) })
.catch(function (error) { .catch(function (error) {
setError(buildErrorStringFromArray(error.response.data)) setError(builfArrayFromObject(error.response.data));
setRespID(0) setRespID(0);
}); });
setSubmitting(false); setSubmitting(false);
resetForm({ values: "" });
}; };
return ( return (
<Formik <Formik
@ -92,7 +91,7 @@ export const CPanelBooking = () => {
<Row> <Row>
<Col> <Col>
<FormGroup> <FormGroup>
<Label for="bookedDate">Date</Label> <Label for="bookedDate">Date *</Label>
<Input <Input
type="date" type="date"
name="booked_date" name="booked_date"
@ -102,21 +101,9 @@ export const CPanelBooking = () => {
/> />
</FormGroup> </FormGroup>
</Col> </Col>
{/* <Col>
<Field
name="dateTime"
component={FormikFieldDateTimePicker}
inputVariant="outlined"
label="Zoned Date and Time"
timezone={timezone}
helperText="Timezone specified"
clearable
margin="dense"
/>
</Col> */}
<Col> <Col>
<FormGroup> <FormGroup>
<Label for="bookedTime">Timeslot</Label> <Label for="bookedTime">Timeslot *</Label>
<Input type="select" name="booked_time" id="bookedTime"> <Input type="select" name="booked_time" id="bookedTime">
<option>Select</option> <option>Select</option>
<option>00:00-03:00</option> <option>00:00-03:00</option>
@ -130,7 +117,7 @@ export const CPanelBooking = () => {
</Col> </Col>
<Col> <Col>
<FormGroup> <FormGroup>
<Label for="bookedDomain">Domain</Label> <Label for="bookedDomain">Domain *</Label>
<Input <Input
type="text" type="text"
name="domain" name="domain"
@ -141,7 +128,7 @@ export const CPanelBooking = () => {
</Col> </Col>
<Col> <Col>
<FormGroup> <FormGroup>
<Label for="bookedUsername">cPanel username</Label> <Label for="bookedUsername">cPanel username *</Label>
<Input <Input
type="text" type="text"
name="username" name="username"
@ -154,7 +141,7 @@ export const CPanelBooking = () => {
<Row> <Row>
<Col> <Col>
<FormGroup> <FormGroup>
<Label for="bookedSource">Original server</Label> <Label for="bookedSource">Original server *</Label>
<Input <Input
type="text" type="text"
name="original_server" name="original_server"
@ -165,7 +152,7 @@ export const CPanelBooking = () => {
</Col> </Col>
<Col> <Col>
<FormGroup> <FormGroup>
<Label for="bookedDestination">New server</Label> <Label for="bookedDestination">New server *</Label>
<Input <Input
type="text" type="text"
name="new_server" name="new_server"
@ -178,7 +165,7 @@ export const CPanelBooking = () => {
<Row> <Row>
<Col> <Col>
<FormGroup> <FormGroup>
<Label for="bookedBrand">Brand</Label> <Label for="bookedBrand">Brand *</Label>
<Input type="select" name="brand" id="bookedBrand"> <Input type="select" name="brand" id="bookedBrand">
<option>Select</option> <option>Select</option>
<option>VentraIP</option> <option>VentraIP</option>
@ -189,7 +176,7 @@ export const CPanelBooking = () => {
</Col> </Col>
<Col> <Col>
<FormGroup> <FormGroup>
<Label for="bookedTicket">Ticket ID</Label> <Label for="bookedTicket">Ticket ID *</Label>
<Input <Input
type="text" type="text"
name="ticket_id" name="ticket_id"
@ -200,7 +187,7 @@ export const CPanelBooking = () => {
</Col> </Col>
<Col> <Col>
<FormGroup> <FormGroup>
<Label for="bookedType">Migration type</Label> <Label for="bookedType">Migration type *</Label>
<Input type="select" name="migration_type" id="bookedType"> <Input type="select" name="migration_type" id="bookedType">
<option>Select</option> <option>Select</option>
<option>cPanel</option> <option>cPanel</option>
@ -211,7 +198,7 @@ export const CPanelBooking = () => {
</Col> </Col>
<Col> <Col>
<FormGroup> <FormGroup>
<Label for="bookedAgent">Agent Initials</Label> <Label for="bookedAgent">Agent Initials *</Label>
<Input <Input
type="text" type="text"
name="agent_booked" name="agent_booked"
@ -243,8 +230,8 @@ export const CPanelBooking = () => {
</FormGroup> </FormGroup>
<Submit withSpinner>Submit</Submit> <Submit withSpinner>Submit</Submit>
</Container> </Container>
{ respID ? <Msgbox linkid={respID}></Msgbox> : null } {respID ? <Msgbox linkid={respID}></Msgbox> : null}
{ error ? <Msgbox error={error}></Msgbox> : null } {error ? <Msgbox error={error}></Msgbox> : null}
</Form> </Form>
)} )}
</Formik> </Formik>

View File

@ -1,113 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import { zonedTimeToUtc, utcToZonedTime, toDate } from "date-fns-tz";
import { DateTimePicker, DatePicker, TimePicker } from "@material-ui/pickers";
const componentTypes = {
datetime: DateTimePicker,
date: DatePicker,
time: TimePicker,
};
const isoDateRegExp = /^(\d{1,})-?(\d{2})?-?(\d{2})T?(\d{2})?:?(\d{2})?:?(\d{2})?\.?(\d{3})?(Z|[+-]\d{2}:\d{2})?/;
const timeRegExp = /^(\d{2}):(\d{2}):?(\d{2})?\.?(\d{3})?/;
const getDateForPicker = (str, timezone) => {
if (isoDateRegExp.test(str)) {
return timezone ? utcToZonedTime(new Date(str), timezone) : toDate(str);
} else if (timeRegExp.test(str)) {
const date = new Date();
const utcDateISOString = new Date(
Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())
).toISOString();
return toDate(
utcDateISOString.substring(0, utcDateISOString.indexOf("T") + 1) + str
);
}
return null;
};
const FormikFieldDateTimePicker = ({
field,
form,
type,
timezone,
returnDateOnly,
...restProps
}) => {
const CustomTag = componentTypes[type];
const currentError = form.errors[field.name];
const pickerValue = getDateForPicker(field.value, timezone);
const handleChange = (date) => {
if (date === null) {
form.setFieldValue(field.name, null, true);
return;
}
let storedValue;
if (timezone) {
storedValue = zonedTimeToUtc(date, timezone).toISOString();
storedValue = returnDateOnly
? storedValue.substring(0, storedValue.indexOf("T"))
: storedValue;
} else {
const utcDateIsoString = new Date(
Date.UTC(
date.getFullYear(),
date.getMonth(),
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds(),
date.getMilliseconds()
)
).toISOString();
if (isoDateRegExp.test(field.value)) {
storedValue = !returnDateOnly
? utcDateIsoString.substring(0, utcDateIsoString.indexOf("Z"))
: utcDateIsoString.substring(0, utcDateIsoString.indexOf("T"));
} else {
storedValue = utcDateIsoString.substring(
utcDateIsoString.indexOf("T") + 1,
utcDateIsoString.indexOf("Z")
);
}
}
form.setFieldValue(field.name, storedValue, true);
};
const handleBlur = (e) => {
field.onBlur(e);
};
return (
<CustomTag
name={field.name}
value={pickerValue}
helperText={currentError}
error={Boolean(currentError)}
onError={(_, error) => form.setFieldError(field.name, error)}
onChange={handleChange}
onBlur={handleBlur}
{...restProps}
/>
);
};
FormikFieldDateTimePicker.propTypes = {
field: PropTypes.shape().isRequired,
form: PropTypes.shape().isRequired,
type: PropTypes.oneOf(["datetime", "date", "time"]),
timezone: PropTypes.string,
returnDateOnly: PropTypes.bool,
};
FormikFieldDateTimePicker.defaultProps = {
type: "datetime",
returnDateOnly: false,
};
export default FormikFieldDateTimePicker;

View File

@ -5,7 +5,7 @@ import { Formik, Form } from "formik";
import { Input, Submit } from "formstrap"; import { Input, Submit } from "formstrap";
import { callAPI } from "../../../actions/API"; import { callAPI } from "../../../actions/API";
import Msgbox from "../../../actions/Msgbox"; import Msgbox from "../../../actions/Msgbox";
import { buildErrorStringFromArray } from "../../../actions/Error"; import { builfArrayFromObject } from "../../../actions/Error";
// Main form element for the UUID linking Migrations page, // Main form element for the UUID linking Migrations page,
// Contians the PUT request to modify data from the API // Contians the PUT request to modify data from the API
@ -38,11 +38,11 @@ const ReportSingleMigration = ({ item }) => {
.then(function (response) { .then(function (response) {
console.log(JSON.stringify(response.values)); console.log(JSON.stringify(response.values));
setRespID(response.data.ticket_id); setRespID(response.data.ticket_id);
setError(0) setError(0);
}) })
.catch(function (error) { .catch(function (error) {
setError(buildErrorStringFromArray(error.response.data)); setError(builfArrayFromObject(error.response.data));
setRespID(0) setRespID(0);
}); });
setSubmitting(false); setSubmitting(false);
}; };

View File

@ -1,9 +1,15 @@
import React from "react"; import React from "react";
export function UList(props){ export function UList(props) {
return (<div> return (
<ul> <div>
{props.listItems.map((item) => (<li className="white-text">{item}</li>))} <ul>
</ul> {props.listItems.map((item) => (
</div>) <li liClass="white-text" className={props.liClass}>
} {item}
</li>
))}
</ul>
</div>
);
}