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:
pepper 2020-12-03 17:33:38 -05:00
parent 8382419e5f
commit 36353aba65
31 changed files with 338 additions and 512 deletions

View File

@ -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>

View File

@ -1,5 +1,7 @@
import axios from "axios";
// Axios create, exporting callAPI
export const callAPI = axios.create({
baseURL: "https://devapi.benjamyn.love/migrations/",
});

View File

@ -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>
<span className="card-title">
<i className="large material-icons">do_not_disturb</i>
</span>
</center>
</div>
</div>
</div>
)
);
export default Error;

View File

@ -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,
});
});
};

View File

@ -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">

View File

@ -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>

View File

@ -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>
);
}
}

View File

@ -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>
);
}

View File

@ -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;

View File

@ -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 (

View 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;

View File

@ -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) {

View File

@ -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;

View File

@ -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 (

View File

@ -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>

View File

@ -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,

View 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>
);
}

View 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;

View File

@ -1,9 +0,0 @@
import React from 'react'
export default function SubmitMigration() {
return (
<div>
</div>
)
}

View File

@ -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;

View File

@ -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);

View File

@ -1,28 +1,50 @@
import React, { Component } from "react";
import ReportSingleMigration from "./Migrations/ReportSingleMigration";
import ReportSingleMigration from "./Forms/ReportSingleMigration";
import { callAPI } from "../../actions/API";
// 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 {
render() {
const migrationId = ({ migrationId }) => {
console.log(migrationId.migrationId);
callAPI
.get(`/${migrationId.migrationId}/`)
constructor(props) {
super(props);
this.state = {
migs: [],
};
}
componentDidMount() {
const {
match: { params },
} = this.props;
const urlID = callAPI
.get(`/${params.migrationId}/`)
.then((response) =>
this.setState({
redirect: true,
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>
);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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>
);
}

View File

@ -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 },

View File

@ -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>

View File

@ -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 },

View File

@ -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() {