Skip to content
This repository has been archived by the owner on Nov 14, 2024. It is now read-only.

Commit

Permalink
Initial work with adding Redux
Browse files Browse the repository at this point in the history
- Ported the auth moduel to use Redux and TypeScript.
- Other related changes.

The exact way we set up our store, ducks and related state will probably
change in future work, so not putting too much effort in it for now.

Using redux-saga for side-effect handling.

The long-running goal is to get rid of Babel and port everything
to using TypeScript. Also replace class components with functional
components using hooks.

Related to #33
  • Loading branch information
henrist committed Jan 5, 2020
1 parent c9f0187 commit 09333ad
Show file tree
Hide file tree
Showing 48 changed files with 763 additions and 463 deletions.
2 changes: 2 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"@babel/preset-typescript"
],
plugins: [
"@babel/plugin-proposal-optional-chaining",
[
"@babel/plugin-proposal-decorators",
{
Expand All @@ -17,6 +18,7 @@
"loose" : true
}
],
"@babel/plugin-transform-runtime",
"react-hot-loader/babel"
]
}
243 changes: 229 additions & 14 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@
"@babel/core": "7.7.7",
"@babel/plugin-proposal-class-properties": "7.7.4",
"@babel/plugin-proposal-decorators": "7.7.4",
"@babel/plugin-proposal-optional-chaining": "7.7.5",
"@babel/plugin-transform-runtime": "7.7.6",
"@babel/preset-env": "7.7.7",
"@babel/preset-react": "7.7.4",
"@babel/preset-typescript": "7.7.7",
"@types/domready": "1.0.0",
"@types/moment-timezone": "0.5.12",
"@types/nuclear-js": "1.4.1",
"@types/react-bootstrap": "0.32.20",
"@types/react-dom": "16.9.4",
"@types/react-redux": "7.1.5",
"@types/react-router": "5.1.3",
"@types/react-router-dom": "5.1.3",
"@typescript-eslint/eslint-plugin": "2.14.0",
Expand Down Expand Up @@ -56,6 +61,7 @@
"reqwest": "2.0.5",
"sass-loader": "8.0.0",
"style-loader": "1.1.2",
"typesafe-actions": "5.1.0",
"typescript": "3.7.4",
"url-loader": "3.0.0",
"webpack": "4.41.5",
Expand All @@ -69,5 +75,10 @@
"lint:fix": "eslint --fix . --ext js --ext jsx --ext ts --ext tsx",
"test": "npm run lint"
},
"dependencies": {}
"dependencies": {
"connected-react-router": "6.6.1",
"react-redux": "7.1.3",
"redux": "4.0.5",
"redux-saga": "1.1.3"
}
}
2 changes: 1 addition & 1 deletion src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ export const api = (url: string) => backendUrl + "api/" + url // see webpack con

export const saml = (url: string) => backendUrl + "saml/" + url

export const admin = (url: string) => backendUrl + "admin/" + url
export const admin = (url = "") => backendUrl + "admin/" + url
23 changes: 10 additions & 13 deletions src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React from "react"
import ReactDOM from "react-dom"
import { hot } from "react-hot-loader"
import { Route } from "react-router"
import { BrowserRouter } from "react-router-dom"
import Admin from "./admin"
import "./app.scss"
import Index from "./components/Index"
Expand All @@ -25,18 +24,16 @@ console.info(
)

const App = () => (
<BrowserRouter>
<Root>
<Route exact path="/" component={Index} />
{Admin}
{Auth}
{Varer}
{Voucher}
{Z}
{Member}
{Intern}
</Root>
</BrowserRouter>
<Root>
<Route exact path="/" component={Index} />
{Admin}
{Auth}
{Varer}
{Voucher}
{Z}
{Member}
{Intern}
</Root>
)

const HotApp = hot(module)(App)
Expand Down
239 changes: 108 additions & 131 deletions src/components/Nav.tsx
Original file line number Diff line number Diff line change
@@ -1,143 +1,120 @@
import { connect } from "nuclear-js-react-addons-chefsplate"
import React from "react"
import { MenuItem, Nav as RefNav, Navbar, NavItem } from "react-bootstrap"
import { useSelector } from "react-redux"
import { Link } from "react-router-dom"
import { authdata, isLoggedIn, userDetails } from "../modules/auth/getters"
import { getAuthState } from "../modules/auth/selectors"
import NavDropdown from "./NavDropdown"
import NavLink from "./NavLink"

interface BareNavProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
authdata: any // TODO
isLoggedIn: boolean
// eslint-disable-next-line @typescript-eslint/no-explicit-any
userDetails: any // TODO
}

class BareNav extends React.Component<BareNavProps> {
renderProfileMenu() {
if (this.props.authdata.get("isLoading")) {
return (
<RefNav pullRight>
<NavItem className="navbar-text">Loading data ..</NavItem>
</RefNav>
)
} else if (this.props.authdata.get("error")) {
return (
<RefNav pullRight>
<NavItem className="navbar-text">
Error: {this.props.authdata.get("error")}
</NavItem>
</RefNav>
)
} else if (this.props.isLoggedIn) {
return (
<RefNav pullRight>
<NavDropdown
title={this.props.userDetails.realname}
id="nav-auth-dropdown"
>
<NavLink to="/profile">Profile</NavLink>
<NavLink to="/logout">Log out</NavLink>
</NavDropdown>
</RefNav>
)
} else {
return (
<RefNav pullRight>
<NavLink to="/login">Log in with UiO-account</NavLink>
</RefNav>
)
}
}

render() {
const profileMenu = this.renderProfileMenu()
const ProfileMenu = () => {
const authState = useSelector(getAuthState)

if (authState.isLoading) {
return (
<RefNav pullRight>
<NavItem className="navbar-text">Loading data ..</NavItem>
</RefNav>
)
} else if (authState.error) {
return (
<RefNav pullRight>
<NavItem className="navbar-text">Error: {authState.error}</NavItem>
</RefNav>
)
} else if (authState.data?.loggedIn) {
return (
<Navbar fixedTop inverse>
<Navbar.Header>
<Navbar.Brand>
<Link to="/">CYB internsystem</Link>
</Navbar.Brand>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse>
<RefNav>
<NavDropdown title="Products" id="nav-products-dropdown">
<NavLink to="/varer/accounts">Account list</NavLink>
<NavLink to="/varer/inventorycounts">Inventory counts</NavLink>
<NavLink to="/varer/inventory">Inventory items</NavLink>
<NavLink to="/varer/salesestimates">Sales estimates</NavLink>
<NavLink to="/varer/products">Sales products</NavLink>
<NavLink to="/varer/vendors">Vendor list</NavLink>
</NavDropdown>
<NavDropdown title="Z" id="nav-z-dropdown">
<NavLink to="/z">Overview</NavLink>
<MenuItem divider />
<MenuItem header>Modules</MenuItem>
<NavLink to="/z/stats">Statistics</NavLink>
</NavDropdown>
<NavDropdown title="Vouchers" id="nav-voucher-dropdown">
<NavLink to="/voucher/stats">Overview</NavLink>
<NavLink to="/voucher/use">Use vouchers</NavLink>
<NavLink to="/voucher/uselogs">Logs of usage</NavLink>
<NavLink to="/voucher/worklogs">Register work / logs</NavLink>
</NavDropdown>
<NavDropdown title="Member" id="nav-member-dropdown">
<NavLink to="/member">Overview</NavLink>
<NavLink to="/member/add">Add member</NavLink>
<NavLink to="/member/list">Member List</NavLink>
<NavLink to="/member/search">Search</NavLink>
<NavLink to="/member/lifetime">Lifetime</NavLink>
</NavDropdown>
<NavDropdown title="Garm" id="nav-intern-dropdown">
<NavLink to="/intern">Overview</NavLink>
<MenuItem divider />
<NavLink to="/intern/levels">Access Levels</NavLink>
<NavLink to="/intern/groups">Groups</NavLink>
<NavLink to="/intern/interns">Interns</NavLink>
<NavLink to="/intern/roles">Roles</NavLink>
</NavDropdown>
<NavDropdown title="Other" id="nav-other-dropdown">
<NavItem
target="_self"
href="http://heim.ifi.uio.no/cyb/tilganger/"
>
Access control management (Garm)
</NavItem>
<NavItem target="_self" href="admin/">
Admin Panel
</NavItem>
<NavItem target="_self" href="https://jira.cyb.no/">
JIRA (task management)
</NavItem>
<NavItem target="_self" href="https://confluence.cyb.no/">
Wiki (Confluence)
</NavItem>
<NavItem target="_self" href="https://github.com/cybernetisk/">
GitHub-organization
</NavItem>
<NavItem target="_self" href="https://cybernetisk.slack.com/">
Slack
</NavItem>
<NavItem
target="_self"
href="https://www.facebook.com/groups/CYB.intern/"
>
Facebook group: CYB Intern
</NavItem>
</NavDropdown>
</RefNav>
{profileMenu}
</Navbar.Collapse>
</Navbar>
<RefNav pullRight>
<NavDropdown
title={authState.data.details.realname}
id="nav-auth-dropdown"
>
<NavLink to="/profile">Profile</NavLink>
<NavLink to="/logout">Log out</NavLink>
</NavDropdown>
</RefNav>
)
} else {
return (
<RefNav pullRight>
<NavLink to="/login">Log in with UiO-account</NavLink>
</RefNav>
)
}
}

export default connect(() => ({
authdata,
userDetails,
isLoggedIn,
}))(BareNav)
export const Nav = () => (
<Navbar fixedTop inverse>
<Navbar.Header>
<Navbar.Brand>
<Link to="/">CYB internsystem</Link>
</Navbar.Brand>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse>
<RefNav>
<NavDropdown title="Products" id="nav-products-dropdown">
<NavLink to="/varer/accounts">Account list</NavLink>
<NavLink to="/varer/inventorycounts">Inventory counts</NavLink>
<NavLink to="/varer/inventory">Inventory items</NavLink>
<NavLink to="/varer/salesestimates">Sales estimates</NavLink>
<NavLink to="/varer/products">Sales products</NavLink>
<NavLink to="/varer/vendors">Vendor list</NavLink>
</NavDropdown>
<NavDropdown title="Z" id="nav-z-dropdown">
<NavLink to="/z">Overview</NavLink>
<MenuItem divider />
<MenuItem header>Modules</MenuItem>
<NavLink to="/z/stats">Statistics</NavLink>
</NavDropdown>
<NavDropdown title="Vouchers" id="nav-voucher-dropdown">
<NavLink to="/voucher/stats">Overview</NavLink>
<NavLink to="/voucher/use">Use vouchers</NavLink>
<NavLink to="/voucher/uselogs">Logs of usage</NavLink>
<NavLink to="/voucher/worklogs">Register work / logs</NavLink>
</NavDropdown>
<NavDropdown title="Member" id="nav-member-dropdown">
<NavLink to="/member">Overview</NavLink>
<NavLink to="/member/add">Add member</NavLink>
<NavLink to="/member/list">Member List</NavLink>
<NavLink to="/member/search">Search</NavLink>
<NavLink to="/member/lifetime">Lifetime</NavLink>
</NavDropdown>
<NavDropdown title="Garm" id="nav-intern-dropdown">
<NavLink to="/intern">Overview</NavLink>
<MenuItem divider />
<NavLink to="/intern/levels">Access Levels</NavLink>
<NavLink to="/intern/groups">Groups</NavLink>
<NavLink to="/intern/interns">Interns</NavLink>
<NavLink to="/intern/roles">Roles</NavLink>
</NavDropdown>
<NavDropdown title="Other" id="nav-other-dropdown">
<NavItem target="_self" href="http://heim.ifi.uio.no/cyb/tilganger/">
Access control management (Garm)
</NavItem>
<NavItem target="_self" href="admin/">
Admin Panel
</NavItem>
<NavItem target="_self" href="https://jira.cyb.no/">
JIRA (task management)
</NavItem>
<NavItem target="_self" href="https://confluence.cyb.no/">
Wiki (Confluence)
</NavItem>
<NavItem target="_self" href="https://github.com/cybernetisk/">
GitHub-organization
</NavItem>
<NavItem target="_self" href="https://cybernetisk.slack.com/">
Slack
</NavItem>
<NavItem
target="_self"
href="https://www.facebook.com/groups/CYB.intern/"
>
Facebook group: CYB Intern
</NavItem>
</NavDropdown>
</RefNav>
<ProfileMenu />
</Navbar.Collapse>
</Navbar>
)
23 changes: 15 additions & 8 deletions src/components/Root.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import { Provider } from "nuclear-js-react-addons-chefsplate"
import { ConnectedRouter } from "connected-react-router"
import { Provider as NuclearProvider } from "nuclear-js-react-addons-chefsplate"
import React from "react"
import { Provider } from "react-redux"
import reactor from "../reactor"
import Nav from "./Nav"
import { history, store } from "../store"
import { Nav } from "./Nav"

export default class Root extends React.Component {
render() {
return (
<Provider reactor={reactor}>
<div>
<Nav />
<div className="container">{this.props.children}</div>
</div>
</Provider>
<NuclearProvider reactor={reactor}>
<Provider store={store}>
<ConnectedRouter history={history}>
<div>
<Nav />
<div className="container">{this.props.children}</div>
</div>
</ConnectedRouter>
</Provider>
</NuclearProvider>
)
}
}
Empty file added src/ducks.ts
Empty file.
7 changes: 0 additions & 7 deletions src/modules/auth/actionTypes.js

This file was deleted.

Loading

0 comments on commit 09333ad

Please sign in to comment.