From 98aacffe38b191f871657fd1f34ce5ba5b3a595b Mon Sep 17 00:00:00 2001 From: Jake Kuo Date: Thu, 19 Oct 2023 16:23:29 +0800 Subject: [PATCH 1/2] feat: bdk ui redesign --- src/ui/components/dokcerlogs.tsx | 43 ++++++++ src/ui/components/logo.tsx | 18 ++++ src/ui/components/option.tsx | 13 +++ src/ui/components/selectInput.tsx | 43 ++++++++ src/ui/components/table.tsx | 12 --- src/ui/{views => components}/terminal.tsx | 6 +- src/ui/views/app.tsx | 116 ++++++++++++++-------- src/ui/views/command.tsx | 11 -- src/ui/views/dockerLogs.tsx | 25 ----- src/ui/views/logo.tsx | 17 ---- 10 files changed, 195 insertions(+), 109 deletions(-) create mode 100644 src/ui/components/dokcerlogs.tsx create mode 100644 src/ui/components/logo.tsx create mode 100644 src/ui/components/option.tsx create mode 100644 src/ui/components/selectInput.tsx delete mode 100644 src/ui/components/table.tsx rename src/ui/{views => components}/terminal.tsx (82%) delete mode 100644 src/ui/views/command.tsx delete mode 100644 src/ui/views/dockerLogs.tsx delete mode 100644 src/ui/views/logo.tsx diff --git a/src/ui/components/dokcerlogs.tsx b/src/ui/components/dokcerlogs.tsx new file mode 100644 index 00000000..88359cb1 --- /dev/null +++ b/src/ui/components/dokcerlogs.tsx @@ -0,0 +1,43 @@ +import React from 'react' +import { Text, Box } from 'ink' +import Docker from 'dockerode' + +export default function DockerLogs () { + const docker = new Docker() + const [containers, setContainers] = React.useState([]) + + const listContainers = () => { + docker.listContainers({ all: true }, (err: any, containerList: any) => { + if (err) { + console.error('Error:', err) + } else { + setContainers(containerList) + } + }) + } + + React.useEffect(() => { + listContainers() + + // renew state every 10 seconds + const interval = setInterval(listContainers, 10000) + + return () => { + clearInterval(interval) + } + }, []) + + return ( + + {containers.map((container: any) => ( + + Container ID: {container.Id} + Image: {container.Image} + Name: {container.Names.join(', ')} + Status: {container.Status} + {/* Ports: {container.Ports.map((port:any) => `${port.PrivatePort}:${port.PublicPort}`).join(', ')} */} + + ))} + + ) +} diff --git a/src/ui/components/logo.tsx b/src/ui/components/logo.tsx new file mode 100644 index 00000000..6ee63ca1 --- /dev/null +++ b/src/ui/components/logo.tsx @@ -0,0 +1,18 @@ +/* eslint-disable react/react-in-jsx-scope */ +import { Newline, Text, Box } from 'ink' + +export default function Logo () { + return ( + // eslint-disable-next-line react/react-in-jsx-scope + + + {' '}:::::::: ::::::: ::: ::: + {' '}:+: :+: :+: :+: :+: :+: + {' '}+:+ +:+ +:+ +:+ +:+ +:+ + {' '}+#++:++#+ +#+ +:+ +#++:++ + {' '}+#+ +#+ +#+ +#+ +#+ +#+ + {' '}#+# #+# #+# #+# #+# #+# + ######## ######## ### ### + + ) +} diff --git a/src/ui/components/option.tsx b/src/ui/components/option.tsx new file mode 100644 index 00000000..5445ac7f --- /dev/null +++ b/src/ui/components/option.tsx @@ -0,0 +1,13 @@ +/* eslint-disable react/react-in-jsx-scope */ +import { Box } from 'ink' +import Terminal from './terminal' + +export default function Option ({ networkType }: any) { + return ( + <> + + + + + ) +} diff --git a/src/ui/components/selectInput.tsx b/src/ui/components/selectInput.tsx new file mode 100644 index 00000000..460de945 --- /dev/null +++ b/src/ui/components/selectInput.tsx @@ -0,0 +1,43 @@ +/* eslint-disable react/react-in-jsx-scope */ +import { useState } from 'react' +import { Text, Box } from 'ink' +import SelectInput from 'ink-select-input' +import CommandContext from '../services/commandContext' + +export default function Select ({ setNetworkType }:any) { + const commandContext = new CommandContext() + + const [items, setItems] = useState([ + { + label: 'Fabric', + value: 'bdk fabric', + }, + { + label: 'Quorum', + value: 'bdk quorum', + }, + ]) + + const selectChain = (item: any) => { + setNetworkType(item.value) + } + + const handleCommand = (item: any) => { + const commandList = commandContext.makeItem(item.value) + if (commandList.length === 0) { + commandContext.executeCommand(item.value) + } else setItems(commandList) + } + + return ( + <> + + + Choose a type of network to deploy: + + + + + + ) +} diff --git a/src/ui/components/table.tsx b/src/ui/components/table.tsx deleted file mode 100644 index aaedd9a7..00000000 --- a/src/ui/components/table.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' -import { Box } from 'ink' - -export default function Table () { - return ( - - - props - - - ) -} diff --git a/src/ui/views/terminal.tsx b/src/ui/components/terminal.tsx similarity index 82% rename from src/ui/views/terminal.tsx rename to src/ui/components/terminal.tsx index 7ff89026..c9a63699 100644 --- a/src/ui/views/terminal.tsx +++ b/src/ui/components/terminal.tsx @@ -12,11 +12,11 @@ export default function Terminal (props: TerminalProps) { }, [props.type]) return ( - + <> Command output: - {output} + {output} - + ) } diff --git a/src/ui/views/app.tsx b/src/ui/views/app.tsx index 69becd4d..977306f4 100644 --- a/src/ui/views/app.tsx +++ b/src/ui/views/app.tsx @@ -1,59 +1,93 @@ -import React, { useState } from 'react' -import { Box, Text, useApp, useInput } from 'ink' -import Logo from './logo' -import Command from './command' -import DockerLogs from './dockerLogs' -import Terminal from './terminal' -import SelectInput from 'ink-select-input' -import CommandContext from '../services/commandContext' +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable react/react-in-jsx-scope */ +import { useState, useEffect } from 'react' +import { Box, Text, useApp, useInput, useStdout } from 'ink' +import Logo from '../components/logo' +import Select from '../components/selectInput' +import Option from '../components/option' +import DockerLogs from '../components/dokcerlogs' export default function App () { const { exit } = useApp() - const commandContext = new CommandContext() - const [type, setType] = useState('bdk fabric') - const [items, setItems] = useState([ - { - label: 'Fabric', - value: 'bdk fabric', - }, - { - label: 'Quorum', - value: 'bdk quorum', - }, - ]) + useInput((input, key) => { if (input === 'q' || (key.ctrl && input === 'c') || key.escape) { exit() } }) - const selectChain = (item:any) => { - setType(item.value) - } + const { stdout }: any = useStdout() + const [width, setWidth] = useState(stdout.columns || 80) + const [height, setHeight] = useState(stdout.rows || 24) + const [windowSize, setWindowSize] = useState({ + columns: process.stdout.columns, + rows: process.stdout.rows, + }) + + useEffect(() => { + const handleResize = () => { + setWidth(stdout.columns) + setHeight(stdout.rows) + } - const handleCommand = (item: any) => { - const commandList = commandContext.makeItem(item.value) - if (commandList.length === 0) { - commandContext.executeCommand(item.value) - } else setItems(commandList) - } + process.stdout.on('resize', handleResize) + return () => { + process.stdout.off('resize', handleResize) + } + }, [stdout.columns, stdout.rows]) + + useEffect(() => { + const handleResize = () => { + setWindowSize({ + columns: process.stdout.columns, + rows: process.stdout.rows, + }) + } + + process.stdout.on('resize', handleResize) + + return () => { + process.stdout.off('resize', handleResize) + } + }, []) + + const [networkType, setNetworkType] = useState('bdk fabric') return ( - - - - - - - - - - + + + - + + + + + + + + Running Docker Container + + + + + + + + - -- Press q to exit -- ) } diff --git a/src/ui/views/command.tsx b/src/ui/views/command.tsx deleted file mode 100644 index d979fe57..00000000 --- a/src/ui/views/command.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import { Text, Box, Newline } from 'ink' - -export default function Command () { - return ( - - Choose a command: - - - ) -} diff --git a/src/ui/views/dockerLogs.tsx b/src/ui/views/dockerLogs.tsx deleted file mode 100644 index a1e83008..00000000 --- a/src/ui/views/dockerLogs.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react' -import { Text, Box, useInput } from 'ink' -import ContainerContext from '../services/containerContext' - -export default function DockerLogs () { - const containerContext = new ContainerContext() - const [items, setItems] = React.useState() - React.useEffect(() => { - setItems(containerContext.listContainers() as any) - }, [setItems]) - - useInput((input) => { - if (input === 'r') { - setItems(containerContext.listContainers() as any) - } - }) - return ( - - Docker Containers: - - { items } - - - ) -} diff --git a/src/ui/views/logo.tsx b/src/ui/views/logo.tsx deleted file mode 100644 index 29edb708..00000000 --- a/src/ui/views/logo.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react' -import { Text, Box } from 'ink' -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -import Gradient from 'ink-gradient' - -export default function Logo () { - return ( - - - - Blockchain Deploy Kit - - - - ) -} From f4557953e23e4ced39e4e23c43c05f315cda40f6 Mon Sep 17 00:00:00 2001 From: Jake Kuo Date: Thu, 19 Oct 2023 10:18:08 +0800 Subject: [PATCH 2/2] fix: bdk ui layout --- .../{dokcerlogs.tsx => dockerlogs.tsx} | 6 +-- src/ui/components/logo.tsx | 3 +- src/ui/components/option.tsx | 2 +- src/ui/components/selectInput.tsx | 3 +- src/ui/components/terminal.tsx | 6 +-- src/ui/views/app.tsx | 37 ++++++------------- 6 files changed, 20 insertions(+), 37 deletions(-) rename src/ui/components/{dokcerlogs.tsx => dockerlogs.tsx} (89%) diff --git a/src/ui/components/dokcerlogs.tsx b/src/ui/components/dockerlogs.tsx similarity index 89% rename from src/ui/components/dokcerlogs.tsx rename to src/ui/components/dockerlogs.tsx index 88359cb1..771d73ea 100644 --- a/src/ui/components/dokcerlogs.tsx +++ b/src/ui/components/dockerlogs.tsx @@ -1,10 +1,10 @@ -import React from 'react' +import React, { useState, useEffect } from 'react' import { Text, Box } from 'ink' import Docker from 'dockerode' export default function DockerLogs () { const docker = new Docker() - const [containers, setContainers] = React.useState([]) + const [containers, setContainers] = useState([]) const listContainers = () => { docker.listContainers({ all: true }, (err: any, containerList: any) => { @@ -16,7 +16,7 @@ export default function DockerLogs () { }) } - React.useEffect(() => { + useEffect(() => { listContainers() // renew state every 10 seconds diff --git a/src/ui/components/logo.tsx b/src/ui/components/logo.tsx index 6ee63ca1..077155cc 100644 --- a/src/ui/components/logo.tsx +++ b/src/ui/components/logo.tsx @@ -1,9 +1,8 @@ -/* eslint-disable react/react-in-jsx-scope */ +import React from 'react' import { Newline, Text, Box } from 'ink' export default function Logo () { return ( - // eslint-disable-next-line react/react-in-jsx-scope {' '}:::::::: ::::::: ::: ::: diff --git a/src/ui/components/option.tsx b/src/ui/components/option.tsx index 5445ac7f..9a7d2f2d 100644 --- a/src/ui/components/option.tsx +++ b/src/ui/components/option.tsx @@ -1,4 +1,4 @@ -/* eslint-disable react/react-in-jsx-scope */ +import React from 'react' import { Box } from 'ink' import Terminal from './terminal' diff --git a/src/ui/components/selectInput.tsx b/src/ui/components/selectInput.tsx index 460de945..32509a60 100644 --- a/src/ui/components/selectInput.tsx +++ b/src/ui/components/selectInput.tsx @@ -1,5 +1,4 @@ -/* eslint-disable react/react-in-jsx-scope */ -import { useState } from 'react' +import React, { useState } from 'react' import { Text, Box } from 'ink' import SelectInput from 'ink-select-input' import CommandContext from '../services/commandContext' diff --git a/src/ui/components/terminal.tsx b/src/ui/components/terminal.tsx index c9a63699..92a79e96 100644 --- a/src/ui/components/terminal.tsx +++ b/src/ui/components/terminal.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useState, useEffect } from 'react' import { Text, Box } from 'ink' import CommandContext from '../services/commandContext' interface TerminalProps { @@ -6,8 +6,8 @@ interface TerminalProps { } export default function Terminal (props: TerminalProps) { const commandContext = new CommandContext() - const [output, setOutput] = React.useState('') - React.useEffect(() => { + const [output, setOutput] = useState('') + useEffect(() => { setOutput(commandContext.getCommandHelp(props.type)) }, [props.type]) diff --git a/src/ui/views/app.tsx b/src/ui/views/app.tsx index 977306f4..26dfa8c9 100644 --- a/src/ui/views/app.tsx +++ b/src/ui/views/app.tsx @@ -1,11 +1,9 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable react/react-in-jsx-scope */ -import { useState, useEffect } from 'react' +import React, { useState, useEffect } from 'react' import { Box, Text, useApp, useInput, useStdout } from 'ink' import Logo from '../components/logo' import Select from '../components/selectInput' import Option from '../components/option' -import DockerLogs from '../components/dokcerlogs' +import DockerLogs from '../components/dockerlogs' export default function App () { const { exit } = useApp() @@ -19,7 +17,7 @@ export default function App () { const { stdout }: any = useStdout() const [width, setWidth] = useState(stdout.columns || 80) const [height, setHeight] = useState(stdout.rows || 24) - const [windowSize, setWindowSize] = useState({ + const [, setWindowSize] = useState({ columns: process.stdout.columns, rows: process.stdout.rows, }) @@ -64,27 +62,14 @@ export default function App () { - - - - - Running Docker Container - - - - - - + + + + + Running Docker Container + + +