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')
-