2020-04-09 00:29:13 +03:00
|
|
|
import * as React from "react";
|
|
|
|
import * as Constants from "~/common/constants";
|
2020-08-08 03:10:28 +03:00
|
|
|
import * as System from "~/components/system";
|
2020-04-09 00:29:13 +03:00
|
|
|
import * as SVG from "~/common/svg";
|
|
|
|
|
|
|
|
import { css } from "@emotion/react";
|
|
|
|
|
2020-09-02 04:09:39 +03:00
|
|
|
import ApplicationUserControls from "~/components/core/ApplicationUserControls";
|
2020-04-09 00:29:13 +03:00
|
|
|
|
|
|
|
const IconMap = {
|
|
|
|
HOME: <SVG.Home height="20px" />,
|
2020-09-25 08:14:19 +03:00
|
|
|
ENCRYPTED: <SVG.SecurityLock height="20px" />,
|
2020-08-18 22:51:16 +03:00
|
|
|
NETWORK: <SVG.Activity height="20px" />,
|
2020-08-18 22:28:33 +03:00
|
|
|
DIRECTORY: <SVG.Directory height="20px" />,
|
2020-04-09 00:29:13 +03:00
|
|
|
FOLDER: <SVG.Folder height="20px" />,
|
2020-09-09 20:56:35 +03:00
|
|
|
WALLET: <SVG.OldWallet height="20px" />,
|
2020-04-09 00:29:13 +03:00
|
|
|
DEALS: <SVG.Deals height="20px" />,
|
2020-09-24 22:42:32 +03:00
|
|
|
MAKE_DEAL: <SVG.HardDrive height="20px" />,
|
2020-08-10 04:22:52 +03:00
|
|
|
SLATES: <SVG.Layers height="20px" />,
|
2020-09-05 02:15:29 +03:00
|
|
|
SLATE: <SVG.Slate height="20px" />,
|
2020-07-21 08:45:15 +03:00
|
|
|
LOCAL_DATA: <SVG.HardDrive height="20px" />,
|
2020-07-22 10:41:29 +03:00
|
|
|
PROFILE_PAGE: <SVG.ProfileUser height="20px" />,
|
2020-09-05 02:15:29 +03:00
|
|
|
SETTINGS_DEVELOPER: <SVG.Tool height="20px" />,
|
2020-09-24 22:42:32 +03:00
|
|
|
SETTINGS: <SVG.Settings height="20px" />,
|
2020-08-31 21:19:46 +03:00
|
|
|
DIRECTORY: <SVG.Directory height="20px" />,
|
2020-09-09 20:56:35 +03:00
|
|
|
FILECOIN: <SVG.Wallet height="20px" />,
|
2020-09-27 19:38:20 +03:00
|
|
|
MINERS: <SVG.Miners height="20px" />,
|
2020-04-09 00:29:13 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
const STYLES_NAVIGATION = css`
|
2020-09-25 09:31:56 +03:00
|
|
|
margin-top: 16px; /* TODO(martina): remove this once the alert banner is gone */
|
2020-04-09 00:29:13 +03:00
|
|
|
width: 100%;
|
2020-08-08 23:13:47 +03:00
|
|
|
display: block;
|
2020-04-09 00:29:13 +03:00
|
|
|
padding: 24px 0 0 0;
|
|
|
|
`;
|
|
|
|
|
|
|
|
const STYLES_NAVIGATION_ITEM = css`
|
|
|
|
display: flex;
|
|
|
|
align-items: flex-start;
|
|
|
|
justify-content: space-between;
|
|
|
|
cursor: pointer;
|
|
|
|
color: ${Constants.system.black};
|
2020-08-09 11:08:46 +03:00
|
|
|
user-select: none;
|
2020-08-08 23:13:47 +03:00
|
|
|
padding-right: 24px;
|
2020-09-05 00:37:50 +03:00
|
|
|
font-family: ${Constants.font.medium};
|
2020-04-09 00:29:13 +03:00
|
|
|
|
|
|
|
:hover {
|
2020-08-08 23:13:47 +03:00
|
|
|
padding-right: 0px;
|
2020-04-09 00:29:13 +03:00
|
|
|
color: ${Constants.system.brand};
|
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
|
|
|
const STYLES_EXPANDER = css`
|
|
|
|
flex-shrink: 0;
|
2020-08-08 23:13:47 +03:00
|
|
|
|
2020-08-09 01:04:17 +03:00
|
|
|
@media (max-width: ${Constants.sizes.mobile}px) {
|
2020-08-08 23:13:47 +03:00
|
|
|
display: none;
|
|
|
|
}
|
2020-04-09 00:29:13 +03:00
|
|
|
`;
|
|
|
|
|
|
|
|
const STYLES_ICON = css`
|
|
|
|
flex-shrink: 0;
|
|
|
|
position: relative;
|
|
|
|
`;
|
|
|
|
|
2020-08-08 23:13:47 +03:00
|
|
|
// NOTE(jim): Adjusts on mobile.
|
2020-04-09 00:29:13 +03:00
|
|
|
const STYLES_CHILDREN = css`
|
|
|
|
min-width: 10%;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
overflow-wrap: break-word;
|
|
|
|
padding: 11px 0px 14px 8px;
|
2020-09-05 00:37:50 +03:00
|
|
|
font-family: ${Constants.font.medium};
|
2020-09-10 06:28:48 +03:00
|
|
|
font-size: ${Constants.typescale.lvl1};
|
2020-04-09 00:29:13 +03:00
|
|
|
position: relative;
|
|
|
|
display: flex;
|
|
|
|
align-items: flex-start;
|
|
|
|
justify-content: flex-start;
|
2020-08-08 23:13:47 +03:00
|
|
|
|
2020-08-09 01:04:17 +03:00
|
|
|
@media (max-width: ${Constants.sizes.mobile}px) {
|
2020-08-08 23:13:47 +03:00
|
|
|
display: none;
|
|
|
|
}
|
2020-04-09 00:29:13 +03:00
|
|
|
`;
|
|
|
|
|
|
|
|
const STYLES_ICON_ELEMENT = css`
|
|
|
|
height: 40px;
|
|
|
|
width: 40px;
|
|
|
|
display: inline-flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
|
|
|
user-select: none;
|
|
|
|
|
|
|
|
svg {
|
|
|
|
transform: rotate(0deg);
|
|
|
|
transition: 200ms ease transform;
|
|
|
|
}
|
2020-08-08 23:13:47 +03:00
|
|
|
|
2020-08-09 01:04:17 +03:00
|
|
|
@media (max-width: ${Constants.sizes.mobile}px) {
|
2020-08-22 02:36:14 +03:00
|
|
|
margin: 0 8px 0 12px;
|
2020-08-08 23:13:47 +03:00
|
|
|
}
|
2020-04-09 00:29:13 +03:00
|
|
|
`;
|
|
|
|
|
2020-08-26 11:08:17 +03:00
|
|
|
const Item = (props) => {
|
2020-04-09 00:29:13 +03:00
|
|
|
return (
|
2020-08-18 22:28:33 +03:00
|
|
|
<span
|
|
|
|
css={STYLES_NAVIGATION_ITEM}
|
2020-08-26 11:08:17 +03:00
|
|
|
style={{ padding: `0 0 0 ${props.level * 16}px` }}
|
2020-08-18 22:28:33 +03:00
|
|
|
>
|
2020-08-26 11:08:17 +03:00
|
|
|
<span
|
|
|
|
css={STYLES_EXPANDER}
|
2020-08-27 07:27:50 +03:00
|
|
|
onMouseUp={props.onToggleShow ? props.onToggleShow : null}
|
|
|
|
onTouchEnd={props.onToggleShow ? props.onToggleShow : null}
|
2020-08-26 11:08:17 +03:00
|
|
|
>
|
2020-04-09 00:29:13 +03:00
|
|
|
<span
|
|
|
|
css={STYLES_ICON_ELEMENT}
|
|
|
|
style={{
|
2020-08-26 11:08:17 +03:00
|
|
|
color: props.activeIds[props.id] ? Constants.system.brand : null,
|
2020-08-18 22:28:33 +03:00
|
|
|
}}
|
|
|
|
>
|
2020-08-26 11:08:17 +03:00
|
|
|
{props.treeChildren && props.treeChildren.length ? (
|
2020-08-18 22:28:33 +03:00
|
|
|
<SVG.ExpandArrow
|
|
|
|
height="8px"
|
2020-08-26 11:08:17 +03:00
|
|
|
style={props.expanded ? { transform: `rotate(90deg)` } : null}
|
2020-08-18 22:28:33 +03:00
|
|
|
/>
|
2020-04-09 00:29:13 +03:00
|
|
|
) : null}
|
|
|
|
</span>
|
|
|
|
</span>
|
2020-08-26 11:08:17 +03:00
|
|
|
<span
|
|
|
|
css={STYLES_ICON}
|
2020-08-27 07:27:50 +03:00
|
|
|
onMouseUp={() => props.onNavigateTo({ id: props.id }, props.data)}
|
|
|
|
onTouchEnd={() => props.onNavigateTo({ id: props.id }, props.data)}
|
2020-08-26 11:08:17 +03:00
|
|
|
>
|
2020-04-09 00:29:13 +03:00
|
|
|
<span
|
|
|
|
css={STYLES_ICON_ELEMENT}
|
2020-08-26 11:08:17 +03:00
|
|
|
children={IconMap[props.decorator]}
|
2020-04-09 00:29:13 +03:00
|
|
|
style={{
|
2020-08-26 11:08:17 +03:00
|
|
|
color: props.activeIds[props.id] ? Constants.system.brand : null,
|
2020-08-18 22:28:33 +03:00
|
|
|
}}
|
2020-08-26 11:08:17 +03:00
|
|
|
/>
|
2020-04-09 00:29:13 +03:00
|
|
|
</span>
|
|
|
|
<span
|
|
|
|
css={STYLES_CHILDREN}
|
2020-08-26 11:08:17 +03:00
|
|
|
children={props.children}
|
2020-08-27 07:27:50 +03:00
|
|
|
onMouseUp={() => props.onNavigateTo({ id: props.id }, props.data)}
|
|
|
|
onTouchEnd={() => props.onNavigateTo({ id: props.id }, props.data)}
|
2020-04-09 00:29:13 +03:00
|
|
|
style={{
|
2020-08-26 11:08:17 +03:00
|
|
|
color: props.activeIds[props.id] ? Constants.system.brand : null,
|
2020-08-18 22:28:33 +03:00
|
|
|
}}
|
2020-08-26 11:08:17 +03:00
|
|
|
/>
|
2020-04-09 00:29:13 +03:00
|
|
|
</span>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
class NodeReference extends React.Component {
|
2020-08-26 11:08:17 +03:00
|
|
|
static defaultProps = {
|
|
|
|
treeChildren: [],
|
|
|
|
};
|
|
|
|
|
2020-04-09 00:29:13 +03:00
|
|
|
state = {
|
|
|
|
showTreeChildren: false,
|
|
|
|
};
|
|
|
|
|
|
|
|
_handleToggleShow = () => {
|
|
|
|
this.setState({ showTreeChildren: !this.state.showTreeChildren });
|
|
|
|
};
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<React.Fragment>
|
|
|
|
<Item
|
2020-08-26 11:08:17 +03:00
|
|
|
id={this.props.id}
|
|
|
|
data={this.props.data}
|
|
|
|
activeId={this.props.activeId}
|
|
|
|
activeIds={this.props.activeIds}
|
|
|
|
level={this.props.level}
|
|
|
|
treeChildren={this.props.treeChildren}
|
|
|
|
onNavigateTo={this.props.onNavigateTo}
|
|
|
|
decorator={this.props.decorator}
|
|
|
|
onToggleShow={this._handleToggleShow}
|
|
|
|
expanded={this.state.showTreeChildren}
|
|
|
|
children={this.props.children}
|
|
|
|
/>
|
2020-04-09 00:29:13 +03:00
|
|
|
|
2020-09-22 05:00:12 +03:00
|
|
|
{this.state.showTreeChildren && this.props.treeChildren
|
2020-08-26 11:08:17 +03:00
|
|
|
? this.props.treeChildren.map((child) => {
|
|
|
|
if (!child || child.ignore) {
|
2020-04-09 00:29:13 +03:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<NodeReference
|
2020-08-26 11:08:17 +03:00
|
|
|
key={child.id}
|
2020-04-09 00:29:13 +03:00
|
|
|
data={child}
|
|
|
|
id={child.id}
|
2020-08-26 11:08:17 +03:00
|
|
|
activeId={this.props.activeId}
|
|
|
|
activeIds={this.props.activeIds}
|
|
|
|
onNavigateTo={this.props.onNavigateTo}
|
|
|
|
level={this.props.level + 1}
|
2020-04-09 00:29:13 +03:00
|
|
|
treeChildren={child.children}
|
2020-08-18 22:28:33 +03:00
|
|
|
decorator={child.decorator}
|
2020-08-26 11:08:17 +03:00
|
|
|
children={child.name}
|
|
|
|
/>
|
2020-04-09 00:29:13 +03:00
|
|
|
);
|
|
|
|
})
|
|
|
|
: null}
|
|
|
|
</React.Fragment>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default class ApplicationNavigation extends React.Component {
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<nav css={STYLES_NAVIGATION}>
|
2020-09-02 04:09:39 +03:00
|
|
|
<ApplicationUserControls
|
|
|
|
viewer={this.props.viewer}
|
|
|
|
onNavigateTo={this.props.onNavigateTo}
|
|
|
|
onAction={this.props.onAction}
|
|
|
|
onSignOut={this.props.onSignOut}
|
|
|
|
/>
|
2020-08-26 13:03:39 +03:00
|
|
|
|
2020-04-09 00:29:13 +03:00
|
|
|
{this.props.navigation.map((each) => {
|
2020-08-26 11:08:17 +03:00
|
|
|
if (!each || each.ignore) {
|
2020-04-09 00:29:13 +03:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<NodeReference
|
|
|
|
data={each}
|
|
|
|
id={each.id}
|
|
|
|
acitveId={this.props.activeId}
|
|
|
|
activeIds={this.props.activeIds}
|
|
|
|
key={each.id}
|
|
|
|
level={0}
|
|
|
|
treeChildren={each.children}
|
2020-08-18 22:28:33 +03:00
|
|
|
decorator={each.decorator}
|
2020-08-26 11:08:17 +03:00
|
|
|
children={each.name}
|
2020-09-02 04:09:39 +03:00
|
|
|
onNavigateTo={this.props.onNavigateTo}
|
2020-08-26 11:08:17 +03:00
|
|
|
/>
|
2020-04-09 00:29:13 +03:00
|
|
|
);
|
|
|
|
})}
|
|
|
|
</nav>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|