woodpecker/web/src/screens/layout.js
2019-11-12 14:27:39 +01:00

228 lines
5.5 KiB
JavaScript

import React, { Component } from "react";
import classnames from "classnames";
import { Route, Switch, Link } from "react-router-dom";
import { connectScreenSize } from "react-screen-size";
import { branch } from "baobab-react/higher-order";
import { inject } from "config/client/inject";
import MenuIcon from "shared/components/icons/menu";
import Feed from "screens/feed";
import RepoRegistry from "screens/repo/screens/registry";
import RepoSecrets from "screens/repo/screens/secrets";
import RepoSettings from "screens/repo/screens/settings";
import RepoBuilds from "screens/repo/screens/builds";
import UserRepos, { UserRepoTitle } from "screens/user/screens/repos";
import UserTokens from "screens/user/screens/tokens";
import RedirectRoot from "./redirect";
import RepoHeader from "screens/repo/screens/builds/header";
import UserReposMenu from "screens/user/screens/repos/menu";
import BuildLogs, { BuildLogsTitle } from "screens/repo/screens/build";
import BuildMenu from "screens/repo/screens/build/menu";
import RepoMenu from "screens/repo/screens/builds/menu";
import { Snackbar } from "shared/components/snackbar";
import { Drawer, DOCK_RIGHT } from "shared/components/drawer/drawer";
import styles from "./layout.less";
const binding = (props, context) => {
return {
user: ["user"],
message: ["message"],
sidebar: ["sidebar"],
menu: ["menu"],
};
};
const mapScreenSizeToProps = screenSize => {
return {
isTablet: screenSize["small"],
isMobile: screenSize["mobile"],
isDesktop: screenSize["> small"],
};
};
@inject
@branch(binding)
@connectScreenSize(mapScreenSizeToProps)
export default class Default extends Component {
constructor(props, context) {
super(props, context);
this.state = {
menu: false,
feed: false,
};
this.openMenu = this.openMenu.bind(this);
this.closeMenu = this.closeMenu.bind(this);
this.closeSnackbar = this.closeSnackbar.bind(this);
}
componentWillReceiveProps(nextProps) {
if (nextProps.location !== this.props.location) {
this.closeMenu(true);
}
}
openMenu() {
this.props.dispatch(tree => {
tree.set(["menu"], true);
});
}
closeMenu() {
this.props.dispatch(tree => {
tree.set(["menu"], false);
});
}
render() {
const { user, message, menu } = this.props;
const classes = classnames(!user || !user.data ? styles.guest : null);
return (
<div className={classes}>
<div className={styles.left}>
<Switch>
<Route path={"/"} component={Feed} />
</Switch>
</div>
<div className={styles.center}>
{!user || !user.data ? (
<a
href={"/login?url=" + window.location.href}
target="_self"
className={styles.login}
>
Click to Login
</a>
) : (
<noscript />
)}
<div className={styles.title}>
<Switch>
<Route path="/account/repos" component={UserRepoTitle} />
<Route
path="/:owner/:repo/:build(\d*)/:proc(\d*)"
exact={true}
component={BuildLogsTitle}
/>
<Route
path="/:owner/:repo/:build(\d*)"
component={BuildLogsTitle}
/>
<Route path="/:owner/:repo" component={RepoHeader} />
</Switch>
{user && user.data ? (
<div className={styles.avatar}>
<img src={user.data.avatar_url} />
</div>
) : (
undefined
)}
{user && user.data ? (
<button onClick={this.openMenu}>
<MenuIcon />
</button>
) : (
<noscript />
)}
</div>
<div className={styles.menu}>
<Switch>
<Route
path="/account/repos"
exact={true}
component={UserReposMenu}
/>
<Route
path="/account/"
exact={false}
component={undefined}
/>BuildMenu
<Route
path="/:owner/:repo/:build(\d*)/:proc(\d*)"
exact={true}
component={BuildMenu}
/>
<Route
path="/:owner/:repo/:build(\d*)"
exact={true}
component={BuildMenu}
/>
<Route path="/:owner/:repo" exact={false} component={RepoMenu} />
</Switch>
</div>
<Switch>
<Route path="/account/token" exact={true} component={UserTokens} />
<Route path="/account/repos" exact={true} component={UserRepos} />
<Route
path="/:owner/:repo/settings/secrets"
exact={true}
component={RepoSecrets}
/>
<Route
path="/:owner/:repo/settings/registry"
exact={true}
component={RepoRegistry}
/>
<Route
path="/:owner/:repo/settings"
exact={true}
component={RepoSettings}
/>
<Route
path="/:owner/:repo/:build(\d*)"
exact={true}
component={BuildLogs}
/>
<Route
path="/:owner/:repo/:build(\d*)/:proc(\d*)"
exact={true}
component={BuildLogs}
/>
<Route path="/:owner/:repo" exact={true} component={RepoBuilds} />
<Route path="/" exact={true} component={RedirectRoot} />
</Switch>
</div>
<Snackbar message={message.text} onClose={this.closeSnackbar} />
<Drawer onClick={this.closeMenu} position={DOCK_RIGHT} open={menu}>
<section>
<ul>
<li>
<Link to="/account/repos">Repositories</Link>
</li>
<li>
<Link to="/account/token">Token</Link>
</li>
</ul>
</section>
<section>
<ul>
<li>
<a href="/logout" target="_self">
Logout
</a>
</li>
</ul>
</section>
</Drawer>
</div>
);
}
closeSnackbar() {
this.props.dispatch(tree => {
tree.unset(["message", "text"]);
});
}
}