Compare commits

..

No commits in common. "faab2fd9211c56b207687ba622ffdb31aed81b19" and "d4b80352d098db40b93678728818630f791984bc" have entirely different histories.

7 changed files with 191 additions and 107 deletions

View File

@ -16,13 +16,13 @@ export const Error = () => (
</div> </div>
); );
export function builfArrayFromObject(error) { export function buildErrorStringFromArray(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,42 +3,21 @@ import { UList } from "../root/common/Functionality/UnorderedList";
// // Generic Msgbox // // Generic Msgbox
function Msgbox(props) { function Msgbox(props) {
return ( return <div>
<div> <div className="card-panel grey darken-1">
<div className="card-panel grey darken-1"> <div className="card-content white-link">
<div className="card-content white-link"> <center>
<center> <span className="card-title">
<span className="card-title"> { props.error ? <span className="white-text"> { "Unable to update: " } <UList className="white-text" listItems={props.error}></UList> </span>
{props.error ? ( : props.msg ? <span className="white-text">{ "Updated migration details for: " + props.msg }</span>
<span className="white-text"> : 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>
{"Error: "}{" "} : null}
<UList className="white-text" listItems={props.error}></UList>{" "} </span>
</span> </center>
) : 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,8 +3,6 @@ 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
@ -19,7 +17,6 @@ export class Home extends Component {
super(props); super(props);
this.state = { this.state = {
migs: [], migs: [],
timeslots: [],
}; };
} }
@ -36,18 +33,6 @@ 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() {
@ -60,13 +45,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>Current availability for {Date()}</p> <p>Migrations tracker</p>
<UList listItems={builfArrayFromObject(this.state.timeslots)} /> {/* <Cards migs={this.state.migs} /> */}
</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>

View File

@ -7,7 +7,8 @@ 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 { builfArrayFromObject } from "../../../actions/Error"; import { buildErrorStringFromArray } 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
@ -24,39 +25,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-%]+&?)?$/i, /^((https?):\/\/)?(www.)?[a-z0-9]+(\.[a-z]{2,}){1,3}(#?\/?[a-zA-Z0-9#]+)*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/,
"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-%]+&?)?)|([a-z0-9]{0,4}-[a-z0-9]{0,2}-[a-z0-9]{0,3})$/i, /^((([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-%]+&?)?)$/,
"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-%]+&?)?)|([a-z0-9]{0,4}-[a-z0-9]{0,2}-[a-z0-9]{0,3})$/i, /^((([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-%]+&?)?)$/,
"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() agent_booked: Yup.string().min(2, "Too short!").required("Requried"),
.min(2, "Too short!") booked_time: Yup.string().required("Requried"),
.required("Please enter your name!"), ticket_id: Yup.string().required("Requried"),
booked_time: Yup.string().required("Time is needed!"), brand: Yup.string().required("Requried"),
ticket_id: Yup.string().required("Please add a ticket ID!"), migration_type: Yup.string().required("Requried"),
brand: Yup.string().required("Bush Did 911"), booked_date: Yup.date().required("Required")
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"),
@ -69,15 +70,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(builfArrayFromObject(error.response.data)); setError(buildErrorStringFromArray(error.response.data))
setRespID(0); setRespID(0)
}); });
setSubmitting(false); setSubmitting(false);
resetForm({ values: "" });
}; };
return ( return (
<Formik <Formik
@ -91,7 +92,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"
@ -101,9 +102,21 @@ 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>
@ -117,7 +130,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"
@ -128,7 +141,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"
@ -141,7 +154,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"
@ -152,7 +165,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"
@ -165,7 +178,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>
@ -176,7 +189,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"
@ -187,7 +200,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>
@ -198,7 +211,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"
@ -230,8 +243,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

@ -0,0 +1,113 @@
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 { builfArrayFromObject } from "../../../actions/Error"; import { buildErrorStringFromArray } 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(builfArrayFromObject(error.response.data)); setError(buildErrorStringFromArray(error.response.data));
setRespID(0); setRespID(0)
}); });
setSubmitting(false); setSubmitting(false);
}; };

View File

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