mirror of
https://github.com/apotdevin/thunderhub.git
synced 2025-02-22 06:21:37 +01:00
refactor: ♻️ forward channels
This commit is contained in:
parent
72860f334e
commit
05fd6b2573
10 changed files with 144 additions and 334 deletions
|
@ -1,10 +1,8 @@
|
|||
import { getForwardChannelsReport } from './resolvers/getForwardChannelsReport';
|
||||
import { getInOut } from './resolvers/getInOut';
|
||||
import { getChannelReport } from './resolvers/getChannelReport';
|
||||
|
||||
export const widgetResolvers = {
|
||||
Query: {
|
||||
getForwardChannelsReport,
|
||||
getInOut,
|
||||
getChannelReport,
|
||||
},
|
||||
|
|
|
@ -1,157 +0,0 @@
|
|||
import { getForwards, getWalletInfo, getClosedChannels } from 'ln-service';
|
||||
import { subHours, subDays } from 'date-fns';
|
||||
import { sortBy } from 'underscore';
|
||||
import { ContextType } from 'server/types/apiTypes';
|
||||
import { getNodeFromChannel } from 'server/helpers/getNodeFromChannel';
|
||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import { to } from 'server/helpers/async';
|
||||
import {
|
||||
GetForwardsType,
|
||||
GetWalletInfoType,
|
||||
GetClosedChannelsType,
|
||||
} from 'server/types/ln-service.types';
|
||||
import { countArray, countRoutes } from './helpers';
|
||||
|
||||
export const getForwardChannelsReport = async (
|
||||
_: undefined,
|
||||
params: any,
|
||||
context: ContextType
|
||||
) => {
|
||||
await requestLimiter(context.ip, 'forwardChannels');
|
||||
|
||||
const { lnd } = context;
|
||||
|
||||
let startDate = new Date();
|
||||
const endDate = new Date();
|
||||
|
||||
if (params.time === 'week') {
|
||||
startDate = subDays(endDate, 7);
|
||||
} else if (params.time === 'month') {
|
||||
startDate = subDays(endDate, 30);
|
||||
} else if (params.time === 'quarter_year') {
|
||||
startDate = subDays(endDate, 90);
|
||||
} else if (params.time === 'half_year') {
|
||||
startDate = subDays(endDate, 180);
|
||||
} else if (params.time === 'year') {
|
||||
startDate = subDays(endDate, 360);
|
||||
} else {
|
||||
startDate = subHours(endDate, 24);
|
||||
}
|
||||
|
||||
const closedChannels = await to<GetClosedChannelsType>(
|
||||
getClosedChannels({
|
||||
lnd,
|
||||
})
|
||||
);
|
||||
|
||||
const getRouteAlias = (array: any[], publicKey: string) =>
|
||||
Promise.all(
|
||||
array.map(async channel => {
|
||||
const nodeAliasIn = await getNodeFromChannel(
|
||||
channel.in,
|
||||
publicKey,
|
||||
lnd,
|
||||
closedChannels?.channels.find(c => c.id === channel.in)
|
||||
);
|
||||
const nodeAliasOut = await getNodeFromChannel(
|
||||
channel.out,
|
||||
publicKey,
|
||||
lnd,
|
||||
closedChannels?.channels.find(c => c.id === channel.out)
|
||||
);
|
||||
|
||||
return {
|
||||
aliasIn: nodeAliasIn.alias,
|
||||
colorIn: nodeAliasIn.color,
|
||||
aliasOut: nodeAliasOut.alias,
|
||||
colorOut: nodeAliasOut.color,
|
||||
...channel,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
const getAlias = (array: any[], publicKey: string) =>
|
||||
Promise.all(
|
||||
array.map(async channel => {
|
||||
const nodeAlias = await getNodeFromChannel(
|
||||
channel.name,
|
||||
publicKey,
|
||||
lnd,
|
||||
closedChannels?.channels.find(c => c.id === channel.name)
|
||||
);
|
||||
return {
|
||||
alias: nodeAlias.alias,
|
||||
color: nodeAlias.color,
|
||||
...channel,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
const forwardsList = await to<GetForwardsType>(
|
||||
getForwards({
|
||||
lnd,
|
||||
after: startDate,
|
||||
before: endDate,
|
||||
})
|
||||
);
|
||||
|
||||
const walletInfo = await to<GetWalletInfoType>(
|
||||
getWalletInfo({
|
||||
lnd,
|
||||
})
|
||||
);
|
||||
|
||||
let forwards = forwardsList.forwards;
|
||||
let next = forwardsList.next;
|
||||
|
||||
let finishedFetching = false;
|
||||
|
||||
if (!next || !forwards || forwards.length <= 0) {
|
||||
finishedFetching = true;
|
||||
}
|
||||
|
||||
while (!finishedFetching) {
|
||||
if (next) {
|
||||
const moreForwards = await to<GetForwardsType>(
|
||||
getForwards({ lnd, token: next })
|
||||
);
|
||||
forwards = [...forwards, ...moreForwards.forwards];
|
||||
if (moreForwards.next) {
|
||||
next = moreForwards.next;
|
||||
} else {
|
||||
finishedFetching = true;
|
||||
}
|
||||
} else {
|
||||
finishedFetching = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (params.type === 'route') {
|
||||
const mapped = forwards.map(forward => {
|
||||
return {
|
||||
route: `${forward.incoming_channel} - ${forward.outgoing_channel}`,
|
||||
...forward,
|
||||
};
|
||||
});
|
||||
const grouped = countRoutes(mapped);
|
||||
|
||||
const routeAlias = await getRouteAlias(grouped, walletInfo.public_key);
|
||||
|
||||
const sortedRoute = sortBy(routeAlias, params.order).reverse().slice(0, 10);
|
||||
return JSON.stringify(sortedRoute);
|
||||
}
|
||||
if (params.type === 'incoming') {
|
||||
const incomingCount = countArray(forwards, true);
|
||||
const incomingAlias = await getAlias(incomingCount, walletInfo.public_key);
|
||||
const sortedInCount = sortBy(incomingAlias, params.order)
|
||||
.reverse()
|
||||
.slice(0, 10);
|
||||
return JSON.stringify(sortedInCount);
|
||||
}
|
||||
const outgoingCount = countArray(forwards, false);
|
||||
const outgoingAlias = await getAlias(outgoingCount, walletInfo.public_key);
|
||||
const sortedOutCount = sortBy(outgoingAlias, params.order)
|
||||
.reverse()
|
||||
.slice(0, 10);
|
||||
return JSON.stringify(sortedOutCount);
|
||||
};
|
|
@ -1,5 +1,3 @@
|
|||
import { reduce, groupBy } from 'underscore';
|
||||
import { ForwardType } from 'server/types/ln-service.types';
|
||||
import { InOutProps, InOutListProps } from './interface';
|
||||
|
||||
export const reduceInOutArray = (list: InOutListProps) => {
|
||||
|
@ -7,8 +5,7 @@ export const reduceInOutArray = (list: InOutListProps) => {
|
|||
for (const key in list) {
|
||||
if (Object.prototype.hasOwnProperty.call(list, key)) {
|
||||
const element: InOutProps[] = list[key];
|
||||
const reducedArray: InOutProps = reduce(
|
||||
element,
|
||||
const reducedArray: InOutProps = element.reduce(
|
||||
(a, b) => ({
|
||||
tokens: a.tokens + b.tokens,
|
||||
}),
|
||||
|
@ -23,62 +20,3 @@ export const reduceInOutArray = (list: InOutListProps) => {
|
|||
}
|
||||
return reducedOrder;
|
||||
};
|
||||
|
||||
export const countArray = (list: ForwardType[], type: boolean) => {
|
||||
const inOrOut = type ? 'incoming_channel' : 'outgoing_channel';
|
||||
const grouped = groupBy(list, inOrOut);
|
||||
|
||||
const channelInfo = [];
|
||||
for (const key in grouped) {
|
||||
if (Object.prototype.hasOwnProperty.call(grouped, key)) {
|
||||
const element = grouped[key];
|
||||
|
||||
const fee = element
|
||||
.map(forward => forward.fee)
|
||||
.reduce((p: number, c: number) => p + c);
|
||||
|
||||
const tokens = element
|
||||
.map(forward => forward.tokens)
|
||||
.reduce((p: number, c: number) => p + c);
|
||||
|
||||
channelInfo.push({
|
||||
name: key,
|
||||
amount: element.length,
|
||||
fee,
|
||||
tokens,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return channelInfo;
|
||||
};
|
||||
|
||||
export const countRoutes = (list: ForwardType[]) => {
|
||||
const grouped = groupBy(list, 'route');
|
||||
|
||||
const channelInfo = [];
|
||||
for (const key in grouped) {
|
||||
if (Object.prototype.hasOwnProperty.call(grouped, key)) {
|
||||
const element = grouped[key];
|
||||
|
||||
const fee = element
|
||||
.map(forward => forward.fee)
|
||||
.reduce((p: number, c: number) => p + c);
|
||||
|
||||
const tokens = element
|
||||
.map(forward => forward.tokens)
|
||||
.reduce((p: number, c: number) => p + c);
|
||||
|
||||
channelInfo.push({
|
||||
route: key,
|
||||
in: element[0].incoming_channel,
|
||||
out: element[0].outgoing_channel,
|
||||
amount: element.length,
|
||||
fee,
|
||||
tokens,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return channelInfo;
|
||||
};
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
/* eslint-disable */
|
||||
import * as Types from '../../types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
export type GetForwardChannelsReportQueryVariables = Types.Exact<{
|
||||
time?: Types.Maybe<Types.Scalars['String']>;
|
||||
order?: Types.Maybe<Types.Scalars['String']>;
|
||||
type?: Types.Maybe<Types.Scalars['String']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GetForwardChannelsReportQuery = (
|
||||
{ __typename?: 'Query' }
|
||||
& Pick<Types.Query, 'getForwardChannelsReport'>
|
||||
);
|
||||
|
||||
|
||||
export const GetForwardChannelsReportDocument = gql`
|
||||
query GetForwardChannelsReport($time: String, $order: String, $type: String) {
|
||||
getForwardChannelsReport(time: $time, order: $order, type: $type)
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useGetForwardChannelsReportQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useGetForwardChannelsReportQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useGetForwardChannelsReportQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useGetForwardChannelsReportQuery({
|
||||
* variables: {
|
||||
* time: // value for 'time'
|
||||
* order: // value for 'order'
|
||||
* type: // value for 'type'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useGetForwardChannelsReportQuery(baseOptions?: Apollo.QueryHookOptions<GetForwardChannelsReportQuery, GetForwardChannelsReportQueryVariables>) {
|
||||
return Apollo.useQuery<GetForwardChannelsReportQuery, GetForwardChannelsReportQueryVariables>(GetForwardChannelsReportDocument, baseOptions);
|
||||
}
|
||||
export function useGetForwardChannelsReportLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetForwardChannelsReportQuery, GetForwardChannelsReportQueryVariables>) {
|
||||
return Apollo.useLazyQuery<GetForwardChannelsReportQuery, GetForwardChannelsReportQueryVariables>(GetForwardChannelsReportDocument, baseOptions);
|
||||
}
|
||||
export type GetForwardChannelsReportQueryHookResult = ReturnType<typeof useGetForwardChannelsReportQuery>;
|
||||
export type GetForwardChannelsReportLazyQueryHookResult = ReturnType<typeof useGetForwardChannelsReportLazyQuery>;
|
||||
export type GetForwardChannelsReportQueryResult = Apollo.QueryResult<GetForwardChannelsReportQuery, GetForwardChannelsReportQueryVariables>;
|
|
@ -1,7 +0,0 @@
|
|||
import { gql } from '@apollo/client';
|
||||
|
||||
export const GET_FORWARD_CHANNELS_REPORT = gql`
|
||||
query GetForwardChannelsReport($time: String, $order: String, $type: String) {
|
||||
getForwardChannelsReport(time: $time, order: $order, type: $type)
|
||||
}
|
||||
`;
|
|
@ -7,28 +7,23 @@ import { ResponsiveSingle } from 'src/components/generic/Styled';
|
|||
import { ReportType, ReportDuration, FlowReportType } from './ForwardReport';
|
||||
|
||||
interface ButtonProps {
|
||||
isTime: ReportDuration;
|
||||
isType: ReportType;
|
||||
days: number;
|
||||
order: ReportType;
|
||||
setDays: (days: number) => void;
|
||||
setIsTime: (text: ReportDuration) => void;
|
||||
setIsType: (text: ReportType) => void;
|
||||
setOrder: (text: ReportType) => void;
|
||||
}
|
||||
|
||||
export const ButtonRow: React.FC<ButtonProps> = ({
|
||||
isTime,
|
||||
setIsTime,
|
||||
days,
|
||||
setDays,
|
||||
isType,
|
||||
setIsType,
|
||||
order,
|
||||
setOrder,
|
||||
}) => {
|
||||
const timeButton = (time: ReportDuration, title: string, days: number) => (
|
||||
const timeButton = (title: string, buttonDays: number) => (
|
||||
<SingleButton
|
||||
withPadding={'4px 8px'}
|
||||
onClick={() => {
|
||||
setIsTime(time);
|
||||
setDays(days);
|
||||
}}
|
||||
selected={isTime === time}
|
||||
onClick={() => setDays(buttonDays)}
|
||||
selected={days === buttonDays}
|
||||
>
|
||||
{title}
|
||||
</SingleButton>
|
||||
|
@ -37,8 +32,8 @@ export const ButtonRow: React.FC<ButtonProps> = ({
|
|||
const typeButton = (type: ReportType, title: string) => (
|
||||
<SingleButton
|
||||
withPadding={'4px 8px'}
|
||||
onClick={() => setIsType(type)}
|
||||
selected={isType === type}
|
||||
onClick={() => setOrder(type)}
|
||||
selected={order === type}
|
||||
>
|
||||
{title}
|
||||
</SingleButton>
|
||||
|
@ -47,12 +42,12 @@ export const ButtonRow: React.FC<ButtonProps> = ({
|
|||
return (
|
||||
<ResponsiveSingle>
|
||||
<MultiButton>
|
||||
{timeButton('day', '1D', 1)}
|
||||
{timeButton('week', '1W', 7)}
|
||||
{timeButton('month', '1M', 30)}
|
||||
{timeButton('quarter_year', '3M', 90)}
|
||||
{timeButton('half_year', '6M', 180)}
|
||||
{timeButton('year', '1Y', 360)}
|
||||
{timeButton('1D', 1)}
|
||||
{timeButton('1W', 7)}
|
||||
{timeButton('1M', 30)}
|
||||
{timeButton('3M', 90)}
|
||||
{timeButton('6M', 180)}
|
||||
{timeButton('1Y', 360)}
|
||||
</MultiButton>
|
||||
<MultiButton>
|
||||
{typeButton('amount', 'Amount')}
|
||||
|
|
|
@ -2,11 +2,12 @@ import React, { useState } from 'react';
|
|||
import { toast } from 'react-toastify';
|
||||
import { GitCommit, ArrowDown, ArrowUp } from 'react-feather';
|
||||
import styled from 'styled-components';
|
||||
import { useGetForwardChannelsReportQuery } from 'src/graphql/queries/__generated__/getForwardChannelsReport.generated';
|
||||
import {
|
||||
MultiButton,
|
||||
SingleButton,
|
||||
} from 'src/components/buttons/multiButton/MultiButton';
|
||||
import { useGetForwardsPastDaysQuery } from 'src/graphql/queries/__generated__/getForwardsPastDays.generated';
|
||||
import { Forward } from 'src/graphql/types';
|
||||
import { getErrorContent } from '../../../../utils/error';
|
||||
import {
|
||||
DarkSubTitle,
|
||||
|
@ -16,7 +17,8 @@ import { LoadingCard } from '../../../../components/loading/LoadingCard';
|
|||
import { getPrice } from '../../../../components/price/Price';
|
||||
import { useConfigState } from '../../../../context/ConfigContext';
|
||||
import { usePriceState } from '../../../../context/PriceContext';
|
||||
import { ReportType, ReportDuration } from './ForwardReport';
|
||||
import { ReportType } from './ForwardReport';
|
||||
import { orderForwardChannels } from './helpers';
|
||||
import { CardContent } from '.';
|
||||
|
||||
const ChannelRow = styled.div`
|
||||
|
@ -39,11 +41,12 @@ const LastTableLine = styled(TableLine)`
|
|||
`;
|
||||
|
||||
type Props = {
|
||||
isTime: ReportDuration;
|
||||
isType: ReportType;
|
||||
days: number;
|
||||
order: ReportType;
|
||||
};
|
||||
|
||||
type ParsedRouteType = {
|
||||
route: string;
|
||||
aliasIn: string;
|
||||
aliasOut: string;
|
||||
fee: number;
|
||||
|
@ -59,16 +62,16 @@ type ParsedChannelType = {
|
|||
amount: number;
|
||||
};
|
||||
|
||||
export const ForwardChannelsReport = ({ isTime, isType }: Props) => {
|
||||
export const ForwardChannelsReport = ({ days, order }: Props) => {
|
||||
const [type, setType] = useState<'route' | 'incoming' | 'outgoing'>('route');
|
||||
|
||||
const { currency, displayValues } = useConfigState();
|
||||
const priceContext = usePriceState();
|
||||
const format = getPrice(currency, displayValues, priceContext);
|
||||
|
||||
const { data, loading } = useGetForwardChannelsReportQuery({
|
||||
const { data, loading } = useGetForwardsPastDaysQuery({
|
||||
ssr: false,
|
||||
variables: { time: isTime, order: isType, type },
|
||||
variables: { days },
|
||||
onError: error => toast.error(getErrorContent(error)),
|
||||
});
|
||||
|
||||
|
@ -76,14 +79,15 @@ export const ForwardChannelsReport = ({ isTime, isType }: Props) => {
|
|||
return <LoadingCard noCard={true} title={'Forward Report'} />;
|
||||
}
|
||||
|
||||
// TODO: JSON.parse is really bad... Absolutely no type safety at all
|
||||
const parsed: (ParsedChannelType | ParsedRouteType)[] = JSON.parse(
|
||||
data.getForwardChannelsReport || '[]'
|
||||
const forwardArray = orderForwardChannels(
|
||||
type,
|
||||
order,
|
||||
data.getForwardsPastDays as Forward[]
|
||||
);
|
||||
|
||||
const getFormatString = (amount: number | string) => {
|
||||
if (typeof amount === 'string') return amount;
|
||||
if (isType !== 'amount') {
|
||||
if (order !== 'amount') {
|
||||
return format({ amount });
|
||||
}
|
||||
return amount;
|
||||
|
@ -94,7 +98,7 @@ export const ForwardChannelsReport = ({ isTime, isType }: Props) => {
|
|||
<ChannelRow key={index}>
|
||||
<TableLine>{channel.aliasIn}</TableLine>
|
||||
<TableLine>{channel.aliasOut}</TableLine>
|
||||
<LastTableLine>{getFormatString(channel[isType])}</LastTableLine>
|
||||
<LastTableLine>{getFormatString(channel[order])}</LastTableLine>
|
||||
</ChannelRow>
|
||||
));
|
||||
|
||||
|
@ -115,7 +119,7 @@ export const ForwardChannelsReport = ({ isTime, isType }: Props) => {
|
|||
<ChannelRow key={index}>
|
||||
<TableLine>{`${channel.alias}`}</TableLine>
|
||||
<DarkSubTitle>{`${channel.name}`}</DarkSubTitle>
|
||||
<LastTableLine>{getFormatString(channel[isType])}</LastTableLine>
|
||||
<LastTableLine>{getFormatString(channel[order])}</LastTableLine>
|
||||
</ChannelRow>
|
||||
));
|
||||
|
||||
|
@ -184,14 +188,14 @@ export const ForwardChannelsReport = ({ isTime, isType }: Props) => {
|
|||
}
|
||||
};
|
||||
|
||||
if (parsed.length <= 0) {
|
||||
if (forwardArray.length <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<CardContent>
|
||||
{renderTitle()}
|
||||
{renderContent(parsed)}
|
||||
{renderContent(forwardArray)}
|
||||
</CardContent>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -36,10 +36,10 @@ export type FlowReportType = 'tokens' | 'amount';
|
|||
|
||||
interface Props {
|
||||
days: number;
|
||||
isType: ReportType;
|
||||
order: ReportType;
|
||||
}
|
||||
|
||||
export const ForwardReport = ({ days, isType }: Props) => {
|
||||
export const ForwardReport = ({ days, order }: Props) => {
|
||||
const { theme, currency, displayValues } = useConfigState();
|
||||
const priceContext = usePriceState();
|
||||
const format = getPrice(currency, displayValues, priceContext);
|
||||
|
@ -72,7 +72,7 @@ export const ForwardReport = ({ days, isType }: Props) => {
|
|||
}
|
||||
|
||||
const getLabelString = (value: number) => {
|
||||
if (isType === 'amount') {
|
||||
if (order === 'amount') {
|
||||
return numeral(value).format('0,0');
|
||||
}
|
||||
return format({ amount: value });
|
||||
|
@ -84,7 +84,7 @@ export const ForwardReport = ({ days, isType }: Props) => {
|
|||
);
|
||||
|
||||
const total = getLabelString(
|
||||
reduced.map(x => x[isType]).reduce((a, c) => a + c, 0)
|
||||
reduced.map(x => x[order]).reduce((a, c) => a + c, 0)
|
||||
);
|
||||
|
||||
const renderContent = () => {
|
||||
|
@ -101,14 +101,14 @@ export const ForwardReport = ({ days, isType }: Props) => {
|
|||
height={110}
|
||||
padding={{
|
||||
top: 20,
|
||||
left: isType === 'tokens' ? 80 : 50,
|
||||
left: order === 'tokens' ? 80 : 50,
|
||||
right: 50,
|
||||
bottom: 10,
|
||||
}}
|
||||
containerComponent={
|
||||
<VictoryVoronoiContainer
|
||||
voronoiDimension="x"
|
||||
labels={({ datum }) => `${getLabelString(datum[isType])}`}
|
||||
labels={({ datum }) => `${getLabelString(datum[order])}`}
|
||||
labelComponent={<VictoryTooltip orientation={'bottom'} />}
|
||||
/>
|
||||
}
|
||||
|
@ -131,13 +131,13 @@ export const ForwardReport = ({ days, isType }: Props) => {
|
|||
axis: { stroke: 'transparent' },
|
||||
}}
|
||||
tickFormat={a =>
|
||||
isType === 'tokens' ? format({ amount: a, breakNumber: true }) : a
|
||||
order === 'tokens' ? format({ amount: a, breakNumber: true }) : a
|
||||
}
|
||||
/>
|
||||
<VictoryBar
|
||||
data={reduced}
|
||||
x="period"
|
||||
y={isType}
|
||||
y={order}
|
||||
style={{
|
||||
data: {
|
||||
fill: chartBarColor[theme],
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { differenceInCalendarDays, differenceInHours, subDays } from 'date-fns';
|
||||
import groupBy from 'lodash.groupby';
|
||||
import sortBy from 'lodash.sortby';
|
||||
import { Forward } from 'src/graphql/types';
|
||||
|
||||
type ListProps = {
|
||||
|
@ -58,3 +59,94 @@ export const orderAndReducedArray = (time: number, forwardArray: Forward[]) => {
|
|||
|
||||
return reducedOrderedDay;
|
||||
};
|
||||
|
||||
const countRoutes = (list: Forward[]) => {
|
||||
const grouped = groupBy(list, 'route');
|
||||
|
||||
const channelInfo = [];
|
||||
for (const key in grouped) {
|
||||
if (Object.prototype.hasOwnProperty.call(grouped, key)) {
|
||||
const element = grouped[key];
|
||||
|
||||
const fee = element
|
||||
.map(forward => forward.fee)
|
||||
.reduce((p: number, c: number) => p + c);
|
||||
|
||||
const tokens = element
|
||||
.map(forward => forward.tokens)
|
||||
.reduce((p: number, c: number) => p + c);
|
||||
|
||||
channelInfo.push({
|
||||
aliasIn: element[0].incoming_node?.alias || 'Unknown',
|
||||
aliasOut: element[0].outgoing_node?.alias || 'Unknown',
|
||||
route: key,
|
||||
amount: element.length,
|
||||
fee,
|
||||
tokens,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return channelInfo;
|
||||
};
|
||||
|
||||
const countArray = (list: Forward[], type: boolean) => {
|
||||
const inOrOut = type ? 'incoming_channel' : 'outgoing_channel';
|
||||
const grouped = groupBy(list, inOrOut);
|
||||
|
||||
const channelInfo = [];
|
||||
for (const key in grouped) {
|
||||
if (Object.prototype.hasOwnProperty.call(grouped, key)) {
|
||||
const element = grouped[key];
|
||||
|
||||
const fee = element
|
||||
.map(forward => forward.fee)
|
||||
.reduce((p: number, c: number) => p + c);
|
||||
|
||||
const tokens = element
|
||||
.map(forward => forward.tokens)
|
||||
.reduce((p: number, c: number) => p + c);
|
||||
|
||||
const alias = type
|
||||
? element[0].incoming_node?.alias || 'Unknown'
|
||||
: element[0].outgoing_node?.alias || 'Unknown';
|
||||
|
||||
channelInfo.push({
|
||||
alias,
|
||||
name: key,
|
||||
amount: element.length,
|
||||
fee,
|
||||
tokens,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return channelInfo;
|
||||
};
|
||||
|
||||
export const orderForwardChannels = (
|
||||
type: string,
|
||||
order: string,
|
||||
forwardArray: Forward[]
|
||||
) => {
|
||||
if (type === 'route') {
|
||||
const mapped = forwardArray.map(forward => {
|
||||
return {
|
||||
route: `${forward.incoming_channel} - ${forward.outgoing_channel}`,
|
||||
...forward,
|
||||
};
|
||||
});
|
||||
const grouped = countRoutes(mapped);
|
||||
|
||||
const sortedRoute = sortBy(grouped, order).reverse().slice(0, 10);
|
||||
return sortedRoute;
|
||||
}
|
||||
if (type === 'incoming') {
|
||||
const incomingCount = countArray(forwardArray, true);
|
||||
const sortedInCount = sortBy(incomingCount, order).reverse().slice(0, 10);
|
||||
return sortedInCount;
|
||||
}
|
||||
const outgoingCount = countArray(forwardArray, false);
|
||||
const sortedOutCount = sortBy(outgoingCount, order).reverse().slice(0, 10);
|
||||
return sortedOutCount;
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
Separation,
|
||||
} from '../../../../components/generic/Styled';
|
||||
import { mediaWidths } from '../../../../styles/Themes';
|
||||
import { ForwardReport, ReportDuration, ReportType } from './ForwardReport';
|
||||
import { ForwardReport, ReportType } from './ForwardReport';
|
||||
import { ForwardChannelsReport } from './ForwardChannelReport';
|
||||
import { ButtonRow } from './Buttons';
|
||||
|
||||
|
@ -24,9 +24,8 @@ export const CardContent = styled.div`
|
|||
`;
|
||||
|
||||
export const ForwardBox = () => {
|
||||
const [isTime, setIsTime] = useState<ReportDuration>('month');
|
||||
const [days, setDays] = useState<number>(30);
|
||||
const [isType, setIsType] = useState<ReportType>('amount');
|
||||
const [order, setOrder] = useState<ReportType>('amount');
|
||||
|
||||
return (
|
||||
<CardWithTitle>
|
||||
|
@ -35,15 +34,14 @@ export const ForwardBox = () => {
|
|||
</CardTitle>
|
||||
<Card mobileCardPadding={'8px'}>
|
||||
<ButtonRow
|
||||
isTime={isTime}
|
||||
isType={isType}
|
||||
days={days}
|
||||
order={order}
|
||||
setDays={setDays}
|
||||
setIsTime={setIsTime}
|
||||
setIsType={setIsType}
|
||||
setOrder={setOrder}
|
||||
/>
|
||||
<ForwardReport days={days} isType={isType} />
|
||||
<ForwardReport days={days} order={order} />
|
||||
<Separation />
|
||||
<ForwardChannelsReport isTime={isTime} isType={isType} />
|
||||
<ForwardChannelsReport days={days} order={order} />
|
||||
</Card>
|
||||
</CardWithTitle>
|
||||
);
|
||||
|
|
Loading…
Add table
Reference in a new issue