From a0ca97d1aeb68a9f1576e00e2dee31ddcba31730 Mon Sep 17 00:00:00 2001 From: tomaszantas Date: Thu, 28 Apr 2022 11:19:49 +0200 Subject: [PATCH 1/4] Set up the Mining dashboard layout --- .../launchpad_v2/src/components/Box/index.tsx | 14 +++++- .../launchpad_v2/src/components/Box/types.ts | 1 + .../src/components/NodeBox/NodeBox.test.tsx | 19 ++++++++ .../src/components/NodeBox/index.tsx | 29 +++++++++++ .../src/components/NodeBox/styles.ts | 3 ++ .../src/components/NodeBox/types.ts | 6 +++ .../src/components/Switch/styles.ts | 10 +++- .../Dashboard/DashboardContainer/index.tsx | 13 ++++- .../Dashboard/DashboardContainer/styles.ts | 3 +- .../MiningContainer/MiningBoxMerged/index.tsx | 7 +++ .../MiningContainer/MiningBoxTari/index.tsx | 7 +++ .../MiningContainer/MiningHeaderTip/index.tsx | 25 ++++++++++ .../MiningContainer/MiningHeaderTip/styles.ts | 7 +++ .../MiningViewActions/index.tsx | 26 ++++++++++ .../src/containers/MiningContainer/index.tsx | 48 +++++++++++++------ .../src/containers/MiningContainer/styles.ts | 16 +++++++ .../src/layouts/MainLayout/index.tsx | 4 +- .../launchpad_v2/src/locales/mining.ts | 9 ++++ 18 files changed, 224 insertions(+), 23 deletions(-) create mode 100644 applications/launchpad_v2/src/components/NodeBox/NodeBox.test.tsx create mode 100644 applications/launchpad_v2/src/components/NodeBox/index.tsx create mode 100644 applications/launchpad_v2/src/components/NodeBox/styles.ts create mode 100644 applications/launchpad_v2/src/components/NodeBox/types.ts create mode 100644 applications/launchpad_v2/src/containers/MiningContainer/MiningBoxMerged/index.tsx create mode 100644 applications/launchpad_v2/src/containers/MiningContainer/MiningBoxTari/index.tsx create mode 100644 applications/launchpad_v2/src/containers/MiningContainer/MiningHeaderTip/index.tsx create mode 100644 applications/launchpad_v2/src/containers/MiningContainer/MiningHeaderTip/styles.ts create mode 100644 applications/launchpad_v2/src/containers/MiningContainer/MiningViewActions/index.tsx create mode 100644 applications/launchpad_v2/src/containers/MiningContainer/styles.ts diff --git a/applications/launchpad_v2/src/components/Box/index.tsx b/applications/launchpad_v2/src/components/Box/index.tsx index 512e4b7c5a..3692d53686 100644 --- a/applications/launchpad_v2/src/components/Box/index.tsx +++ b/applications/launchpad_v2/src/components/Box/index.tsx @@ -15,7 +15,13 @@ import { BoxProps } from './types' * @prop {string} end - color on gradient end * @prop {number} rotation - gradient rotation in degress (45 by default) */ -const Box = ({ children, gradient, border, style: inlineStyle }: BoxProps) => { +const Box = ({ + children, + gradient, + border, + style: inlineStyle, + testId = 'box-cmp', +}: BoxProps) => { const style = { border: border === false ? 'none' : undefined, background: @@ -29,7 +35,11 @@ const Box = ({ children, gradient, border, style: inlineStyle }: BoxProps) => { ...inlineStyle, } - return {children} + return ( + + {children} + + ) } export default Box diff --git a/applications/launchpad_v2/src/components/Box/types.ts b/applications/launchpad_v2/src/components/Box/types.ts index 55cb5aedbf..97256051ee 100644 --- a/applications/launchpad_v2/src/components/Box/types.ts +++ b/applications/launchpad_v2/src/components/Box/types.ts @@ -11,4 +11,5 @@ export type BoxProps = { border?: boolean style?: CSSProperties gradient?: Gradient + testId?: string } diff --git a/applications/launchpad_v2/src/components/NodeBox/NodeBox.test.tsx b/applications/launchpad_v2/src/components/NodeBox/NodeBox.test.tsx new file mode 100644 index 0000000000..c340e32f69 --- /dev/null +++ b/applications/launchpad_v2/src/components/NodeBox/NodeBox.test.tsx @@ -0,0 +1,19 @@ +import { render, screen } from '@testing-library/react' +import { ThemeProvider } from 'styled-components' + +import themes from '../../styles/themes' + +import NodeBox from '.' + +describe('NodeBox', () => { + it('should render without crashing', async () => { + render( + + + , + ) + + const el = screen.getByTestId('node-box-cmp') + expect(el).toBeInTheDocument() + }) +}) diff --git a/applications/launchpad_v2/src/components/NodeBox/index.tsx b/applications/launchpad_v2/src/components/NodeBox/index.tsx new file mode 100644 index 0000000000..be109bdfd1 --- /dev/null +++ b/applications/launchpad_v2/src/components/NodeBox/index.tsx @@ -0,0 +1,29 @@ +import Box from '../Box' +import Text from '../Text' + +import { NodeBoxProps } from './types' + +/** + * The advanced Box component handling: + * - custom title + * - header tag + * - background depending on the status prop + * + * Used as a UI representation of the Node (aka. Docker container). + * + * @param {string} [title] - the box heading + * @param {NodeBoxStatusType} [status = 'inactive'] - the status of the box/node + * + * @example + * TODO + */ +const NodeBox = ({ title, status = 'inactive' }: NodeBoxProps) => { + return ( + + {title ? {title} : null} +

The box {status}

+
+ ) +} + +export default NodeBox diff --git a/applications/launchpad_v2/src/components/NodeBox/styles.ts b/applications/launchpad_v2/src/components/NodeBox/styles.ts new file mode 100644 index 0000000000..5693fdc1fa --- /dev/null +++ b/applications/launchpad_v2/src/components/NodeBox/styles.ts @@ -0,0 +1,3 @@ +import styled from 'styled-components' + +export const StyledBox = styled.div`` diff --git a/applications/launchpad_v2/src/components/NodeBox/types.ts b/applications/launchpad_v2/src/components/NodeBox/types.ts new file mode 100644 index 0000000000..a9b3c8a0b9 --- /dev/null +++ b/applications/launchpad_v2/src/components/NodeBox/types.ts @@ -0,0 +1,6 @@ +export type NodeBoxStatusType = 'inactive' | 'active' + +export interface NodeBoxProps { + title?: string + status?: NodeBoxStatusType +} diff --git a/applications/launchpad_v2/src/components/Switch/styles.ts b/applications/launchpad_v2/src/components/Switch/styles.ts index c2b49dd338..962e5f0c17 100644 --- a/applications/launchpad_v2/src/components/Switch/styles.ts +++ b/applications/launchpad_v2/src/components/Switch/styles.ts @@ -11,12 +11,15 @@ export const SwitchContainer = styled.label` export const SwitchController = styled(animated.div)` height: 14px; width: 24px; - border: 1.5px solid ${colors.dark.primary}; + border: 1px solid ${colors.dark.primary}; border-radius: 6px; position: relative; box-sizing: border-box; box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.08); cursor: pointer; + -webkit-box-shadow: 0px 0px 2px -1px ${colors.dark.primary}; + -moz-box-shadow: 0px 0px 2px -1px ${colors.dark.primary}; + box-shadow: 0px 0px 2px -1px ${colors.dark.primary}; ` export const SwitchCircle = styled(animated.div)` @@ -28,7 +31,10 @@ export const SwitchCircle = styled(animated.div)` border-radius: 6px; box-sizing: border-box; background: #fff; - border: 1.5px solid ${colors.dark.primary}; + border: 1px solid ${colors.dark.primary}; + -webkit-box-shadow: 0px 0px 2px -1px ${colors.dark.primary}; + -moz-box-shadow: 0px 0px 2px -1px ${colors.dark.primary}; + box-shadow: 0px 0px 2px -1px ${colors.dark.primary}; ` export const LabelText = styled(animated.span)` diff --git a/applications/launchpad_v2/src/containers/Dashboard/DashboardContainer/index.tsx b/applications/launchpad_v2/src/containers/Dashboard/DashboardContainer/index.tsx index 6bb44c896c..9aeb99a2f3 100644 --- a/applications/launchpad_v2/src/containers/Dashboard/DashboardContainer/index.tsx +++ b/applications/launchpad_v2/src/containers/Dashboard/DashboardContainer/index.tsx @@ -1,4 +1,6 @@ import { useSelector } from 'react-redux' +import { CSSProperties } from 'styled-components' +import { SpringValue } from 'react-spring' import { DashboardContent, DashboardLayout } from './styles' @@ -14,7 +16,14 @@ import { selectView } from '../../../store/app/selectors' /** * Dashboard view containing three main tabs: Mining, Wallet and BaseNode */ -const DashboardContainer = () => { +const DashboardContainer = ({ + style, +}: { + style?: + | CSSProperties + | Record> + | Record> +}) => { const currentPage = useSelector(selectView) const renderPage = () => { @@ -31,7 +40,7 @@ const DashboardContainer = () => { } return ( - + {renderPage()} diff --git a/applications/launchpad_v2/src/containers/Dashboard/DashboardContainer/styles.ts b/applications/launchpad_v2/src/containers/Dashboard/DashboardContainer/styles.ts index e4d0f67971..91e387b47f 100644 --- a/applications/launchpad_v2/src/containers/Dashboard/DashboardContainer/styles.ts +++ b/applications/launchpad_v2/src/containers/Dashboard/DashboardContainer/styles.ts @@ -1,6 +1,7 @@ +import { animated } from 'react-spring' import styled from 'styled-components' -export const DashboardLayout = styled.div` +export const DashboardLayout = styled(animated.div)` display: flex; flex-direction: column; height: 100%; diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxMerged/index.tsx b/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxMerged/index.tsx new file mode 100644 index 0000000000..cb1ce1a81d --- /dev/null +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxMerged/index.tsx @@ -0,0 +1,7 @@ +import NodeBox from '../../../components/NodeBox' + +const MiningBoxMerged = () => { + return +} + +export default MiningBoxMerged diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxTari/index.tsx b/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxTari/index.tsx new file mode 100644 index 0000000000..f29b3263f3 --- /dev/null +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxTari/index.tsx @@ -0,0 +1,7 @@ +import NodeBox from '../../../components/NodeBox' + +const MiningBoxTari = () => { + return +} + +export default MiningBoxTari diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningHeaderTip/index.tsx b/applications/launchpad_v2/src/containers/MiningContainer/MiningHeaderTip/index.tsx new file mode 100644 index 0000000000..0b47648197 --- /dev/null +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningHeaderTip/index.tsx @@ -0,0 +1,25 @@ +import t from '../../../locales' + +import Button from '../../../components/Button' +import Text from '../../../components/Text' + +import SvgStar from '../../../styles/Icons/Star' +import SvgInfo1 from '../../../styles/Icons/Info1' +import { StyledMiningHeaderTip } from './styles' + +/** + * @TODO - draft - add other states + */ +const MiningHeaderTip = () => { + return ( + + + {t.mining.headerTips.oneStepAway} + + + ) +} + +export default MiningHeaderTip diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningHeaderTip/styles.ts b/applications/launchpad_v2/src/containers/MiningContainer/MiningHeaderTip/styles.ts new file mode 100644 index 0000000000..16ca77e707 --- /dev/null +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningHeaderTip/styles.ts @@ -0,0 +1,7 @@ +import styled from 'styled-components' + +export const StyledMiningHeaderTip = styled.div` + display: flex; + margin-top: ${({ theme }) => theme.spacingVertical(3)}; + margin-bottom: ${({ theme }) => theme.spacingVertical(2.392)}; +` diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningViewActions/index.tsx b/applications/launchpad_v2/src/containers/MiningContainer/MiningViewActions/index.tsx new file mode 100644 index 0000000000..06dbbc944c --- /dev/null +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningViewActions/index.tsx @@ -0,0 +1,26 @@ +import Button from '../../../components/Button' +import t from '../../../locales' +import SvgChart from '../../../styles/Icons/Chart' +import SvgClock from '../../../styles/Icons/Clock' +import SvgSetting2 from '../../../styles/Icons/Setting2' + +/** + * Renders set of links/actions in Mining dashboard + */ +const MiningViewActions = () => { + return ( +
+ + + +
+ ) +} + +export default MiningViewActions diff --git a/applications/launchpad_v2/src/containers/MiningContainer/index.tsx b/applications/launchpad_v2/src/containers/MiningContainer/index.tsx index c5842a5189..9bd5b43263 100644 --- a/applications/launchpad_v2/src/containers/MiningContainer/index.tsx +++ b/applications/launchpad_v2/src/containers/MiningContainer/index.tsx @@ -5,32 +5,50 @@ import Text from '../../components/Text' import SvgSun from '../../styles/Icons/Sun' import SvgMoon from '../../styles/Icons/Moon' +import MiningHeaderTip from './MiningHeaderTip' +import MiningViewActions from './MiningViewActions' + import { setTheme } from '../../store/app' import { selectTheme } from '../../store/app/selectors' +import { NodesContainer } from './styles' +import MiningBoxTari from './MiningBoxTari' +import MiningBoxMerged from './MiningBoxMerged' + /** - * @TODO move user-facing text to i18n file when implementing + * The Mining dashboard */ - const MiningContainer = () => { const dispatch = useDispatch() const currentTheme = useSelector(selectTheme) return (
-

Mining

- - -
- Select theme - } - rightLabel={} - value={currentTheme === 'dark'} - onClick={v => dispatch(setTheme(v ? 'dark' : 'light'))} - /> + + + + + + + + + +
+ + +
+ Select theme + } + rightLabel={} + value={currentTheme === 'dark'} + onClick={v => dispatch(setTheme(v ? 'dark' : 'light'))} + /> +
) diff --git a/applications/launchpad_v2/src/containers/MiningContainer/styles.ts b/applications/launchpad_v2/src/containers/MiningContainer/styles.ts new file mode 100644 index 0000000000..f5dd8d3edf --- /dev/null +++ b/applications/launchpad_v2/src/containers/MiningContainer/styles.ts @@ -0,0 +1,16 @@ +import styled from 'styled-components' + +export const NodesContainer = styled.div` + display: flex; + flex-wrap: wrap; + + & > div { + margin: ${({ theme }) => theme.spacing(0.34)}; + } + & > div:first-child { + margin-left: 0; + } + & > div:last-child { + margin-right: 0; + } +` diff --git a/applications/launchpad_v2/src/layouts/MainLayout/index.tsx b/applications/launchpad_v2/src/layouts/MainLayout/index.tsx index e664bac6a3..387c1384a6 100644 --- a/applications/launchpad_v2/src/layouts/MainLayout/index.tsx +++ b/applications/launchpad_v2/src/layouts/MainLayout/index.tsx @@ -59,6 +59,8 @@ const MainLayout = ({ drawerViewWidth = '50%' }: MainLayoutProps) => { */ const mainContainerStyle = useSpring({ width: expertView === 'open' ? invertedExpertViewSize : '100%', + }) + const dashboardContainerStyle = useSpring({ paddingLeft: expertView === 'open' || tightSpace ? 40 : 100, paddingRight: expertView === 'open' || tightSpace ? 40 : 100, }) @@ -83,7 +85,7 @@ const MainLayout = ({ drawerViewWidth = '50%' }: MainLayoutProps) => { ...mainContainerStyle, }} > - + {/* Background overlay: */} diff --git a/applications/launchpad_v2/src/locales/mining.ts b/applications/launchpad_v2/src/locales/mining.ts index 8a44a1d3dd..8dc6df1392 100644 --- a/applications/launchpad_v2/src/locales/mining.ts +++ b/applications/launchpad_v2/src/locales/mining.ts @@ -1,5 +1,14 @@ const translations = { set_up_mining_hours: 'Set up mining hours', + headerTips: { + oneStepAway: 'You are one step away from staring mining.', + wantToKnowMore: 'Want to know more', + }, + viewActions: { + setUpMiningHours: 'Set up mining hours', + miningSettings: 'Mining settings', + statistics: 'Statistics', + }, } export default translations From 00993ae4c372524d3426f8d16caf2b2a641c5b34 Mon Sep 17 00:00:00 2001 From: tomaszantas Date: Thu, 28 Apr 2022 18:14:04 +0200 Subject: [PATCH 2/4] Add handling mining node states --- .../src/components/NodeBox/index.tsx | 19 ++- .../src/components/NodeBox/styles.ts | 9 +- .../src/components/NodeBox/types.ts | 9 +- .../MiningContainer/MiningBox/index.tsx | 151 ++++++++++++++++++ .../MiningContainer/MiningBox/types.ts | 16 ++ .../MiningContainer/MiningBoxMerged/index.tsx | 13 +- .../MiningContainer/MiningBoxTari/index.tsx | 64 +++++++- .../src/containers/MiningContainer/index.tsx | 14 +- applications/launchpad_v2/src/store/index.ts | 4 +- .../launchpad_v2/src/store/mining/index.ts | 66 ++++++++ .../src/store/mining/selectors.ts | 12 ++ .../launchpad_v2/src/store/mining/thunks.ts | 28 ++++ .../launchpad_v2/src/store/mining/types.ts | 34 ++++ 13 files changed, 428 insertions(+), 11 deletions(-) create mode 100644 applications/launchpad_v2/src/containers/MiningContainer/MiningBox/index.tsx create mode 100644 applications/launchpad_v2/src/containers/MiningContainer/MiningBox/types.ts create mode 100644 applications/launchpad_v2/src/store/mining/index.ts create mode 100644 applications/launchpad_v2/src/store/mining/selectors.ts create mode 100644 applications/launchpad_v2/src/store/mining/thunks.ts create mode 100644 applications/launchpad_v2/src/store/mining/types.ts diff --git a/applications/launchpad_v2/src/components/NodeBox/index.tsx b/applications/launchpad_v2/src/components/NodeBox/index.tsx index be109bdfd1..c6a594ec45 100644 --- a/applications/launchpad_v2/src/components/NodeBox/index.tsx +++ b/applications/launchpad_v2/src/components/NodeBox/index.tsx @@ -1,6 +1,8 @@ import Box from '../Box' +import Tag from '../Tag' import Text from '../Text' +import { BoxHeader, BoxContent } from './styles' import { NodeBoxProps } from './types' /** @@ -17,11 +19,22 @@ import { NodeBoxProps } from './types' * @example * TODO */ -const NodeBox = ({ title, status = 'inactive' }: NodeBoxProps) => { +const NodeBox = ({ title, tag, children }: NodeBoxProps) => { return ( - {title ? {title} : null} -

The box {status}

+ + {tag ? ( + + {tag.text} + + ) : null} + + {title ? ( + + {title} + + ) : null} + {children}
) } diff --git a/applications/launchpad_v2/src/components/NodeBox/styles.ts b/applications/launchpad_v2/src/components/NodeBox/styles.ts index 5693fdc1fa..b0cff1eb5d 100644 --- a/applications/launchpad_v2/src/components/NodeBox/styles.ts +++ b/applications/launchpad_v2/src/components/NodeBox/styles.ts @@ -1,3 +1,10 @@ import styled from 'styled-components' -export const StyledBox = styled.div`` +export const BoxHeader = styled.div` + height: 36px; +` + +export const BoxContent = styled.div` + padding-top: ${({ theme }) => theme.spacingVertical(1)}; + padding-bottom: ${({ theme }) => theme.spacingVertical(1)}; +` diff --git a/applications/launchpad_v2/src/components/NodeBox/types.ts b/applications/launchpad_v2/src/components/NodeBox/types.ts index a9b3c8a0b9..d57d64e116 100644 --- a/applications/launchpad_v2/src/components/NodeBox/types.ts +++ b/applications/launchpad_v2/src/components/NodeBox/types.ts @@ -1,6 +1,11 @@ -export type NodeBoxStatusType = 'inactive' | 'active' +import { ReactNode } from 'react' +import { TagType } from '../Tag/types' export interface NodeBoxProps { title?: string - status?: NodeBoxStatusType + tag?: { + text: string + type?: TagType + } + children?: ReactNode } diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/index.tsx b/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/index.tsx new file mode 100644 index 0000000000..41e080c10b --- /dev/null +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/index.tsx @@ -0,0 +1,151 @@ +import NodeBox from '../../../components/NodeBox' +import Text from '../../../components/Text' +import { TagType } from '../../../components/Tag/types' +import { useAppDispatch, useAppSelector } from '../../../store/hooks' +import { selectMiningNode } from '../../../store/mining/selectors' +import { actions } from '../../../store/mining' +import { + MiningNodesStatus, + MiningNodeStates, +} from '../../../store/mining/types' + +import { MiningBoxProps } from './types' + +interface Config { + tag?: { + text: string + type?: TagType + } +} + +const MiningBox = ({ node, children }: MiningBoxProps) => { + const dispatch = useAppDispatch() + + const nodeState: MiningNodeStates = useAppSelector(state => + selectMiningNode(state, node), + ) + + const defaultConfig = { + title: `${node.substring(0, 1).toUpperCase() + node.substring(1)} Mining`, + } + + const defaultStates: Partial<{ + [key in keyof typeof MiningNodesStatus]: Config + }> = { + UNKNOWN: {}, + SETUP_REQUIRED: { + tag: { + text: 'Start here', + }, + }, + ERROR: { + tag: { + text: 'Problem', + type: 'warning', + }, + }, + } + + const currentState = { + ...defaultConfig, + ...defaultStates[nodeState.status], + } + + const componentForCurrentStatus = () => { + if (children) { + return children + } + + switch (nodeState.status) { + case 'UNKNOWN': + return ( +
+ Unknown + +
+ ) + case 'SETUP_REQUIRED': + return ( +
+ Setup required + +
+ ) + case 'ERROR': + return ( +
+ Error + +
+ ) + case 'PAUSED': + return ( +
+ Paused + +
+ ) + case 'RUNNING': + return ( +
+ Running + +
+ ) + } + } + + console.log('MINING BOX a', node, nodeState.status) + + const content = componentForCurrentStatus() + + return ( + + {content} + {nodeState.pending ? Pending... : null} + + ) +} + +export default MiningBox diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/types.ts b/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/types.ts new file mode 100644 index 0000000000..cf60a0faa4 --- /dev/null +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/types.ts @@ -0,0 +1,16 @@ +import { ReactNode } from 'react' +import { TagType } from '../../../components/Tag/types' +import { MiningNodesStatus, NodeType } from '../../../store/mining/types' + +export interface NodeBoxStatusConfig { + tag: { + text: string + type: TagType + } +} + +export interface MiningBoxProps { + node: NodeType + statuses?: Record + children?: ReactNode +} diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxMerged/index.tsx b/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxMerged/index.tsx index cb1ce1a81d..ac17e245ec 100644 --- a/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxMerged/index.tsx +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxMerged/index.tsx @@ -1,7 +1,18 @@ +import Button from '../../../components/Button' import NodeBox from '../../../components/NodeBox' +import { useAppDispatch, useAppSelector } from '../../../store/hooks' + +import { actions as miningActions } from '../../../store/mining' +import { selectMiningNode } from '../../../store/mining/selectors' +import MiningBox from '../MiningBox' + const MiningBoxMerged = () => { - return + // const dispatch = useAppDispatch() + // const miningState = useAppSelector(state => selectMiningNode(state, 'merged')) + console.log('MERGED ----') + + return } export default MiningBoxMerged diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxTari/index.tsx b/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxTari/index.tsx index f29b3263f3..535173727b 100644 --- a/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxTari/index.tsx +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxTari/index.tsx @@ -1,7 +1,69 @@ +import Button from '../../../components/Button' import NodeBox from '../../../components/NodeBox' +import { useAppDispatch, useAppSelector } from '../../../store/hooks' + +import { actions as miningActions } from '../../../store/mining' +import { selectMiningNode } from '../../../store/mining/selectors' +import { MiningNodeState } from '../../../store/mining/types' +import { selectState as selectWalletState } from '../../../store/wallet/selectors' +import MiningBox from '../MiningBox' + const MiningBoxTari = () => { - return + // const dispatch = useAppDispatch() + const miningState = useAppSelector(state => selectMiningNode(state, 'tari')) + const walletState = useAppSelector(selectWalletState) + console.log('TARI ----') + + /* 3-4 states here + 1. Disabled - missing wallet (or wallet has not been configured) - this is pretty much custom, sometimes it depends on many reasons + 2. Inactive 1 - nothing mined + 3. Inactive 2 - paused - running false, but something has been already mined + 4. Active - running + */ + + const defaultProps = { + title: 'Tari mining', + chains: ['XTR'], + style: { + box: { + background: '#fff', + color: '#222', + }, + }, + } + + const statusesConfig = { + configure: { + tag: { + text: 'Start here', + type: 'default', + }, + }, + paused: {}, + running: { + style: { + box: { + background: 'red', + color: '#fff', + }, + }, + }, + } + + const evaluateStatus = () => { + if (walletState.address && walletState.address.length > 1) { + return 'configure' + } + + if (miningState.running) { + return 'running' + } + + return 'paused' + } + + return } export default MiningBoxTari diff --git a/applications/launchpad_v2/src/containers/MiningContainer/index.tsx b/applications/launchpad_v2/src/containers/MiningContainer/index.tsx index 9bd5b43263..f4feb8b303 100644 --- a/applications/launchpad_v2/src/containers/MiningContainer/index.tsx +++ b/applications/launchpad_v2/src/containers/MiningContainer/index.tsx @@ -1,4 +1,4 @@ -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' import Switch from '../../components/Switch' import Text from '../../components/Text' @@ -14,12 +14,14 @@ import { selectTheme } from '../../store/app/selectors' import { NodesContainer } from './styles' import MiningBoxTari from './MiningBoxTari' import MiningBoxMerged from './MiningBoxMerged' +import { actions } from '../../store/wallet' +import { useAppDispatch } from '../../store/hooks' /** * The Mining dashboard */ const MiningContainer = () => { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const currentTheme = useSelector(selectTheme) return ( @@ -33,6 +35,14 @@ const MiningContainer = () => { + + + +
-
+ + {t.mining.placeholders.statusUnknown} + ) case 'SETUP_REQUIRED': return ( -
- Setup required - -
+ + {t.mining.placeholders.statusSetupRequired} + + ) + case 'BLOCKED': + return ( + + {t.mining.placeholders.statusBlocked} + ) case 'ERROR': return ( -
- Error - -
+ + {t.mining.placeholders.statusError} + ) case 'PAUSED': return ( -
- Paused - -
+ {t.mining.actions.startMining} + + ) case 'RUNNING': return ( -
- Running - -
+ {t.common.verbs.pause} + + ) } } - console.log('MINING BOX a', node, nodeState.status) - const content = componentForCurrentStatus() return ( - + {content} - {nodeState.pending ? Pending... : null} ) } diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/styles.ts b/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/styles.ts new file mode 100644 index 0000000000..47d468b12a --- /dev/null +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/styles.ts @@ -0,0 +1,9 @@ +import styled from 'styled-components' + +export const MiningBoxContent = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: space-between; + flex: 1; +` diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/types.ts b/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/types.ts index cf60a0faa4..d3e05d4209 100644 --- a/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/types.ts +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/types.ts @@ -1,6 +1,7 @@ import { ReactNode } from 'react' import { TagType } from '../../../components/Tag/types' -import { MiningNodesStatus, NodeType } from '../../../store/mining/types' +import { MiningNodesStatus } from '../../../store/mining/types' +import { MiningNodeType } from '../../../types/general' export interface NodeBoxStatusConfig { tag: { @@ -10,7 +11,7 @@ export interface NodeBoxStatusConfig { } export interface MiningBoxProps { - node: NodeType + node: MiningNodeType statuses?: Record children?: ReactNode } diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxMerged/index.tsx b/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxMerged/index.tsx index ac17e245ec..3aba2da3a6 100644 --- a/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxMerged/index.tsx +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxMerged/index.tsx @@ -1,17 +1,6 @@ -import Button from '../../../components/Button' -import NodeBox from '../../../components/NodeBox' - -import { useAppDispatch, useAppSelector } from '../../../store/hooks' - -import { actions as miningActions } from '../../../store/mining' -import { selectMiningNode } from '../../../store/mining/selectors' import MiningBox from '../MiningBox' const MiningBoxMerged = () => { - // const dispatch = useAppDispatch() - // const miningState = useAppSelector(state => selectMiningNode(state, 'merged')) - console.log('MERGED ----') - return } diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxTari/index.tsx b/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxTari/index.tsx index 535173727b..b2b89fcd08 100644 --- a/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxTari/index.tsx +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningBoxTari/index.tsx @@ -1,68 +1,6 @@ -import Button from '../../../components/Button' -import NodeBox from '../../../components/NodeBox' - -import { useAppDispatch, useAppSelector } from '../../../store/hooks' - -import { actions as miningActions } from '../../../store/mining' -import { selectMiningNode } from '../../../store/mining/selectors' -import { MiningNodeState } from '../../../store/mining/types' -import { selectState as selectWalletState } from '../../../store/wallet/selectors' import MiningBox from '../MiningBox' const MiningBoxTari = () => { - // const dispatch = useAppDispatch() - const miningState = useAppSelector(state => selectMiningNode(state, 'tari')) - const walletState = useAppSelector(selectWalletState) - console.log('TARI ----') - - /* 3-4 states here - 1. Disabled - missing wallet (or wallet has not been configured) - this is pretty much custom, sometimes it depends on many reasons - 2. Inactive 1 - nothing mined - 3. Inactive 2 - paused - running false, but something has been already mined - 4. Active - running - */ - - const defaultProps = { - title: 'Tari mining', - chains: ['XTR'], - style: { - box: { - background: '#fff', - color: '#222', - }, - }, - } - - const statusesConfig = { - configure: { - tag: { - text: 'Start here', - type: 'default', - }, - }, - paused: {}, - running: { - style: { - box: { - background: 'red', - color: '#fff', - }, - }, - }, - } - - const evaluateStatus = () => { - if (walletState.address && walletState.address.length > 1) { - return 'configure' - } - - if (miningState.running) { - return 'running' - } - - return 'paused' - } - return } diff --git a/applications/launchpad_v2/src/custom.d.ts b/applications/launchpad_v2/src/custom.d.ts index 77e2acb07f..63ef126e1f 100644 --- a/applications/launchpad_v2/src/custom.d.ts +++ b/applications/launchpad_v2/src/custom.d.ts @@ -43,6 +43,8 @@ declare module 'styled-components' { warningText: string expert: string expertText: string + lightTag: string + lightTagText: string placeholderText: string inverted: { @@ -65,6 +67,8 @@ declare module 'styled-components' { warningText: string expert: string expertText: string + lightTag: string + lightTagText: string } } } diff --git a/applications/launchpad_v2/src/locales/common.ts b/applications/launchpad_v2/src/locales/common.ts index fbb7673d4b..20294c704d 100644 --- a/applications/launchpad_v2/src/locales/common.ts +++ b/applications/launchpad_v2/src/locales/common.ts @@ -3,16 +3,23 @@ const translations = { accept: 'Accept', cancel: 'Cancel', stop: 'Stop', + pause: 'Pause', continue: 'Continue', }, nouns: { baseNode: 'Base Node', mining: 'Mining', + problem: 'Problem', settings: 'Settings', wallet: 'Wallet', }, adjectives: { running: 'Running', + paused: 'Paused', + }, + pharses: { + actionRequired: 'Action required', + startHere: 'Start here', }, } diff --git a/applications/launchpad_v2/src/locales/mining.ts b/applications/launchpad_v2/src/locales/mining.ts index 8dc6df1392..e34f6dc7bb 100644 --- a/applications/launchpad_v2/src/locales/mining.ts +++ b/applications/launchpad_v2/src/locales/mining.ts @@ -1,14 +1,24 @@ const translations = { set_up_mining_hours: 'Set up mining hours', + minedInLastSession: 'mined in last session', headerTips: { oneStepAway: 'You are one step away from staring mining.', wantToKnowMore: 'Want to know more', }, + actions: { + startMining: 'Start mining', + }, viewActions: { setUpMiningHours: 'Set up mining hours', miningSettings: 'Mining settings', statistics: 'Statistics', }, + placeholders: { + statusUnknown: 'The node status is unknown.', + statusBlocked: 'The node cannot be started.', + statusSetupRequired: 'The node requires further configuration.', + statusError: 'The node failed.', + }, } export default translations diff --git a/applications/launchpad_v2/src/store/mining/index.ts b/applications/launchpad_v2/src/store/mining/index.ts index 76e0e2a71e..edcf705d8e 100644 --- a/applications/launchpad_v2/src/store/mining/index.ts +++ b/applications/launchpad_v2/src/store/mining/index.ts @@ -1,16 +1,43 @@ import { createSlice } from '@reduxjs/toolkit' +import { MiningNodeType } from '../../types/general' import { startMiningNode, stopMiningNode } from './thunks' -import { MiningNodesStatus, MiningState, NodeType } from './types' +import { MiningNodesStatus, MiningState } from './types' export const initialState: MiningState = { tari: { pending: false, - status: MiningNodesStatus.UNKNOWN, + status: MiningNodesStatus.PAUSED, + sessions: [ + { + total: { + xtr: '1000', + }, + }, + { + total: { + xtr: '2000', + }, + }, + ], }, merged: { pending: false, - status: MiningNodesStatus.RUNNING, + status: MiningNodesStatus.PAUSED, + sessions: [ + { + total: { + xtr: '1000', + xmr: '1001', + }, + }, + { + total: { + xtr: '2000', + xmr: '2001', + }, + }, + ], }, } @@ -20,7 +47,9 @@ const miningSlice = createSlice({ reducers: { setNodeStatus( state, - { payload }: { payload: { node: NodeType; status: MiningNodesStatus } }, + { + payload, + }: { payload: { node: MiningNodeType; status: MiningNodesStatus } }, ) { state[payload.node].status = payload.status }, diff --git a/applications/launchpad_v2/src/store/mining/selectors.ts b/applications/launchpad_v2/src/store/mining/selectors.ts index 8433a5e996..d81af79ced 100644 --- a/applications/launchpad_v2/src/store/mining/selectors.ts +++ b/applications/launchpad_v2/src/store/mining/selectors.ts @@ -1,5 +1,5 @@ import { createSelector } from '@reduxjs/toolkit' -import { NodeType } from './types' +import { MiningNodeType } from '../../types/general' /** * Get Redux state of the given mining node @@ -7,6 +7,17 @@ import { NodeType } from './types' * const miningState = useAppSelector(state => selectMiningNode(state, 'merged')) */ export const selectMiningNode = createSelector( - [state => state.mining, (_, node: NodeType) => node], + [state => state.mining, (_, node: MiningNodeType) => node], (miningState, node) => miningState[node], ) + +/** + * Get stats for last/current session + */ +export const selectLastSession = createSelector( + [state => state.mining, (_, node: MiningNodeType) => node], + (miningState, node) => + miningState[node].sessions && miningState[node].sessions.length > 0 + ? miningState[node].sessions[miningState[node].sessions.length - 1] + : undefined, +) diff --git a/applications/launchpad_v2/src/store/mining/thunks.ts b/applications/launchpad_v2/src/store/mining/thunks.ts index f5de7e5b56..3142ae371a 100644 --- a/applications/launchpad_v2/src/store/mining/thunks.ts +++ b/applications/launchpad_v2/src/store/mining/thunks.ts @@ -1,12 +1,12 @@ import { createAsyncThunk } from '@reduxjs/toolkit' -import { NodeType } from './types' +import { MiningNodeType } from '../../types/general' /** * Start given mining node * @prop {NodeType} node - the node name, ie. 'tari', 'merged' * @returns {Promise} */ -export const startMiningNode = createAsyncThunk( +export const startMiningNode = createAsyncThunk( 'mining/startNode', async ({ node }) => { console.log(`starting ${node} node`) @@ -19,7 +19,7 @@ export const startMiningNode = createAsyncThunk( * @prop {NodeType} node - the node name, ie. 'tari', 'merged' * @returns {Promise} */ -export const stopMiningNode = createAsyncThunk( +export const stopMiningNode = createAsyncThunk( 'mining/stopNode', async ({ node }) => { console.log(`stopping ${node} node`) diff --git a/applications/launchpad_v2/src/store/mining/types.ts b/applications/launchpad_v2/src/store/mining/types.ts index 0d85ef47e7..650721a866 100644 --- a/applications/launchpad_v2/src/store/mining/types.ts +++ b/applications/launchpad_v2/src/store/mining/types.ts @@ -1,30 +1,53 @@ -export type NodeType = 'tari' | 'merged' - +/** + * @TODO - the list of possible statuses may change. + * If so, then MiningBox and Mining Container may need to be changed as well. + * UNKNOWN - the status of the container/node is unknown, ie. on app launch it can be default status + * SETUP_REQUIRED - node/container cannot be run because of missing configuration (merge with BLOCKED?) + * BLOCKED - node/container cannot be run because some requirement is not satisfied, ie. mining node needs base node running + * PAUSED - node/container is not running. NOTE: node and container are not necessary the same. Ie. Docker container can be live, but process running inside the container can be stopped. So maybe we should split this also into PAUSED and STOPPED? + * RUNNING - node/container is running and healthy + * ERROR - node/container is failed + */ export enum MiningNodesStatus { 'UNKNOWN' = 'UNKNOWN', 'SETUP_REQUIRED' = 'SETUP_REQUIRED', + 'BLOCKED' = 'BLOCKED', 'PAUSED' = 'PAUSED', 'RUNNING' = 'RUNNING', 'ERROR' = 'ERROR', } -export enum DisabledReasonTari { +export enum CodesOfTariMining { 'MISSING_WALLET_ADDRESS', } -export enum DisabledReasonMerged { +export enum CodesOfMergedMining { 'MISSING_WALLET_ADDRESS', 'MISSING_MONERO_ADDRESS', } +export interface MiningSession { + startedAt?: string // UTC timestamp + finishedAt?: string + id?: string // uuid (?) + total?: Record // i,e { xtr: 1000 bignumber (?) } + history?: { + timestamp?: string // UTC timestamp + amount?: string // bignumber (?) + chain?: string // ie. xtr, xmr aka coin/currency? + type?: string // to enum, ie. mined, earned, received, sent + }[] +} + export interface MiningNodeState { pending: boolean status: MiningNodesStatus disabledReason?: TDisabledReason + sessions?: MiningSession[] } -export type TariMiningNodeState = MiningNodeState -export type MergedMiningNodeState = MiningNodeState +export type TariMiningNodeState = MiningNodeState +export type MergedMiningNodeState = MiningNodeState export type MiningNodeStates = TariMiningNodeState | MergedMiningNodeState diff --git a/applications/launchpad_v2/src/styles/themes/dark.ts b/applications/launchpad_v2/src/styles/themes/dark.ts index 81e809ef07..117b30e296 100644 --- a/applications/launchpad_v2/src/styles/themes/dark.ts +++ b/applications/launchpad_v2/src/styles/themes/dark.ts @@ -23,6 +23,8 @@ const darkTheme = { warningText: styles.colors.secondary.warningText, expert: 'rgba(147, 48, 255, 0.05)', expertText: styles.gradients.tari, + lightTag: styles.colors.light.backgroundImage, + lightTagText: styles.colors.dark.secondary, placeholderText: styles.colors.dark.placeholder, inverted: { @@ -45,6 +47,8 @@ const darkTheme = { warningText: styles.colors.secondary.warningText, expert: 'rgba(147, 48, 255, 0.05)', expertText: styles.gradients.tari, + lightTag: styles.colors.light.backgroundImage, + lightTagText: styles.colors.dark.secondary, borderColor: styles.colors.light.backgroundImage, borderColorLight: styles.colors.secondary.borderLight, controlBackground: 'transparent', diff --git a/applications/launchpad_v2/src/styles/themes/light.ts b/applications/launchpad_v2/src/styles/themes/light.ts index 03ddad9bfe..c612a1c190 100644 --- a/applications/launchpad_v2/src/styles/themes/light.ts +++ b/applications/launchpad_v2/src/styles/themes/light.ts @@ -29,11 +29,13 @@ const lightTheme = { warningText: styles.colors.secondary.warningText, expert: 'rgba(147, 48, 255, 0.05)', expertText: styles.gradients.tari, + lightTag: styles.colors.light.backgroundImage, + lightTagText: styles.colors.dark.secondary, placeholderText: styles.colors.dark.placeholder, inverted: { primary: styles.colors.light.primary, - secondary: styles.colors.dark.secondary, + secondary: styles.colors.light.textSecondary, tertiary: styles.colors.dark.tertiary, background: styles.colors.darkMode.modalBackgroundSecondary, backgroundSecondary: styles.colors.darkMode.modalBackground, @@ -51,6 +53,8 @@ const lightTheme = { warningText: styles.colors.secondary.warningText, expert: 'rgba(147, 48, 255, 0.05)', expertText: styles.gradients.tari, + lightTag: styles.colors.light.backgroundImage, + lightTagText: styles.colors.dark.secondary, borderColor: styles.colors.secondary.borderLight, borderColorLight: styles.colors.secondary.borderLight, actionBackground: styles.colors.secondary.actionBackground, diff --git a/applications/launchpad_v2/src/types/.keep b/applications/launchpad_v2/src/types/.keep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/applications/launchpad_v2/src/types/general.ts b/applications/launchpad_v2/src/types/general.ts new file mode 100644 index 0000000000..989db3d16d --- /dev/null +++ b/applications/launchpad_v2/src/types/general.ts @@ -0,0 +1,14 @@ +import { CSSProperties } from 'react' +import { SpringValue } from 'react-spring' + +export type CoinType = 'xtr' | ' xmr' + +export type MiningNodeType = 'tari' | 'merged' + +/** + * Style types + */ +export type CSSWithSpring = + | CSSProperties + | Record> + | Record> From 0f879d78ddeefae80b27b6406b700e6f55fbc9a1 Mon Sep 17 00:00:00 2001 From: tomaszantas Date: Mon, 2 May 2022 16:45:41 +0200 Subject: [PATCH 4/4] Fix typo and mining header styling --- .../src/containers/MiningContainer/MiningBox/index.tsx | 6 +++--- .../containers/MiningContainer/MiningHeaderTip/index.tsx | 9 +++++++-- applications/launchpad_v2/src/locales/common.ts | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/index.tsx b/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/index.tsx index e4275e018a..4d05e476a3 100644 --- a/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/index.tsx +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningBox/index.tsx @@ -42,7 +42,7 @@ const parseLastSessionToCoins = (lastSession: MiningSession | undefined) => { lastSession.total && lastSession.total[coin] ? lastSession.total[coin] : '0', - loading: false, + loading: true, suffixText: t.mining.minedInLastSession, })) } @@ -113,12 +113,12 @@ const MiningBox = ({ node, children }: MiningBoxProps) => { UNKNOWN: {}, SETUP_REQUIRED: { tag: { - text: t.common.pharses.startHere, + text: t.common.phrases.startHere, }, }, BLOCKED: { tag: { - text: t.common.pharses.actionRequired, + text: t.common.phrases.actionRequired, type: 'warning', }, }, diff --git a/applications/launchpad_v2/src/containers/MiningContainer/MiningHeaderTip/index.tsx b/applications/launchpad_v2/src/containers/MiningContainer/MiningHeaderTip/index.tsx index 0b47648197..938576e6f9 100644 --- a/applications/launchpad_v2/src/containers/MiningContainer/MiningHeaderTip/index.tsx +++ b/applications/launchpad_v2/src/containers/MiningContainer/MiningHeaderTip/index.tsx @@ -13,9 +13,14 @@ import { StyledMiningHeaderTip } from './styles' const MiningHeaderTip = () => { return ( - + {t.mining.headerTips.oneStepAway} - diff --git a/applications/launchpad_v2/src/locales/common.ts b/applications/launchpad_v2/src/locales/common.ts index 20294c704d..b164a877ff 100644 --- a/applications/launchpad_v2/src/locales/common.ts +++ b/applications/launchpad_v2/src/locales/common.ts @@ -17,7 +17,7 @@ const translations = { running: 'Running', paused: 'Paused', }, - pharses: { + phrases: { actionRequired: 'Action required', startHere: 'Start here', },