Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bookkeeper Dashboard #75

Open
wants to merge 55 commits into
base: Release-0.0.7
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
40795d1
Fetch and Process Balance Sheet data
evansmj Apr 23, 2024
afaf80c
skip balance sheet tests for now
evansmj Jun 2, 2024
3cdbd27
Hide 'external' accounts
evansmj Jun 2, 2024
eb74302
Format table sats with 3 decimal places.
evansmj Jun 3, 2024
16f5cc7
Remove comma from y-axis
evansmj Jun 10, 2024
25ad19b
Add sats label to y-axis
evansmj Jun 10, 2024
f70b156
add 5 percent top margin so max y-axis value displays
evansmj Jun 10, 2024
10fff38
Add tooltip on hover of bars
evansmj Jun 11, 2024
b407ea5
Highlight entire row when a cell is hovered
evansmj Jun 11, 2024
e874008
Highlight bar color on hover
evansmj Jun 11, 2024
d6cb084
Support zooming and panning
evansmj Jun 22, 2024
024e2ed
Add clip so elements dont render behind y axis after zooming or panning
evansmj Jun 22, 2024
cc37805
Add minutely and yearly time granularity
evansmj Jun 24, 2024
0af46c6
Fix zooming
evansmj Jun 24, 2024
40c1203
Center x-axis ticks under each bar when zooming
evansmj Jun 24, 2024
481e2e6
Memoize fetchBalanceSheetData and suppress exhaustive deps since we d…
evansmj Jun 25, 2024
b23cc33
Pass BalanceSheetRoot container width to graph
evansmj Jun 29, 2024
4fd0c50
constraint table to container width and make scrollable
evansmj Jul 1, 2024
9e58031
Make table scrollable vertically
evansmj Jul 2, 2024
63294cb
Refactor balance sheet types to convert raw sql to workable object.
evansmj Jul 13, 2024
de03aa6
Clarify balance sheet data processing
evansmj Jul 17, 2024
f915351
Add sats-flow chart
evansmj Aug 6, 2024
6414719
Add checkbox to hide zero activity
evansmj Aug 7, 2024
5ae9263
Refactor bar drawing
evansmj Aug 8, 2024
36147e0
Update zoom behavior
evansmj Aug 20, 2024
3c7dc4d
Display Invoice Rune (#56)
evansmj Jun 6, 2024
666af30
Move @types/d3 to devDependencies
evansmj Aug 21, 2024
38f7f4a
Set default TimeGranularity to Monthly
evansmj Aug 22, 2024
7fa0e76
Add VolumeGraph
evansmj Sep 12, 2024
4fc8cd3
Add sql terminal
evansmj Oct 1, 2024
552e342
Fix header not rendering in bookkeeper routes
evansmj Oct 1, 2024
037e4f1
Add date range to balance sheet
evansmj Oct 3, 2024
372661e
Update TimeGranularity button style and support dark mode
evansmj Oct 21, 2024
0f96c76
Style balance sheet according to figma
evansmj Oct 31, 2024
1dd01bb
Update styles
evansmj Nov 11, 2024
52ad20c
format volume sats
evansmj Nov 11, 2024
d1af585
format net inflow
evansmj Nov 11, 2024
9cbb1af
Fix lint issues on VolumeGraph
evansmj Nov 22, 2024
f5bc2a3
Hide dropdown icon when value is selected in DatepickerInput
evansmj Nov 22, 2024
4c7445a
Hide zero activity periods on balance sheet.
evansmj Nov 22, 2024
3363007
Add total period balance to balance sheet graph tool tip
evansmj Nov 23, 2024
2868b3f
Move balance format to constants.ts
evansmj Nov 23, 2024
d950883
Refactor timestamp range calculation out of sql into transform function
evansmj Nov 23, 2024
e6ef93b
Add date range options to sats flow
evansmj Nov 28, 2024
7f02992
Bookkeeper landing layout
evansmj Dec 20, 2024
65de998
Fix dark/light mode colors
evansmj Dec 20, 2024
2b8af66
Fetch data for bookkeeper landing
evansmj Dec 23, 2024
44c2d94
Fix volume summation
evansmj Dec 26, 2024
322bc65
Display routes for volume chart instead of channels
evansmj Dec 26, 2024
14d6e3d
Add terminal button
evansmj Dec 26, 2024
e04fa20
fix lints
evansmj Dec 26, 2024
dc95773
Update bar color scheme
evansmj Dec 26, 2024
218ce94
Merge branch 'Release-0.0.7' of github.com:ElementsProject/cln-applic…
evansmj Dec 26, 2024
094e7e8
Fix inbound display
evansmj Dec 26, 2024
f8dc8a7
Add tests for bookkeeper components
evansmj Dec 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/frontend/build/asset-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
"static/css/main.1ce19166.css",
"static/js/main.12dcd792.js"
]
}
}
2 changes: 1 addition & 1 deletion apps/frontend/build/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./images/cln-favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="color-scheme" content="light dark"><meta name="description" content="Core lightning application"/><link rel="apple-touch-icon" href="./images/cln-logo-dark.png"/><title>Core Lightning</title><script defer="defer" src="/static/js/main.12dcd792.js"></script><link href="/static/css/main.1ce19166.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./images/cln-favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="color-scheme" content="light dark"><meta name="description" content="Core lightning application"/><link rel="apple-touch-icon" href="./images/cln-logo-dark.png"/><title>Core Lightning</title><script defer="defer" src="/static/js/main.12dcd792.js"></script><link href="/static/css/main.1ce19166.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
3 changes: 3 additions & 0 deletions apps/frontend/build/static/js/main.ab5edb57.js

Large diffs are not rendered by default.

90 changes: 90 additions & 0 deletions apps/frontend/build/static/js/main.ab5edb57.js.LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*!
Copyright (c) 2018 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/

/*!
* perfect-scrollbar v1.5.3
* Copyright 2021 Hyunje Jun, MDBootstrap and Contributors
* Licensed under MIT
*/

/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/**
* @license qrcode.react
* Copyright (c) Paul O'Shannessy
* SPDX-License-Identifier: ISC
*/

/**
* @remix-run/router v1.15.2
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/

/**
* React Router DOM v6.22.2
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/

/**
* React Router v6.22.2
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
1 change: 1 addition & 0 deletions apps/frontend/build/static/js/main.ab5edb57.js.map

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@
"bootstrap": "^5.3.2",
"copy-to-clipboard": "^3.3.3",
"crypto-js": "^4.2.0",
"d3": "^7.9.0",
"framer-motion": "^10.16.5",
"moment": "^2.30.1",
"node-sass": "^7.0.3",
"qrcode.react": "^3.1.0",
"react": "^18.2.0",
"react-bootstrap": "^2.10.1",
"react-datepicker": "^7.3.0",
"react-dom": "^18.2.0",
"react-perfect-scrollbar": "^1.5.8",
"react-router-dom": "^6.22.1",
Expand All @@ -31,6 +34,7 @@
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.2.1",
"@testing-library/user-event": "^14.5.1",
"@types/d3": "^7.4.3",
"@types/jest": "^29.5.12",
"@types/node": "^20.9.4",
"@types/react": "^18.2.61",
Expand Down
10 changes: 8 additions & 2 deletions apps/frontend/src/components/App/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import React from 'react';

import './App.scss';
import { useContext, useEffect } from 'react';
import { Navigate, Outlet, RouterProvider, createBrowserRouter } from 'react-router-dom';
Expand All @@ -20,6 +18,10 @@ import logger from '../../services/logger.service';
import { AuthResponse } from '../../types/app-config.type';
import Bookkeeper from '../bookkeeper/BkprRoot/BkprRoot';
import CLNHome from '../cln/CLNHome/CLNHome';
import BalanceSheetRoot from '../bookkeeper/BalanceSheet/BalanceSheetRoot';
import SatsFlowRoot from '../bookkeeper/SatsFlow/SatsFlowRoot';
import VolumeRoot from '../bookkeeper/Volume/VolumeRoot';
import Terminal from '../bookkeeper/Terminal/TerminalRoot';

export const rootRouteConfig = [
{
Expand All @@ -28,6 +30,10 @@ export const rootRouteConfig = [
{ path: "/", Component: () => <Navigate to="/home" replace /> },
{ path: "home", Component: CLNHome },
{ path: "bookkeeper", Component: Bookkeeper },
{ path: "bookkeeper/balancesheet", Component: BalanceSheetRoot },
{ path: "bookkeeper/satsflow", Component: SatsFlowRoot },
{ path: "bookkeeper/volume", Component: VolumeRoot },
{ path: "bookkeeper/terminal", Component: Terminal }
]
},
];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
@import '../../../styles/constants.scss';

.react-datepicker-popper {
.react-datepicker {
border-color: $border-color;

&__header {
background-color: transparent;
border-bottom-color: $border-color;
}

&__navigation {
&-icon::before {
border-color: currentColor;
}

&:hover *::before {
border-color: $primary;
}
}

&__day {
&:hover {
background-color: rgba($primary, 0.1);
color: $primary;
}

&--selected {
background-color: $primary;
color: white;

&:hover {
background-color: darken($primary, 5%);
}
}

&--keyboard-selected {
background-color: rgba($primary, 0.1);
color: $primary;
}
}

&__current-month,
&__day-name {
color: inherit;
}
}
}

@include color-mode(dark) {
.react-datepicker-popper {
.react-datepicker {
background-color: $picker-background-color-dark;
border-color: $picker-border-color-dark;

&__header {
background-color: $picker-background-color-dark;
border-bottom-color: $picker-border-color-dark;
}

&__current-month,
&__day-name,
&__day {
color: $light-dark;
}

&__day {
&:hover {
background-color: rgba($primary, 0.1);
color: $primary;
}

&--selected {
background-color: $primary;
color: $white;

&:hover {
background-color: darken($primary, 5%);
}
}

&--keyboard-selected {
background-color: rgba($primary, 0.1);
color: $primary;
}
}

&__navigation-icon::before {
border-color: $light-dark;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { render, screen } from '@testing-library/react';
import BalanceSheetRoot from './BalanceSheetRoot';

jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: jest.fn(),
}));

describe('Balance Sheet component ', () => {
beforeEach(() => render(<BalanceSheetRoot />));

it('should be in the document', () => {
expect(screen.getByTestId('balancesheet-container')).not.toBeEmptyDOMElement()
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { useCallback, useContext, useEffect, useRef, useState } from 'react';

import './BalanceSheetRoot.scss';
import 'react-datepicker/dist/react-datepicker.css';
import Card from 'react-bootstrap/Card';
import Row from 'react-bootstrap/Row';
import BalanceSheetGraph from './Graph/BalanceSheetGraph';
import { AppContext } from '../../../store/AppContext';
import BalanceSheetTable from './Table/BalanceSheetTable';
import useHttp from '../../../hooks/use-http';
import { TimeGranularity } from '../../../utilities/constants';
import { BalanceSheet } from '../../../types/lightning-balancesheet.type';
import TimeGranularitySelection from '../TimeGranularitySelection/TimeGranularitySelection';
import { Container } from 'react-bootstrap';
import DatePicker from 'react-datepicker';
import DatepickerInput from '../DatepickerInput/DatepickerInput';

const BalanceSheetRoot = () => {
const appCtx = useContext(AppContext);
const [containerWidth, setContainerWidth] = useState(0);
const containerRef = useRef<HTMLDivElement>(null);
const [balanceSheetData, setBalanceSheetData] = useState<BalanceSheet>({ periods: [] });
const [timeGranularity, setTimeGranularity] = useState<TimeGranularity>(TimeGranularity.MONTHLY);
const [rangeStart, setRangeStart] = useState<Date | undefined>(undefined);
const [rangeEnd, setRangeEnd] = useState<Date | undefined>(undefined);
const [hideZeroActivityPeriods, setHideZeroActivityPeriods] = useState<boolean>(true);
const { getBalanceSheet } = useHttp();

const updateWidth = () => {
if (containerRef.current) {
setContainerWidth(containerRef.current.getBoundingClientRect().width);
}
};

const fetchBalanceSheetData = useCallback(
async (timeGranularity: TimeGranularity, hideZeroActivityPeriods: Boolean, startDate?: Date, endDate?: Date) => {
getBalanceSheet(timeGranularity, hideZeroActivityPeriods, startDate, endDate)
.then((response: BalanceSheet) => {
setBalanceSheetData(response);
})
.catch(err => {
console.error('fetchBalanceSheet error ' + JSON.stringify(err));
});
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[],
);

const timeGranularityChangeHandler = timeGranularity => {
setTimeGranularity(timeGranularity);
};

const hideZeroActivityPeriodsChangeHandler = (event) => {
setHideZeroActivityPeriods(event.target.checked);
};

useEffect(() => {
updateWidth();
window.addEventListener('resize', updateWidth);
return () => window.removeEventListener('resize', updateWidth);
}, []);

useEffect(() => {
if (appCtx.authStatus.isAuthenticated) {
fetchBalanceSheetData(timeGranularity, hideZeroActivityPeriods, rangeStart, rangeEnd);
}
}, [
appCtx.authStatus.isAuthenticated,
timeGranularity,
rangeStart,
rangeEnd,
fetchBalanceSheetData,
hideZeroActivityPeriods,
]);

return (
<div data-testid="balancesheet-container" ref={containerRef}>
<Card className="d-flex align-items-stretch inner-box-shadow">
<Card.Header className="p-2">
<Container fluid>
<Row>
<div className="fs-4 mt-2 fw-bold">Balance Sheet</div>
</Row>
<div className="d-flex align-items-center mt-2 gap-4">
<div className="fw-bold">Time Granularity</div>
<TimeGranularitySelection
className="time-granularity-dropdown"
timeGranularity={timeGranularity}
onTimeGranularityChanged={timeGranularityChangeHandler}
/>
<DatePicker
customInput={<DatepickerInput />}
selected={rangeStart}
onChange={date => setRangeStart(date ?? undefined)}
placeholderText="Starts"
/>
<DatePicker
customInput={<DatepickerInput />}
selected={rangeEnd}
onChange={date => setRangeEnd(date ?? undefined)}
placeholderText="Ends"
/>
<div className="ms-3 me-3 mt-2 d-flex align-items-center">
<input
type="checkbox"
id="hideZeroActivityCheckbox"
name="hideZeroActivity"
checked={hideZeroActivityPeriods}
onChange={hideZeroActivityPeriodsChangeHandler}
/>
<label htmlFor="hideZeroActivityCheckbox" className="ms-2">
Hide Zero Activity
</label>
</div>
</div>
</Container>
</Card.Header>
<Card.Body className="pb-4 d-flex flex-column align-items-center">
<Row>
<BalanceSheetGraph balanceSheetData={balanceSheetData} width={containerWidth} />
</Row>
<Row className="w-100 overflow-x-auto">
<BalanceSheetTable balanceSheetData={balanceSheetData} />
</Row>
</Card.Body>
</Card>
</div>
);
};

export default BalanceSheetRoot;
Loading