diff --git a/resources/assets/v2/api/v2/chart/budget/dashboard.js b/resources/assets/v2/api/v2/chart/budget/dashboard.js new file mode 100644 index 0000000000..873220ab6d --- /dev/null +++ b/resources/assets/v2/api/v2/chart/budget/dashboard.js @@ -0,0 +1,30 @@ +/* + * overview.js + * Copyright (c) 2022 james@firefly-iii.org + * + * This file is part of Firefly III (https://github.com/firefly-iii). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import {api} from "../../../../boot/axios"; +import {format} from "date-fns"; + +export default class Dashboard { + dashboard(start, end) { + let startStr = format(start, 'y-MM-dd'); + let endStr = format(end, 'y-MM-dd'); + return api.get('/api/v2/chart/budget/dashboard', {params: {start: startStr, end: endStr}}); + } +} diff --git a/resources/assets/v2/dashboard.js b/resources/assets/v2/dashboard.js index 8389685606..45b8883d3c 100644 --- a/resources/assets/v2/dashboard.js +++ b/resources/assets/v2/dashboard.js @@ -22,8 +22,9 @@ import './bootstrap.js'; import dates from './pages/shared/dates.js'; import boxes from './pages/dashboard/boxes.js'; import accounts from './pages/dashboard/accounts.js'; +import budgets from './pages/dashboard/budgets.js'; -const comps = {dates, boxes, accounts}; +const comps = {dates, boxes, accounts, budgets}; function loadPage(comps) { Object.keys(comps).forEach(comp => { diff --git a/resources/assets/v2/pages/dashboard/accounts.js b/resources/assets/v2/pages/dashboard/accounts.js index 0c77acb348..03e4f88328 100644 --- a/resources/assets/v2/pages/dashboard/accounts.js +++ b/resources/assets/v2/pages/dashboard/accounts.js @@ -57,7 +57,8 @@ export default () => ({ legend: {show: false}, chart: { height: 400, - toolbar: {tools: {zoom: false, download: false, pan: false}}, type: 'line' + toolbar: {tools: {zoom: false, download: false, pan: false}}, + type: 'line' }, series: [], settings: [], xaxis: { @@ -137,16 +138,11 @@ export default () => ({ let accountId = values[0][i]; // grab account info for box: (new Get).get(accountId, new Date(window.store.get('end'))).then((response) => { - let current = response.data.data; - this.accountList[i] = { - name: current.attributes.name, - id: current.id, - balance: formatMoney(current.attributes.current_balance, current.attributes.currency_code), - groups: [], - }; + let parent = response.data.data; // get groups for account: - (new Get).transactions(current.id, 1).then((response) => { + (new Get).transactions(parent.id, 1).then((response) => { + let groups = []; for (let ii = 0; ii < response.data.data.length; ii++) { if (ii >= max) { break; @@ -165,17 +161,19 @@ export default () => ({ amount: formatMoney(currentTransaction.amount, currentTransaction.currency_code), }); } - this.accountList[i].groups.push(group); + groups.push(group); } - // will become false after the FIRST account is loaded. - this.loadingAccounts = false; + this.accountList[i] = { + name: parent.attributes.name, + id: parent.id, + balance: formatMoney(parent.attributes.current_balance, parent.attributes.currency_code), + groups: groups, + }; }); - }).then(() => { - // console.log(this.accountList); }); } } - + this.loadingAccounts = false; }); }, diff --git a/resources/assets/v2/pages/dashboard/budgets.js b/resources/assets/v2/pages/dashboard/budgets.js new file mode 100644 index 0000000000..444d5054f7 --- /dev/null +++ b/resources/assets/v2/pages/dashboard/budgets.js @@ -0,0 +1,148 @@ +/* + * budgets.js + * Copyright (c) 2023 james@firefly-iii.org + * + * This file is part of Firefly III (https://github.com/firefly-iii). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +import {getVariable} from "../../store/get-variable.js"; +import Dashboard from "../../api/v2/chart/budget/dashboard.js"; +import ApexCharts from "apexcharts"; + +export default () => ({ + loadingChart: false, + chart: null, + autoConversion: false, + loadChart() { + if (this.loadingChart) { + return; + } + // load chart data + this.loadingChart = true; + const dashboard = new Dashboard(); + dashboard.dashboard(new Date(window.store.get('start')), new Date(window.store.get('end')), null).then((response) => { + console.log(response.data); + + let options = { + legend: {show: false}, + series: [{ + name: 'Spent', + data: [] + }, { + name: 'Left', + data: [] + }, { + name: 'Overspent', + data: [] + }], + chart: { + type: 'bar', + height: 400, + stacked: true, + toolbar: {tools: {zoom: false, download: false, pan: false}}, + zoom: { + enabled: true + } + }, + responsive: [{ + breakpoint: 480, + options: { + legend: { + position: 'bottom', + offsetX: -10, + offsetY: 0 + } + } + }], + plotOptions: { + bar: { + horizontal: false, + borderRadius: 10, + dataLabels: { + total: { + enabled: true, + style: { + fontSize: '13px', + fontWeight: 900 + } + } + } + }, + }, + xaxis: { + categories: [] + }, + fill: { + opacity: 0.8 + } + }; + + + for (const i in response.data) { + if (response.data.hasOwnProperty(i)) { + let current = response.data[i]; + // convert to EUR yes no? + let label = current.label + ' (' + current.currency_code + ')'; + options.xaxis.categories.push(label); + console.log(current); + if (this.autoConversion) { + // series 0: spent + options.series[0].data.push(parseFloat(current.native_entries.spent) * -1); + // series 1: left + options.series[1].data.push(parseFloat(current.native_entries.left)); + // series 2: overspent + options.series[2].data.push(parseFloat(current.native_entries.overspent)); + } + if (!this.autoConversion) { + // series 0: spent + options.series[0].data.push(parseFloat(current.entries.spent) * -1); + // series 1: left + options.series[1].data.push(parseFloat(current.entries.left)); + // series 2: overspent + options.series[2].data.push(parseFloat(current.entries.overspent)); + } + + } + } + + + if (null !== this.chart) { + // chart already in place, refresh: + this.chart.updateOptions(options); + } + if (null === this.chart) { + this.chart = new ApexCharts(document.querySelector("#budget-chart"), options); + this.chart.render(); + } + this.loadingChart = false; + }); + + + }, + init() { + console.log('init budgets'); + Promise.all([getVariable('autoConversion', false),]).then((values) => { + this.autoConversion = values[0]; + console.log('here we are, budgets.'); + this.loadChart(); + }); + window.store.observe('end', () => { + this.loadChart(); + }); + }, + +}); + + diff --git a/resources/views/v2/index.blade.php b/resources/views/v2/index.blade.php index 953e7c7f0c..3eea50fed3 100644 --- a/resources/views/v2/index.blade.php +++ b/resources/views/v2/index.blade.php @@ -9,8 +9,8 @@
@include('partials.dashboard.boxes') -
-
+
+
@@ -44,7 +44,7 @@
-
+
@@ -78,7 +78,7 @@