summaryrefslogtreecommitdiff
path: root/src/components/simulations
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/simulations')
-rw-r--r--src/components/simulations/FilterButton.js23
-rw-r--r--src/components/simulations/FilterButton.sass23
-rw-r--r--src/components/simulations/FilterPanel.js15
-rw-r--r--src/components/simulations/FilterPanel.sass21
-rw-r--r--src/components/simulations/NewSimulationButton.js16
-rw-r--r--src/components/simulations/NewSimulationButton.sass31
-rw-r--r--src/components/simulations/NoSimulationsAlert.js11
-rw-r--r--src/components/simulations/NoSimulationsAlert.sass10
-rw-r--r--src/components/simulations/SimulationActionButtons.js26
-rw-r--r--src/components/simulations/SimulationAuth.js24
-rw-r--r--src/components/simulations/SimulationAuthList.js33
-rw-r--r--src/components/simulations/SimulationAuthList.sass104
12 files changed, 337 insertions, 0 deletions
diff --git a/src/components/simulations/FilterButton.js b/src/components/simulations/FilterButton.js
new file mode 100644
index 00000000..2105d281
--- /dev/null
+++ b/src/components/simulations/FilterButton.js
@@ -0,0 +1,23 @@
+import classNames from 'classnames';
+import PropTypes from 'prop-types';
+import React from 'react';
+import "./FilterButton.css";
+
+const FilterButton = ({active, children, onClick}) => (
+ <div className={classNames("simulation-filter-button", {"active": active})}
+ onClick={() => {
+ if (!active) {
+ onClick();
+ }
+ }}>
+ {children}
+ </div>
+);
+
+FilterButton.propTypes = {
+ active: PropTypes.bool.isRequired,
+ children: PropTypes.node.isRequired,
+ onClick: PropTypes.func.isRequired
+};
+
+export default FilterButton;
diff --git a/src/components/simulations/FilterButton.sass b/src/components/simulations/FilterButton.sass
new file mode 100644
index 00000000..60f6faca
--- /dev/null
+++ b/src/components/simulations/FilterButton.sass
@@ -0,0 +1,23 @@
+@import ../../style-globals/_mixins.sass
+@import ../../style-globals/_variables.sass
+
+.simulation-filter-button
+ display: inline-block
+ width: 33.3%
+ //margin-right: -4px
+ padding: 10px $global-padding
+
+ font-size: 12pt
+ border-right: 1px solid #06326b
+
+ +clickable
+ +transition(background, $transition-length)
+
+.simulation-filter-button:last-of-type
+ border: 0
+
+.simulation-filter-button:hover
+ background: #0c60bf
+
+.simulation-filter-button:active, .simulation-filter-button.active
+ background: #073d7d
diff --git a/src/components/simulations/FilterPanel.js b/src/components/simulations/FilterPanel.js
new file mode 100644
index 00000000..b43139c1
--- /dev/null
+++ b/src/components/simulations/FilterPanel.js
@@ -0,0 +1,15 @@
+import React from 'react';
+import FilterLink from "../../containers/simulations/FilterLink";
+import "./FilterPanel.css";
+
+const FilterPanel = () => (
+ <div className="filter-menu">
+ <div className="simulation-filters">
+ <FilterLink filter="SHOW_ALL">All Simulations</FilterLink>
+ <FilterLink filter="SHOW_OWN">My Simulations</FilterLink>
+ <FilterLink filter="SHOW_SHARED">Simulations shared with me</FilterLink>
+ </div>
+ </div>
+);
+
+export default FilterPanel;
diff --git a/src/components/simulations/FilterPanel.sass b/src/components/simulations/FilterPanel.sass
new file mode 100644
index 00000000..a59ffdfd
--- /dev/null
+++ b/src/components/simulations/FilterPanel.sass
@@ -0,0 +1,21 @@
+@import ../../style-globals/_mixins.sass
+@import ../../style-globals/_variables.sass
+
+.filter-menu
+ display: block
+
+ background: #0761b1
+ border: 1px solid #06326b
+ color: #eee
+
+ text-align: center
+
+ +border-radius($standard-border-radius)
+ overflow: hidden
+
+ margin-bottom: 20px
+
+ .simulation-filters
+ display: block
+ overflow: hidden
+ margin: 0 -1px
diff --git a/src/components/simulations/NewSimulationButton.js b/src/components/simulations/NewSimulationButton.js
new file mode 100644
index 00000000..468f7678
--- /dev/null
+++ b/src/components/simulations/NewSimulationButton.js
@@ -0,0 +1,16 @@
+import PropTypes from 'prop-types';
+import React from 'react';
+import './NewSimulationButton.css';
+
+const NewSimulationButton = ({onClick}) => (
+ <div className="new-simulation-btn" onClick={onClick}>
+ <span className="fa fa-plus"/>
+ New Simulation
+ </div>
+);
+
+NewSimulationButton.propTypes = {
+ onClick: PropTypes.func.isRequired,
+};
+
+export default NewSimulationButton;
diff --git a/src/components/simulations/NewSimulationButton.sass b/src/components/simulations/NewSimulationButton.sass
new file mode 100644
index 00000000..9bf82c49
--- /dev/null
+++ b/src/components/simulations/NewSimulationButton.sass
@@ -0,0 +1,31 @@
+@import ../../style-globals/_mixins.sass
+@import ../../style-globals/_variables.sass
+
+.new-simulation-btn
+ $button-height: 35px
+
+ display: inline-block
+ position: absolute
+ bottom: $navbar-height + 40px
+ right: 40px
+ padding: 0 10px
+ height: $button-height
+ line-height: $button-height
+ font-size: 14pt
+
+ background: #679436
+ color: #eee
+ border: 1px solid #507830
+
+ +border-radius($standard-border-radius)
+ +clickable
+ +transition(all, $transition-length)
+
+ span
+ margin-right: 10px
+
+.new-simulation-btn:hover
+ background: #73ac45
+
+.new-simulation-btn:active
+ background: #5c8835
diff --git a/src/components/simulations/NoSimulationsAlert.js b/src/components/simulations/NoSimulationsAlert.js
new file mode 100644
index 00000000..d688ae56
--- /dev/null
+++ b/src/components/simulations/NoSimulationsAlert.js
@@ -0,0 +1,11 @@
+import React from 'react';
+import "./NoSimulationsAlert.css";
+
+const NoSimulationsAlert = () => (
+ <div className="no-simulations-alert alert alert-info">
+ <span className="info-icon fa fa-2x fa-question-circle"/>
+ <strong>No simulations here yet...</strong> Add some with the 'New Simulation' button!
+ </div>
+);
+
+export default NoSimulationsAlert;
diff --git a/src/components/simulations/NoSimulationsAlert.sass b/src/components/simulations/NoSimulationsAlert.sass
new file mode 100644
index 00000000..10e89e51
--- /dev/null
+++ b/src/components/simulations/NoSimulationsAlert.sass
@@ -0,0 +1,10 @@
+.no-simulations-alert
+ position: relative
+ padding-left: 50px
+
+ .info-icon
+ position: absolute
+ top: 11px
+ left: 15px
+ bottom: 10px
+ font-size: 20pt
diff --git a/src/components/simulations/SimulationActionButtons.js b/src/components/simulations/SimulationActionButtons.js
new file mode 100644
index 00000000..d48b4bcf
--- /dev/null
+++ b/src/components/simulations/SimulationActionButtons.js
@@ -0,0 +1,26 @@
+import PropTypes from "prop-types";
+import React from 'react';
+
+const SimulationActionButtons = ({simulationId, onOpen, onViewUsers, onDelete}) => (
+ <div className="simulation-icons">
+ <div className="open" title="Open this simulation" onClick={() => onOpen(simulationId)}>
+ <span className="fa fa-play"/>
+ </div>
+ <div className="users" title="View and edit collaborators on this simulation"
+ onClick={() => onViewUsers(simulationId)}>
+ <span className="fa fa-users"/>
+ </div>
+ <div className="delete" title="Delete this simulation" onClick={() => onDelete(simulationId)}>
+ <span className="fa fa-trash"/>
+ </div>
+ </div>
+);
+
+SimulationActionButtons.propTypes = {
+ simulationId: PropTypes.number.isRequired,
+ onOpen: PropTypes.func,
+ onViewUsers: PropTypes.func,
+ onDelete: PropTypes.func,
+};
+
+export default SimulationActionButtons;
diff --git a/src/components/simulations/SimulationAuth.js b/src/components/simulations/SimulationAuth.js
new file mode 100644
index 00000000..9b887991
--- /dev/null
+++ b/src/components/simulations/SimulationAuth.js
@@ -0,0 +1,24 @@
+import classNames from 'classnames';
+import React from 'react';
+import SimulationActions from "../../containers/simulations/SimulationActions";
+import Shapes from "../../shapes/index";
+import {AUTH_DESCRIPTION_MAP, AUTH_ICON_MAP} from "../../util/authorizations";
+import {parseAndFormatDateTime} from "../../util/date-time";
+
+const SimulationAuth = ({simulationAuth}) => (
+ <div className="simulation-row">
+ <div>{simulationAuth.simulation.name}</div>
+ <div>{parseAndFormatDateTime(simulationAuth.simulation.datetimeLastEdited)}</div>
+ <div>
+ <span className={classNames("fa", "fa-" + AUTH_ICON_MAP[simulationAuth.authorizationLevel])}/>
+ {AUTH_DESCRIPTION_MAP[simulationAuth.authorizationLevel]}
+ </div>
+ <SimulationActions simulationId={simulationAuth.simulation.id}/>
+ </div>
+);
+
+SimulationAuth.propTypes = {
+ simulationAuth: Shapes.Authorization.isRequired,
+};
+
+export default SimulationAuth;
diff --git a/src/components/simulations/SimulationAuthList.js b/src/components/simulations/SimulationAuthList.js
new file mode 100644
index 00000000..7653f178
--- /dev/null
+++ b/src/components/simulations/SimulationAuthList.js
@@ -0,0 +1,33 @@
+import PropTypes from 'prop-types';
+import React from 'react';
+import Shapes from "../../shapes/index";
+import NoSimulationsAlert from "./NoSimulationsAlert";
+import SimulationAuth from "./SimulationAuth";
+import "./SimulationAuthList.css";
+
+const SimulationAuthList = ({authorizations}) => {
+ if (authorizations.length === 0) {
+ return <NoSimulationsAlert/>;
+ }
+
+ return (
+ <div className="simulation-list">
+ <div className="list-head">
+ <div>Simulation name</div>
+ <div>Last edited</div>
+ <div>Access rights</div>
+ </div>
+ <div className="list-body">
+ {authorizations.map(authorization => (
+ <SimulationAuth simulationAuth={authorization} key={authorization.simulation.id}/>
+ ))}
+ </div>
+ </div>
+ );
+};
+
+SimulationAuthList.propTypes = {
+ authorizations: PropTypes.arrayOf(Shapes.Authorization).isRequired,
+};
+
+export default SimulationAuthList;
diff --git a/src/components/simulations/SimulationAuthList.sass b/src/components/simulations/SimulationAuthList.sass
new file mode 100644
index 00000000..4edfb99e
--- /dev/null
+++ b/src/components/simulations/SimulationAuthList.sass
@@ -0,0 +1,104 @@
+@import ../../style-globals/_mixins.sass
+@import ../../style-globals/_variables.sass
+
+.simulation-list
+ display: block
+ font-size: 12pt
+ border: 0
+
+ .list-head, .list-body .simulation-row
+ display: block
+ position: relative
+
+ .list-head div, .list-body .simulation-row div
+ padding: 0 10px
+ display: inline-block
+
+ .list-head
+ font-weight: bold
+
+ // Address default margin between inline-blocks
+ div
+ margin-right: -4px
+
+.simulation-row
+ background: #f8f8f8
+ border: 1px solid #b6b6b6
+ height: 40px
+ line-height: 40px
+ clear: both
+
+.simulation-row:not(:first-of-type)
+ margin-top: -1px
+
+// Sizing of table columns
+.simulation-row, .simulation-list .list-head
+ div:first-of-type
+ width: 40%
+
+ div:nth-of-type(2)
+ width: 20%
+
+ div:nth-of-type(3)
+ width: 20%
+
+ div:last-of-type
+ width: 20%
+
+ span
+ margin-right: 10px
+
+.simulation-row .simulation-icons
+ text-align: right
+
+.simulation-row .simulation-icons div
+ display: inline
+ position: relative
+ top: 4px
+ width: 30px
+ height: 30px
+ margin-right: 5px
+ font-size: 12pt
+ color: white
+ +border-radius(100%)
+ +clickable
+ +transition(background, $transition-length)
+
+ span
+ position: relative
+ top: -4px
+ left: -1px
+
+ &.open
+ $icon-color: #0c60bf
+ background: $icon-color
+
+ &:hover
+ background: lighten($icon-color, 10%)
+
+ &:active
+ background: darken($icon-color, 10%)
+
+ &.users
+ font-size: 10pt
+ $icon-color: #17bf55
+ background: $icon-color
+
+ span
+ left: -2px
+
+ &:hover
+ background: lighten($icon-color, 10%)
+
+ &:active
+ background: darken($icon-color, 10%)
+
+ &.delete
+ $icon-color: #e3474d
+ background: $icon-color
+
+ &:hover
+ background: lighten($icon-color, 10%)
+
+ &:active
+ background: darken($icon-color, 10%)