From ec68e97bd504cf8aae61fb043ae8a74d7d17fcc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadach?= Date: Sun, 1 Dec 2024 12:52:48 +0100 Subject: [PATCH 01/20] generate login modal icons from both apiEndpoint and nodeAddress --- src/components/ConnectNode/index.tsx | 19 ++++++++---- src/components/ConnectNode/modal.tsx | 5 ++++ .../Select/index.tsx | 8 +++-- src/router.tsx | 3 +- src/store/slices/auth/index.ts | 30 ++++++++++++++++++- src/store/slices/auth/initialState.ts | 5 +++- src/store/slices/node/actionsAsync.ts | 8 +++++ src/utils/functions.ts | 5 ++-- 8 files changed, 70 insertions(+), 13 deletions(-) diff --git a/src/components/ConnectNode/index.tsx b/src/components/ConnectNode/index.tsx index bd3b7e01..829ac226 100644 --- a/src/components/ConnectNode/index.tsx +++ b/src/components/ConnectNode/index.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect, useRef } from 'react'; import styled from '@emotion/styled'; import { Link, useNavigate } from 'react-router-dom'; -import { generateBase64Jazz } from '../../utils/functions'; +import { toHexMD5, generateBase64Jazz } from '../../utils/functions'; // Components import Modal from './modal'; @@ -62,10 +62,15 @@ const NodeButton = styled.div` .node-info { color: #414141; line-height: 12px; + height: 12px; + white-space: nowrap; } .node-info-localname { font-weight: 700; color: #000050; + height: 12px; + line-height: 12px; + white-space: nowrap; } `; @@ -99,6 +104,7 @@ export default function ConnectNode() { const openLoginModalToNode = useAppSelector((store) => store.auth.helper.openLoginModalToNode); const peerId = useAppSelector((store) => store.node.addresses.data.hopr); const localName = useAppSelector((store) => store.auth.loginData.localName); + const nodeAddress = useAppSelector((store) => store.node.addresses.data.native); const localNameToDisplay = localName && localName.length > 17 ? `${localName?.substring(0, 5)}…${localName?.substring(localName.length - 11, localName.length)}` @@ -124,10 +130,13 @@ export default function ConnectNode() { }, []); useEffect(() => { + if (!connected) set_nodeAddressIcon(null); if (!apiEndpoint) return; - const b64 = generateBase64Jazz(apiEndpoint); - if (b64) set_nodeAddressIcon(b64); - }, [apiEndpoint]); + + const md5 = toHexMD5(apiEndpoint); + const b64 = generateBase64Jazz(md5); + if (connected && b64) set_nodeAddressIcon(b64); + }, [connected, apiEndpoint, nodeAddress]); useEffect(() => { if (error) set_modalVisible(true); @@ -186,7 +195,7 @@ export default function ConnectNode() { id="jazz-icon-node" > diff --git a/src/components/ConnectNode/modal.tsx b/src/components/ConnectNode/modal.tsx index bf9e46a5..5db18e0d 100644 --- a/src/components/ConnectNode/modal.tsx +++ b/src/components/ConnectNode/modal.tsx @@ -30,6 +30,7 @@ type ParsedNode = { value: string; apiEndpoint: string; apiToken: string; + jazzIcon?: string; }; type ConnectNodeModalProps = { @@ -140,6 +141,7 @@ function ConnectNodeModal(props: ConnectNodeModalProps) { const loginData = useAppSelector((store) => store.auth.loginData); const [searchParams, set_searchParams] = useSearchParams(); const [localName, set_localName] = useState(loginData.localName ? loginData.localName : ''); + const [jazzIcon, set_jazzIcon] = useState(loginData.jazzIcon ? loginData.jazzIcon : null); const [apiEndpoint, set_apiEndpoint] = useState(loginData.apiEndpoint ? loginData.apiEndpoint : ''); const [apiToken, set_apiToken] = useState(loginData.apiToken ? loginData.apiToken : ''); const [saveApiToken, set_saveApiToken] = useState(false); @@ -156,6 +158,7 @@ function ConnectNodeModal(props: ConnectNodeModalProps) { value: index.toString(), apiEndpoint: node.apiEndpoint, apiToken: node.apiToken, + jazzIcon: node.jazzIcon, }; }) as ParsedNode[]; set_nodesSavedLocallyParsed(parsed); @@ -261,6 +264,7 @@ function ConnectNodeModal(props: ConnectNodeModalProps) { apiEndpoint: formattedApiEndpoint, apiToken, localName, + jazzIcon }), ); dispatch( @@ -350,6 +354,7 @@ function ConnectNodeModal(props: ConnectNodeModalProps) { set_apiToken(chosenNode.apiToken); set_saveApiToken(chosenNode.apiToken?.length > 0); set_localName(chosenNode.localName); + chosenNode.jazzIcon && set_jazzIcon(chosenNode.jazzIcon); }; return ( diff --git a/src/future-hopr-lib-components/Select/index.tsx b/src/future-hopr-lib-components/Select/index.tsx index 211d5395..6f005fc8 100644 --- a/src/future-hopr-lib-components/Select/index.tsx +++ b/src/future-hopr-lib-components/Select/index.tsx @@ -8,7 +8,7 @@ import FormControl from '@mui/material/FormControl'; import SelectMui, { SelectProps as SelectMuiProps } from '@mui/material/Select'; import { Tooltip, IconButton } from '@mui/material'; import DeleteIcon from '@mui/icons-material/Delete'; -import { generateBase64Jazz } from '../../utils/functions'; +import { toHexMD5, generateBase64Jazz } from '../../utils/functions'; const SFormControl = styled(FormControl)` margin-bottom: 16px; @@ -50,12 +50,14 @@ interface Props extends SelectMuiProps { value: string | number; name: string | number | null; apiEndpoint: string | null; + jazzIcon?: string | null; disabled?: boolean; }[]; native?: boolean; } const Select: React.FC = (props) => { + console.log('props.values', props.values) return ( = (props) => { > {props.values && props.values.map((elem, index) => { - const icon = elem.apiEndpoint && generateBase64Jazz(elem.apiEndpoint); + const jazzMd5apiEndpoint = elem.apiEndpoint && toHexMD5(elem.apiEndpoint); + const icon = elem.jazzIcon ? generateBase64Jazz(elem.jazzIcon) : jazzMd5apiEndpoint && generateBase64Jazz(jazzMd5apiEndpoint); return ( = (props) => { )} {elem.name} diff --git a/src/router.tsx b/src/router.tsx index 1431677a..fd8867be 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -230,10 +230,11 @@ const LayoutEnhanced = () => { if (!apiEndpoint) return; if (loginData.apiEndpoint === apiEndpoint && loginData.apiToken === apiToken) return; const formattedApiEndpoint = parseAndFormatUrl(apiEndpoint); + console.log('Node Admin login from url', formattedApiEndpoint); dispatch( authActions.useNodeData({ apiEndpoint, - apiToken: apiToken ? apiToken : '', + apiToken: apiToken ? apiToken : '' }), ); dispatch(nodeActions.setApiEndpoint({ apiEndpoint: formattedApiEndpoint })); diff --git a/src/store/slices/auth/index.ts b/src/store/slices/auth/index.ts index 50488e9e..e938b7e6 100644 --- a/src/store/slices/auth/index.ts +++ b/src/store/slices/auth/index.ts @@ -3,6 +3,7 @@ import { bubbleSortObject } from '../../../utils/functions'; import { loadStateFromLocalStorage } from '../../../utils/localStorage'; import { actionsAsync, createAsyncReducer } from './actionsAsync'; import { initialState } from './initialState'; +import { isAddress } from 'viem'; const authSlice = createSlice({ name: 'auth', @@ -20,9 +21,10 @@ const authSlice = createSlice({ apiToken: string; apiEndpoint: string; localName?: string; + jazzIcon?: string | null; }>, ) { - // Check if we have name saved locally + // Check if we have a name saved locally let localName: string | null = action.payload.localName ? action.payload.localName : ''; if (!localName) { const existingItem = state.nodes.findIndex((item) => item.apiEndpoint === action.payload.apiEndpoint); @@ -30,9 +32,18 @@ const authSlice = createSlice({ localName = state.nodes[existingItem].localName ? state.nodes[existingItem].localName : ''; } + // Check if we have a jazzIcon saved locally + let jazzIcon: string | null = action.payload.jazzIcon ? action.payload.jazzIcon : null; + if (!jazzIcon) { + const existingItem = state.nodes.findIndex((item) => item.apiEndpoint === action.payload.apiEndpoint); + if (existingItem !== -1) + jazzIcon = state.nodes[existingItem].jazzIcon ? state.nodes[existingItem].jazzIcon as string : null; + } + state.loginData.apiEndpoint = action.payload.apiEndpoint; state.loginData.apiToken = action.payload.apiToken ? action.payload.apiToken : ''; state.loginData.localName = localName; + state.loginData.jazzIcon = jazzIcon; }, setConnected(state) { state.status.connecting = false; @@ -65,6 +76,23 @@ const authSlice = createSlice({ localStorage.setItem('admin-ui-node-list', JSON.stringify(state.nodes)); }, + addNodeJazzIcon( + state, + action: PayloadAction<{ + apiEndpoint: string; + jazzIcon: string; + }>, + ) { + const existingItem = state.nodes.findIndex((item) => item.apiEndpoint === action.payload.apiEndpoint); + if (existingItem === -1) return; + if(isAddress(action.payload.jazzIcon)) { + state.nodes[existingItem].jazzIcon = action.payload.jazzIcon; + } else { + state.nodes[existingItem].jazzIcon = action.payload.jazzIcon; + } + + localStorage.setItem('admin-ui-node-list', JSON.stringify(state.nodes)); + }, clearLocalNodes(state) { state.nodes = []; localStorage.removeItem('admin-ui-node-list'); diff --git a/src/store/slices/auth/initialState.ts b/src/store/slices/auth/initialState.ts index 4bc47393..11d103c0 100644 --- a/src/store/slices/auth/initialState.ts +++ b/src/store/slices/auth/initialState.ts @@ -1,7 +1,7 @@ import { loadStateFromLocalStorage } from '../../../utils/localStorage'; const ADMIN_UI_NODE_LIST = loadStateFromLocalStorage('admin-ui-node-list') as - | { apiEndpoint: string | null; apiToken: string | null; localName: string | null }[] + | { apiEndpoint: string | null; apiToken: string | null; localName: string | null; jazzIcon?: string | null }[] | null; type InitialState = { @@ -18,11 +18,13 @@ type InitialState = { apiToken: string | null; localName: string | null; peerId: string | null; + jazzIcon: string | null; }; nodes: { apiEndpoint: string | null; apiToken: string | null; localName: string | null; + jazzIcon?: string | null; }[]; helper: { openLoginModalToNode: boolean; @@ -40,6 +42,7 @@ export const initialState: InitialState = { apiToken: null, localName: null, peerId: null, + jazzIcon: null, }, nodes: ADMIN_UI_NODE_LIST ? ADMIN_UI_NODE_LIST : [], helper: { openLoginModalToNode: false }, diff --git a/src/store/slices/node/actionsAsync.ts b/src/store/slices/node/actionsAsync.ts index a4571454..3a23af05 100644 --- a/src/store/slices/node/actionsAsync.ts +++ b/src/store/slices/node/actionsAsync.ts @@ -48,6 +48,8 @@ import { formatEther } from 'viem'; import { nodeActionsFetching } from './actionsFetching'; import { sendNotification } from '../../../hooks/useWatcher/notifications'; import { useAppDispatch } from '../../../store'; +import { authActions } from '../auth'; + const { sdkApiError } = utils; const { closeChannel, @@ -145,6 +147,12 @@ const getAddressesThunk = createAsyncThunk< dispatch(nodeActionsFetching.setAddressesFetching(true)); try { const addresses = await getAddresses(payload); + if(addresses?.native){ + dispatch(authActions.addNodeJazzIcon({ + apiEndpoint: payload.apiEndpoint as string, + jazzIcon: addresses.native + })); + } return addresses; } catch (e) { if (e instanceof sdkApiError) { diff --git a/src/utils/functions.ts b/src/utils/functions.ts index c6b1680d..f49c2eed 100644 --- a/src/utils/functions.ts +++ b/src/utils/functions.ts @@ -152,10 +152,9 @@ export function toHexMD5(d: string) { return createHash('md5').update(d).digest('hex'); } -export function generateBase64Jazz(string: string) { +export function generateBase64Jazz(input: string) { try { - const md5 = toHexMD5(string); - const jazzSvg = jazzicon(16, parseInt(md5.slice(2, 10), 16)); + const jazzSvg = jazzicon(16, parseInt(input.slice(2, 10), 16)); const html = jazzSvg.children[0].outerHTML.replace(' Date: Sun, 1 Dec 2024 13:07:04 +0100 Subject: [PATCH 02/20] change the node icon in the navbar once nodeAddress is loaded --- src/components/ConnectNode/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ConnectNode/index.tsx b/src/components/ConnectNode/index.tsx index 829ac226..ad201b08 100644 --- a/src/components/ConnectNode/index.tsx +++ b/src/components/ConnectNode/index.tsx @@ -134,7 +134,7 @@ export default function ConnectNode() { if (!apiEndpoint) return; const md5 = toHexMD5(apiEndpoint); - const b64 = generateBase64Jazz(md5); + const b64 = generateBase64Jazz(nodeAddress ? nodeAddress : md5); if (connected && b64) set_nodeAddressIcon(b64); }, [connected, apiEndpoint, nodeAddress]); From f5d83669e7605aa24ee82ee482b837e9f0f97886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadach?= Date: Sun, 1 Dec 2024 13:12:14 +0100 Subject: [PATCH 03/20] change the node icon in the navbar based on localStorage --- src/components/ConnectNode/index.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/components/ConnectNode/index.tsx b/src/components/ConnectNode/index.tsx index ad201b08..744cd86c 100644 --- a/src/components/ConnectNode/index.tsx +++ b/src/components/ConnectNode/index.tsx @@ -103,12 +103,13 @@ export default function ConnectNode() { const error = useAppSelector((store) => store.auth.status.error); const openLoginModalToNode = useAppSelector((store) => store.auth.helper.openLoginModalToNode); const peerId = useAppSelector((store) => store.node.addresses.data.hopr); - const localName = useAppSelector((store) => store.auth.loginData.localName); + const localNameFromLocalStorage = useAppSelector((store) => store.auth.loginData.localName); + const jazzIconFromLocalStorage = useAppSelector((store) => store.auth.loginData.jazzIcon); const nodeAddress = useAppSelector((store) => store.node.addresses.data.native); const localNameToDisplay = - localName && localName.length > 17 - ? `${localName?.substring(0, 5)}…${localName?.substring(localName.length - 11, localName.length)}` - : localName; + localNameFromLocalStorage && localNameFromLocalStorage.length > 17 + ? `${localNameFromLocalStorage?.substring(0, 5)}…${localNameFromLocalStorage?.substring(localNameFromLocalStorage.length - 11, localNameFromLocalStorage.length)}` + : localNameFromLocalStorage; const apiEndpoint = useAppSelector((store) => store.auth.loginData.apiEndpoint); const [nodeAddressIcon, set_nodeAddressIcon] = useState(null); const [anchorEl, setAnchorEl] = useState(null); // State variable to hold the anchor element for the menu @@ -132,11 +133,11 @@ export default function ConnectNode() { useEffect(() => { if (!connected) set_nodeAddressIcon(null); if (!apiEndpoint) return; - + console.log(jazzIconFromLocalStorage) const md5 = toHexMD5(apiEndpoint); - const b64 = generateBase64Jazz(nodeAddress ? nodeAddress : md5); + const b64 = generateBase64Jazz(nodeAddress ? nodeAddress : jazzIconFromLocalStorage ? jazzIconFromLocalStorage : md5); if (connected && b64) set_nodeAddressIcon(b64); - }, [connected, apiEndpoint, nodeAddress]); + }, [connected, apiEndpoint, nodeAddress, jazzIconFromLocalStorage]); useEffect(() => { if (error) set_modalVisible(true); From 24afdcf4b7af40efee3e42564bfc1f2b22cdcba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadach?= Date: Sun, 1 Dec 2024 13:27:31 +0100 Subject: [PATCH 04/20] better config overview --- src/components/ConnectNode/modal.tsx | 2 ++ src/pages/node/configuration.tsx | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/components/ConnectNode/modal.tsx b/src/components/ConnectNode/modal.tsx index 5db18e0d..ee8003cb 100644 --- a/src/components/ConnectNode/modal.tsx +++ b/src/components/ConnectNode/modal.tsx @@ -139,6 +139,7 @@ function ConnectNodeModal(props: ConnectNodeModalProps) { const [nodesSavedLocallyParsed, set_nodesSavedLocallyParsed] = useState([] as ParsedNode[]); const errorMessage = useAppSelector((store) => store.auth.status.error?.data); const loginData = useAppSelector((store) => store.auth.loginData); + const loginPending = useAppSelector((store) => store.auth.status.connecting); const [searchParams, set_searchParams] = useSearchParams(); const [localName, set_localName] = useState(loginData.localName ? loginData.localName : ''); const [jazzIcon, set_jazzIcon] = useState(loginData.jazzIcon ? loginData.jazzIcon : null); @@ -439,6 +440,7 @@ function ConnectNodeModal(props: ConnectNodeModalProps) { diff --git a/src/pages/node/configuration.tsx b/src/pages/node/configuration.tsx index 93a24558..9155f8f0 100644 --- a/src/pages/node/configuration.tsx +++ b/src/pages/node/configuration.tsx @@ -23,8 +23,10 @@ function SettingsPage() { const dispatch = useAppDispatch(); const prevNotificationSettings = useAppSelector((store) => store.app.configuration.notifications); const strategies = useAppSelector((store) => store.node.configuration.data?.hopr?.strategy); + const configuration = useAppSelector((store) => store.node.configuration.data); const ticketPrice = useAppSelector((store) => store.node.ticketPrice.data); const [strategiesString, set_strategiesString] = useState(null); + const [configurationString, set_configurationString] = useState(null); const [localNotificationSettings, set_localNotificationSettings] = useState(); useEffect(() => { @@ -139,6 +141,16 @@ function SettingsPage() { } }, [strategies, ticketPrice]); + useEffect(() => { + if (configuration) { + let tmp = JSON.parse(JSON.stringify(configuration)); + tmp.hopr['strategy'] && delete tmp.hopr['strategy']; + tmp = JSON.stringify(tmp, null, 2); + set_configurationString(tmp); + } + }, [configuration]); + + const handleSaveSettings = async () => { if (localNotificationSettings) { dispatch(appActions.setNotificationSettings(localNotificationSettings)); @@ -246,6 +258,17 @@ function SettingsPage() { )} + + Configuration + + {configurationString && ( + + )} + + + Strategies @@ -276,15 +286,6 @@ function SettingsPage() { - ); From 9d557b4cee38aab4b1a03cad268505ba4df9700a Mon Sep 17 00:00:00 2001 From: mjadach-iv Date: Sun, 1 Dec 2024 16:13:31 +0100 Subject: [PATCH 07/20] open swagger and scallar ui --- public/assets/scalar-removebg-preview.png | Bin 0 -> 12819 bytes src/pages/node/configuration.tsx | 150 ++++++++-------------- src/pages/node/info/index.tsx | 30 ++++- 3 files changed, 80 insertions(+), 100 deletions(-) create mode 100644 public/assets/scalar-removebg-preview.png diff --git a/public/assets/scalar-removebg-preview.png b/public/assets/scalar-removebg-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..95f3d63b61f0854daf9cd5a4f3852b7c1aa64a7a GIT binary patch literal 12819 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 { + const valueBigInt = BigInt(value) * DECIMALS_MULTIPLIER; + const ticketBigInt = BigInt(ticketPrice); + return valueBigInt / ticketBigInt; +}; + +const updateStrategyString = ( + originalString: string, + key: string, + value: string, + tickets: bigint +): string => { + const stringToReplace = `"${key}": "${value} HOPR"`; + const formattedEther = formatEther(BigInt(value)); + const replacement = `"${key}": "${value}" // ${formattedEther} HOPR, tickets: ${rounder(Number(tickets))}`; + + return originalString.includes(stringToReplace + ',') + ? originalString.replace(stringToReplace + ',', replacement + ',') + : originalString.replace(stringToReplace, replacement); +}; + + function SettingsPage() { const dispatch = useAppDispatch(); const prevNotificationSettings = useAppSelector((store) => store.app.configuration.notifications); @@ -36,113 +69,32 @@ function SettingsPage() { } }, [prevNotificationSettings]); + // Usage in useEffect useEffect(() => { - if (strategies) { - let tmp = JSON.stringify(strategies, null, 2); + if (!strategies || !ticketPrice) return; - try { - if (ticketPrice) { - // min_stake_threshold - if (strategies?.strategies?.AutoFunding?.min_stake_threshold) { - const key = 'min_stake_threshold'; - const min_stake_threshold = strategies.strategies.AutoFunding[key].replace(' HOPR', ''); - const formattedEther = formatEther(min_stake_threshold); - const min_stake_thresholdBigInt = BigInt(min_stake_threshold) * BigInt(1e18); - const ticketBigInt = BigInt(ticketPrice); - const ticketsBigInt = min_stake_thresholdBigInt / ticketBigInt; - const ticketsString = ticketsBigInt.toString(); - const stringToReplace = `"${key}": "${strategies.strategies.AutoFunding[key]}"`; - if (tmp.includes(stringToReplace + ',')) { - tmp = tmp.replace( - stringToReplace + ',', - `"${key}": "${strategies.strategies.AutoFunding[key]}", // ${formattedEther} HOPR, tickets: ${ticketsString}`, - ); - } else { - tmp = tmp.replace( - stringToReplace, - `"${key}": "${strategies.strategies.AutoFunding[key]}" // ${formattedEther} HOPR, tickets: ${ticketsString}`, - ); - } - } + try { + const configs: StrategyConfig[] = [ + { path: ['AutoFunding', 'min_stake_threshold'], value: strategies.strategies?.AutoFunding?.min_stake_threshold?.replace(' HOPR', '') }, + { path: ['AutoFunding', 'funding_amount'], value: strategies.strategies?.AutoFunding?.funding_amount?.replace(' HOPR', '') }, + { path: ['AutoRedeeming', 'minimum_redeem_ticket_value'], value: strategies.strategies?.AutoRedeeming?.minimum_redeem_ticket_value?.replace(' HOPR', '') }, + { path: ['AutoRedeeming', 'on_close_redeem_single_tickets_value_min'], value: strategies.strategies?.AutoRedeeming?.on_close_redeem_single_tickets_value_min?.replace(' HOPR', '') }, + ]; - // funding_amount - if (strategies?.strategies?.AutoFunding?.funding_amount) { - const key = 'funding_amount'; - const funding_amount = strategies.strategies.AutoFunding[key].replace(' HOPR', ''); - const formattedEther = formatEther(funding_amount); - const funding_amountBigInt = BigInt(funding_amount) * BigInt(1e18); - const ticketBigInt = BigInt(ticketPrice); - const ticketsBigInt = funding_amountBigInt / ticketBigInt; - const ticketsString = ticketsBigInt.toString(); - const stringToReplace = `"${key}": "${strategies.strategies.AutoFunding[key]}"`; - if (tmp.includes(stringToReplace + ',')) { - tmp = tmp.replace( - stringToReplace + ',', - `"${key}": "${strategies.strategies.AutoFunding[key]}", // ${formattedEther} HOPR, tickets: ${ticketsString}`, - ); - } else { - tmp = tmp.replace( - stringToReplace, - `"${key}": "${strategies.strategies.AutoFunding[key]}" // ${formattedEther} HOPR, tickets: ${ticketsString}`, - ); - } - } + console.log('configs', configs) - // minimum_redeem_ticket_value - if (strategies?.strategies?.AutoRedeeming?.minimum_redeem_ticket_value) { - const key = 'minimum_redeem_ticket_value'; - const minimum_redeem_ticket_value = strategies.strategies.AutoRedeeming[key].replace(' HOPR', ''); - const formattedEther = formatEther(minimum_redeem_ticket_value); - const minimum_redeem_ticket_valueBigInt = BigInt(minimum_redeem_ticket_value) * BigInt(1e18); - const ticketBigInt = BigInt(ticketPrice); - const ticketsBigInt = minimum_redeem_ticket_valueBigInt / ticketBigInt; - const ticketsString = ticketsBigInt.toString(); - const stringToReplace = `"${key}": "${strategies.strategies.AutoRedeeming[key]}"`; - if (tmp.includes(stringToReplace + ',')) { - tmp = tmp.replace( - stringToReplace + ',', - `"${key}": "${strategies.strategies.AutoRedeeming[key]}", // ${formattedEther} HOPR, tickets: ${ticketsString}`, - ); - } else { - tmp = tmp.replace( - stringToReplace, - `"${key}": "${strategies.strategies.AutoRedeeming[key]}" // ${formattedEther} HOPR, tickets: ${ticketsString}`, - ); - } - } + let result = JSON.stringify(strategies, null, 2); - // on_close_redeem_single_tickets_value_min - if (strategies?.strategies?.AutoRedeeming?.on_close_redeem_single_tickets_value_min) { - const key = 'on_close_redeem_single_tickets_value_min'; - const on_close_redeem_single_tickets_value_min = strategies.strategies.AutoRedeeming[key].replace( - ' HOPR', - '', - ); - const formattedEther = formatEther(on_close_redeem_single_tickets_value_min); - const on_close_redeem_single_tickets_value_minBigInt = - BigInt(on_close_redeem_single_tickets_value_min) * BigInt(1e18); - const ticketBigInt = BigInt(ticketPrice); - const ticketsBigInt = on_close_redeem_single_tickets_value_minBigInt / ticketBigInt; - const ticketsString = ticketsBigInt.toString(); - const stringToReplace = `"${key}": "${strategies.strategies.AutoRedeeming[key]}"`; - if (tmp.includes(stringToReplace + ',')) { - tmp = tmp.replace( - stringToReplace + ',', - `"${key}": "${strategies.strategies.AutoRedeeming[key]}", // ${formattedEther} HOPR, tickets: ${ticketsString}`, - ); - } else { - tmp = tmp.replace( - stringToReplace, - `"${key}": "${strategies.strategies.AutoRedeeming[key]}" // ${formattedEther} HOPR, tickets: ${ticketsString}`, - ); - } - } + for (const config of configs) { + if (config.value) { + const tickets = calculateTickets(config.value, ticketPrice); + result = updateStrategyString(result, config.path[1], config.value, tickets); } - } catch (e) { - console.warn('Error while counting strategies against current ticket price.', e); } - set_strategiesString(tmp); + set_strategiesString(result); + } catch (e) { + console.warn('Error while counting strategies against current ticket price.', e); } }, [strategies, ticketPrice]); diff --git a/src/pages/node/info/index.tsx b/src/pages/node/info/index.tsx index 0d3cfe46..8ed57be2 100644 --- a/src/pages/node/info/index.tsx +++ b/src/pages/node/info/index.tsx @@ -18,10 +18,12 @@ import WithdrawModal from '../../../components/Modal/node/WithdrawModal'; import SmallActionButton from '../../../future-hopr-lib-components/Button/SmallActionButton'; import { ColorStatus } from '../../../components/InfoBar/details'; import ProgressBar from '../../../future-hopr-lib-components/Progressbar'; +import IconButton from '../../../future-hopr-lib-components/Button/IconButton'; //Icons import CopyIcon from '@mui/icons-material/ContentCopy'; import LaunchIcon from '@mui/icons-material/Launch'; +import DataObjectIcon from '@mui/icons-material/DataObject'; //Info Components import NodeUptime from './node-uptime'; @@ -188,7 +190,33 @@ function InfoPage() { title="INFO" refreshFunction={fetchInfoData} reloading={isFetchingAnyData} - actions={} + actions={<> + + } + tooltipText={ + + OPEN +
+ Swagger UI +
+ } + //@ts-ignore + onClick={()=>{window.open(apiEndpoint + '/swagger-ui/index.html#/', '_blank').focus();}} + /> + } + tooltipText={ + + OPEN +
+ Scalar UI +
+ } + //@ts-ignore + onClick={()=>{window.open(apiEndpoint + '/scalar', '_blank').focus();}} + /> + } /> Date: Sun, 1 Dec 2024 16:35:54 +0100 Subject: [PATCH 08/20] peers page, nodes and peers in 1 column --- .../PeerInfo/index.tsx | 65 +++++++++++++++++++ src/pages/node/peers.tsx | 30 ++++++++- 2 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 src/future-hopr-lib-components/PeerInfo/index.tsx diff --git a/src/future-hopr-lib-components/PeerInfo/index.tsx b/src/future-hopr-lib-components/PeerInfo/index.tsx new file mode 100644 index 00000000..463e17a5 --- /dev/null +++ b/src/future-hopr-lib-components/PeerInfo/index.tsx @@ -0,0 +1,65 @@ +import { useEffect } from 'react'; +import { useAppDispatch, useAppSelector } from '../../store'; +import { Link } from 'react-router-dom'; + +// HOPR Components +import SmallActionButton from '../../future-hopr-lib-components/Button/SmallActionButton'; + +//Mui +import CopyIcon from '@mui/icons-material/ContentCopy'; +import LaunchIcon from '@mui/icons-material/Launch'; + +interface Props { + peerId?: string; + nodeAddress?: string; +} + +const PeersInfo: React.FC = (props) => { + const { peerId, nodeAddress, ...rest } = props; + const aliases = useAppSelector((store) => store.node.aliases.data); + const peerIdToAliasLink = useAppSelector((store) => store.node.links.peerIdToAlias); + + + const getAliasByPeerId = (peerId: string): string => { + if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${peerId})`; + return peerId; + }; + + const noCopyPaste = !( + window.location.protocol === 'https:' || + window.location.hostname === 'localhost' || + window.location.hostname === '127.0.0.1' + ); + + return ( +
+
+ {peerId} navigator.clipboard.writeText(peerId as string)} + disabled={noCopyPaste} + tooltip={noCopyPaste ? 'Clipboard not supported on HTTP' : 'Copy'} + > + +
+ {nodeAddress} navigator.clipboard.writeText(nodeAddress as string)} + disabled={noCopyPaste} + tooltip={noCopyPaste ? 'Clipboard not supported on HTTP' : 'Copy'} + > + + + + + + + +
+
+ + ); +} + +export default PeersInfo; diff --git a/src/pages/node/peers.tsx b/src/pages/node/peers.tsx index eab37130..b3896465 100644 --- a/src/pages/node/peers.tsx +++ b/src/pages/node/peers.tsx @@ -2,6 +2,7 @@ import { useEffect } from 'react'; import { useAppDispatch, useAppSelector } from '../../store'; import { actionsAsync } from '../../store/slices/node/actionsAsync'; import { exportToCsv } from '../../utils/helpers'; +import { Link } from 'react-router-dom'; // HOPR Components import Section from '../../future-hopr-lib-components/Section'; @@ -13,12 +14,16 @@ import { SendMessageModal } from '../../components/Modal/node/SendMessageModal'; import IconButton from '../../future-hopr-lib-components/Button/IconButton'; import TablePro from '../../future-hopr-lib-components/Table/table-pro'; import ProgressBar from '../../future-hopr-lib-components/Progressbar'; +import SmallActionButton from '../../future-hopr-lib-components/Button/SmallActionButton'; +import PeersInfo from '../../future-hopr-lib-components/PeerInfo'; // Modals import { PingModal } from '../../components/Modal/node/PingModal'; //Mui import GetAppIcon from '@mui/icons-material/GetApp'; +import CopyIcon from '@mui/icons-material/ContentCopy'; +import LaunchIcon from '@mui/icons-material/Launch'; function PeersPage() { const dispatch = useAppDispatch(); @@ -79,21 +84,28 @@ function PeersPage() { key: 'number', name: '#', }, + { + key: 'node', + name: 'Node', + maxWidth: '350px', + }, { key: 'peerId', name: 'Peer Id', search: true, tooltip: true, - copy: true, + // copy: true, maxWidth: '160px', + hidden: true, }, { key: 'peerAddress', name: 'Node Address', search: true, tooltip: true, - copy: true, + // copy: true, maxWidth: '160px', + hidden: true, }, { key: 'lastSeen', @@ -104,7 +116,7 @@ function PeersPage() { { key: 'quality', name: 'Quality', - maxWidth: '20px', + maxWidth: '15px', }, { key: 'actions', @@ -114,11 +126,23 @@ function PeersPage() { maxWidth: '168px', }, ]; + + + const noCopyPaste = !( + window.location.protocol === 'https:' || + window.location.hostname === 'localhost' || + window.location.hostname === '127.0.0.1' + ); + const parsedTableData = Object.entries(peers?.connected ?? {}).map(([id, peer]) => { return { id: id, number: id, + node: , peerId: getAliasByPeerId(peer.peerId), peerAddress: peer.peerAddress, quality: , From 5b98b40c7e9e4a8813737369f98dff1e11406330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadach?= Date: Sun, 1 Dec 2024 22:25:22 +0100 Subject: [PATCH 09/20] peer address and peer id in the same lines in subpages --- src/pages/node/aliases.tsx | 17 ++++++++++++----- src/pages/node/channelsIncoming.tsx | 24 +++++++++++++++++++++--- src/pages/node/channelsOutgoing.tsx | 28 +++++++++++++++++++++++----- src/pages/node/peers.tsx | 12 +----------- 4 files changed, 57 insertions(+), 24 deletions(-) diff --git a/src/pages/node/aliases.tsx b/src/pages/node/aliases.tsx index 3de1a957..ee014201 100644 --- a/src/pages/node/aliases.tsx +++ b/src/pages/node/aliases.tsx @@ -12,6 +12,7 @@ import IconButton from '../../future-hopr-lib-components/Button/IconButton'; import { SendMessageModal } from '../../components/Modal/node/SendMessageModal'; import RemoveAliasIcon from '../../future-hopr-lib-components/Icons/RemoveAlias'; import TablePro from '../../future-hopr-lib-components/Table/table-pro'; +import PeersInfo from '../../future-hopr-lib-components/PeerInfo'; // Modals import { PingModal } from '../../components/Modal/node/PingModal'; @@ -126,6 +127,10 @@ function AliasesPage() { id: peerId, key: key.toString(), alias, + node: , peerId, peerAddress: peerAddress ?? '', actions: ( @@ -211,21 +216,23 @@ function AliasesPage() { tooltip: true, maxWidth: '0px', }, + { + key: 'node', + name: 'Node', + maxWidth: '350px', + }, { key: 'peerId', name: 'Peer Id', search: true, - tooltip: true, - copy: true, - maxWidth: '60px', + hidden: true, }, { key: 'peerAddress', name: 'Node Address', search: true, - tooltip: true, - copy: true, maxWidth: '60px', + hidden: true, }, { key: 'actions', diff --git a/src/pages/node/channelsIncoming.tsx b/src/pages/node/channelsIncoming.tsx index 1aa867a9..57f7243d 100644 --- a/src/pages/node/channelsIncoming.tsx +++ b/src/pages/node/channelsIncoming.tsx @@ -16,6 +16,7 @@ import { SubpageTitle } from '../../components/SubpageTitle'; import IconButton from '../../future-hopr-lib-components/Button/IconButton'; import TablePro from '../../future-hopr-lib-components/Table/table-pro'; import CloseChannelIcon from '../../future-hopr-lib-components/Icons/CloseChannel'; +import PeersInfo from '../../future-hopr-lib-components/PeerInfo'; // Modals import { PingModal } from '../../components/Modal/node/PingModal'; @@ -26,6 +27,7 @@ import { SendMessageModal } from '../../components/Modal/node/SendMessageModal'; // Mui import GetAppIcon from '@mui/icons-material/GetApp'; +import { truncateEthereumAddress } from '../../utils/blockchain'; function ChannelsPage() { const dispatch = useAppDispatch(); @@ -101,13 +103,23 @@ function ChannelsPage() { key: 'id', name: '#', }, + { + key: 'node', + name: 'Node', + maxWidth: '568px', + }, { key: 'peerAddress', name: 'Node Address', search: true, copy: true, - maxWidth: '568px', - tooltip: true, + hidden: true, + }, + { + key: 'peerId', + name: 'Peer Id', + search: true, + hidden: true, }, { key: 'status', @@ -197,6 +209,7 @@ function ChannelsPage() { !!nodeAddressToOutgoingChannelLink[channelsIncomingObject[id].peerAddress] ); const peerId = getPeerIdFromPeerAddress(channelsIncomingObject[id].peerAddress as string); + const peerAddress = channelsIncomingObject[id].peerAddress; const totalTicketsPerChannel = `${formatEther( BigInt(tickets?.redeemed[id]?.value || '0') + BigInt(tickets?.unredeemed[id]?.value || '0'), @@ -207,7 +220,12 @@ function ChannelsPage() { return { id: (index + 1).toString(), key: id, - peerAddress: getAliasByPeerAddress(channelsIncomingObject[id].peerAddress as string), + node: , + peerAddress: getAliasByPeerAddress(peerAddress as string), + peerId: peerId, status: channelsIncomingObject[id].status, funds: `${utils.formatEther(channelsIncomingObject[id].balance as string)} ${HOPR_TOKEN_USED}`, tickets: unredeemedTicketsPerChannel, diff --git a/src/pages/node/channelsOutgoing.tsx b/src/pages/node/channelsOutgoing.tsx index b07e8b25..e22c66d1 100644 --- a/src/pages/node/channelsOutgoing.tsx +++ b/src/pages/node/channelsOutgoing.tsx @@ -15,6 +15,7 @@ import { SubpageTitle } from '../../components/SubpageTitle'; import IconButton from '../../future-hopr-lib-components/Button/IconButton'; import CloseChannelIcon from '../../future-hopr-lib-components/Icons/CloseChannel'; import TablePro from '../../future-hopr-lib-components/Table/table-pro'; +import PeersInfo from '../../future-hopr-lib-components/PeerInfo'; // Modals import { OpenMultipleChannelsModal } from '../../components/Modal/node/OpenMultipleChannelsModal'; @@ -148,13 +149,22 @@ function ChannelsPage() { key: 'id', name: '#', }, + { + key: 'node', + name: 'Node', + maxWidth: '350px', + }, { key: 'peerAddress', name: 'Node Address', search: true, - tooltip: true, - copy: true, - maxWidth: '168px', + hidden: true, + }, + { + key: 'peerId', + name: 'Peer Id', + search: true, + hidden: true, }, { key: 'status', @@ -186,12 +196,20 @@ function ChannelsPage() { !channelsOutgoingObject[id].status ) return; - const peerId = getPeerIdFromPeerAddress(channelsOutgoingObject[id].peerAddress as string); + + const peerAddress = channelsOutgoingObject[id].peerAddress; + const peerId = getPeerIdFromPeerAddress(peerAddress as string); + return { id: index.toString(), key: id, - peerAddress: getAliasByPeerAddress(channelsOutgoingObject[id].peerAddress as string), + node: , + peerAddress: getAliasByPeerAddress(peerAddress as string), + peerId: peerId, status: channelsOutgoingObject[id].status as string, funds: `${utils.formatEther(channelsOutgoingObject[id].balance as string)} ${HOPR_TOKEN_USED}`, actions: ( diff --git a/src/pages/node/peers.tsx b/src/pages/node/peers.tsx index b3896465..7ca987bf 100644 --- a/src/pages/node/peers.tsx +++ b/src/pages/node/peers.tsx @@ -2,7 +2,6 @@ import { useEffect } from 'react'; import { useAppDispatch, useAppSelector } from '../../store'; import { actionsAsync } from '../../store/slices/node/actionsAsync'; import { exportToCsv } from '../../utils/helpers'; -import { Link } from 'react-router-dom'; // HOPR Components import Section from '../../future-hopr-lib-components/Section'; @@ -14,7 +13,6 @@ import { SendMessageModal } from '../../components/Modal/node/SendMessageModal'; import IconButton from '../../future-hopr-lib-components/Button/IconButton'; import TablePro from '../../future-hopr-lib-components/Table/table-pro'; import ProgressBar from '../../future-hopr-lib-components/Progressbar'; -import SmallActionButton from '../../future-hopr-lib-components/Button/SmallActionButton'; import PeersInfo from '../../future-hopr-lib-components/PeerInfo'; // Modals @@ -22,8 +20,6 @@ import { PingModal } from '../../components/Modal/node/PingModal'; //Mui import GetAppIcon from '@mui/icons-material/GetApp'; -import CopyIcon from '@mui/icons-material/ContentCopy'; -import LaunchIcon from '@mui/icons-material/Launch'; function PeersPage() { const dispatch = useAppDispatch(); @@ -93,18 +89,12 @@ function PeersPage() { key: 'peerId', name: 'Peer Id', search: true, - tooltip: true, - // copy: true, - maxWidth: '160px', hidden: true, }, { key: 'peerAddress', name: 'Node Address', search: true, - tooltip: true, - // copy: true, - maxWidth: '160px', hidden: true, }, { @@ -126,7 +116,7 @@ function PeersPage() { maxWidth: '168px', }, ]; - + const noCopyPaste = !( window.location.protocol === 'https:' || From 1c6350fe00af96b43cbf3264b9510c820ffecebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadach?= Date: Sun, 1 Dec 2024 22:29:55 +0100 Subject: [PATCH 10/20] cleanup --- src/pages/node/aliases.tsx | 70 ++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/src/pages/node/aliases.tsx b/src/pages/node/aliases.tsx index ee014201..80daf441 100644 --- a/src/pages/node/aliases.tsx +++ b/src/pages/node/aliases.tsx @@ -174,6 +174,41 @@ function AliasesPage() { }; }); + const header = [ + { + key: 'alias', + name: 'Alias', + search: true, + tooltip: true, + maxWidth: '0px', + }, + { + key: 'node', + name: 'Node', + maxWidth: '350px', + }, + { + key: 'peerId', + name: 'Peer Id', + search: true, + hidden: true, + }, + { + key: 'peerAddress', + name: 'Node Address', + search: true, + maxWidth: '60px', + hidden: true, + }, + { + key: 'actions', + name: 'Actions', + search: false, + width: '168px', + maxWidth: '168px', + }, + ] + return (
From a8792a750ee02b8c7d7d1b4fbc2f0876e81072f0 Mon Sep 17 00:00:00 2001 From: mjadach-iv Date: Mon, 2 Dec 2024 10:10:27 +0100 Subject: [PATCH 11/20] node-jazz --- .../PeerInfo/index.tsx | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/future-hopr-lib-components/PeerInfo/index.tsx b/src/future-hopr-lib-components/PeerInfo/index.tsx index 463e17a5..6a794eb5 100644 --- a/src/future-hopr-lib-components/PeerInfo/index.tsx +++ b/src/future-hopr-lib-components/PeerInfo/index.tsx @@ -1,9 +1,11 @@ import { useEffect } from 'react'; import { useAppDispatch, useAppSelector } from '../../store'; import { Link } from 'react-router-dom'; +import styled from '@emotion/styled'; // HOPR Components import SmallActionButton from '../../future-hopr-lib-components/Button/SmallActionButton'; +import { generateBase64Jazz } from '../../utils/functions'; //Mui import CopyIcon from '@mui/icons-material/ContentCopy'; @@ -14,6 +16,15 @@ interface Props { nodeAddress?: string; } +const Container = styled.div` + display: flex; + align-items: center; + .node-jazz-icon{ + height: 30px; + width: 30px; + } +` + const PeersInfo: React.FC = (props) => { const { peerId, nodeAddress, ...rest } = props; const aliases = useAppSelector((store) => store.node.aliases.data); @@ -31,8 +42,15 @@ const PeersInfo: React.FC = (props) => { window.location.hostname === '127.0.0.1' ); + const icon = nodeAddress && generateBase64Jazz(nodeAddress); + return ( -
+ +
{peerId} navigator.clipboard.writeText(peerId as string)} @@ -57,7 +75,7 @@ const PeersInfo: React.FC = (props) => {
-
+ ); } From 503dada6ca1dd81405e57df552d3b5dfbfdfc34a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadach?= Date: Mon, 2 Dec 2024 12:04:58 +0100 Subject: [PATCH 12/20] scalar icon changed --- public/assets/scalar-removebg-preview.png | Bin 12819 -> 4126 bytes .../Modal/node/OpenChannelModal.tsx | 7 +++++++ src/components/Modal/node/PingModal.tsx | 11 +++++++++-- .../PeerInfo/index.tsx | 14 ++++++++------ src/pages/node/info/index.tsx | 2 +- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/public/assets/scalar-removebg-preview.png b/public/assets/scalar-removebg-preview.png index 95f3d63b61f0854daf9cd5a4f3852b7c1aa64a7a..cc18facfc6f352221987149ce199bab25db961ef 100644 GIT binary patch literal 4126 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 literal 12819 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 { const dispatch = useAppDispatch(); const loginData = useAppSelector((store) => store.auth.loginData); const outgoingOpening = useAppSelector((store) => store.node.channels.parsed.outgoingOpening); + const aliases = useAppSelector((store) => store.node.aliases.data); + const peerIdToAliasLink = useAppSelector((store) => store.node.links.peerIdToAlias); const channelIsBeingOpened = props.peerAddress ? !!outgoingOpening[props.peerAddress] : false; const [openChannelModal, set_openChannelModal] = useState(false); const [amount, set_amount] = useState(''); const [peerAddress, set_peerAddress] = useState(props.peerAddress ? props.peerAddress : ''); + const getAliasByPeerId = (peerId: string): string => { + if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${peerId})`; + return peerId + }; + const handleOpenChannelDialog = () => { set_openChannelModal(true); }; diff --git a/src/components/Modal/node/PingModal.tsx b/src/components/Modal/node/PingModal.tsx index acdfaf2f..642d714a 100644 --- a/src/components/Modal/node/PingModal.tsx +++ b/src/components/Modal/node/PingModal.tsx @@ -22,10 +22,17 @@ type PingModalProps = { export const PingModal = (props: PingModalProps) => { const dispatch = useAppDispatch(); const loginData = useAppSelector((selector) => selector.auth.loginData); + const aliases = useAppSelector((store) => store.node.aliases.data); + const peerIdToAliasLink = useAppSelector((store) => store.node.links.peerIdToAlias); const [peerId, set_peerId] = useState(props.peerId ? props.peerId : ''); const [openModal, set_OpenModal] = useState(false); const [disableButton, set_disableButton] = useState(false); + const getAliasByPeerId = (peerId: string): string => { + if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${peerId})`; + return peerId + }; + const handleChange = (event: React.ChangeEvent) => { set_peerId(event.target.value); }; @@ -57,7 +64,7 @@ export const PingModal = (props: PingModalProps) => { ) .unwrap() .then((resp: any) => { - const msg = `Ping of ${peerId} succeded with latency of ${resp.latency}ms`; + const msg = `Ping of ${getAliasByPeerId(peerId)} succeeded with latency of ${resp.latency}ms`; console.log(msg, resp); sendNotification({ notificationPayload: { @@ -76,7 +83,7 @@ export const PingModal = (props: PingModalProps) => { ).unwrap(); if (!isCurrentApiEndpointTheSame) return; - let errMsg = `Ping of ${peerId} failed`; + let errMsg = `Ping of ${getAliasByPeerId(peerId)} failed`; if (e instanceof sdkApiError && e.hoprdErrorPayload?.status) errMsg = errMsg + `.\n${e.hoprdErrorPayload.status}`; if (e instanceof sdkApiError && e.hoprdErrorPayload?.error) diff --git a/src/future-hopr-lib-components/PeerInfo/index.tsx b/src/future-hopr-lib-components/PeerInfo/index.tsx index 6a794eb5..8fd9f90f 100644 --- a/src/future-hopr-lib-components/PeerInfo/index.tsx +++ b/src/future-hopr-lib-components/PeerInfo/index.tsx @@ -32,8 +32,9 @@ const PeersInfo: React.FC = (props) => { const getAliasByPeerId = (peerId: string): string => { - if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${peerId})`; - return peerId; + const shortPeerId = peerId && `${peerId.substring(0, 6)}...${peerId.substring(peerId.length - 8, peerId.length)}`; + if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${shortPeerId})`; + return shortPeerId }; const noCopyPaste = !( @@ -48,21 +49,22 @@ const PeersInfo: React.FC = (props) => {
- {peerId} {peerId && getAliasByPeerId(peerId)} navigator.clipboard.writeText(peerId as string)} disabled={noCopyPaste} - tooltip={noCopyPaste ? 'Clipboard not supported on HTTP' : 'Copy'} + tooltip={noCopyPaste ? 'Clipboard not supported on HTTP' : 'Copy Peer Id'} >
{nodeAddress} navigator.clipboard.writeText(nodeAddress as string)} disabled={noCopyPaste} - tooltip={noCopyPaste ? 'Clipboard not supported on HTTP' : 'Copy'} + tooltip={noCopyPaste ? 'Clipboard not supported on HTTP' : 'Copy Node Address'} > diff --git a/src/pages/node/info/index.tsx b/src/pages/node/info/index.tsx index 8ed57be2..62ca8fc4 100644 --- a/src/pages/node/info/index.tsx +++ b/src/pages/node/info/index.tsx @@ -205,7 +205,7 @@ function InfoPage() { onClick={()=>{window.open(apiEndpoint + '/swagger-ui/index.html#/', '_blank').focus();}} /> } + iconComponent={} tooltipText={ OPEN From 519872af53277fd84d367e25fa1f9be48e07657f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadach?= Date: Mon, 2 Dec 2024 12:54:25 +0100 Subject: [PATCH 13/20] sortable tables --- .../Table/table-pro.tsx | 56 +++++++++++++++++-- src/pages/node/aliases.tsx | 1 + src/pages/node/channelsIncoming.tsx | 2 + src/pages/node/channelsOutgoing.tsx | 16 +++--- src/pages/node/peers.tsx | 2 +- src/store/slices/node/actionsAsync.ts | 1 - 6 files changed, 65 insertions(+), 13 deletions(-) diff --git a/src/future-hopr-lib-components/Table/table-pro.tsx b/src/future-hopr-lib-components/Table/table-pro.tsx index c5f28892..b056779e 100644 --- a/src/future-hopr-lib-components/Table/table-pro.tsx +++ b/src/future-hopr-lib-components/Table/table-pro.tsx @@ -148,6 +148,45 @@ interface Props { search?: boolean; loading?: boolean; onRowClick?: Function; + orderByDefault?: string; +} + +type Order = 'asc' | 'desc'; + +const isString = (value: any) => typeof value === 'string' || value instanceof String; + +function descendingComparator(a: { [key in string]: number | string }, b: { [key in string]: number | string }, orderBy: string) { + console.log(a, b, orderBy); + + if(isString(b[orderBy]) && isString(a[orderBy])){ + if (b[orderBy].toLowerCase() < a[orderBy].toLowerCase()) { + return -1; + } + if (b[orderBy].toLowerCase() > a[orderBy].toLowerCase()) { + return 1; + } + } + + if (b[orderBy] < a[orderBy]) { + return -1; + } + if (b[orderBy] > a[orderBy]) { + return 1; + } + + return 0; +} + +function getComparator( + order: Order, + orderBy: string, +): ( + a: { [key in Key]: number | string }, + b: { [key in Key]: number | string }, +) => number { + return order === 'desc' + ? (a, b) => descendingComparator(a, b, orderBy) + : (a, b) => -descendingComparator(a, b, orderBy); } export default function CustomPaginationActionsTable(props: Props) { @@ -156,6 +195,8 @@ export default function CustomPaginationActionsTable(props: Props) { const [rowsPerPage, set_RowsPerPage] = React.useState( props.id && rowsPerPageFromLocalStorage ? rowsPerPageFromLocalStorage : 10, ); + const [order, setOrder] = React.useState('asc'); + const [orderBy, setOrderBy] = React.useState(props.orderByDefault || props.header[0].key || 'id'); const [searchPhrase, set_searchPhrase] = React.useState(''); const [filteredData, set_filteredData] = React.useState([]); @@ -212,6 +253,16 @@ export default function CustomPaginationActionsTable(props: Props) { return; } + + const visibleRows = React.useMemo( + () => + [...filteredData] + //@ts-ignore as we can input JSX into the data, but we will not sort by it + .sort(getComparator(order, orderBy)) + .slice(page * rowsPerPage, rowsPerPage !== -1 ? page * rowsPerPage + rowsPerPage : filteredData.length), + [rowsPerPage, filteredData, order, orderBy, page, rowsPerPage], + ); + return ( - {(rowsPerPage > 0 - ? filteredData.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) - : filteredData - ).map((row) => ( + {visibleRows.map((row) => ( ); diff --git a/src/pages/node/channelsIncoming.tsx b/src/pages/node/channelsIncoming.tsx index 57f7243d..c3710810 100644 --- a/src/pages/node/channelsIncoming.tsx +++ b/src/pages/node/channelsIncoming.tsx @@ -219,6 +219,7 @@ function ChannelsPage() { return { id: (index + 1).toString(), + number: parseInt(id), key: id, node: ); diff --git a/src/pages/node/channelsOutgoing.tsx b/src/pages/node/channelsOutgoing.tsx index e22c66d1..f2d550d0 100644 --- a/src/pages/node/channelsOutgoing.tsx +++ b/src/pages/node/channelsOutgoing.tsx @@ -204,6 +204,7 @@ function ChannelsPage() { return { id: index.toString(), key: id, + number: parseInt(id), node: elem !== undefined) as { - id: string; - key: string; - peerAddress: string; - status: 'Open' | 'PendingToClose' | 'Closed'; - funds: string; - actions: JSX.Element; - }[]; + id: string; + key: string; + peerAddress: string; + status: 'Open' | 'PendingToClose' | 'Closed'; + funds: string; + actions: JSX.Element; + }[]; return (
); diff --git a/src/pages/node/peers.tsx b/src/pages/node/peers.tsx index 7ca987bf..aff4573f 100644 --- a/src/pages/node/peers.tsx +++ b/src/pages/node/peers.tsx @@ -128,7 +128,7 @@ function PeersPage() { const parsedTableData = Object.entries(peers?.connected ?? {}).map(([id, peer]) => { return { id: id, - number: id, + number: parseInt(id), node: { try { const configuration = await getConfiguration(payload); - console.log('Configuration:\n', configuration); return configuration; } catch (e) { if (e instanceof sdkApiError) { From 3ae68be867ee004ee7ba82dac9abe6b760fbccc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadach?= Date: Mon, 2 Dec 2024 13:00:48 +0100 Subject: [PATCH 14/20] format --- src/components/ConnectNode/index.tsx | 15 ++- src/components/ConnectNode/modal.tsx | 2 +- .../Modal/node/OpenChannelModal.tsx | 2 +- src/components/Modal/node/PingModal.tsx | 2 +- .../PeerInfo/index.tsx | 120 +++++++++--------- .../Select/index.tsx | 8 +- .../Table/table-pro.tsx | 14 +- src/pages/node/aliases.tsx | 14 +- src/pages/node/channelsIncoming.tsx | 12 +- src/pages/node/channelsOutgoing.tsx | 27 ++-- src/pages/node/configuration.tsx | 36 +++--- src/pages/node/info/index.tsx | 72 ++++++----- src/pages/node/peers.tsx | 12 +- src/router.tsx | 2 +- src/store/slices/auth/index.ts | 4 +- src/store/slices/node/actionsAsync.ts | 12 +- 16 files changed, 191 insertions(+), 163 deletions(-) diff --git a/src/components/ConnectNode/index.tsx b/src/components/ConnectNode/index.tsx index 744cd86c..13c1eb54 100644 --- a/src/components/ConnectNode/index.tsx +++ b/src/components/ConnectNode/index.tsx @@ -105,10 +105,13 @@ export default function ConnectNode() { const peerId = useAppSelector((store) => store.node.addresses.data.hopr); const localNameFromLocalStorage = useAppSelector((store) => store.auth.loginData.localName); const jazzIconFromLocalStorage = useAppSelector((store) => store.auth.loginData.jazzIcon); - const nodeAddress = useAppSelector((store) => store.node.addresses.data.native); + const nodeAddress = useAppSelector((store) => store.node.addresses.data.native); const localNameToDisplay = localNameFromLocalStorage && localNameFromLocalStorage.length > 17 - ? `${localNameFromLocalStorage?.substring(0, 5)}…${localNameFromLocalStorage?.substring(localNameFromLocalStorage.length - 11, localNameFromLocalStorage.length)}` + ? `${localNameFromLocalStorage?.substring(0, 5)}…${localNameFromLocalStorage?.substring( + localNameFromLocalStorage.length - 11, + localNameFromLocalStorage.length, + )}` : localNameFromLocalStorage; const apiEndpoint = useAppSelector((store) => store.auth.loginData.apiEndpoint); const [nodeAddressIcon, set_nodeAddressIcon] = useState(null); @@ -133,9 +136,11 @@ export default function ConnectNode() { useEffect(() => { if (!connected) set_nodeAddressIcon(null); if (!apiEndpoint) return; - console.log(jazzIconFromLocalStorage) + console.log(jazzIconFromLocalStorage); const md5 = toHexMD5(apiEndpoint); - const b64 = generateBase64Jazz(nodeAddress ? nodeAddress : jazzIconFromLocalStorage ? jazzIconFromLocalStorage : md5); + const b64 = generateBase64Jazz( + nodeAddress ? nodeAddress : jazzIconFromLocalStorage ? jazzIconFromLocalStorage : md5, + ); if (connected && b64) set_nodeAddressIcon(b64); }, [connected, apiEndpoint, nodeAddress, jazzIconFromLocalStorage]); @@ -196,7 +201,7 @@ export default function ConnectNode() { id="jazz-icon-node" >
diff --git a/src/components/ConnectNode/modal.tsx b/src/components/ConnectNode/modal.tsx index ee8003cb..eaa4c035 100644 --- a/src/components/ConnectNode/modal.tsx +++ b/src/components/ConnectNode/modal.tsx @@ -265,7 +265,7 @@ function ConnectNodeModal(props: ConnectNodeModalProps) { apiEndpoint: formattedApiEndpoint, apiToken, localName, - jazzIcon + jazzIcon, }), ); dispatch( diff --git a/src/components/Modal/node/OpenChannelModal.tsx b/src/components/Modal/node/OpenChannelModal.tsx index f6af6e52..b9867188 100644 --- a/src/components/Modal/node/OpenChannelModal.tsx +++ b/src/components/Modal/node/OpenChannelModal.tsx @@ -37,7 +37,7 @@ export const OpenChannelModal = ({ ...props }: OpenChannelModalProps) => { const getAliasByPeerId = (peerId: string): string => { if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${peerId})`; - return peerId + return peerId; }; const handleOpenChannelDialog = () => { diff --git a/src/components/Modal/node/PingModal.tsx b/src/components/Modal/node/PingModal.tsx index 642d714a..71765884 100644 --- a/src/components/Modal/node/PingModal.tsx +++ b/src/components/Modal/node/PingModal.tsx @@ -30,7 +30,7 @@ export const PingModal = (props: PingModalProps) => { const getAliasByPeerId = (peerId: string): string => { if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${peerId})`; - return peerId + return peerId; }; const handleChange = (event: React.ChangeEvent) => { diff --git a/src/future-hopr-lib-components/PeerInfo/index.tsx b/src/future-hopr-lib-components/PeerInfo/index.tsx index 8fd9f90f..321df066 100644 --- a/src/future-hopr-lib-components/PeerInfo/index.tsx +++ b/src/future-hopr-lib-components/PeerInfo/index.tsx @@ -12,74 +12,74 @@ import CopyIcon from '@mui/icons-material/ContentCopy'; import LaunchIcon from '@mui/icons-material/Launch'; interface Props { - peerId?: string; - nodeAddress?: string; + peerId?: string; + nodeAddress?: string; } const Container = styled.div` - display: flex; - align-items: center; - .node-jazz-icon{ - height: 30px; - width: 30px; - } -` + display: flex; + align-items: center; + .node-jazz-icon { + height: 30px; + width: 30px; + } +`; const PeersInfo: React.FC = (props) => { - const { peerId, nodeAddress, ...rest } = props; - const aliases = useAppSelector((store) => store.node.aliases.data); - const peerIdToAliasLink = useAppSelector((store) => store.node.links.peerIdToAlias); + const { peerId, nodeAddress, ...rest } = props; + const aliases = useAppSelector((store) => store.node.aliases.data); + const peerIdToAliasLink = useAppSelector((store) => store.node.links.peerIdToAlias); + const getAliasByPeerId = (peerId: string): string => { + const shortPeerId = peerId && `${peerId.substring(0, 6)}...${peerId.substring(peerId.length - 8, peerId.length)}`; + if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${shortPeerId})`; + return shortPeerId; + }; - const getAliasByPeerId = (peerId: string): string => { - const shortPeerId = peerId && `${peerId.substring(0, 6)}...${peerId.substring(peerId.length - 8, peerId.length)}`; - if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${shortPeerId})`; - return shortPeerId - }; + const noCopyPaste = !( + window.location.protocol === 'https:' || + window.location.hostname === 'localhost' || + window.location.hostname === '127.0.0.1' + ); - const noCopyPaste = !( - window.location.protocol === 'https:' || - window.location.hostname === 'localhost' || - window.location.hostname === '127.0.0.1' - ); + const icon = nodeAddress && generateBase64Jazz(nodeAddress); - const icon = nodeAddress && generateBase64Jazz(nodeAddress); - - return ( - - -
- - {peerId && getAliasByPeerId(peerId)} navigator.clipboard.writeText(peerId as string)} - disabled={noCopyPaste} - tooltip={noCopyPaste ? 'Clipboard not supported on HTTP' : 'Copy Peer Id'} - > - -
- {nodeAddress} navigator.clipboard.writeText(nodeAddress as string)} - disabled={noCopyPaste} - tooltip={noCopyPaste ? 'Clipboard not supported on HTTP' : 'Copy Node Address'} - > - - - - - - - -
-
- - ); -} + return ( + + +
+ {peerId && getAliasByPeerId(peerId)}{' '} + navigator.clipboard.writeText(peerId as string)} + disabled={noCopyPaste} + tooltip={noCopyPaste ? 'Clipboard not supported on HTTP' : 'Copy Peer Id'} + > + + +
+ {nodeAddress}{' '} + navigator.clipboard.writeText(nodeAddress as string)} + disabled={noCopyPaste} + tooltip={noCopyPaste ? 'Clipboard not supported on HTTP' : 'Copy Node Address'} + > + + + + + + + +
+
+ ); +}; export default PeersInfo; diff --git a/src/future-hopr-lib-components/Select/index.tsx b/src/future-hopr-lib-components/Select/index.tsx index 6f005fc8..988bde87 100644 --- a/src/future-hopr-lib-components/Select/index.tsx +++ b/src/future-hopr-lib-components/Select/index.tsx @@ -57,7 +57,7 @@ interface Props extends SelectMuiProps { } const Select: React.FC = (props) => { - console.log('props.values', props.values) + console.log('props.values', props.values); return ( = (props) => { {props.values && props.values.map((elem, index) => { const jazzMd5apiEndpoint = elem.apiEndpoint && toHexMD5(elem.apiEndpoint); - const icon = elem.jazzIcon ? generateBase64Jazz(elem.jazzIcon) : jazzMd5apiEndpoint && generateBase64Jazz(jazzMd5apiEndpoint); + const icon = elem.jazzIcon + ? generateBase64Jazz(elem.jazzIcon) + : jazzMd5apiEndpoint && generateBase64Jazz(jazzMd5apiEndpoint); return ( = (props) => { )} {elem.name} diff --git a/src/future-hopr-lib-components/Table/table-pro.tsx b/src/future-hopr-lib-components/Table/table-pro.tsx index b056779e..a77ce43d 100644 --- a/src/future-hopr-lib-components/Table/table-pro.tsx +++ b/src/future-hopr-lib-components/Table/table-pro.tsx @@ -155,10 +155,14 @@ type Order = 'asc' | 'desc'; const isString = (value: any) => typeof value === 'string' || value instanceof String; -function descendingComparator(a: { [key in string]: number | string }, b: { [key in string]: number | string }, orderBy: string) { +function descendingComparator( + a: { [key in string]: number | string }, + b: { [key in string]: number | string }, + orderBy: string, +) { console.log(a, b, orderBy); - if(isString(b[orderBy]) && isString(a[orderBy])){ + if (isString(b[orderBy]) && isString(a[orderBy])) { if (b[orderBy].toLowerCase() < a[orderBy].toLowerCase()) { return -1; } @@ -180,10 +184,7 @@ function descendingComparator(a: { [key in string]: number | string }, b: { [ function getComparator( order: Order, orderBy: string, -): ( - a: { [key in Key]: number | string }, - b: { [key in Key]: number | string }, -) => number { +): (a: { [key in Key]: number | string }, b: { [key in Key]: number | string }) => number { return order === 'desc' ? (a, b) => descendingComparator(a, b, orderBy) : (a, b) => -descendingComparator(a, b, orderBy); @@ -253,7 +254,6 @@ export default function CustomPaginationActionsTable(props: Props) { return; } - const visibleRows = React.useMemo( () => [...filteredData] diff --git a/src/pages/node/aliases.tsx b/src/pages/node/aliases.tsx index 24406ad3..62716e33 100644 --- a/src/pages/node/aliases.tsx +++ b/src/pages/node/aliases.tsx @@ -127,10 +127,12 @@ function AliasesPage() { id: peerId, key: key.toString(), alias, - node: , + node: ( + + ), peerId, peerAddress: peerAddress ?? '', actions: ( @@ -207,7 +209,7 @@ function AliasesPage() { width: '168px', maxWidth: '168px', }, - ] + ]; return (
); diff --git a/src/pages/node/channelsIncoming.tsx b/src/pages/node/channelsIncoming.tsx index c3710810..e4923e8e 100644 --- a/src/pages/node/channelsIncoming.tsx +++ b/src/pages/node/channelsIncoming.tsx @@ -221,10 +221,12 @@ function ChannelsPage() { id: (index + 1).toString(), number: parseInt(id), key: id, - node: , + node: ( + + ), peerAddress: getAliasByPeerAddress(peerAddress as string), peerId: peerId, status: channelsIncomingObject[id].status, @@ -343,7 +345,7 @@ function ChannelsPage() { header={headerIncoming} search loading={parsedTableData.length === 0 && channelsFetching} - orderByDefault='number' + orderByDefault="number" /> ); diff --git a/src/pages/node/channelsOutgoing.tsx b/src/pages/node/channelsOutgoing.tsx index f2d550d0..ceea5a18 100644 --- a/src/pages/node/channelsOutgoing.tsx +++ b/src/pages/node/channelsOutgoing.tsx @@ -200,15 +200,16 @@ function ChannelsPage() { const peerAddress = channelsOutgoingObject[id].peerAddress; const peerId = getPeerIdFromPeerAddress(peerAddress as string); - return { id: index.toString(), key: id, number: parseInt(id), - node: , + node: ( + + ), peerAddress: getAliasByPeerAddress(peerAddress as string), peerId: peerId, status: channelsOutgoingObject[id].status as string, @@ -279,13 +280,13 @@ function ChannelsPage() { }; }) .filter((elem) => elem !== undefined) as { - id: string; - key: string; - peerAddress: string; - status: 'Open' | 'PendingToClose' | 'Closed'; - funds: string; - actions: JSX.Element; - }[]; + id: string; + key: string; + peerAddress: string; + status: 'Open' | 'PendingToClose' | 'Closed'; + funds: string; + actions: JSX.Element; + }[]; return (
); diff --git a/src/pages/node/configuration.tsx b/src/pages/node/configuration.tsx index 460b6159..20785f0f 100644 --- a/src/pages/node/configuration.tsx +++ b/src/pages/node/configuration.tsx @@ -28,21 +28,13 @@ interface StrategyConfig { value: string; } -const calculateTickets = ( - value: string, - ticketPrice: string, -) => { +const calculateTickets = (value: string, ticketPrice: string) => { const valueBigInt = BigInt(value) * DECIMALS_MULTIPLIER; const ticketBigInt = BigInt(ticketPrice); return valueBigInt / ticketBigInt; }; -const updateStrategyString = ( - originalString: string, - key: string, - value: string, - tickets: bigint -): string => { +const updateStrategyString = (originalString: string, key: string, value: string, tickets: bigint): string => { const stringToReplace = `"${key}": "${value} HOPR"`; const formattedEther = formatEther(BigInt(value)); const replacement = `"${key}": "${value}" // ${formattedEther} HOPR, tickets: ${rounder(Number(tickets))}`; @@ -52,7 +44,6 @@ const updateStrategyString = ( : originalString.replace(stringToReplace, replacement); }; - function SettingsPage() { const dispatch = useAppDispatch(); const prevNotificationSettings = useAppSelector((store) => store.app.configuration.notifications); @@ -75,13 +66,25 @@ function SettingsPage() { try { const configs: StrategyConfig[] = [ - { path: ['AutoFunding', 'min_stake_threshold'], value: strategies.strategies?.AutoFunding?.min_stake_threshold?.replace(' HOPR', '') }, - { path: ['AutoFunding', 'funding_amount'], value: strategies.strategies?.AutoFunding?.funding_amount?.replace(' HOPR', '') }, - { path: ['AutoRedeeming', 'minimum_redeem_ticket_value'], value: strategies.strategies?.AutoRedeeming?.minimum_redeem_ticket_value?.replace(' HOPR', '') }, - { path: ['AutoRedeeming', 'on_close_redeem_single_tickets_value_min'], value: strategies.strategies?.AutoRedeeming?.on_close_redeem_single_tickets_value_min?.replace(' HOPR', '') }, + { + path: ['AutoFunding', 'min_stake_threshold'], + value: strategies.strategies?.AutoFunding?.min_stake_threshold?.replace(' HOPR', ''), + }, + { + path: ['AutoFunding', 'funding_amount'], + value: strategies.strategies?.AutoFunding?.funding_amount?.replace(' HOPR', ''), + }, + { + path: ['AutoRedeeming', 'minimum_redeem_ticket_value'], + value: strategies.strategies?.AutoRedeeming?.minimum_redeem_ticket_value?.replace(' HOPR', ''), + }, + { + path: ['AutoRedeeming', 'on_close_redeem_single_tickets_value_min'], + value: strategies.strategies?.AutoRedeeming?.on_close_redeem_single_tickets_value_min?.replace(' HOPR', ''), + }, ]; - console.log('configs', configs) + console.log('configs', configs); let result = JSON.stringify(strategies, null, 2); @@ -107,7 +110,6 @@ function SettingsPage() { } }, [configuration]); - const handleSaveSettings = async () => { if (localNotificationSettings) { dispatch(appActions.setNotificationSettings(localNotificationSettings)); diff --git a/src/pages/node/info/index.tsx b/src/pages/node/info/index.tsx index 62ca8fc4..ea48629a 100644 --- a/src/pages/node/info/index.tsx +++ b/src/pages/node/info/index.tsx @@ -62,9 +62,10 @@ function InfoPage() { const blockNumberFromInfo = useAppSelector((store) => store.node.info.data?.indexerBlock); // >=2.1.3 const blockNumberCheckSumFromInfo = useAppSelector((store) => store.node.info.data?.indexerChecksum); // >=2.1.3 const blockNumberPrevIndexedWithHOPRdata = useAppSelector((store) => store.node.info.data?.indexBlockPrevChecksum); // >=2.1.4 - const blockNumberIndexedWithHOPRdata = blockNumberPrevIndexedWithHOPRdata - ? blockNumberPrevIndexedWithHOPRdata + 1 - : null; + const blockNumberIndexedWithHOPRdata = + blockNumberPrevIndexedWithHOPRdata && blockNumberFromInfo !== blockNumberPrevIndexedWithHOPRdata + ? blockNumberPrevIndexedWithHOPRdata + 1 + : null; const blockNumber = blockNumberFromInfo ?? blockNumberFromMetrics; const blockNumberCheckSum = blockNumberCheckSumFromInfo ?? blockNumberCheckSumFromMetrics; const ticketPrice = useAppSelector((store) => store.node.ticketPrice.data); @@ -190,33 +191,44 @@ function InfoPage() { title="INFO" refreshFunction={fetchInfoData} reloading={isFetchingAnyData} - actions={<> - - } - tooltipText={ - - OPEN -
- Swagger UI -
- } - //@ts-ignore - onClick={()=>{window.open(apiEndpoint + '/swagger-ui/index.html#/', '_blank').focus();}} - /> - } - tooltipText={ - - OPEN -
- Scalar UI -
- } - //@ts-ignore - onClick={()=>{window.open(apiEndpoint + '/scalar', '_blank').focus();}} - /> - } + actions={ + <> + + } + tooltipText={ + + OPEN +
+ Swagger UI +
+ } + //@ts-ignore + onClick={() => { + window.open(apiEndpoint + '/swagger-ui/index.html#/', '_blank').focus(); + }} + /> + + } + tooltipText={ + + OPEN +
+ Scalar UI +
+ } + //@ts-ignore + onClick={() => { + window.open(apiEndpoint + '/scalar', '_blank').focus(); + }} + /> + + } /> { return { id: id, number: parseInt(id), - node: , + node: ( + + ), peerId: getAliasByPeerId(peer.peerId), peerAddress: peer.peerAddress, quality: , diff --git a/src/router.tsx b/src/router.tsx index fd8867be..c77c20bd 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -234,7 +234,7 @@ const LayoutEnhanced = () => { dispatch( authActions.useNodeData({ apiEndpoint, - apiToken: apiToken ? apiToken : '' + apiToken: apiToken ? apiToken : '', }), ); dispatch(nodeActions.setApiEndpoint({ apiEndpoint: formattedApiEndpoint })); diff --git a/src/store/slices/auth/index.ts b/src/store/slices/auth/index.ts index e938b7e6..e9f392b6 100644 --- a/src/store/slices/auth/index.ts +++ b/src/store/slices/auth/index.ts @@ -37,7 +37,7 @@ const authSlice = createSlice({ if (!jazzIcon) { const existingItem = state.nodes.findIndex((item) => item.apiEndpoint === action.payload.apiEndpoint); if (existingItem !== -1) - jazzIcon = state.nodes[existingItem].jazzIcon ? state.nodes[existingItem].jazzIcon as string : null; + jazzIcon = state.nodes[existingItem].jazzIcon ? (state.nodes[existingItem].jazzIcon as string) : null; } state.loginData.apiEndpoint = action.payload.apiEndpoint; @@ -85,7 +85,7 @@ const authSlice = createSlice({ ) { const existingItem = state.nodes.findIndex((item) => item.apiEndpoint === action.payload.apiEndpoint); if (existingItem === -1) return; - if(isAddress(action.payload.jazzIcon)) { + if (isAddress(action.payload.jazzIcon)) { state.nodes[existingItem].jazzIcon = action.payload.jazzIcon; } else { state.nodes[existingItem].jazzIcon = action.payload.jazzIcon; diff --git a/src/store/slices/node/actionsAsync.ts b/src/store/slices/node/actionsAsync.ts index f0822f72..9ac693a9 100644 --- a/src/store/slices/node/actionsAsync.ts +++ b/src/store/slices/node/actionsAsync.ts @@ -147,11 +147,13 @@ const getAddressesThunk = createAsyncThunk< dispatch(nodeActionsFetching.setAddressesFetching(true)); try { const addresses = await getAddresses(payload); - if(addresses?.native){ - dispatch(authActions.addNodeJazzIcon({ - apiEndpoint: payload.apiEndpoint as string, - jazzIcon: addresses.native - })); + if (addresses?.native) { + dispatch( + authActions.addNodeJazzIcon({ + apiEndpoint: payload.apiEndpoint as string, + jazzIcon: addresses.native, + }), + ); } return addresses; } catch (e) { From aa6036e87d53c180180ccd3a6500ba3a84f22154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadach?= Date: Mon, 2 Dec 2024 13:13:33 +0100 Subject: [PATCH 15/20] fix build errors --- config.ts | 2 +- package.json | 3 +-- scripts/post-build.js | 13 ---------- scripts/prepare-build-hub.js | 22 ---------------- scripts/prepare-build-node.js | 25 ------------------- .../Table/table-pro.tsx | 8 +++--- src/pages/node/info/index.tsx | 10 +++++--- 7 files changed, 11 insertions(+), 72 deletions(-) delete mode 100644 scripts/post-build.js delete mode 100644 scripts/prepare-build-hub.js delete mode 100644 scripts/prepare-build-node.js diff --git a/config.ts b/config.ts index f92fad5f..16a39c32 100644 --- a/config.ts +++ b/config.ts @@ -1,4 +1,4 @@ -export const environment: 'dev' | 'node' | 'web3' = 'node'; //'node'; +export const environment: 'dev' | 'node' | 'web3' = 'node'; //'node'; //'node'; // Smart Contracts export const mHOPR_TOKEN_SMART_CONTRACT_ADDRESS = '0x66225dE86Cac02b32f34992eb3410F59DE416698'; diff --git a/package.json b/package.json index c4cd1e71..2f9e8792 100644 --- a/package.json +++ b/package.json @@ -49,8 +49,7 @@ "dev": "vite", "dev:clean": "npm run dev -- --force", "build-vite": "tsc && vite build", - "build-hub": "node ./scripts/prepare-build-hub.js && tsc && vite build && node ./scripts/post-build.js", - "build": "node ./scripts/prepare-build-node.js && tsc && vite build && node ./scripts/post-build.js", + "build": "tsc && vite build", "test": "echo \"Error: no test specified\" && exit 0", "serve": "vite preview --port 3000", "format": "prettier --write src/ .github/ *.ts *.json *.md", diff --git a/scripts/post-build.js b/scripts/post-build.js deleted file mode 100644 index 90ec348d..00000000 --- a/scripts/post-build.js +++ /dev/null @@ -1,13 +0,0 @@ -const fs = require('fs'); - -configPath = `${__dirname.replace('scripts', 'config.ts')}`; - -fs.unlink(configPath, function (err) { - if (err) { throw err } - else { - fs.rename(`${configPath}_`, configPath, function (err) { - if (err) throw err - console.log('Original config brought back.') - }); - } -}); \ No newline at end of file diff --git a/scripts/prepare-build-hub.js b/scripts/prepare-build-hub.js deleted file mode 100644 index 0160e133..00000000 --- a/scripts/prepare-build-hub.js +++ /dev/null @@ -1,22 +0,0 @@ -const fs = require('fs'); -configPath = `${__dirname.replace('scripts', 'config.ts')}`; - -fs.copyFile(configPath, `${configPath}_`, (err) => { - if (err) { - console.log("Error Found:", err); - } else { - console.log("Config backed up."); - - fs.readFile(configPath, function(err, data) { - if(err) throw err; - data = data.toString(); - data = data.replace(`export const environment: 'dev' | 'node' | 'web3' = `, `export const environment:('dev' | 'node' | 'web3') = 'web3'; //`); - fs.writeFile(configPath, data, function(err) { - err || console.log('Data replaced to build only Staking Hub.'); - }); - }); - - } -}); - - diff --git a/scripts/prepare-build-node.js b/scripts/prepare-build-node.js deleted file mode 100644 index 74b8f7b6..00000000 --- a/scripts/prepare-build-node.js +++ /dev/null @@ -1,25 +0,0 @@ -const fs = require('fs'); -configPath = `${__dirname.replace('scripts', 'config.ts')}`; - - -fs.copyFile(configPath, `${configPath}_`, (err) => { - if (err) { - console.log("Error Found:", err); - } else { - console.log("Config backed up."); - - fs.readFile(configPath, function(err, data) { - if(err) throw err; - data = data.toString(); - data = data.replace(`export const environment: 'dev' | 'node' | 'web3' = `, `export const environment:('dev' | 'node' | 'web3') = 'node'; //`); - fs.writeFile(configPath, data, function(err) { - err || console.log('Data replaced to build only Node Admin.'); - }); - }); - - } -}); - - - - diff --git a/src/future-hopr-lib-components/Table/table-pro.tsx b/src/future-hopr-lib-components/Table/table-pro.tsx index a77ce43d..428a8606 100644 --- a/src/future-hopr-lib-components/Table/table-pro.tsx +++ b/src/future-hopr-lib-components/Table/table-pro.tsx @@ -128,7 +128,7 @@ const STextField = styled(TextField)` interface Props { data: { - [key: string]: string | JSX.Element; + [key: string]: string | number | JSX.Element; id: string; actions: JSX.Element; }[]; @@ -160,13 +160,11 @@ function descendingComparator( b: { [key in string]: number | string }, orderBy: string, ) { - console.log(a, b, orderBy); - if (isString(b[orderBy]) && isString(a[orderBy])) { - if (b[orderBy].toLowerCase() < a[orderBy].toLowerCase()) { + if ((b[orderBy] as string).toLowerCase() < (a[orderBy] as string).toLowerCase()) { return -1; } - if (b[orderBy].toLowerCase() > a[orderBy].toLowerCase()) { + if ((b[orderBy] as string).toLowerCase() > (a[orderBy] as string).toLowerCase()) { return 1; } } diff --git a/src/pages/node/info/index.tsx b/src/pages/node/info/index.tsx index ea48629a..b63c1c81 100644 --- a/src/pages/node/info/index.tsx +++ b/src/pages/node/info/index.tsx @@ -203,9 +203,10 @@ function InfoPage() { Swagger UI } - //@ts-ignore onClick={() => { - window.open(apiEndpoint + '/swagger-ui/index.html#/', '_blank').focus(); + const externalUrl = apiEndpoint + '/swagger-ui/index.html#/'; + const w = window.open(externalUrl, '_blank'); + w && w.focus(); }} /> } - //@ts-ignore onClick={() => { - window.open(apiEndpoint + '/scalar', '_blank').focus(); + const externalUrl = apiEndpoint + '/scalar'; + const w = window.open(externalUrl, '_blank'); + w && w.focus(); }} /> From 7fe7f2a37769dda05ff0ebd742e0025d7aeddfa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadach?= Date: Mon, 2 Dec 2024 14:49:13 +0100 Subject: [PATCH 16/20] sort peers subpage --- .../PeerInfo/index.tsx | 7 +++- .../Table/table-pro.tsx | 8 +++- src/pages/node/channelsIncoming.tsx | 2 +- src/pages/node/channelsOutgoing.tsx | 4 +- src/pages/node/peers.tsx | 39 +++++++++++++------ 5 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/future-hopr-lib-components/PeerInfo/index.tsx b/src/future-hopr-lib-components/PeerInfo/index.tsx index 321df066..2f44310c 100644 --- a/src/future-hopr-lib-components/PeerInfo/index.tsx +++ b/src/future-hopr-lib-components/PeerInfo/index.tsx @@ -11,9 +11,11 @@ import { generateBase64Jazz } from '../../utils/functions'; import CopyIcon from '@mui/icons-material/ContentCopy'; import LaunchIcon from '@mui/icons-material/Launch'; + interface Props { peerId?: string; nodeAddress?: string; + shortenPeerId?: boolean; } const Container = styled.div` @@ -32,8 +34,9 @@ const PeersInfo: React.FC = (props) => { const getAliasByPeerId = (peerId: string): string => { const shortPeerId = peerId && `${peerId.substring(0, 6)}...${peerId.substring(peerId.length - 8, peerId.length)}`; - if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${shortPeerId})`; - return shortPeerId; + const displayPeerId = props.shortenPeerId ? shortPeerId : peerId; + if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${displayPeerId})`; + return displayPeerId; }; const noCopyPaste = !( diff --git a/src/future-hopr-lib-components/Table/table-pro.tsx b/src/future-hopr-lib-components/Table/table-pro.tsx index 428a8606..16a40555 100644 --- a/src/future-hopr-lib-components/Table/table-pro.tsx +++ b/src/future-hopr-lib-components/Table/table-pro.tsx @@ -129,7 +129,7 @@ const STextField = styled(TextField)` interface Props { data: { [key: string]: string | number | JSX.Element; - id: string; + id: string | number; actions: JSX.Element; }[]; id?: string; @@ -325,7 +325,8 @@ export default function CustomPaginationActionsTable(props: Props) { ))} @@ -352,10 +353,12 @@ export default function CustomPaginationActionsTable(props: Props) { } const CustomTableRow = ({ + id, row, header, onRowClick, }: { + id: string; row: Props['data'][0]; header: Props['header']; onRowClick?: Function; @@ -376,6 +379,7 @@ const CustomTableRow = ({ return ( { onRowClick && onRowClick(row); }} diff --git a/src/pages/node/channelsIncoming.tsx b/src/pages/node/channelsIncoming.tsx index e4923e8e..09edaa7f 100644 --- a/src/pages/node/channelsIncoming.tsx +++ b/src/pages/node/channelsIncoming.tsx @@ -219,12 +219,12 @@ function ChannelsPage() { return { id: (index + 1).toString(), - number: parseInt(id), key: id, node: ( ), peerAddress: getAliasByPeerAddress(peerAddress as string), diff --git a/src/pages/node/channelsOutgoing.tsx b/src/pages/node/channelsOutgoing.tsx index ceea5a18..b5f99960 100644 --- a/src/pages/node/channelsOutgoing.tsx +++ b/src/pages/node/channelsOutgoing.tsx @@ -201,13 +201,13 @@ function ChannelsPage() { const peerId = getPeerIdFromPeerAddress(peerAddress as string); return { - id: index.toString(), + id: (index+1).toString(), key: id, - number: parseInt(id), node: ( ), peerAddress: getAliasByPeerAddress(peerAddress as string), diff --git a/src/pages/node/peers.tsx b/src/pages/node/peers.tsx index bd917176..e2c95c91 100644 --- a/src/pages/node/peers.tsx +++ b/src/pages/node/peers.tsx @@ -77,7 +77,7 @@ function PeersPage() { const header = [ { - key: 'number', + key: 'id', name: '#', }, { @@ -117,20 +117,37 @@ function PeersPage() { }, ]; - const noCopyPaste = !( - window.location.protocol === 'https:' || - window.location.hostname === 'localhost' || - window.location.hostname === '127.0.0.1' - ); + const peersWithAliases = (peers?.connected || []).filter(peer => aliases && peer.peerId && peerIdToAliasLink[peer.peerId]) ; + const peersWithAliasesSorted = peersWithAliases.sort((a, b) => { + if (getAliasByPeerId(b.peerId).toLowerCase() > getAliasByPeerId(a.peerId).toLowerCase()) { + return -1; + } + if (getAliasByPeerId(b.peerId).toLowerCase() < getAliasByPeerId(a.peerId).toLowerCase()) { + return 1; + } + return 0 + }); + const peersWithoutAliases = (peers?.connected || []).filter(peer => aliases && peer.peerId && !peerIdToAliasLink[peer.peerId]) ; + const peersWithoutAliasesSorted = peersWithoutAliases.sort((a, b) => { + if (b.peerId > a.peerId) { + return -1; + } + if (b.peerId < a.peerId) { + return 1; + } + return 0 + }); + + const peersSorted = [...peersWithAliasesSorted, ...peersWithoutAliasesSorted] - const parsedTableData = Object.entries(peers?.connected ?? {}).map(([id, peer]) => { + const parsedTableData = peersSorted.map((peer, index)=>{ return { - id: id, - number: parseInt(id), + id: index+1, node: ( ), peerId: getAliasByPeerId(peer.peerId), @@ -163,8 +180,8 @@ function PeersPage() { ), - }; - }); + } + }) return (
Date: Mon, 2 Dec 2024 14:57:38 +0100 Subject: [PATCH 17/20] sort channels subpages --- src/pages/node/channelsIncoming.tsx | 28 ++++++++++++++++++++++++++-- src/pages/node/channelsOutgoing.tsx | 28 ++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/pages/node/channelsIncoming.tsx b/src/pages/node/channelsIncoming.tsx index 09edaa7f..766bb6cf 100644 --- a/src/pages/node/channelsIncoming.tsx +++ b/src/pages/node/channelsIncoming.tsx @@ -32,6 +32,7 @@ import { truncateEthereumAddress } from '../../utils/blockchain'; function ChannelsPage() { const dispatch = useAppDispatch(); const channels = useAppSelector((store) => store.node.channels.data); + const channelsIncoming = useAppSelector((store) => store.node.channels.data?.incoming); const channelsIncomingObject = useAppSelector((store) => store.node.channels.parsed.incoming); const channelsFetching = useAppSelector((store) => store.node.channels.isFetching); const aliases = useAppSelector((store) => store.node.aliases.data); @@ -195,8 +196,31 @@ function ChannelsPage() { }); }; - const parsedTableData = Object.keys(channelsIncomingObject) - .map((id, index) => { + const peersWithAliases = (channelsIncoming || []).filter(peer => aliases && peer.peerAddress && getAliasByPeerAddress(peer.peerAddress) !== peer.peerAddress) ; + const peersWithAliasesSorted = peersWithAliases.sort((a, b) => { + if (getAliasByPeerAddress(b.peerAddress).toLowerCase() > getAliasByPeerAddress(a.peerAddress).toLowerCase()) { + return -1; + } + if (getAliasByPeerAddress(b.peerAddress).toLowerCase() < getAliasByPeerAddress(a.peerAddress).toLowerCase()) { + return 1; + } + return 0 + }); + const peersWithoutAliases = (channelsIncoming || []).filter(peer => aliases && peer.peerAddress && getAliasByPeerAddress(peer.peerAddress) === peer.peerAddress) ; + const peersWithoutAliasesSorted = peersWithoutAliases.sort((a, b) => { + if (b.peerAddress > a.peerAddress) { + return -1; + } + if (b.peerAddress < a.peerAddress) { + return 1; + } + return 0 + }); + + const peersSorted = [...peersWithAliasesSorted, ...peersWithoutAliasesSorted] + + const parsedTableData = peersSorted.map((channel, index) => { + const id = channel.id; if ( !channelsIncomingObject[id].peerAddress || !channelsIncomingObject[id].balance || diff --git a/src/pages/node/channelsOutgoing.tsx b/src/pages/node/channelsOutgoing.tsx index b5f99960..e34dd163 100644 --- a/src/pages/node/channelsOutgoing.tsx +++ b/src/pages/node/channelsOutgoing.tsx @@ -33,6 +33,7 @@ function ChannelsPage() { const dispatch = useAppDispatch(); const channels = useAppSelector((store) => store.node.channels.data); const channelsOutgoingObject = useAppSelector((store) => store.node.channels.parsed.outgoing); + const channelsOutgoing = useAppSelector((store) => store.node.channels.data?.outgoing); const channelsFetching = useAppSelector((store) => store.node.channels.isFetching); const aliases = useAppSelector((store) => store.node.aliases.data); const loginData = useAppSelector((store) => store.auth.loginData); @@ -188,8 +189,31 @@ function ChannelsPage() { }, ]; - const parsedTableData = Object.keys(channelsOutgoingObject) - .map((id, index) => { + const peersWithAliases = (channelsOutgoing || []).filter(peer => aliases && peer.peerAddress && getAliasByPeerAddress(peer.peerAddress) !== peer.peerAddress) ; + const peersWithAliasesSorted = peersWithAliases.sort((a, b) => { + if (getAliasByPeerAddress(b.peerAddress).toLowerCase() > getAliasByPeerAddress(a.peerAddress).toLowerCase()) { + return -1; + } + if (getAliasByPeerAddress(b.peerAddress).toLowerCase() < getAliasByPeerAddress(a.peerAddress).toLowerCase()) { + return 1; + } + return 0 + }); + const peersWithoutAliases = (channelsOutgoing || []).filter(peer => aliases && peer.peerAddress && getAliasByPeerAddress(peer.peerAddress) === peer.peerAddress) ; + const peersWithoutAliasesSorted = peersWithoutAliases.sort((a, b) => { + if (b.peerAddress > a.peerAddress) { + return -1; + } + if (b.peerAddress < a.peerAddress) { + return 1; + } + return 0 + }); + + const peersSorted = [...peersWithAliasesSorted, ...peersWithoutAliasesSorted] + + const parsedTableData = peersSorted.map((channel, index) => { + const id = channel.id; if ( !channelsOutgoingObject[id].peerAddress || !channelsOutgoingObject[id].balance || From 4397c232002bf74e2a1d4df465599d2272787e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadach?= Date: Mon, 2 Dec 2024 14:58:00 +0100 Subject: [PATCH 18/20] format --- .../PeerInfo/index.tsx | 1 - src/pages/node/channelsIncoming.tsx | 17 +++++++++----- src/pages/node/channelsOutgoing.tsx | 19 ++++++++++------ src/pages/node/peers.tsx | 22 +++++++++++-------- 4 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/future-hopr-lib-components/PeerInfo/index.tsx b/src/future-hopr-lib-components/PeerInfo/index.tsx index 2f44310c..dab920e0 100644 --- a/src/future-hopr-lib-components/PeerInfo/index.tsx +++ b/src/future-hopr-lib-components/PeerInfo/index.tsx @@ -11,7 +11,6 @@ import { generateBase64Jazz } from '../../utils/functions'; import CopyIcon from '@mui/icons-material/ContentCopy'; import LaunchIcon from '@mui/icons-material/Launch'; - interface Props { peerId?: string; nodeAddress?: string; diff --git a/src/pages/node/channelsIncoming.tsx b/src/pages/node/channelsIncoming.tsx index 766bb6cf..0fb9de79 100644 --- a/src/pages/node/channelsIncoming.tsx +++ b/src/pages/node/channelsIncoming.tsx @@ -196,7 +196,9 @@ function ChannelsPage() { }); }; - const peersWithAliases = (channelsIncoming || []).filter(peer => aliases && peer.peerAddress && getAliasByPeerAddress(peer.peerAddress) !== peer.peerAddress) ; + const peersWithAliases = (channelsIncoming || []).filter( + (peer) => aliases && peer.peerAddress && getAliasByPeerAddress(peer.peerAddress) !== peer.peerAddress, + ); const peersWithAliasesSorted = peersWithAliases.sort((a, b) => { if (getAliasByPeerAddress(b.peerAddress).toLowerCase() > getAliasByPeerAddress(a.peerAddress).toLowerCase()) { return -1; @@ -204,9 +206,11 @@ function ChannelsPage() { if (getAliasByPeerAddress(b.peerAddress).toLowerCase() < getAliasByPeerAddress(a.peerAddress).toLowerCase()) { return 1; } - return 0 + return 0; }); - const peersWithoutAliases = (channelsIncoming || []).filter(peer => aliases && peer.peerAddress && getAliasByPeerAddress(peer.peerAddress) === peer.peerAddress) ; + const peersWithoutAliases = (channelsIncoming || []).filter( + (peer) => aliases && peer.peerAddress && getAliasByPeerAddress(peer.peerAddress) === peer.peerAddress, + ); const peersWithoutAliasesSorted = peersWithoutAliases.sort((a, b) => { if (b.peerAddress > a.peerAddress) { return -1; @@ -214,12 +218,13 @@ function ChannelsPage() { if (b.peerAddress < a.peerAddress) { return 1; } - return 0 + return 0; }); - const peersSorted = [...peersWithAliasesSorted, ...peersWithoutAliasesSorted] + const peersSorted = [...peersWithAliasesSorted, ...peersWithoutAliasesSorted]; - const parsedTableData = peersSorted.map((channel, index) => { + const parsedTableData = peersSorted + .map((channel, index) => { const id = channel.id; if ( !channelsIncomingObject[id].peerAddress || diff --git a/src/pages/node/channelsOutgoing.tsx b/src/pages/node/channelsOutgoing.tsx index e34dd163..efcb53c5 100644 --- a/src/pages/node/channelsOutgoing.tsx +++ b/src/pages/node/channelsOutgoing.tsx @@ -189,7 +189,9 @@ function ChannelsPage() { }, ]; - const peersWithAliases = (channelsOutgoing || []).filter(peer => aliases && peer.peerAddress && getAliasByPeerAddress(peer.peerAddress) !== peer.peerAddress) ; + const peersWithAliases = (channelsOutgoing || []).filter( + (peer) => aliases && peer.peerAddress && getAliasByPeerAddress(peer.peerAddress) !== peer.peerAddress, + ); const peersWithAliasesSorted = peersWithAliases.sort((a, b) => { if (getAliasByPeerAddress(b.peerAddress).toLowerCase() > getAliasByPeerAddress(a.peerAddress).toLowerCase()) { return -1; @@ -197,9 +199,11 @@ function ChannelsPage() { if (getAliasByPeerAddress(b.peerAddress).toLowerCase() < getAliasByPeerAddress(a.peerAddress).toLowerCase()) { return 1; } - return 0 + return 0; }); - const peersWithoutAliases = (channelsOutgoing || []).filter(peer => aliases && peer.peerAddress && getAliasByPeerAddress(peer.peerAddress) === peer.peerAddress) ; + const peersWithoutAliases = (channelsOutgoing || []).filter( + (peer) => aliases && peer.peerAddress && getAliasByPeerAddress(peer.peerAddress) === peer.peerAddress, + ); const peersWithoutAliasesSorted = peersWithoutAliases.sort((a, b) => { if (b.peerAddress > a.peerAddress) { return -1; @@ -207,12 +211,13 @@ function ChannelsPage() { if (b.peerAddress < a.peerAddress) { return 1; } - return 0 + return 0; }); - const peersSorted = [...peersWithAliasesSorted, ...peersWithoutAliasesSorted] + const peersSorted = [...peersWithAliasesSorted, ...peersWithoutAliasesSorted]; - const parsedTableData = peersSorted.map((channel, index) => { + const parsedTableData = peersSorted + .map((channel, index) => { const id = channel.id; if ( !channelsOutgoingObject[id].peerAddress || @@ -225,7 +230,7 @@ function ChannelsPage() { const peerId = getPeerIdFromPeerAddress(peerAddress as string); return { - id: (index+1).toString(), + id: (index + 1).toString(), key: id, node: ( aliases && peer.peerId && peerIdToAliasLink[peer.peerId]) ; + const peersWithAliases = (peers?.connected || []).filter( + (peer) => aliases && peer.peerId && peerIdToAliasLink[peer.peerId], + ); const peersWithAliasesSorted = peersWithAliases.sort((a, b) => { if (getAliasByPeerId(b.peerId).toLowerCase() > getAliasByPeerId(a.peerId).toLowerCase()) { return -1; @@ -125,9 +127,11 @@ function PeersPage() { if (getAliasByPeerId(b.peerId).toLowerCase() < getAliasByPeerId(a.peerId).toLowerCase()) { return 1; } - return 0 + return 0; }); - const peersWithoutAliases = (peers?.connected || []).filter(peer => aliases && peer.peerId && !peerIdToAliasLink[peer.peerId]) ; + const peersWithoutAliases = (peers?.connected || []).filter( + (peer) => aliases && peer.peerId && !peerIdToAliasLink[peer.peerId], + ); const peersWithoutAliasesSorted = peersWithoutAliases.sort((a, b) => { if (b.peerId > a.peerId) { return -1; @@ -135,14 +139,14 @@ function PeersPage() { if (b.peerId < a.peerId) { return 1; } - return 0 + return 0; }); - const peersSorted = [...peersWithAliasesSorted, ...peersWithoutAliasesSorted] + const peersSorted = [...peersWithAliasesSorted, ...peersWithoutAliasesSorted]; - const parsedTableData = peersSorted.map((peer, index)=>{ + const parsedTableData = peersSorted.map((peer, index) => { return { - id: index+1, + id: index + 1, node: ( ), - } - }) + }; + }); return (
Date: Tue, 3 Dec 2024 14:08:53 +0100 Subject: [PATCH 19/20] bold alias and alias page last seen --- .../PeerInfo/index.tsx | 4 +-- src/pages/node/aliases.tsx | 21 ++++++++++++-- src/pages/node/peers.tsx | 28 +++++++++---------- src/store/slices/node/actionsAsync.ts | 13 ++++++--- src/store/slices/node/initialState.ts | 23 +++++++++++++++ 5 files changed, 66 insertions(+), 23 deletions(-) diff --git a/src/future-hopr-lib-components/PeerInfo/index.tsx b/src/future-hopr-lib-components/PeerInfo/index.tsx index dab920e0..05853657 100644 --- a/src/future-hopr-lib-components/PeerInfo/index.tsx +++ b/src/future-hopr-lib-components/PeerInfo/index.tsx @@ -31,10 +31,10 @@ const PeersInfo: React.FC = (props) => { const aliases = useAppSelector((store) => store.node.aliases.data); const peerIdToAliasLink = useAppSelector((store) => store.node.links.peerIdToAlias); - const getAliasByPeerId = (peerId: string): string => { + const getAliasByPeerId = (peerId: string): string | JSX.Element => { const shortPeerId = peerId && `${peerId.substring(0, 6)}...${peerId.substring(peerId.length - 8, peerId.length)}`; const displayPeerId = props.shortenPeerId ? shortPeerId : peerId; - if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${displayPeerId})`; + if (aliases && peerId && peerIdToAliasLink[peerId]) return <>{peerIdToAliasLink[peerId]} ({displayPeerId}); return displayPeerId; }; diff --git a/src/pages/node/aliases.tsx b/src/pages/node/aliases.tsx index 62716e33..c14c8d4a 100644 --- a/src/pages/node/aliases.tsx +++ b/src/pages/node/aliases.tsx @@ -27,7 +27,7 @@ import DriveFolderUploadIcon from '@mui/icons-material/DriveFolderUpload'; function AliasesPage() { const dispatch = useAppDispatch(); const aliases = useAppSelector((store) => store.node.aliases.data); - const peers = useAppSelector((store) => store.node.peers.data); + const peersObject = useAppSelector((store) => store.node.peers.parsed.connected); const aliasesFetching = useAppSelector((store) => store.node.aliases.isFetching); const hoprAddress = useAppSelector((store) => store.node.addresses.data.hopr); const myNodeAddress = useAppSelector((store) => store.node.addresses.data.native); @@ -123,6 +123,16 @@ function AliasesPage() { const parsedTableData = Object.entries(aliases ?? {}).map(([alias, peerId], key) => { const peerAddress = getNodeAddressByPeerId(peerId); + const lastSeenNumeric = peerId && peersObject[peerId]?.lastSeen; + const lastSeen = lastSeenNumeric as number > 0 ? new Date(lastSeenNumeric).toLocaleString('en-US', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + timeZoneName: 'short', + }).replace(', ', '\n') : 'Not seen'; + return { id: peerId, key: key.toString(), @@ -133,6 +143,7 @@ function AliasesPage() { nodeAddress={peerAddress ?? ''} /> ), + lastSeen: {peerId === hoprAddress ? '-' : lastSeen}, peerId, peerAddress: peerAddress ?? '', actions: ( @@ -181,14 +192,18 @@ function AliasesPage() { key: 'alias', name: 'Alias', search: true, - tooltip: true, - maxWidth: '0px', + hidden: true, }, { key: 'node', name: 'Node', maxWidth: '350px', }, + { + key: 'lastSeen', + name: 'Last Seen', + maxWidth: '20px', + }, { key: 'peerId', name: 'Peer Id', diff --git a/src/pages/node/peers.tsx b/src/pages/node/peers.tsx index 5dc66366..15a946e1 100644 --- a/src/pages/node/peers.tsx +++ b/src/pages/node/peers.tsx @@ -79,11 +79,12 @@ function PeersPage() { { key: 'id', name: '#', + maxWidth: '5px', }, { key: 'node', name: 'Node', - maxWidth: '350px', + maxWidth: '300px', }, { key: 'peerId', @@ -101,12 +102,12 @@ function PeersPage() { key: 'lastSeen', name: 'Last seen', tooltip: true, - maxWidth: '60px', + maxWidth: '10px', }, { key: 'quality', name: 'Quality', - maxWidth: '15px', + maxWidth: '10px', }, { key: 'actions', @@ -145,6 +146,15 @@ function PeersPage() { const peersSorted = [...peersWithAliasesSorted, ...peersWithoutAliasesSorted]; const parsedTableData = peersSorted.map((peer, index) => { + const lastSeen = peer.lastSeen as number > 0 ? new Date(peer.lastSeen).toLocaleString('en-US', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + timeZoneName: 'short', + }).replace(', ', '\n') : 'Not seen'; + return { id: index + 1, node: ( @@ -157,17 +167,7 @@ function PeersPage() { peerId: getAliasByPeerId(peer.peerId), peerAddress: peer.peerAddress, quality: , - lastSeen: - peer.lastSeen > 0 - ? new Date(peer.lastSeen).toLocaleString('en-US', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - timeZoneName: 'short', - }) - : 'Not seen', + lastSeen: {lastSeen}, actions: ( <> diff --git a/src/store/slices/node/actionsAsync.ts b/src/store/slices/node/actionsAsync.ts index 9ac693a9..66080667 100644 --- a/src/store/slices/node/actionsAsync.ts +++ b/src/store/slices/node/actionsAsync.ts @@ -1193,13 +1193,18 @@ export const createAsyncReducer = (builder: ActionReducerMapBuilder Date: Tue, 3 Dec 2024 14:09:11 +0100 Subject: [PATCH 20/20] format --- .../PeerInfo/index.tsx | 7 +++++- src/pages/node/aliases.tsx | 23 +++++++++++-------- src/pages/node/peers.tsx | 21 ++++++++++------- src/store/slices/node/actionsAsync.ts | 4 ++-- src/store/slices/node/initialState.ts | 8 +++---- 5 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/future-hopr-lib-components/PeerInfo/index.tsx b/src/future-hopr-lib-components/PeerInfo/index.tsx index 05853657..6d9c3d0e 100644 --- a/src/future-hopr-lib-components/PeerInfo/index.tsx +++ b/src/future-hopr-lib-components/PeerInfo/index.tsx @@ -34,7 +34,12 @@ const PeersInfo: React.FC = (props) => { const getAliasByPeerId = (peerId: string): string | JSX.Element => { const shortPeerId = peerId && `${peerId.substring(0, 6)}...${peerId.substring(peerId.length - 8, peerId.length)}`; const displayPeerId = props.shortenPeerId ? shortPeerId : peerId; - if (aliases && peerId && peerIdToAliasLink[peerId]) return <>{peerIdToAliasLink[peerId]} ({displayPeerId}); + if (aliases && peerId && peerIdToAliasLink[peerId]) + return ( + <> + {peerIdToAliasLink[peerId]} ({displayPeerId}) + + ); return displayPeerId; }; diff --git a/src/pages/node/aliases.tsx b/src/pages/node/aliases.tsx index c14c8d4a..c0446c26 100644 --- a/src/pages/node/aliases.tsx +++ b/src/pages/node/aliases.tsx @@ -124,14 +124,19 @@ function AliasesPage() { const parsedTableData = Object.entries(aliases ?? {}).map(([alias, peerId], key) => { const peerAddress = getNodeAddressByPeerId(peerId); const lastSeenNumeric = peerId && peersObject[peerId]?.lastSeen; - const lastSeen = lastSeenNumeric as number > 0 ? new Date(lastSeenNumeric).toLocaleString('en-US', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - timeZoneName: 'short', - }).replace(', ', '\n') : 'Not seen'; + const lastSeen = + (lastSeenNumeric as number) > 0 + ? new Date(lastSeenNumeric) + .toLocaleString('en-US', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + timeZoneName: 'short', + }) + .replace(', ', '\n') + : 'Not seen'; return { id: peerId, @@ -143,7 +148,7 @@ function AliasesPage() { nodeAddress={peerAddress ?? ''} /> ), - lastSeen: {peerId === hoprAddress ? '-' : lastSeen}, + lastSeen: {peerId === hoprAddress ? '-' : lastSeen}, peerId, peerAddress: peerAddress ?? '', actions: ( diff --git a/src/pages/node/peers.tsx b/src/pages/node/peers.tsx index 15a946e1..ef886cd0 100644 --- a/src/pages/node/peers.tsx +++ b/src/pages/node/peers.tsx @@ -146,14 +146,19 @@ function PeersPage() { const peersSorted = [...peersWithAliasesSorted, ...peersWithoutAliasesSorted]; const parsedTableData = peersSorted.map((peer, index) => { - const lastSeen = peer.lastSeen as number > 0 ? new Date(peer.lastSeen).toLocaleString('en-US', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - timeZoneName: 'short', - }).replace(', ', '\n') : 'Not seen'; + const lastSeen = + (peer.lastSeen as number) > 0 + ? new Date(peer.lastSeen) + .toLocaleString('en-US', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + timeZoneName: 'short', + }) + .replace(', ', '\n') + : 'Not seen'; return { id: index + 1, diff --git a/src/store/slices/node/actionsAsync.ts b/src/store/slices/node/actionsAsync.ts index 66080667..6e95c88d 100644 --- a/src/store/slices/node/actionsAsync.ts +++ b/src/store/slices/node/actionsAsync.ts @@ -1193,7 +1193,7 @@ export const createAsyncReducer = (builder: ActionReducerMapBuilder