Compare commits
No commits in common. "1050709fd231fc9f10b9acfb2697dd62aa3061fb" and "a3c380ffd1060b2d7d373503376bdf895569a576" have entirely different histories.
1050709fd2
...
a3c380ffd1
3
.gitignore
vendored
3
.gitignore
vendored
@ -10,16 +10,13 @@
|
||||
|
||||
# production
|
||||
/build
|
||||
build.zip
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env
|
||||
.env.local
|
||||
.env.development
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
|
||||
5
package-lock.json
generated
5
package-lock.json
generated
@ -13561,11 +13561,6 @@
|
||||
"symbol-observable": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"redux-thunk": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
|
||||
"integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw=="
|
||||
},
|
||||
"regenerate": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"react-scripts": "4.0.0",
|
||||
"reactstrap": "^8.7.1",
|
||||
"redux": "^4.0.5",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"web-vitals": "^0.2.4",
|
||||
"yup": "^0.32.5"
|
||||
},
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="main.css">
|
||||
@ -15,14 +16,17 @@
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://npmcdn.com/react-bootstrap-table/dist/react-bootstrap-table-all.min.css">
|
||||
</link>
|
||||
|
||||
<title>Migrations Tracker</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!-- Compiled and minified JavaScript -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
||||
<!-- This breaks things -->
|
||||
<!-- <script src="https://npmcdn.com/react-bootstrap-table/dist/react-bootstrap-table.min.js"></script> -->
|
||||
<script src="https://npmcdn.com/react-bootstrap-table/dist/react-bootstrap-table.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -1,10 +1,9 @@
|
||||
import React, { Component } from "react";
|
||||
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
|
||||
|
||||
// Store currently in progress
|
||||
|
||||
// import { Provider } from "react-redux";
|
||||
// import store from "../redux/store";
|
||||
// Store
|
||||
import { Provider } from "react-redux";
|
||||
import store from "../redux/store";
|
||||
|
||||
// Routes
|
||||
import Migrations from "./root/Pages/Migrations";
|
||||
@ -22,10 +21,12 @@ import Navigation from "./root/Navigation";
|
||||
class App extends Component {
|
||||
render() {
|
||||
return (
|
||||
// <Provider store={store}>
|
||||
<Provider store={store}>
|
||||
<Router>
|
||||
<Navigation />
|
||||
<div className="col 13">
|
||||
<div className="row">
|
||||
<div className="col s12 m4 13">
|
||||
<div className="container-fluid">
|
||||
<Switch>
|
||||
<Route exact path="/" component={Home} />
|
||||
<Route exact path="/book" component={Book} />
|
||||
@ -35,12 +36,16 @@ class App extends Component {
|
||||
<Route
|
||||
exact
|
||||
path="/upcoming-migrations"
|
||||
render={(props) => <GenericList {...props} APILINK="/pending/" />}
|
||||
render={(props) => (
|
||||
<GenericList {...props} APILINK="/pending/" />
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/missed"
|
||||
render={(props) => <GenericList {...props} APILINK="/missed/" />}
|
||||
render={(props) => (
|
||||
<GenericList {...props} APILINK="/missed/" />
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
@ -66,17 +71,23 @@ class App extends Component {
|
||||
<Route
|
||||
exact
|
||||
path="/historical-migrations"
|
||||
render={(props) => <GenericList {...props} APILINK="/all/" />}
|
||||
render={(props) => (
|
||||
<GenericList {...props} APILINK="/all/" />
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/booked"
|
||||
render={(props) => <GenericList {...props} APILINK="/booked/" />}
|
||||
render={(props) => (
|
||||
<GenericList {...props} APILINK="/booked/" />
|
||||
)}
|
||||
/>
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Router>
|
||||
// </Provider>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
8
src/components/App.test.js
Normal file
8
src/components/App.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
const linkElement = screen.getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
||||
@ -2,8 +2,6 @@ import axios from "axios";
|
||||
|
||||
// Axios create, exporting callAPI
|
||||
|
||||
|
||||
export const callAPI = axios.create({
|
||||
baseURL: process.env.REACT_APP_API_ADDRESS,
|
||||
headers: {'Authorization': "Api-Key " + process.env.REACT_APP_API_KEY}
|
||||
});
|
||||
|
||||
@ -10,7 +10,6 @@ export const Error = () => (
|
||||
<span className="card-title">
|
||||
<i className="large material-icons">do_not_disturb</i>
|
||||
</span>
|
||||
<h3>API OFFLINE</h3>
|
||||
</center>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -3,8 +3,6 @@ import React, { Component } from "react";
|
||||
import { callAPI } from "../actions/API";
|
||||
import Cards from "./Pages/Cards";
|
||||
import GenericList from "../root/Pages/GenericList";
|
||||
import TimeSlotHelper from "./Pages/TimeSlotHelper";
|
||||
|
||||
import { UList } from "../root/common/Functionality/UnorderedList";
|
||||
import { builfArrayFromObject } from "../actions/Error";
|
||||
|
||||
@ -25,19 +23,6 @@ export class Home extends Component {
|
||||
};
|
||||
}
|
||||
|
||||
getTimeslot(days) {
|
||||
callAPI
|
||||
.get("/timeslots/?days=" + days)
|
||||
.then((request) => {
|
||||
return request.data;
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
error: error,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
callAPI
|
||||
.get("/")
|
||||
@ -51,28 +36,40 @@ export class Home extends Component {
|
||||
error: error,
|
||||
});
|
||||
});
|
||||
callAPI
|
||||
.get("/timeslots")
|
||||
.then((request) => {
|
||||
this.setState({
|
||||
timeslots: request.data,
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
error: error,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col s12"></div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col s4 18">
|
||||
<div className="divider"></div>
|
||||
|
||||
<div className="section">
|
||||
<div className="col s7">
|
||||
<Cards migs={this.state.migs} />
|
||||
</div>
|
||||
<div className="col s8 12">
|
||||
{/* <p>Current availability for {Date()}</p>
|
||||
<UList listItems={builfArrayFromObject(this.state.timeslots)} /> */}
|
||||
{/* <TimeSlotHelper /> */}
|
||||
<div className="col s5">
|
||||
<p>Current availability for {Date()}</p>
|
||||
<UList listItems={builfArrayFromObject(this.state.timeslots)} />
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="divider"></div>
|
||||
<div className="section">
|
||||
<div className="col s12">
|
||||
<GenericList APILINK="/pending/" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="divider"></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import React, { Component } from "react";
|
||||
|
||||
import { callAPI } from "../../actions/API";
|
||||
import FormPage from "../common/Forms/FormPage";
|
||||
|
||||
// Parent page for the Book component,
|
||||
@ -11,22 +10,9 @@ export default class Book extends Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
migs: [],
|
||||
timeslots: [],
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
callAPI
|
||||
.get('/gettimeslots/')
|
||||
.then( (response) => {
|
||||
this.setState({
|
||||
timeslots: response.data
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.timeslots.length > 0) {
|
||||
return (
|
||||
<div className="container-fluid">
|
||||
<div className="section">
|
||||
@ -36,13 +22,10 @@ export default class Book extends Component {
|
||||
|
||||
<div className="section">
|
||||
<div className="col s12">
|
||||
<FormPage timeslots={this.state.timeslots} />
|
||||
<FormPage />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}else{
|
||||
return(<div></div>)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { Component } from "react";
|
||||
import CompTable from "../common/Tables/CompTable";
|
||||
import { callAPI } from "../../actions/API";
|
||||
import { callAPI } from "../../actions/API"
|
||||
import { Error } from "../../actions/Error";
|
||||
|
||||
// Missing parent page,
|
||||
@ -18,10 +18,9 @@ class GenericList extends Component {
|
||||
}
|
||||
|
||||
renderItems() {
|
||||
console.log(this.props.APILINK)
|
||||
if (!this.state.error) {
|
||||
return (
|
||||
<CompTable data={callAPI(this.props.APILINK)} key={this.state.error} />
|
||||
);
|
||||
return <CompTable data={callAPI(this.props.APILINK)} />;
|
||||
} else {
|
||||
console.log("error");
|
||||
return <Error />;
|
||||
@ -29,7 +28,19 @@ class GenericList extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div>{this.renderItems()}</div>;
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="divider"></div>
|
||||
<div className="section">
|
||||
<div className="col s12"></div>
|
||||
</div>
|
||||
<div className="divider"></div>
|
||||
<div className="section">
|
||||
<div className="col s12">{this.renderItems()}</div>
|
||||
</div>
|
||||
<div className="divider"></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
import React, { Component } from "react";
|
||||
import TimeSlots from "../common/Tables/TimeSlots";
|
||||
import { callAPI } from "../../actions/API";
|
||||
import { Error } from "../../actions/Error";
|
||||
|
||||
// Missing 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 GenericList extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
error: false,
|
||||
timeslots: [],
|
||||
bookedslots: [],
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
callAPI.get("/gettimeslots/").then((response) => {
|
||||
this.setState({
|
||||
timeslots: response.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
renderItems() {
|
||||
if (!this.state.error) {
|
||||
return (
|
||||
<TimeSlots
|
||||
timeSlots={this.state.timeslots}
|
||||
bookedSlots={this.state.bookedslots}
|
||||
key={this.state.timeslots}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return <Error />;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div>{this.renderItems()}</div>;
|
||||
}
|
||||
}
|
||||
export default GenericList;
|
||||
|
||||
// if (this.state.timeslots > 0) {
|
||||
// else {
|
||||
// return <Error />;
|
||||
// }
|
||||
// }
|
||||
@ -23,8 +23,16 @@ const InputValidation = Yup.object().shape({
|
||||
.required("Please enter a domain"),
|
||||
username: Yup.string().min(2, "Too Short!").required("Required"),
|
||||
original_server: Yup.string()
|
||||
.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,
|
||||
"Please enter a valid IPv4 Address or domain"
|
||||
)
|
||||
.required("Please enter a valid IPv4 or domain"),
|
||||
new_server: Yup.string()
|
||||
.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,
|
||||
"Please enter a valid IPv4 Address or domain"
|
||||
)
|
||||
.required("Please enter a valid IPv4 or domain"),
|
||||
agent_booked: Yup.string()
|
||||
.min(2, "Too short!")
|
||||
@ -36,7 +44,7 @@ const InputValidation = Yup.object().shape({
|
||||
booked_date: Yup.date().required("Please enter a date!"),
|
||||
});
|
||||
|
||||
export const CPanelBooking = (timeslots) => {
|
||||
export const CPanelBooking = () => {
|
||||
const [respID, setRespID] = useState(0);
|
||||
const [error, setError] = useState(0);
|
||||
|
||||
@ -48,7 +56,7 @@ export const CPanelBooking = (timeslots) => {
|
||||
const onSubmit = async (values, { setSubmitting, resetForm }) => {
|
||||
console.log(values);
|
||||
callAPI
|
||||
.post("/book/", values)
|
||||
.post("/", values)
|
||||
.then(function (response) {
|
||||
// console.log(response);
|
||||
// add function here
|
||||
@ -62,7 +70,6 @@ export const CPanelBooking = (timeslots) => {
|
||||
});
|
||||
setSubmitting(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
@ -101,7 +108,12 @@ export const CPanelBooking = (timeslots) => {
|
||||
className="has-success"
|
||||
>
|
||||
<option>Select</option>
|
||||
{timeslots.timeslots.map((slot) => <option>{slot}</option>)}
|
||||
<option>00:00-03:00</option>
|
||||
<option>03:00-06:00</option>
|
||||
<option>06:00-09:00</option>
|
||||
<option>08:00-12:00</option>
|
||||
<option>12:00-18:00</option>
|
||||
<option>18:00-00:00</option>
|
||||
</Input>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
@ -13,7 +13,7 @@ import classnames from "classnames";
|
||||
import { CPanelBooking } from "./CPanelBooking";
|
||||
import EmailBooking from "./EmailBooking";
|
||||
|
||||
const FormPage = ({ timeslots, item }) => {
|
||||
const FormPage = ({ item }) => {
|
||||
const [activeTab, setActiveTab] = useState("1");
|
||||
|
||||
const toggle = (tab) => {
|
||||
@ -23,6 +23,7 @@ const FormPage = ({ timeslots, item }) => {
|
||||
// Parent page from the Book section,
|
||||
// Can be expanded to offer email migration bookings,
|
||||
// elements below do the POST requests.
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Nav tabs>
|
||||
@ -51,7 +52,7 @@ const FormPage = ({ timeslots, item }) => {
|
||||
<TabPane tabId="1">
|
||||
<Row>
|
||||
<Col sm="12">
|
||||
<CPanelBooking timeslots={timeslots} />
|
||||
<CPanelBooking />
|
||||
</Col>
|
||||
</Row>
|
||||
</TabPane>
|
||||
|
||||
@ -5,7 +5,7 @@ export function UList(props) {
|
||||
<div>
|
||||
<ul>
|
||||
{props.listItems.map((item) => (
|
||||
<li liclass="white-text" className={props.liclass} key={item}>
|
||||
<li liClass="white-text" className={props.liClass}>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
|
||||
@ -14,6 +14,7 @@ import ToolkitProvider, {
|
||||
const CompTable = (props) => {
|
||||
const [list, setList] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const { SearchBar } = Search;
|
||||
const { ExportCSVButton } = CSVExport;
|
||||
const sizePerPageRenderer = ({
|
||||
@ -106,6 +107,7 @@ const CompTable = (props) => {
|
||||
),
|
||||
},
|
||||
{ dataField: "booked_date", text: "Booked Date", sort: true },
|
||||
// { dataField: "booked_time", text: "Booked Time", sort: true },
|
||||
{ dataField: "agent_booked", text: "Agent initials", sort: true },
|
||||
{
|
||||
dataField: "domain",
|
||||
@ -118,7 +120,9 @@ const CompTable = (props) => {
|
||||
{ dataField: "migration_type", text: "Type", sort: true },
|
||||
{ dataField: "original_server", text: "Original Server", sort: true },
|
||||
{ dataField: "new_server", text: "New Server", sort: true },
|
||||
// { dataField: "term_date", text: "Termination Date", sort: true },
|
||||
{ dataField: "notes", text: "Notes", sort: true },
|
||||
// { dataField: "submit_time", text: "Submit Time", sort: true },
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
@ -126,7 +130,7 @@ const CompTable = (props) => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="HistoricalSingle">
|
||||
{loading ? (
|
||||
<ToolkitProvider
|
||||
keyField="name"
|
||||
@ -134,13 +138,12 @@ const CompTable = (props) => {
|
||||
columns={columns}
|
||||
search
|
||||
exportCSV
|
||||
key={columns.id}
|
||||
>
|
||||
{(props) => (
|
||||
<div>
|
||||
<div className="serSec">
|
||||
<h3 className="hdrOne"></h3>
|
||||
<SearchBar {...props.searchProps} key={columns} />
|
||||
<SearchBar {...props.searchProps} />
|
||||
</div>
|
||||
|
||||
<div className="table-responsive">
|
||||
@ -151,11 +154,9 @@ const CompTable = (props) => {
|
||||
striped
|
||||
hover
|
||||
condensed
|
||||
key={columns.id}
|
||||
keyField="id"
|
||||
/>
|
||||
</div>
|
||||
<ExportCSVButton {...props.csvProps} key={columns}>
|
||||
<ExportCSVButton {...props.csvProps}>
|
||||
Export CSV!!
|
||||
</ExportCSVButton>
|
||||
</div>
|
||||
|
||||
@ -1,133 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
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";
|
||||
|
||||
// notes
|
||||
//
|
||||
|
||||
const TimeSlots = (props) => {
|
||||
const [list, setList, setTimeSlots, setBookedSlots] = 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 setList = await props.setList;
|
||||
setList();
|
||||
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: "bookedSlots", text: "bookedslots", sort: true },
|
||||
{ dataField: "timeSlots", text: "timeslots", sort: true },
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
getListData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{loading ? (
|
||||
<ToolkitProvider
|
||||
keyField="name"
|
||||
data={list}
|
||||
columns={columns}
|
||||
search
|
||||
exportCSV
|
||||
key={columns.id}
|
||||
keyField="id"
|
||||
>
|
||||
{(props) => (
|
||||
<div>
|
||||
<div className="serSec">
|
||||
<h3 className="hdrOne"></h3>
|
||||
<SearchBar {...props.searchProps} key={columns} />
|
||||
</div>
|
||||
|
||||
<div className="table-responsive">
|
||||
<BootstrapTable
|
||||
{...props.baseProps}
|
||||
filter={filterFactory()}
|
||||
pagination={paginationFactory(options)}
|
||||
striped
|
||||
hover
|
||||
condensed
|
||||
key={columns.id}
|
||||
/>
|
||||
</div>
|
||||
<ExportCSVButton {...props.csvProps} key={columns}>
|
||||
Export CSV!!
|
||||
</ExportCSVButton>
|
||||
</div>
|
||||
)}
|
||||
</ToolkitProvider>
|
||||
) : (
|
||||
<ReactBootstrap.Spinner animation="border" />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TimeSlots;
|
||||
13
src/index.css
Normal file
13
src/index.css
Normal file
@ -0,0 +1,13 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import "./index.css";
|
||||
import App from "./components/App";
|
||||
import reportWebVitals from "./reportWebVitals";
|
||||
|
||||
@ -10,4 +11,7 @@ ReactDOM.render(
|
||||
document.getElementById("root")
|
||||
);
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals();
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
export const GET_MIGRATIONS = "GET_MIGRATIONS";
|
||||
export const ADD_ARTICLE = "ADD_ARTICLE";
|
||||
export const DATA_LOADED = "DATA_LOADED";
|
||||
export const API_ERRORED = "API_ERRORED";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { GET_MIGRATIONS } from "../constants/action-types";
|
||||
import { ADD_ARTICLE } from "../constants/action-types";
|
||||
|
||||
const forbiddenWords = ["spam", "money"];
|
||||
|
||||
@ -6,7 +6,7 @@ export function forbiddenWordsMiddleware({ dispatch }) {
|
||||
return function (next) {
|
||||
return function (action) {
|
||||
// do your stuff
|
||||
if (action.type === GET_MIGRATIONS) {
|
||||
if (action.type === ADD_ARTICLE) {
|
||||
const foundWord = forbiddenWords.filter((word) =>
|
||||
action.payload.title.includes(word)
|
||||
);
|
||||
|
||||
@ -1,21 +1,20 @@
|
||||
import { GET_MIGRATIONS, DATA_LOADED } from "../constants/action-types";
|
||||
import { ADD_ARTICLE, DATA_LOADED } from "../constants/action-types";
|
||||
|
||||
const initialState = {
|
||||
migs: [],
|
||||
timeslots: [],
|
||||
error: false,
|
||||
articles: [],
|
||||
remoteArticles: [],
|
||||
};
|
||||
|
||||
function rootReducer(state = initialState, action) {
|
||||
if (action.type === GET_MIGRATIONS) {
|
||||
if (action.type === ADD_ARTICLE) {
|
||||
return Object.assign({}, state, {
|
||||
migs: state.migs.concat(action.payload),
|
||||
articles: state.articles.concat(action.payload),
|
||||
});
|
||||
}
|
||||
|
||||
if (action.type === DATA_LOADED) {
|
||||
return Object.assign({}, state, {
|
||||
timeslots: state.timeslots.concat(action.payload),
|
||||
remoteArticles: state.remoteArticles.concat(action.payload),
|
||||
});
|
||||
}
|
||||
return state;
|
||||
|
||||
Reference in New Issue
Block a user