summaryrefslogtreecommitdiff
path: root/frontend/src/pages
diff options
context:
space:
mode:
authorGeorgios Andreadis <info@gandreadis.com>2020-06-29 15:47:09 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2020-08-24 16:08:41 +0200
commit90fae26aa4bd0e0eb3272ff6e6524060e9004fbb (patch)
treebf6943882f5fa5f3114c01fc571503c79ee1056d /frontend/src/pages
parent7032a007d4431f5a0c4c5e2d3f3bd20462d49950 (diff)
Prepare frontend repository for monorepo
This change prepares the frontend Git repository for the monorepo residing at https://github.com/atlarge-research.com/opendc. To accomodate for this, we move all files into a frontend subdirectory.
Diffstat (limited to 'frontend/src/pages')
-rw-r--r--frontend/src/pages/App.js125
-rw-r--r--frontend/src/pages/Experiments.js75
-rw-r--r--frontend/src/pages/Home.js62
-rw-r--r--frontend/src/pages/Home.sass9
-rw-r--r--frontend/src/pages/NotFound.js14
-rw-r--r--frontend/src/pages/NotFound.sass11
-rw-r--r--frontend/src/pages/Profile.js40
-rw-r--r--frontend/src/pages/Simulations.js46
8 files changed, 382 insertions, 0 deletions
diff --git a/frontend/src/pages/App.js b/frontend/src/pages/App.js
new file mode 100644
index 00000000..ad201e7d
--- /dev/null
+++ b/frontend/src/pages/App.js
@@ -0,0 +1,125 @@
+import PropTypes from "prop-types";
+import React from "react";
+import DocumentTitle from "react-document-title";
+import { connect } from "react-redux";
+import { ShortcutManager } from "react-shortcuts";
+import { openExperimentSucceeded } from "../actions/experiments";
+import { openSimulationSucceeded } from "../actions/simulations";
+import { resetCurrentDatacenter } from "../actions/topology/building";
+import ToolPanelComponent from "../components/app/map/controls/ToolPanelComponent";
+import LoadingScreen from "../components/app/map/LoadingScreen";
+import SimulationSidebarComponent from "../components/app/sidebars/simulation/SimulationSidebarComponent";
+import AppNavbar from "../components/navigation/AppNavbar";
+import ScaleIndicatorContainer from "../containers/app/map/controls/ScaleIndicatorContainer";
+import MapStage from "../containers/app/map/MapStage";
+import TopologySidebar from "../containers/app/sidebars/topology/TopologySidebar";
+import TimelineContainer from "../containers/app/timeline/TimelineContainer";
+import DeleteMachineModal from "../containers/modals/DeleteMachineModal";
+import DeleteRackModal from "../containers/modals/DeleteRackModal";
+import DeleteRoomModal from "../containers/modals/DeleteRoomModal";
+import EditRackNameModal from "../containers/modals/EditRackNameModal";
+import EditRoomNameModal from "../containers/modals/EditRoomNameModal";
+import KeymapConfiguration from "../shortcuts/keymap";
+
+const shortcutManager = new ShortcutManager(KeymapConfiguration);
+
+class AppComponent extends React.Component {
+ static propTypes = {
+ simulationId: PropTypes.number.isRequired,
+ inSimulation: PropTypes.bool,
+ experimentId: PropTypes.number,
+ simulationName: PropTypes.string
+ };
+ static childContextTypes = {
+ shortcuts: PropTypes.object.isRequired
+ };
+
+ componentDidMount() {
+ this.props.resetCurrentDatacenter();
+ if (this.props.inSimulation) {
+ this.props.openExperimentSucceeded(
+ this.props.simulationId,
+ this.props.experimentId
+ );
+ return;
+ }
+ this.props.openSimulationSucceeded(this.props.simulationId);
+ }
+
+ getChildContext() {
+ return {
+ shortcuts: shortcutManager
+ };
+ }
+
+ render() {
+ return (
+ <DocumentTitle
+ title={
+ this.props.simulationName
+ ? this.props.simulationName + " - OpenDC"
+ : "Simulation - OpenDC"
+ }
+ >
+ <div className="page-container full-height">
+ <AppNavbar
+ simulationId={this.props.simulationId}
+ inSimulation={true}
+ fullWidth={true}
+ />
+ {this.props.datacenterIsLoading ? (
+ <div className="full-height d-flex align-items-center justify-content-center">
+ <LoadingScreen />
+ </div>
+ ) : (
+ <div className="full-height">
+ <MapStage />
+ <ScaleIndicatorContainer />
+ <ToolPanelComponent />
+ <TopologySidebar />
+ {this.props.inSimulation ? <TimelineContainer /> : undefined}
+ {this.props.inSimulation ? (
+ <SimulationSidebarComponent />
+ ) : (
+ undefined
+ )}
+ </div>
+ )}
+ <EditRoomNameModal />
+ <DeleteRoomModal />
+ <EditRackNameModal />
+ <DeleteRackModal />
+ <DeleteMachineModal />
+ </div>
+ </DocumentTitle>
+ );
+ }
+}
+
+const mapStateToProps = state => {
+ let simulationName = undefined;
+ if (
+ state.currentSimulationId !== -1 &&
+ state.objects.simulation[state.currentSimulationId]
+ ) {
+ simulationName = state.objects.simulation[state.currentSimulationId].name;
+ }
+
+ return {
+ datacenterIsLoading: state.currentDatacenterId === -1,
+ simulationName
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ resetCurrentDatacenter: () => dispatch(resetCurrentDatacenter()),
+ openSimulationSucceeded: id => dispatch(openSimulationSucceeded(id)),
+ openExperimentSucceeded: (simulationId, experimentId) =>
+ dispatch(openExperimentSucceeded(simulationId, experimentId))
+ };
+};
+
+const App = connect(mapStateToProps, mapDispatchToProps)(AppComponent);
+
+export default App;
diff --git a/frontend/src/pages/Experiments.js b/frontend/src/pages/Experiments.js
new file mode 100644
index 00000000..2f73cd7e
--- /dev/null
+++ b/frontend/src/pages/Experiments.js
@@ -0,0 +1,75 @@
+import PropTypes from "prop-types";
+import React from "react";
+import DocumentTitle from "react-document-title";
+import { connect } from "react-redux";
+import { fetchExperimentsOfSimulation } from "../actions/experiments";
+import { openSimulationSucceeded } from "../actions/simulations";
+import AppNavbar from "../components/navigation/AppNavbar";
+import ExperimentListContainer from "../containers/experiments/ExperimentListContainer";
+import NewExperimentButtonContainer from "../containers/experiments/NewExperimentButtonContainer";
+import NewExperimentModal from "../containers/modals/NewExperimentModal";
+
+class ExperimentsComponent extends React.Component {
+ static propTypes = {
+ simulationId: PropTypes.number.isRequired,
+ simulationName: PropTypes.string
+ };
+
+ componentDidMount() {
+ this.props.storeSimulationId(this.props.simulationId);
+ this.props.fetchExperimentsOfSimulation(this.props.simulationId);
+ }
+
+ render() {
+ return (
+ <DocumentTitle
+ title={
+ this.props.simulationName
+ ? "Experiments - " + this.props.simulationName + " - OpenDC"
+ : "Experiments - OpenDC"
+ }
+ >
+ <div className="full-height">
+ <AppNavbar
+ simulationId={this.props.simulationId}
+ inSimulation={true}
+ fullWidth={true}
+ />
+ <div className="container text-page-container full-height">
+ <ExperimentListContainer />
+ <NewExperimentButtonContainer />
+ </div>
+ <NewExperimentModal />
+ </div>
+ </DocumentTitle>
+ );
+ }
+}
+
+const mapStateToProps = state => {
+ let simulationName = undefined;
+ if (
+ state.currentSimulationId !== -1 &&
+ state.objects.simulation[state.currentSimulationId]
+ ) {
+ simulationName = state.objects.simulation[state.currentSimulationId].name;
+ }
+
+ return {
+ simulationName
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ storeSimulationId: id => dispatch(openSimulationSucceeded(id)),
+ fetchExperimentsOfSimulation: id =>
+ dispatch(fetchExperimentsOfSimulation(id))
+ };
+};
+
+const Experiments = connect(mapStateToProps, mapDispatchToProps)(
+ ExperimentsComponent
+);
+
+export default Experiments;
diff --git a/frontend/src/pages/Home.js b/frontend/src/pages/Home.js
new file mode 100644
index 00000000..f6479722
--- /dev/null
+++ b/frontend/src/pages/Home.js
@@ -0,0 +1,62 @@
+import React from "react";
+import DocumentTitle from "react-document-title";
+import ContactSection from "../components/home/ContactSection";
+import IntroSection from "../components/home/IntroSection";
+import JumbotronHeader from "../components/home/JumbotronHeader";
+import ModelingSection from "../components/home/ModelingSection";
+import SimulationSection from "../components/home/SimulationSection";
+import StakeholderSection from "../components/home/StakeholderSection";
+import TeamSection from "../components/home/TeamSection";
+import TechnologiesSection from "../components/home/TechnologiesSection";
+import HomeNavbar from "../components/navigation/HomeNavbar";
+import jQuery from "../util/jquery";
+import "./Home.css";
+
+class Home extends React.Component {
+ state = {
+ scrollSpySetup: false
+ };
+
+ componentDidMount() {
+ const scrollOffset = 60;
+ jQuery("#navbar")
+ .find("li a")
+ .click(function(e) {
+ if (jQuery(e.target).parents(".auth-links").length > 0) {
+ return;
+ }
+ e.preventDefault();
+ jQuery(jQuery(this).attr("href"))[0].scrollIntoView();
+ window.scrollBy(0, -scrollOffset);
+ });
+
+ if (!this.state.scrollSpySetup) {
+ jQuery("body").scrollspy({
+ target: "#navbar",
+ offset: scrollOffset
+ });
+ this.setState({ scrollSpySetup: true });
+ }
+ }
+
+ render() {
+ return (
+ <div>
+ <HomeNavbar />
+ <div className="body-wrapper page-container">
+ <JumbotronHeader />
+ <IntroSection />
+ <StakeholderSection />
+ <ModelingSection />
+ <SimulationSection />
+ <TechnologiesSection />
+ <TeamSection />
+ <ContactSection />
+ <DocumentTitle title="OpenDC" />
+ </div>
+ </div>
+ );
+ }
+}
+
+export default Home;
diff --git a/frontend/src/pages/Home.sass b/frontend/src/pages/Home.sass
new file mode 100644
index 00000000..9c812db2
--- /dev/null
+++ b/frontend/src/pages/Home.sass
@@ -0,0 +1,9 @@
+.body-wrapper
+ position: relative
+ overflow-y: hidden
+
+.intro-section, .modeling-section, .technologies-section
+ background-color: #fff
+
+.stakeholder-section, .simulation-section, .team-section
+ background-color: #f2f2f2
diff --git a/frontend/src/pages/NotFound.js b/frontend/src/pages/NotFound.js
new file mode 100644
index 00000000..b344e923
--- /dev/null
+++ b/frontend/src/pages/NotFound.js
@@ -0,0 +1,14 @@
+import React from "react";
+import DocumentTitle from "react-document-title";
+import TerminalWindow from "../components/not-found/TerminalWindow";
+import "./NotFound.css";
+
+const NotFound = () => (
+ <DocumentTitle title="Page Not Found - OpenDC">
+ <div className="not-found-backdrop">
+ <TerminalWindow />
+ </div>
+ </DocumentTitle>
+);
+
+export default NotFound;
diff --git a/frontend/src/pages/NotFound.sass b/frontend/src/pages/NotFound.sass
new file mode 100644
index 00000000..9457da01
--- /dev/null
+++ b/frontend/src/pages/NotFound.sass
@@ -0,0 +1,11 @@
+.not-found-backdrop
+ position: absolute
+ left: 0
+ top: 0
+
+ margin: 0
+ padding: 0
+ width: 100%
+ height: 100%
+
+ background-image: linear-gradient(135deg, #00678a, #008fbf, #00A6D6)
diff --git a/frontend/src/pages/Profile.js b/frontend/src/pages/Profile.js
new file mode 100644
index 00000000..106ec97e
--- /dev/null
+++ b/frontend/src/pages/Profile.js
@@ -0,0 +1,40 @@
+import React from "react";
+import DocumentTitle from "react-document-title";
+import { connect } from "react-redux";
+import { openDeleteProfileModal } from "../actions/modals/profile";
+import AppNavbar from "../components/navigation/AppNavbar";
+import DeleteProfileModal from "../containers/modals/DeleteProfileModal";
+
+const ProfileContainer = ({ onDelete }) => (
+ <DocumentTitle title="My Profile - OpenDC">
+ <div className="full-height">
+ <AppNavbar inSimulation={false} fullWidth={false} />
+ <div className="container text-page-container full-height">
+ <button
+ className="btn btn-danger mb-2 ml-auto mr-auto"
+ style={{ maxWidth: 300 }}
+ onClick={onDelete}
+ >
+ Delete my account on OpenDC
+ </button>
+ <p className="text-muted text-center">
+ This does not delete your Google account, but simply disconnects it
+ from the OpenDC platform and deletes any simulation info that is
+ associated with you (simulations you own and any authorizations you
+ may have on other projects).
+ </p>
+ </div>
+ <DeleteProfileModal />
+ </div>
+ </DocumentTitle>
+);
+
+const mapDispatchToProps = dispatch => {
+ return {
+ onDelete: () => dispatch(openDeleteProfileModal())
+ };
+};
+
+const Profile = connect(undefined, mapDispatchToProps)(ProfileContainer);
+
+export default Profile;
diff --git a/frontend/src/pages/Simulations.js b/frontend/src/pages/Simulations.js
new file mode 100644
index 00000000..ecff8fe6
--- /dev/null
+++ b/frontend/src/pages/Simulations.js
@@ -0,0 +1,46 @@
+import React from "react";
+import DocumentTitle from "react-document-title";
+import { connect } from "react-redux";
+import { openNewSimulationModal } from "../actions/modals/simulations";
+import { fetchAuthorizationsOfCurrentUser } from "../actions/users";
+import AppNavbar from "../components/navigation/AppNavbar";
+import SimulationFilterPanel from "../components/simulations/FilterPanel";
+import NewSimulationModal from "../containers/modals/NewSimulationModal";
+import NewSimulationButtonContainer from "../containers/simulations/NewSimulationButtonContainer";
+import VisibleSimulationList from "../containers/simulations/VisibleSimulationAuthList";
+
+class SimulationsContainer extends React.Component {
+ componentDidMount() {
+ this.props.fetchAuthorizationsOfCurrentUser();
+ }
+
+ render() {
+ return (
+ <DocumentTitle title="My Simulations - OpenDC">
+ <div className="full-height">
+ <AppNavbar inSimulation={false} fullWidth={false} />
+ <div className="container text-page-container full-height">
+ <SimulationFilterPanel />
+ <VisibleSimulationList />
+ <NewSimulationButtonContainer />
+ </div>
+ <NewSimulationModal />
+ </div>
+ </DocumentTitle>
+ );
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ fetchAuthorizationsOfCurrentUser: () =>
+ dispatch(fetchAuthorizationsOfCurrentUser()),
+ openNewSimulationModal: () => dispatch(openNewSimulationModal())
+ };
+};
+
+const Simulations = connect(undefined, mapDispatchToProps)(
+ SimulationsContainer
+);
+
+export default Simulations;