Some semi-major changes
- Added notes to each page with info/goals - removed the clutter - moved files into more meaningful directories - renamed route Reports to Migrations - Added a Reports route that's empty
This commit is contained in:
parent
8382419e5f
commit
36353aba65
@ -3,14 +3,18 @@ import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
|
||||
|
||||
// Routes
|
||||
import Upcoming from "./root/Pages/Upcoming";
|
||||
import Reports from "./root/Pages/Reports";
|
||||
import Migrations from "./root/Pages/Migrations";
|
||||
import Historical from "./root/Pages/Historical";
|
||||
import Reports from "./root/Pages/Reports";
|
||||
import Book from "./root/Pages/Book";
|
||||
import IDSingle from "./root/Pages/IDSingle";
|
||||
// Components
|
||||
import Home from "./root/Home";
|
||||
import Navigation from "./root/Navigation";
|
||||
|
||||
// Main app component, react-router comes from here,
|
||||
// and links to all of the sub pages
|
||||
|
||||
class App extends Component {
|
||||
render() {
|
||||
return (
|
||||
@ -21,9 +25,10 @@ class App extends Component {
|
||||
<Route exact path="/" component={Home} />
|
||||
<Route exact path="/book" component={Book} />
|
||||
<Route exact path="/upcoming-migrations" component={Upcoming} />
|
||||
<Route exact path="/migrations" component={Migrations} />
|
||||
<Route exact path="/reports" component={Reports} />
|
||||
<Route exact path="/historical-migrations" component={Historical} />
|
||||
<Route exact path="/reports/:migrationId" component={IDSingle} />
|
||||
<Route path="/migrations/:migrationId" component={IDSingle} />
|
||||
</Switch>
|
||||
</div>
|
||||
</Router>
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import axios from "axios";
|
||||
|
||||
// Axios create, exporting callAPI
|
||||
|
||||
export const callAPI = axios.create({
|
||||
baseURL: "https://devapi.benjamyn.love/migrations/",
|
||||
});
|
||||
|
||||
@ -1,20 +1,19 @@
|
||||
import React from 'react'
|
||||
import React from "react";
|
||||
|
||||
// Generic error
|
||||
|
||||
const Error = () => (
|
||||
<div>
|
||||
|
||||
|
||||
<div className="card-panel blue-grey darken-1">
|
||||
<div className="card-content white-text">
|
||||
<center>
|
||||
<span className="card-title"><i className="large material-icons">do_not_disturb</i></span>
|
||||
</center>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="card-panel blue-grey darken-1">
|
||||
<div className="card-content white-text">
|
||||
<center>
|
||||
<span className="card-title">
|
||||
<i className="large material-icons">do_not_disturb</i>
|
||||
</span>
|
||||
</center>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
</div>
|
||||
);
|
||||
|
||||
export default Error;
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
import axios from "axios";
|
||||
|
||||
const url = `https://devapi.benjamyn.love/migrations/`;
|
||||
|
||||
export const getMigrations = () => (dispatch) => {
|
||||
axios
|
||||
.get(url)
|
||||
.then((response) => {
|
||||
dispatch({
|
||||
migs: response.data,
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
error: true,
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -1,9 +1,17 @@
|
||||
import React, { Component } from "react";
|
||||
|
||||
import { callAPI } from "../actions/API";
|
||||
import Migrations from "./Pages/Migrations";
|
||||
import Cards from "./Pages/Cards";
|
||||
import SideMigrations from "./Pages/Migrations/SideMigrations";
|
||||
|
||||
// Homepage/Cards, first API call here to pass down to cards
|
||||
// and the pending migration list, if there's no data, nothing will show
|
||||
// This would benefit from an error/notification if there is no data
|
||||
//
|
||||
// Two main components linked here are the Dashboard, and the SideMigrations comp,
|
||||
// SideMigrations calls the pending migration list, with its own API call
|
||||
// Dashboard performs the rendering of the cards and the numbers from each migration status.
|
||||
|
||||
export class Home extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -34,19 +42,11 @@ export class Home extends Component {
|
||||
<div className="divider"></div>
|
||||
|
||||
<div className="section">
|
||||
<div className="col s6">
|
||||
<Migrations migs={this.state.migs} />
|
||||
<div className="col s7">
|
||||
<Cards migs={this.state.migs} />
|
||||
</div>
|
||||
<div className="col s6">
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam
|
||||
quis est vitae sapien venenatis viverra. Suspendisse bibendum
|
||||
tristique est, et gravida neque porta ut. Pellentesque egestas
|
||||
vehicula nulla eu aliquet. Morbi id lacus eget lorem aliquam
|
||||
ornare. Vivamus pulvinar ligula sapien, ut pulvinar eros
|
||||
sollicitudin sodales. Donec sed ipsum sit amet mauris posuere
|
||||
maximus. Aenean finibus turpis eu urna suscipit venenatis.
|
||||
</p>
|
||||
<div className="col s5">
|
||||
<p>Migrations tracker</p>
|
||||
</div>
|
||||
<div className="divider"></div>
|
||||
<div className="section">
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
import React, { Component } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import InLineSearch from "./Pages/Functionality/InlineSearchBar";
|
||||
|
||||
// Navbar class component, Just simple href's to retain styling
|
||||
|
||||
export class Navigation extends Component {
|
||||
render() {
|
||||
@ -16,6 +19,9 @@ export class Navigation extends Component {
|
||||
<li>
|
||||
<Link to="/upcoming-migrations">Upcoming Migrations</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/migrations">Migrations</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/reports">Reports</Link>
|
||||
</li>
|
||||
@ -26,6 +32,18 @@ export class Navigation extends Component {
|
||||
<Link to="/book">Book</Link>
|
||||
</li>
|
||||
</ul>
|
||||
{/* Inline UUID search bar is here */}
|
||||
<ul className="right hide-on-med-and-down">
|
||||
<li style={{ paddingRight: "1em" }}>UUID:</li>
|
||||
<li>
|
||||
<InLineSearch style={{ paddingRight: "4em" }}></InLineSearch>
|
||||
</li>
|
||||
{/* <li>
|
||||
<Link>
|
||||
<IdSearchForm />
|
||||
</Link>
|
||||
</li> */}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@ -1,61 +0,0 @@
|
||||
import React, { Component, useEffect, useState } from "react";
|
||||
import moment from "moment";
|
||||
import { Col, FormGroup, Row, Container, Label } from "reactstrap";
|
||||
import { Formik, Form } from "formik";
|
||||
import { Input, Submit } from "formstrap";
|
||||
import { callAPI } from "../../../actions/API";
|
||||
|
||||
const initialValues = {
|
||||
submit_time: moment().format("YYYY-MM-DD"),
|
||||
};
|
||||
const onSubmit = async (values, { setSubmitting }) => {
|
||||
callAPI
|
||||
.get("/", values)
|
||||
.then((response) => {
|
||||
console.log(response.data);
|
||||
this.setState({
|
||||
singlemigs: response.data,
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
setSubmitting(false);
|
||||
};
|
||||
|
||||
export default class GetSingleMigration extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
singlemigs: [],
|
||||
e: false,
|
||||
};
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Formik initialValues={initialValues} onSubmit={onSubmit}>
|
||||
<Form>
|
||||
<Container>
|
||||
<Row>
|
||||
<Col>
|
||||
<FormGroup>
|
||||
<Label for="Migration ID">Migration ID</Label>
|
||||
<Input
|
||||
type="text"
|
||||
name="id"
|
||||
id="id"
|
||||
placeholder="Migration ID"
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
<Submit withSpinner>Submit</Submit>
|
||||
</Container>
|
||||
</Form>
|
||||
</Formik>
|
||||
{/* <ShowMigrations /> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
import { Col, FormGroup, Row, Container, Label } from "reactstrap";
|
||||
import { Formik, Form } from "formik";
|
||||
import { Input, Submit } from "formstrap";
|
||||
|
||||
export default function IdSearchForm({ api }) {
|
||||
const initialValues = {};
|
||||
|
||||
return (
|
||||
<Formik initialValues={initialValues} onSubmit={api}>
|
||||
<Container>
|
||||
<Form>
|
||||
<Row>
|
||||
<Col>
|
||||
<FormGroup>
|
||||
<Label for="migrationId"></Label>
|
||||
<Input
|
||||
type="text"
|
||||
name="migrationId"
|
||||
id="migrationId"
|
||||
placeholder="uuid"
|
||||
/>
|
||||
</FormGroup>
|
||||
<Submit withSpinner>Submit</Submit>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
</Container>
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
@ -1,150 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { callAPI } from "../../../actions/API";
|
||||
import BootstrapTable from "react-bootstrap-table-next";
|
||||
import paginationFactory from "react-bootstrap-table2-paginator";
|
||||
import * as ReactBootstrap from "react-bootstrap";
|
||||
import filterFactory from "react-bootstrap-table2-filter";
|
||||
import ToolkitProvider, {
|
||||
Search,
|
||||
CSVExport,
|
||||
} from "react-bootstrap-table2-toolkit";
|
||||
|
||||
const ShowMigrations = () => {
|
||||
const [list, setList] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { SearchBar } = Search;
|
||||
const { ExportCSVButton } = CSVExport;
|
||||
const sizePerPageRenderer = ({
|
||||
options,
|
||||
currSizePerPage,
|
||||
onSizePerPageChange,
|
||||
}) => (
|
||||
<div className="btn-group" role="group">
|
||||
{options.map((option) => {
|
||||
const isSelect = currSizePerPage === `${option.page}`;
|
||||
return (
|
||||
<button
|
||||
key={option.text}
|
||||
type="button"
|
||||
onClick={() => onSizePerPageChange(option.page)}
|
||||
className={`btn ${isSelect ? "btn-secondary" : "btn-success"}`}
|
||||
>
|
||||
{option.text}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
|
||||
const getListData = async () => {
|
||||
try {
|
||||
const data = await console.log(data);
|
||||
setList(data.data);
|
||||
setLoading(true);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
const options = {
|
||||
paginationSize: 4,
|
||||
pageStartIndex: 0,
|
||||
// alwaysShowAllBtns: true, // Always show next and previous button
|
||||
// withFirstAndLast: false, // Hide the going to First and Last page button
|
||||
// hideSizePerPage: true, // Hide the sizePerPage dropdown always
|
||||
// hidePageListOnlyOnePage: true, // Hide the pagination list when only one page
|
||||
firstPageText: "First",
|
||||
prePageText: "Back",
|
||||
nextPageText: "Next",
|
||||
lastPageText: "Last",
|
||||
nextPageTitle: "First page",
|
||||
prePageTitle: "Pre page",
|
||||
firstPageTitle: "Next page",
|
||||
lastPageTitle: "Last page",
|
||||
showTotal: true,
|
||||
disablePageTitle: true,
|
||||
sizePerPageList: [
|
||||
{
|
||||
text: "50",
|
||||
value: 50,
|
||||
},
|
||||
{
|
||||
text: "100",
|
||||
value: 100,
|
||||
},
|
||||
],
|
||||
sizePerPageRenderer, // A numeric array is also available. the purpose of above example is custom the text
|
||||
};
|
||||
const columns = [
|
||||
{ dataField: "id", text: "ID", hidden: true },
|
||||
{ dataField: "submit_time", text: "Submit Time", sort: true },
|
||||
{
|
||||
dataField: "domain",
|
||||
text: "Domain",
|
||||
sort: true,
|
||||
formatter: (cell, row) => <a href={"reports/" + row.id}> {cell} </a>,
|
||||
},
|
||||
{ dataField: "booked_date", text: "Booked Date", sort: true },
|
||||
{ dataField: "booked_time", text: "Booked Time", sort: true },
|
||||
{ dataField: "original_server", text: "Original Server", sort: true },
|
||||
{ dataField: "new_server", text: "New Server", sort: true },
|
||||
{ dataField: "username", text: "Username", sort: true },
|
||||
{ dataField: "brand", text: "Brand", sort: true },
|
||||
{ dataField: "ticket_id", text: "TicketID", sort: true },
|
||||
{ dataField: "migration_status", text: "Status", sort: true },
|
||||
{ dataField: "agent_booked", text: "Agent initials", sort: true },
|
||||
{ dataField: "additional_domains", text: "Additional Domains", sort: true },
|
||||
{ dataField: "migration_type", text: "Type", sort: true },
|
||||
{ dataField: "term_date", text: "Termination Date", sort: true },
|
||||
{ dataField: "notes", text: "Notes", sort: true },
|
||||
{
|
||||
dataField: "report",
|
||||
text: "Show Detailed Report",
|
||||
formatter: (cell, row) => <a href={cell + row.id}> {cell} </a>,
|
||||
},
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
getListData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="ShowMigrations">
|
||||
{loading ? (
|
||||
<ToolkitProvider
|
||||
keyField="name"
|
||||
data={list}
|
||||
columns={columns}
|
||||
search
|
||||
exportCSV
|
||||
>
|
||||
{(props) => (
|
||||
<div>
|
||||
<div className="serSec">
|
||||
<h3 className="hdrOne"></h3>
|
||||
<SearchBar {...props.searchProps} />
|
||||
</div>
|
||||
|
||||
<div className="table-responsive">
|
||||
<BootstrapTable
|
||||
{...props.baseProps}
|
||||
filter={filterFactory()}
|
||||
pagination={paginationFactory(options)}
|
||||
striped
|
||||
hover
|
||||
condensed
|
||||
/>
|
||||
</div>
|
||||
<ExportCSVButton {...props.csvProps}>
|
||||
Export CSV!!
|
||||
</ExportCSVButton>
|
||||
</div>
|
||||
)}
|
||||
</ToolkitProvider>
|
||||
) : (
|
||||
<ReactBootstrap.Spinner animation="border" />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ShowMigrations;
|
||||
@ -2,6 +2,9 @@ import React, { Component } from "react";
|
||||
|
||||
import FormPage from "./Forms/FormPage";
|
||||
|
||||
// Parent page for the Book component,
|
||||
// links directly to FormPage which contains the POST request
|
||||
|
||||
export default class Book extends Component {
|
||||
render() {
|
||||
return (
|
||||
|
||||
79
src/components/root/Pages/Cards.js
Normal file
79
src/components/root/Pages/Cards.js
Normal file
@ -0,0 +1,79 @@
|
||||
import React, { Component } from "react";
|
||||
|
||||
// styles and collects each endpoint
|
||||
// booked, awaitterm, complete and missed
|
||||
// is referenced on Home
|
||||
|
||||
class Cards extends Component {
|
||||
bookedMig() {
|
||||
return this.props.migs[0]["booked_count"];
|
||||
}
|
||||
waitingMig() {
|
||||
return this.props.migs[0]["awaitterm_count"];
|
||||
}
|
||||
completedMig() {
|
||||
return this.props.migs[0]["complete_count"];
|
||||
}
|
||||
missedMig() {
|
||||
return this.props.migs[0]["missed_count"];
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.props.migs[0]) {
|
||||
return <div />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col s6 m4">
|
||||
<div className="card grey darken-1">
|
||||
<div className="card-content white-text">
|
||||
<span className="card-title"></span>
|
||||
{this.bookedMig()}
|
||||
</div>
|
||||
<div className="card-action">
|
||||
<a href="/upcoming-migrations">booked</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s6 m4">
|
||||
<div className="card grey darken-1">
|
||||
<div className="card-content white-text">
|
||||
<span className="card-title"></span>
|
||||
<p></p>
|
||||
{this.waitingMig()}
|
||||
</div>
|
||||
<div className="card-action">
|
||||
<a href="/upcoming-migrations">waiting</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col s6 m4">
|
||||
<div className="card grey darken-1">
|
||||
<div className="card-content white-text">
|
||||
<span className="card-title"></span>
|
||||
{this.completedMig()}
|
||||
</div>
|
||||
<div className="card-action">
|
||||
<a href="/historical-migrations">complete</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s6 m3">
|
||||
<div className="card grey darken-1">
|
||||
<div className="card-content white-text">
|
||||
<span className="card-title"></span>
|
||||
{this.missedMig()}
|
||||
</div>
|
||||
<div className="card-action">
|
||||
<a href="/historical-migrations">missed</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Cards;
|
||||
@ -6,6 +6,11 @@ import { Formik, Form } from "formik";
|
||||
import { Input, Submit } from "formstrap";
|
||||
import { callAPI } from "../../../actions/API";
|
||||
|
||||
// Main form and POST Request to add migrations
|
||||
// found at /book under the web hosting migration tab
|
||||
// Things to add:
|
||||
// better date time picking.
|
||||
|
||||
export const CPanelBooking = () => {
|
||||
const initialValues = {
|
||||
submit_time: moment().format("YYYY-MM-DD"),
|
||||
@ -15,7 +20,7 @@ export const CPanelBooking = () => {
|
||||
callAPI
|
||||
.post("/", values)
|
||||
.then(function (response) {
|
||||
console.log(JSON.stringify(response.values));
|
||||
console.log(response.data.id);
|
||||
// add function here
|
||||
})
|
||||
.catch(function (error) {
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
import React from "react";
|
||||
var DatePicker = require("reactstrap-date-picker");
|
||||
|
||||
class DateTimePicker extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
value: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
handleChange(value, formattedValue) {
|
||||
this.setState({
|
||||
value: value, // ISO String, ex: "2016-11-19T12:00:00.000Z"
|
||||
formattedValue: formattedValue, // Formatted String, ex: "11/19/2016"
|
||||
});
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
// Access ISO String and formatted values from the DOM.
|
||||
var hiddenInputElement = document.getElementById("example-datepicker");
|
||||
console.log(hiddenInputElement.value); // ISO String, ex: "2016-11-19T12:00:00.000Z"
|
||||
console.log(hiddenInputElement.getAttribute("data-formattedvalue")); // Formatted String, ex: "11/19/2016"
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<DatePicker
|
||||
id="example-datepicker"
|
||||
value={this.state.value}
|
||||
onChange={(v, f) => this.handleChange(v, f)}
|
||||
minDate={Date()}
|
||||
width="100%"
|
||||
size="lg"
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default DateTimePicker;
|
||||
@ -1,5 +1,8 @@
|
||||
import React, { Component } from "react";
|
||||
|
||||
// Needs to be populated with email specific migration
|
||||
// information
|
||||
|
||||
export default class EmailBooking extends Component {
|
||||
render() {
|
||||
return (
|
||||
|
||||
@ -20,6 +20,10 @@ const FormPage = (props) => {
|
||||
if (activeTab !== tab) setActiveTab(tab);
|
||||
};
|
||||
|
||||
// Parent page from the Book section,
|
||||
// Can be expanded to offer email migration bookings,
|
||||
// elements below do the POST requests.
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Nav tabs>
|
||||
|
||||
@ -5,6 +5,9 @@ import { Formik, Form } from "formik";
|
||||
import { Input, Submit } from "formstrap";
|
||||
import { callAPI } from "../../../actions/API";
|
||||
|
||||
// Main form element for the UUID linking Migrations page,
|
||||
// Contians the PUT request to modify data from the API
|
||||
|
||||
const ReportSingleMigration = ({ item }) => {
|
||||
const initialValues = {
|
||||
submit_time: item.submit_time,
|
||||
38
src/components/root/Pages/Functionality/IdSearchForm.js
Normal file
38
src/components/root/Pages/Functionality/IdSearchForm.js
Normal file
@ -0,0 +1,38 @@
|
||||
import React from "react";
|
||||
|
||||
import { FormGroup, Label } from "reactstrap";
|
||||
import { Formik, Form } from "formik";
|
||||
import { Input, Submit } from "formstrap";
|
||||
|
||||
// Needs to be changed, to not use a library,
|
||||
// currently the form populates the fields on migrations, if you
|
||||
// enter a UUID into field,
|
||||
|
||||
export default function IdSearchForm({ api }) {
|
||||
const initialValues = {};
|
||||
|
||||
return (
|
||||
<Formik initialValues={initialValues} onSubmit={api}>
|
||||
{/* <Container>
|
||||
|
||||
<Row>
|
||||
<Col> */}
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<Label for="migrationId"></Label>
|
||||
<Input
|
||||
type="text"
|
||||
name="migrationId"
|
||||
id="migrationId"
|
||||
placeholder="uuid"
|
||||
/>
|
||||
</FormGroup>
|
||||
<Submit withSpinner>Submit</Submit>
|
||||
</Form>
|
||||
{/* </Col>
|
||||
</Row>
|
||||
|
||||
</Container> */}
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
38
src/components/root/Pages/Functionality/InlineSearchBar.js
Normal file
38
src/components/root/Pages/Functionality/InlineSearchBar.js
Normal file
@ -0,0 +1,38 @@
|
||||
import React from "react";
|
||||
|
||||
// Inline search bar with direct UUID linking,
|
||||
// Changes URL and populates the form at /migrations/ with the information from the request
|
||||
|
||||
class InLineSearch extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { data: "" };
|
||||
|
||||
this.onChange = this.onChange.bind(this);
|
||||
}
|
||||
onChange(e) {
|
||||
this.setState({ data: e.target.value });
|
||||
}
|
||||
onKeyPressed = (e) => {
|
||||
// This is so we can access the state within the function
|
||||
if (e.keyCode === 13) {
|
||||
window.location.href =
|
||||
"https://devui.benjamyn.love/migrations/" + this.state.data;
|
||||
}
|
||||
};
|
||||
render() {
|
||||
return (
|
||||
<span>
|
||||
<input
|
||||
className="right"
|
||||
name="uuidIn"
|
||||
value={this.state.data}
|
||||
onChange={this.onChange}
|
||||
onKeyDown={this.onKeyPressed}
|
||||
></input>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default InLineSearch;
|
||||
@ -1,9 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function SubmitMigration() {
|
||||
return (
|
||||
<div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
import DataGrid from 'react-data-grid';
|
||||
import 'react-data-grid/dist/react-data-grid.css';
|
||||
|
||||
const columns = [
|
||||
{ key: 'id', name: 'ID' },
|
||||
{ key: 'title', name: 'Title' }
|
||||
];
|
||||
|
||||
const rows = [
|
||||
{ id: 0, title: 'Example' },
|
||||
{ id: 1, title: 'Demo' },
|
||||
{ id: 3, title: 'Example' },
|
||||
{ id: 4, title: 'Demo' },
|
||||
{ id: 5, title: 'Example' },
|
||||
{ id: 6, title: 'Demo' },
|
||||
{ id: 7, title: 'Example' },
|
||||
{ id: 8, title: 'Demo' },
|
||||
{ id: 9, title: 'Demo' },
|
||||
{ id: 10, title: 'Example' },
|
||||
{ id: 11, title: 'Demo' },
|
||||
{ id: 12, title: 'Example' },
|
||||
{ id: 13, title: 'Demo' },
|
||||
{ id: 14, title: 'Example' },
|
||||
{ id: 15, title: 'Demo' },
|
||||
{ id: 16, title: 'Demo' },
|
||||
{ id: 17, title: 'Example' },
|
||||
{ id: 18, title: 'Demo' },
|
||||
{ id: 19, title: 'Example' },
|
||||
{ id: 20, title: 'Demo' },
|
||||
{ id: 21, title: 'Example' },
|
||||
{ id: 22, title: 'Demo' }
|
||||
];
|
||||
|
||||
function Table() {
|
||||
return (
|
||||
<DataGrid
|
||||
columns={columns}
|
||||
rows={rows}
|
||||
rowsGetter={this.state.sidemigs.domain}
|
||||
rowsCount={20}
|
||||
/>
|
||||
);
|
||||
}
|
||||
export default Table;
|
||||
@ -1,9 +1,15 @@
|
||||
import React, { Component } from "react";
|
||||
|
||||
import { callAPI } from "../../actions/API";
|
||||
import HistoricalSingle from "./Migrations/HistoricalSingle";
|
||||
import HistoricalSingle from "./Tables/HistoricalSingle";
|
||||
import Error from "../../actions/Error";
|
||||
|
||||
// Parent page for the /historical-migrations page,
|
||||
// is referenced in the react route, and calls the main table using
|
||||
// HIstoricalSingle,
|
||||
// All migrations are called, and can be searched
|
||||
// It actuall does error reporting, using `renderItems`
|
||||
|
||||
class Historical extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
@ -1,28 +1,50 @@
|
||||
import React, { Component } from "react";
|
||||
|
||||
import ReportSingleMigration from "./Migrations/ReportSingleMigration";
|
||||
import ReportSingleMigration from "./Forms/ReportSingleMigration";
|
||||
import { callAPI } from "../../actions/API";
|
||||
|
||||
export default class Reports extends Component {
|
||||
render() {
|
||||
const migrationId = ({ migrationId }) => {
|
||||
console.log(migrationId.migrationId);
|
||||
callAPI
|
||||
.get(`/${migrationId.migrationId}/`)
|
||||
.then((response) =>
|
||||
this.setState({
|
||||
redirect: true,
|
||||
migs: response.data,
|
||||
})
|
||||
)
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
// This class will populate a form from a UUID in the address bar,
|
||||
// e.g. /migrations/a7740b79-a7d9-4de7-b01e-00522fa4455a
|
||||
// the form will populate with that migration UUID
|
||||
// ReportSingleMigration is the form that you can modify and sent PUT requests
|
||||
// to the DB
|
||||
|
||||
export default class Reports extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
migs: [],
|
||||
};
|
||||
}
|
||||
componentDidMount() {
|
||||
const {
|
||||
match: { params },
|
||||
} = this.props;
|
||||
|
||||
const urlID = callAPI
|
||||
.get(`/${params.migrationId}/`)
|
||||
.then((response) =>
|
||||
this.setState({
|
||||
migs: response.data,
|
||||
})
|
||||
)
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
// const urlID = ({ migrationId }) => {
|
||||
// console.log(migrationId.migrationId);
|
||||
|
||||
// };
|
||||
return (
|
||||
<div>
|
||||
<ReportSingleMigration key={migrationId.id} item={migrationId} />
|
||||
{/* {this.state.migs} */}
|
||||
<ReportSingleMigration
|
||||
key={this.state.migs.id}
|
||||
item={this.state.migs}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,63 +1,47 @@
|
||||
import React, { Component } from "react";
|
||||
|
||||
class Migrations extends Component {
|
||||
bookedMig() {
|
||||
return this.props.migs.filter(
|
||||
(booked) => booked.migration_status === "Booked"
|
||||
).length;
|
||||
}
|
||||
waitingMig() {
|
||||
return this.props.migs.filter(
|
||||
(waiting) => waiting.migration_status === "Waiting Termination"
|
||||
).length;
|
||||
}
|
||||
completedMig() {
|
||||
return this.props.migs.filter(
|
||||
(complete) => complete.migration_status === "Completed"
|
||||
).length;
|
||||
import IdSearchForm from "./Functionality/IdSearchForm";
|
||||
import ReportSingleMigration from "./Forms/ReportSingleMigration";
|
||||
import { callAPI } from "../../actions/API";
|
||||
|
||||
// /migrations in the address bar,
|
||||
// Allows the modification of migrations, and also populating a form
|
||||
// by UUID.
|
||||
// IDSearchForm is the UUID form at the top of the page,
|
||||
// ReportSingleMigration is the actual form, witha PUT API request on that page.
|
||||
|
||||
export default class Migrations extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
migs: [],
|
||||
redirect: false,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const onSubmit = async (migrationId, { setSubmitting }) => {
|
||||
callAPI
|
||||
.get(`/${migrationId.migrationId}/`)
|
||||
.then((response) =>
|
||||
this.setState({
|
||||
redirect: true,
|
||||
migs: response.data,
|
||||
})
|
||||
)
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
setSubmitting(false);
|
||||
};
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col s6 m4">
|
||||
<div className="card grey darken-1">
|
||||
<div className="card-content white-text">
|
||||
<span className="card-title"></span>
|
||||
{this.bookedMig()}
|
||||
</div>
|
||||
<div className="card-action">
|
||||
<a href="/upcoming-migrations">booked</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col s6 m4">
|
||||
<div className="card grey darken-1">
|
||||
<div className="card-content white-text">
|
||||
<span className="card-title"></span>
|
||||
<p></p>
|
||||
{this.waitingMig()}
|
||||
</div>
|
||||
<div className="card-action">
|
||||
<a href="/upcoming-migrations">waiting</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col s6 m4">
|
||||
<div className="card grey darken-1">
|
||||
<div className="card-content white-text">
|
||||
<span className="card-title"></span>
|
||||
{this.completedMig()}
|
||||
</div>
|
||||
<div className="card-action">
|
||||
<a href="/historical-migrations">complete</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<IdSearchForm api={onSubmit} />
|
||||
<ReportSingleMigration
|
||||
key={this.state.migs.id}
|
||||
item={this.state.migs}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Migrations;
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
const MigrationSingle = ({ item }) => (
|
||||
<div className="col s4 m4">
|
||||
<div className="card-panel">
|
||||
<div className="card-content black-text">
|
||||
<ul className="collection with-header">
|
||||
<li className="collection-header">
|
||||
<a href={item.id}>
|
||||
<p>{item.migration_status}</p>
|
||||
</a>
|
||||
</li>
|
||||
<li className="collection-item">{item.domain}</li>
|
||||
<li className="collection-item">{item.booked_time}</li>
|
||||
<li className="collection-item">{item.migration_status}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default MigrationSingle;
|
||||
@ -1,7 +1,10 @@
|
||||
import React, { Component } from "react";
|
||||
import { SingleSide } from "./SingleSide";
|
||||
import { SingleSide } from "../Tables/SingleSide";
|
||||
import { callAPI } from "../../../actions/API";
|
||||
|
||||
// Side Migrations is displayed on the Home page,
|
||||
// This page contains the API request, and storing state for the request,
|
||||
|
||||
export default class SideMigrations extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
@ -1,40 +1,13 @@
|
||||
import React, { Component } from "react";
|
||||
|
||||
import IdSearchForm from "./AllReports/IdSearchForm";
|
||||
import ReportSingleMigration from "./Migrations/ReportSingleMigration";
|
||||
import { callAPI } from "../../actions/API";
|
||||
// This page was should hold a way to generate reports/lists of
|
||||
// Migrations in varied statuses.
|
||||
|
||||
export default class Reports extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
migs: [],
|
||||
redirect: false,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const onSubmit = async (migrationId, { setSubmitting }) => {
|
||||
callAPI
|
||||
.get(`/${migrationId.migrationId}/`)
|
||||
.then((response) =>
|
||||
this.setState({
|
||||
redirect: true,
|
||||
migs: response.data,
|
||||
})
|
||||
)
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
setSubmitting(false);
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<IdSearchForm api={onSubmit} />
|
||||
<ReportSingleMigration
|
||||
key={this.state.migs.id}
|
||||
item={this.state.migs}
|
||||
/>
|
||||
<h1>Reports</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -9,6 +9,9 @@ import ToolkitProvider, {
|
||||
CSVExport,
|
||||
} from "react-bootstrap-table2-toolkit";
|
||||
|
||||
// Main table for the Historical migrations tab,
|
||||
// receives all API information and displays as a table with a searchbox
|
||||
|
||||
const HistoricalSingle = () => {
|
||||
const [list, setList] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@ -82,7 +85,7 @@ const HistoricalSingle = () => {
|
||||
dataField: "domain",
|
||||
text: "Domain",
|
||||
sort: true,
|
||||
formatter: (cell, row) => <a href={"reports/" + row.id}> {cell} </a>,
|
||||
formatter: (cell, row) => <a href={"migrations/" + row.id}> {cell} </a>,
|
||||
},
|
||||
{ dataField: "booked_date", text: "Booked Date", sort: true },
|
||||
{ dataField: "booked_time", text: "Booked Time", sort: true },
|
||||
@ -2,6 +2,10 @@ import React from "react";
|
||||
import { BootstrapTable, TableHeaderColumn } from "react-bootstrap-table";
|
||||
import "../../../../react-bootstrap-table.css";
|
||||
|
||||
// Single Side is directly referenced on the SideMigrations page,
|
||||
// receives data from the get request and only displays small amounts of info
|
||||
// this could be fleshed out/ linked to UUID's
|
||||
|
||||
export const SingleSide = ({ data }) => {
|
||||
return (
|
||||
<div>
|
||||
@ -9,6 +9,10 @@ import ToolkitProvider, {
|
||||
CSVExport,
|
||||
} from "react-bootstrap-table2-toolkit";
|
||||
|
||||
// Directly linked to the parent page "Upcoming"
|
||||
// this element creates the table
|
||||
// Each domain links to a uuid, which then links to the page Migrations/uuid
|
||||
|
||||
const UpcomingSingle = () => {
|
||||
const [list, setList] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@ -82,7 +86,7 @@ const UpcomingSingle = () => {
|
||||
dataField: "domain",
|
||||
text: "Domain",
|
||||
sort: true,
|
||||
formatter: (cell, row) => <a href={"reports/" + row.id}> {cell} </a>,
|
||||
formatter: (cell, row) => <a href={"migrations/" + row.id}> {cell} </a>,
|
||||
},
|
||||
{ dataField: "booked_date", text: "Booked Date", sort: true },
|
||||
{ dataField: "booked_time", text: "Booked Time", sort: true },
|
||||
@ -1,6 +1,11 @@
|
||||
import React, { Component } from "react";
|
||||
import UpcomingSingle from "./Tables/UpcomingSingle";
|
||||
|
||||
import UpcomingSingle from "./Migrations/UpcomingSingle";
|
||||
// Upcoming parent page,
|
||||
// Most of the good stuff is happening in UpcomingSingle, which does the
|
||||
// main rendering of the table,
|
||||
// may want to eventually do the API call here, to re-use the table
|
||||
// instead of duplicating it.
|
||||
|
||||
class Upcoming extends Component {
|
||||
render() {
|
||||
|
||||
Reference in New Issue
Block a user