diff --git a/app/Api/V1/Controllers/Summary/BasicController.php b/app/Api/V1/Controllers/Summary/BasicController.php
index 72734fd361..6cf94eacd7 100644
--- a/app/Api/V1/Controllers/Summary/BasicController.php
+++ b/app/Api/V1/Controllers/Summary/BasicController.php
@@ -322,16 +322,11 @@ class BasicController extends Controller
'currency_decimal_places' => $row['currency_decimal_places'],
'value_parsed' => app('amount')->formatFlat($row['currency_symbol'], $row['currency_decimal_places'], $leftToSpend, false),
'local_icon' => 'money',
- 'sub_title' => (string)trans(
- 'firefly.box_spend_per_day',
- [
- 'amount' => app('amount')->formatFlat(
- $row['currency_symbol'],
- $row['currency_decimal_places'],
- $perDay,
- false
- ),
- ]
+ 'sub_title' => app('amount')->formatFlat(
+ $row['currency_symbol'],
+ $row['currency_decimal_places'],
+ $perDay,
+ false
),
];
}
diff --git a/package-lock.json b/package-lock.json
index 3a1e03d2d3..6581c72f83 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
"alpinejs": "^3.12.3",
"bootstrap": "^5.3.0",
"date-fns": "^2.30.0",
- "store2": "^2.14.2"
+ "store": "^2.0.12"
},
"devDependencies": {
"axios": "^1.1.2",
@@ -885,10 +885,13 @@
"node": ">=0.10.0"
}
},
- "node_modules/store2": {
- "version": "2.14.2",
- "resolved": "https://registry.npmjs.org/store2/-/store2-2.14.2.tgz",
- "integrity": "sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w=="
+ "node_modules/store": {
+ "version": "2.0.12",
+ "resolved": "https://registry.npmjs.org/store/-/store-2.0.12.tgz",
+ "integrity": "sha512-eO9xlzDpXLiMr9W1nQ3Nfp9EzZieIQc10zPPMP5jsVV7bLOziSFFBP0XoDXACEIFtdI+rIz0NwWVA/QVJ8zJtw==",
+ "engines": {
+ "node": "*"
+ }
},
"node_modules/to-regex-range": {
"version": "5.0.1",
@@ -1466,10 +1469,10 @@
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"dev": true
},
- "store2": {
- "version": "2.14.2",
- "resolved": "https://registry.npmjs.org/store2/-/store2-2.14.2.tgz",
- "integrity": "sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w=="
+ "store": {
+ "version": "2.0.12",
+ "resolved": "https://registry.npmjs.org/store/-/store-2.0.12.tgz",
+ "integrity": "sha512-eO9xlzDpXLiMr9W1nQ3Nfp9EzZieIQc10zPPMP5jsVV7bLOziSFFBP0XoDXACEIFtdI+rIz0NwWVA/QVJ8zJtw=="
},
"to-regex-range": {
"version": "5.0.1",
diff --git a/package.json b/package.json
index bbaafc7517..62f1ef512b 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,6 @@
"alpinejs": "^3.12.3",
"bootstrap": "^5.3.0",
"date-fns": "^2.30.0",
- "store2": "^2.14.2"
+ "store": "^2.0.12"
}
}
diff --git a/resources/assets/v4/app.js b/resources/assets/v4/app.js
index 903e5feaa9..c80d9aefeb 100644
--- a/resources/assets/v4/app.js
+++ b/resources/assets/v4/app.js
@@ -1,206 +1,187 @@
-import './bootstrap';
-import {
- addMonths,
- endOfDay,
- endOfMonth,
- endOfQuarter,
- endOfWeek,
- startOfDay,
- startOfMonth,
- startOfQuarter,
- startOfWeek,
- startOfYear,
- subDays,
- subMonths
-} from "date-fns";
-import format from './util/format'
-
-class MainApp {
- range = {
- start: null, end: null
- };
- defaultRange = {
- start: null, end: null
- };
- viewRange = '1M';
- locale = 'en-US';
- language = 'en-US';
-
- constructor() {
- console.log('MainApp constructor');
- let start = window.BasicStore.get('start');
- let end = window.BasicStore.get('end');
- if (null !== start && null !== end) {
- console.log('start + end is not null, recycle it.');
- this.range = {
- start: new Date(start),
- end: new Date(end),
- };
- return;
- }
- console.log('start + end = null!');
-
- }
-
- init() {
- console.log('MainApp init');
- // get values from store and use them accordingly.
- this.viewRange = window.BasicStore.get('viewRange');
- this.locale = window.BasicStore.get('locale');
- this.language = window.BasicStore.get('language');
- this.locale = 'equal' === this.locale ? this.language : this.locale;
- window.__localeId__ = this.language;
-
- // the range is always null but later on we will store it in BasicStore.
- if (null === this.range.start && null === this.range.end) {
- console.log('start + end = null, calling setDatesFromViewRange()');
- this.range = this.setDatesFromViewRange(new Date);
- }
- console.log('MainApp: set defaultRange');
- this.defaultRange = this.setDatesFromViewRange(new Date);
- // default range is always the current period (initialized ahead)
- }
-
-
- buildDateRange() {
- console.log('MainApp: buildDateRange');
- // generate ranges
- let nextRange = this.getNextRange();
- let prevRange = this.getPrevRange();
- let last7 = this.lastDays(7);
- let last30 = this.lastDays(30);
- let mtd = this.mtd();
- let ytd = this.ytd();
-
- // set the title:
- let element = document.getElementsByClassName('daterange-holder')[0];
- element.textContent = format(this.range.start) + ' - ' + format(this.range.end);
- element.setAttribute('data-start', format(this.range.start, 'yyyy-MM-dd'));
- element.setAttribute('data-end', format(this.range.end, 'yyyy-MM-dd'));
-
- // set the current one
- element = document.getElementsByClassName('daterange-current')[0];
- element.textContent = format(this.defaultRange.start) + ' - ' + format(this.defaultRange.end);
- element.setAttribute('data-start', format(this.defaultRange.start, 'yyyy-MM-dd'));
- element.setAttribute('data-end', format(this.defaultRange.end, 'yyyy-MM-dd'));
-
- // generate next range
- element = document.getElementsByClassName('daterange-next')[0];
- element.textContent = format(nextRange.start) + ' - ' + format(nextRange.end);
- element.setAttribute('data-start', format(nextRange.start, 'yyyy-MM-dd'));
- element.setAttribute('data-end', format(nextRange.end, 'yyyy-MM-dd'));
-
- // previous range.
- element = document.getElementsByClassName('daterange-prev')[0];
- element.textContent = format(prevRange.start) + ' - ' + format(prevRange.end);
- element.setAttribute('data-start', format(prevRange.start, 'yyyy-MM-dd'));
- element.setAttribute('data-end', format(prevRange.end, 'yyyy-MM-dd'));
-
- // last 7
- element = document.getElementsByClassName('daterange-7d')[0];
- element.setAttribute('data-start', format(last7.start, 'yyyy-MM-dd'));
- element.setAttribute('data-end', format(last7.end, 'yyyy-MM-dd'));
-
- // last 30
- element = document.getElementsByClassName('daterange-90d')[0];
- element.setAttribute('data-start', format(last30.start, 'yyyy-MM-dd'));
- element.setAttribute('data-end', format(last30.end, 'yyyy-MM-dd'));
-
- // MTD
- element = document.getElementsByClassName('daterange-mtd')[0];
- element.setAttribute('data-start', format(mtd.start, 'yyyy-MM-dd'));
- element.setAttribute('data-end', format(mtd.end, 'yyyy-MM-dd'));
-
- // YTD
- element = document.getElementsByClassName('daterange-ytd')[0];
- element.setAttribute('data-start', format(ytd.start, 'yyyy-MM-dd'));
- element.setAttribute('data-end', format(ytd.end, 'yyyy-MM-dd'));
-
- // custom range.
- console.log('MainApp: buildDateRange end');
- }
-
- getNextRange() {
- let start = startOfMonth(this.range.start);
- let nextMonth = addMonths(start, 1);
- let end = endOfMonth(nextMonth);
- return {start: nextMonth, end: end};
- }
-
- getPrevRange() {
- let start = startOfMonth(this.range.start);
- let prevMonth = subMonths(start, 1);
- let end = endOfMonth(prevMonth);
- return {start: prevMonth, end: end};
- }
-
- ytd() {
- let end = new Date;
- let start = startOfYear(this.range.start);
- return {start: start, end: end};
- }
-
- mtd() {
-
- let end = new Date;
- let start = startOfMonth(this.range.start);
- return {start: start, end: end};
- }
-
- lastDays(days) {
- let end = new Date;
- let start = subDays(end, days);
- return {start: start, end: end};
- }
-
- changeDateRange(e) {
- console.log('MainApp: changeDateRange');
- let target = e.currentTarget;
- //alert('OK 3');
- let start = new Date(target.getAttribute('data-start'));
- let end = new Date(target.getAttribute('data-end'));
- console.log('MainApp: Change date range', start, end);
- e.preventDefault();
- // TODO send start + end to the store and trigger this again?
- window.app.setStart(start);
- window.app.setEnd(end);
- window.app.buildDateRange();
- console.log('MainApp: end changeDateRange');
- return false;
- }
-
- setStart(date) {
- console.log('MainApp: setStart');
- this.range.start = date;
- window.BasicStore.store('start', date);
- }
-
- setEnd(date) {
- console.log('MainApp: setEnd');
- this.range.end = date;
- window.BasicStore.store('end', date);
- }
-}
-
-let app = new MainApp();
-
-// Listen for the basic store, we need it to continue with the
-document.addEventListener("BasicStoreReady", (e) => {
- console.log('MainApp: app.js from event handler');
- app.init();
- app.buildDateRange();
- const event = new Event("AppReady");
- document.dispatchEvent(event);
-}, false,);
-
-if (window.BasicStore.isReady()) {
- console.log('MainApp: app.js from store ready');
- app.init();
- app.buildDateRange();
- const event = new Event("AppReady");
- document.dispatchEvent(event);
-}
-
-window.app = app;
-
-export default app;
+// import './bootstrap';
+// import {
+// addMonths,
+// endOfDay,
+// endOfMonth,
+// endOfQuarter,
+// endOfWeek,
+// startOfDay,
+// startOfMonth,
+// startOfQuarter,
+// startOfWeek,
+// startOfYear,
+// subDays,
+// subMonths
+// } from "date-fns";
+// import format from './util/format'
+//
+// export default () => ({
+// range: {
+// start: null, end: null
+// },
+// defaultRange: {
+// start: null, end: null
+// },
+//
+// init() {
+// console.log('MainApp init');
+// // get values from store and use them accordingly.
+// // this.viewRange = window.BasicStore.get('viewRange');
+// // this.locale = window.BasicStore.get('locale');
+// // this.language = window.BasicStore.get('language');
+// // this.locale = 'equal' === this.locale ? this.language : this.locale;
+// // window.__localeId__ = this.language;
+// //
+// // // the range is always null but later on we will store it in BasicStore.
+// // if (null === this.range.start && null === this.range.end) {
+// // console.log('start + end = null, calling setDatesFromViewRange()');
+// // this.range = this.setDatesFromViewRange(new Date);
+// // }
+// // console.log('MainApp: set defaultRange');
+// // this.defaultRange = this.setDatesFromViewRange(new Date);
+// // // default range is always the current period (initialized ahead)
+// },
+//
+//
+// buildDateRange() {
+// console.log('MainApp: buildDateRange');
+// // generate ranges
+// let nextRange = this.getNextRange();
+// let prevRange = this.getPrevRange();
+// let last7 = this.lastDays(7);
+// let last30 = this.lastDays(30);
+// let mtd = this.mtd();
+// let ytd = this.ytd();
+//
+// // set the title:
+// let element = document.getElementsByClassName('daterange-holder')[0];
+// element.textContent = format(this.range.start) + ' - ' + format(this.range.end);
+// element.setAttribute('data-start', format(this.range.start, 'yyyy-MM-dd'));
+// element.setAttribute('data-end', format(this.range.end, 'yyyy-MM-dd'));
+//
+// // set the current one
+// element = document.getElementsByClassName('daterange-current')[0];
+// element.textContent = format(this.defaultRange.start) + ' - ' + format(this.defaultRange.end);
+// element.setAttribute('data-start', format(this.defaultRange.start, 'yyyy-MM-dd'));
+// element.setAttribute('data-end', format(this.defaultRange.end, 'yyyy-MM-dd'));
+//
+// // generate next range
+// element = document.getElementsByClassName('daterange-next')[0];
+// element.textContent = format(nextRange.start) + ' - ' + format(nextRange.end);
+// element.setAttribute('data-start', format(nextRange.start, 'yyyy-MM-dd'));
+// element.setAttribute('data-end', format(nextRange.end, 'yyyy-MM-dd'));
+//
+// // previous range.
+// element = document.getElementsByClassName('daterange-prev')[0];
+// element.textContent = format(prevRange.start) + ' - ' + format(prevRange.end);
+// element.setAttribute('data-start', format(prevRange.start, 'yyyy-MM-dd'));
+// element.setAttribute('data-end', format(prevRange.end, 'yyyy-MM-dd'));
+//
+// // last 7
+// element = document.getElementsByClassName('daterange-7d')[0];
+// element.setAttribute('data-start', format(last7.start, 'yyyy-MM-dd'));
+// element.setAttribute('data-end', format(last7.end, 'yyyy-MM-dd'));
+//
+// // last 30
+// element = document.getElementsByClassName('daterange-90d')[0];
+// element.setAttribute('data-start', format(last30.start, 'yyyy-MM-dd'));
+// element.setAttribute('data-end', format(last30.end, 'yyyy-MM-dd'));
+//
+// // MTD
+// element = document.getElementsByClassName('daterange-mtd')[0];
+// element.setAttribute('data-start', format(mtd.start, 'yyyy-MM-dd'));
+// element.setAttribute('data-end', format(mtd.end, 'yyyy-MM-dd'));
+//
+// // YTD
+// element = document.getElementsByClassName('daterange-ytd')[0];
+// element.setAttribute('data-start', format(ytd.start, 'yyyy-MM-dd'));
+// element.setAttribute('data-end', format(ytd.end, 'yyyy-MM-dd'));
+//
+// // custom range.
+// console.log('MainApp: buildDateRange end');
+// },
+//
+// getNextRange() {
+// let start = startOfMonth(this.range.start);
+// let nextMonth = addMonths(start, 1);
+// let end = endOfMonth(nextMonth);
+// return {start: nextMonth, end: end};
+// },
+//
+// getPrevRange() {
+// let start = startOfMonth(this.range.start);
+// let prevMonth = subMonths(start, 1);
+// let end = endOfMonth(prevMonth);
+// return {start: prevMonth, end: end};
+// },
+//
+// ytd() {
+// let end = new Date;
+// let start = startOfYear(this.range.start);
+// return {start: start, end: end};
+// },
+//
+// mtd() {
+//
+// let end = new Date;
+// let start = startOfMonth(this.range.start);
+// return {start: start, end: end};
+// },
+//
+// lastDays(days) {
+// let end = new Date;
+// let start = subDays(end, days);
+// return {start: start, end: end};
+// },
+//
+// changeDateRange(e) {
+// console.log('MainApp: changeDateRange');
+// let target = e.currentTarget;
+// //alert('OK 3');
+// let start = new Date(target.getAttribute('data-start'));
+// let end = new Date(target.getAttribute('data-end'));
+// console.log('MainApp: Change date range', start, end);
+// e.preventDefault();
+// // TODO send start + end to the store and trigger this again?
+// window.app.setStart(start);
+// window.app.setEnd(end);
+// window.app.buildDateRange();
+// console.log('MainApp: end changeDateRange');
+// return false;
+// },
+//
+// setStart(date) {
+// console.log('MainApp: setStart');
+// this.range.start = date;
+// window.BasicStore.store('start', date);
+// },
+//
+// setEnd(date) {
+// console.log('MainApp: setEnd');
+// this.range.end = date;
+// window.BasicStore.store('end', date);
+// },
+// });
+//
+// // let app = new MainApp();
+// //
+// // // Listen for the basic store, we need it to continue with the
+// // document.addEventListener("BasicStoreReady", (e) => {
+// // console.log('MainApp: app.js from event handler');
+// // app.init();
+// // app.buildDateRange();
+// // const event = new Event("AppReady");
+// // document.dispatchEvent(event);
+// // }, false,);
+// //
+// // if (window.BasicStore.isReady()) {
+// // console.log('MainApp: app.js from store ready');
+// // app.init();
+// // app.buildDateRange();
+// // const event = new Event("AppReady");
+// // document.dispatchEvent(event);
+// // }
+// //
+// // window.app = app;
+// //
+// // export default app;
diff --git a/resources/assets/v4/bootstrap.js b/resources/assets/v4/bootstrap.js
index f8476277c3..6e58db854e 100644
--- a/resources/assets/v4/bootstrap.js
+++ b/resources/assets/v4/bootstrap.js
@@ -4,9 +4,17 @@
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/
+// import things
import axios from 'axios';
-import store from 'store2';
+import store from "store";
+import observePlugin from 'store/plugins/observe';
import Alpine from "alpinejs";
+
+// add plugin to store and put in window
+store.addPlugin(observePlugin);
+window.store = store;
+
+// import even more
import {getVariable} from "./store/get-variable.js";
import {getViewRange} from "./support/get-viewrange.js";
@@ -15,9 +23,10 @@ window.bootstrapped = false;
Promise.all([
getVariable('viewRange'),
getVariable('darkMode'),
- getVariable('locale')
+ getVariable('locale'),
+ getVariable('language'),
]).then((values) => {
- if (!store.has('start') || !store.has('end')) {
+ if (!store.get('start') || !store.get('end')) {
// calculate new start and end, and store them.
const range = getViewRange(values[0], new Date);
store.set('start', range.start);
diff --git a/resources/assets/v4/dashboard.js b/resources/assets/v4/dashboard.js
index db987889ff..9ecb2ba206 100644
--- a/resources/assets/v4/dashboard.js
+++ b/resources/assets/v4/dashboard.js
@@ -19,9 +19,10 @@
*/
import './bootstrap.js';
+import dates from './pages/shared/dates.js';
import boxes from './pages/dashboard/boxes.js';
-const comps = {boxes};
+const comps = {dates, boxes};
function loadPage(comps) {
Object.keys(comps).forEach(comp => {
diff --git a/resources/assets/v4/pages/dashboard/boxes.js b/resources/assets/v4/pages/dashboard/boxes.js
index d1e4a17a2b..e0ea2c9e74 100644
--- a/resources/assets/v4/pages/dashboard/boxes.js
+++ b/resources/assets/v4/pages/dashboard/boxes.js
@@ -18,20 +18,64 @@
* along with this program. If not, see