mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Lots of new code.
This commit is contained in:
parent
f1173263b6
commit
a6503fda39
174
package-lock.json
generated
174
package-lock.json
generated
@ -8,6 +8,7 @@
|
||||
"@fortawesome/fontawesome-free": "^6.4.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"alpinejs": "^3.12.3",
|
||||
"apexcharts": "^3.41.0",
|
||||
"bootstrap": "^5.3.0",
|
||||
"date-fns": "^2.30.0",
|
||||
"store": "^2.0.12"
|
||||
@ -434,6 +435,19 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/apexcharts": {
|
||||
"version": "3.41.0",
|
||||
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.41.0.tgz",
|
||||
"integrity": "sha512-FJXA7NVjxs1q+ptR3b1I+pN8K/gWuXn+qLZjFz8EHvJOokdgcuwa/HSe5aC465HW/LWnrjWLSTsOQejQbQ42hQ==",
|
||||
"dependencies": {
|
||||
"svg.draggable.js": "^2.2.2",
|
||||
"svg.easing.js": "^2.0.0",
|
||||
"svg.filter.js": "^2.0.2",
|
||||
"svg.pathmorphing.js": "^0.1.3",
|
||||
"svg.resize.js": "^1.4.3",
|
||||
"svg.select.js": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
@ -893,6 +907,89 @@
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.draggable.js": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz",
|
||||
"integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.easing.js": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz",
|
||||
"integrity": "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==",
|
||||
"dependencies": {
|
||||
"svg.js": ">=2.3.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.filter.js": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz",
|
||||
"integrity": "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.2.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.js": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz",
|
||||
"integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA=="
|
||||
},
|
||||
"node_modules/svg.pathmorphing.js": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz",
|
||||
"integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.resize.js": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz",
|
||||
"integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.6.5",
|
||||
"svg.select.js": "^2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.resize.js/node_modules/svg.select.js": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz",
|
||||
"integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.2.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.select.js": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz",
|
||||
"integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.6.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
@ -1178,6 +1275,19 @@
|
||||
"picomatch": "^2.0.4"
|
||||
}
|
||||
},
|
||||
"apexcharts": {
|
||||
"version": "3.41.0",
|
||||
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.41.0.tgz",
|
||||
"integrity": "sha512-FJXA7NVjxs1q+ptR3b1I+pN8K/gWuXn+qLZjFz8EHvJOokdgcuwa/HSe5aC465HW/LWnrjWLSTsOQejQbQ42hQ==",
|
||||
"requires": {
|
||||
"svg.draggable.js": "^2.2.2",
|
||||
"svg.easing.js": "^2.0.0",
|
||||
"svg.filter.js": "^2.0.2",
|
||||
"svg.pathmorphing.js": "^0.1.3",
|
||||
"svg.resize.js": "^1.4.3",
|
||||
"svg.select.js": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
@ -1474,6 +1584,70 @@
|
||||
"resolved": "https://registry.npmjs.org/store/-/store-2.0.12.tgz",
|
||||
"integrity": "sha512-eO9xlzDpXLiMr9W1nQ3Nfp9EzZieIQc10zPPMP5jsVV7bLOziSFFBP0XoDXACEIFtdI+rIz0NwWVA/QVJ8zJtw=="
|
||||
},
|
||||
"svg.draggable.js": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz",
|
||||
"integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==",
|
||||
"requires": {
|
||||
"svg.js": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"svg.easing.js": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz",
|
||||
"integrity": "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==",
|
||||
"requires": {
|
||||
"svg.js": ">=2.3.x"
|
||||
}
|
||||
},
|
||||
"svg.filter.js": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz",
|
||||
"integrity": "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==",
|
||||
"requires": {
|
||||
"svg.js": "^2.2.5"
|
||||
}
|
||||
},
|
||||
"svg.js": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz",
|
||||
"integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA=="
|
||||
},
|
||||
"svg.pathmorphing.js": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz",
|
||||
"integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==",
|
||||
"requires": {
|
||||
"svg.js": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"svg.resize.js": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz",
|
||||
"integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==",
|
||||
"requires": {
|
||||
"svg.js": "^2.6.5",
|
||||
"svg.select.js": "^2.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"svg.select.js": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz",
|
||||
"integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==",
|
||||
"requires": {
|
||||
"svg.js": "^2.2.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"svg.select.js": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz",
|
||||
"integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==",
|
||||
"requires": {
|
||||
"svg.js": "^2.6.5"
|
||||
}
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"@fortawesome/fontawesome-free": "^6.4.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"alpinejs": "^3.12.3",
|
||||
"apexcharts": "^3.41.0",
|
||||
"bootstrap": "^5.3.0",
|
||||
"date-fns": "^2.30.0",
|
||||
"store": "^2.0.12"
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
7
public/v2/css/adminlte.rtl.min.css
vendored
7
public/v2/css/adminlte.rtl.min.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -136,10 +136,10 @@
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
const DATA_KEY$2 = 'lte.push-menu';
|
||||
const EVENT_KEY$2 = `.${DATA_KEY$2}`;
|
||||
const EVENT_OPEN = `open${EVENT_KEY$2}`;
|
||||
const EVENT_COLLAPSE = `collapse${EVENT_KEY$2}`;
|
||||
const DATA_KEY$1 = 'lte.push-menu';
|
||||
const EVENT_KEY$1 = `.${DATA_KEY$1}`;
|
||||
const EVENT_OPEN = `open${EVENT_KEY$1}`;
|
||||
const EVENT_COLLAPSE = `collapse${EVENT_KEY$1}`;
|
||||
const CLASS_NAME_SIDEBAR_MINI = 'sidebar-mini';
|
||||
const CLASS_NAME_SIDEBAR_COLLAPSE = 'sidebar-collapse';
|
||||
const CLASS_NAME_SIDEBAR_OPEN = 'sidebar-open';
|
||||
@ -282,17 +282,17 @@
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
// const NAME = 'Treeview'
|
||||
const DATA_KEY$1 = 'lte.treeview';
|
||||
const EVENT_KEY$1 = `.${DATA_KEY$1}`;
|
||||
const EVENT_EXPANDED$1 = `expanded${EVENT_KEY$1}`;
|
||||
const EVENT_COLLAPSED$1 = `collapsed${EVENT_KEY$1}`;
|
||||
const DATA_KEY = 'lte.treeview';
|
||||
const EVENT_KEY = `.${DATA_KEY}`;
|
||||
const EVENT_EXPANDED = `expanded${EVENT_KEY}`;
|
||||
const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`;
|
||||
// const EVENT_LOAD_DATA_API = `load${EVENT_KEY}`
|
||||
const CLASS_NAME_MENU_OPEN = 'menu-open';
|
||||
const SELECTOR_NAV_ITEM = '.nav-item';
|
||||
const SELECTOR_NAV_LINK = '.nav-link';
|
||||
const SELECTOR_TREEVIEW_MENU = '.nav-treeview';
|
||||
const SELECTOR_DATA_TOGGLE = '[data-lte-toggle="treeview"]';
|
||||
const Default$1 = {
|
||||
const Default = {
|
||||
animationSpeed: 300
|
||||
};
|
||||
/**
|
||||
@ -302,11 +302,11 @@
|
||||
class Treeview {
|
||||
constructor(element, config) {
|
||||
this._element = element;
|
||||
this._config = Object.assign(Object.assign({}, Default$1), config);
|
||||
this._config = Object.assign(Object.assign({}, Default), config);
|
||||
}
|
||||
open() {
|
||||
var _a;
|
||||
const event = new Event(EVENT_EXPANDED$1);
|
||||
const event = new Event(EVENT_EXPANDED);
|
||||
this._element.classList.add(CLASS_NAME_MENU_OPEN);
|
||||
const childElement = (_a = this._element) === null || _a === void 0 ? void 0 : _a.querySelector(SELECTOR_TREEVIEW_MENU);
|
||||
if (childElement) {
|
||||
@ -316,7 +316,7 @@
|
||||
}
|
||||
close() {
|
||||
var _a;
|
||||
const event = new Event(EVENT_COLLAPSED$1);
|
||||
const event = new Event(EVENT_COLLAPSED);
|
||||
this._element.classList.remove(CLASS_NAME_MENU_OPEN);
|
||||
const childElement = (_a = this._element) === null || _a === void 0 ? void 0 : _a.querySelector(SELECTOR_TREEVIEW_MENU);
|
||||
if (childElement) {
|
||||
@ -349,203 +349,13 @@
|
||||
event.preventDefault();
|
||||
}
|
||||
if (targetItem) {
|
||||
const data = new Treeview(targetItem, Default$1);
|
||||
const data = new Treeview(targetItem, Default);
|
||||
data.toggle();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* --------------------------------------------
|
||||
* AdminLTE card-widget.ts
|
||||
* License MIT
|
||||
* --------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* Constants
|
||||
* ====================================================
|
||||
*/
|
||||
const DATA_KEY = 'lte.card-widget';
|
||||
const EVENT_KEY = `.${DATA_KEY}`;
|
||||
const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`;
|
||||
const EVENT_EXPANDED = `expanded${EVENT_KEY}`;
|
||||
const EVENT_REMOVE = `remove${EVENT_KEY}`;
|
||||
const EVENT_MAXIMIZED = `maximized${EVENT_KEY}`;
|
||||
const EVENT_MINIMIZED = `minimized${EVENT_KEY}`;
|
||||
const CLASS_NAME_CARD = 'card';
|
||||
const CLASS_NAME_COLLAPSED = 'collapsed-card';
|
||||
const CLASS_NAME_COLLAPSING = 'collapsing-card';
|
||||
const CLASS_NAME_EXPANDING = 'expanding-card';
|
||||
const CLASS_NAME_WAS_COLLAPSED = 'was-collapsed';
|
||||
const CLASS_NAME_MAXIMIZED = 'maximized-card';
|
||||
const SELECTOR_DATA_REMOVE = '[data-lte-toggle="card-remove"]';
|
||||
const SELECTOR_DATA_COLLAPSE = '[data-lte-toggle="card-collapse"]';
|
||||
const SELECTOR_DATA_MAXIMIZE = '[data-lte-toggle="card-maximize"]';
|
||||
const SELECTOR_CARD = `.${CLASS_NAME_CARD}`;
|
||||
const SELECTOR_CARD_BODY = '.card-body';
|
||||
const SELECTOR_CARD_FOOTER = '.card-footer';
|
||||
const Default = {
|
||||
animationSpeed: 500,
|
||||
collapseTrigger: SELECTOR_DATA_COLLAPSE,
|
||||
removeTrigger: SELECTOR_DATA_REMOVE,
|
||||
maximizeTrigger: SELECTOR_DATA_MAXIMIZE
|
||||
};
|
||||
class CardWidget {
|
||||
constructor(element, config) {
|
||||
this._element = element;
|
||||
this._parent = element.closest(SELECTOR_CARD);
|
||||
if (element.classList.contains(CLASS_NAME_CARD)) {
|
||||
this._parent = element;
|
||||
}
|
||||
this._config = Object.assign(Object.assign({}, Default), config);
|
||||
}
|
||||
collapse() {
|
||||
var _a, _b;
|
||||
const event = new Event(EVENT_COLLAPSED);
|
||||
if (this._parent) {
|
||||
this._parent.classList.add(CLASS_NAME_COLLAPSING);
|
||||
const elm = (_a = this._parent) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`);
|
||||
elm.forEach(el => {
|
||||
if (el instanceof HTMLElement) {
|
||||
slideUp(el, this._config.animationSpeed);
|
||||
}
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (this._parent) {
|
||||
this._parent.classList.add(CLASS_NAME_COLLAPSED);
|
||||
this._parent.classList.remove(CLASS_NAME_COLLAPSING);
|
||||
}
|
||||
}, this._config.animationSpeed);
|
||||
}
|
||||
(_b = this._element) === null || _b === void 0 ? void 0 : _b.dispatchEvent(event);
|
||||
}
|
||||
expand() {
|
||||
var _a, _b;
|
||||
const event = new Event(EVENT_EXPANDED);
|
||||
if (this._parent) {
|
||||
this._parent.classList.add(CLASS_NAME_EXPANDING);
|
||||
const elm = (_a = this._parent) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`);
|
||||
elm.forEach(el => {
|
||||
if (el instanceof HTMLElement) {
|
||||
slideDown(el, this._config.animationSpeed);
|
||||
}
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (this._parent) {
|
||||
this._parent.classList.remove(CLASS_NAME_COLLAPSED);
|
||||
this._parent.classList.remove(CLASS_NAME_EXPANDING);
|
||||
}
|
||||
}, this._config.animationSpeed);
|
||||
}
|
||||
(_b = this._element) === null || _b === void 0 ? void 0 : _b.dispatchEvent(event);
|
||||
}
|
||||
remove() {
|
||||
var _a;
|
||||
const event = new Event(EVENT_REMOVE);
|
||||
if (this._parent) {
|
||||
slideUp(this._parent, this._config.animationSpeed);
|
||||
}
|
||||
(_a = this._element) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
|
||||
}
|
||||
toggle() {
|
||||
var _a;
|
||||
if ((_a = this._parent) === null || _a === void 0 ? void 0 : _a.classList.contains(CLASS_NAME_COLLAPSED)) {
|
||||
this.expand();
|
||||
return;
|
||||
}
|
||||
this.collapse();
|
||||
}
|
||||
maximize() {
|
||||
var _a;
|
||||
const event = new Event(EVENT_MAXIMIZED);
|
||||
if (this._parent) {
|
||||
this._parent.style.height = `${this._parent.offsetHeight}px`;
|
||||
this._parent.style.width = `${this._parent.offsetWidth}px`;
|
||||
this._parent.style.transition = 'all .15s';
|
||||
setTimeout(() => {
|
||||
const htmlTag = document.querySelector('html');
|
||||
if (htmlTag) {
|
||||
htmlTag.classList.add(CLASS_NAME_MAXIMIZED);
|
||||
}
|
||||
if (this._parent) {
|
||||
this._parent.classList.add(CLASS_NAME_MAXIMIZED);
|
||||
if (this._parent.classList.contains(CLASS_NAME_COLLAPSED)) {
|
||||
this._parent.classList.add(CLASS_NAME_WAS_COLLAPSED);
|
||||
}
|
||||
}
|
||||
}, 150);
|
||||
}
|
||||
(_a = this._element) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
|
||||
}
|
||||
minimize() {
|
||||
var _a;
|
||||
const event = new Event(EVENT_MINIMIZED);
|
||||
if (this._parent) {
|
||||
this._parent.style.height = 'auto';
|
||||
this._parent.style.width = 'auto';
|
||||
this._parent.style.transition = 'all .15s';
|
||||
setTimeout(() => {
|
||||
var _a;
|
||||
const htmlTag = document.querySelector('html');
|
||||
if (htmlTag) {
|
||||
htmlTag.classList.remove(CLASS_NAME_MAXIMIZED);
|
||||
}
|
||||
if (this._parent) {
|
||||
this._parent.classList.remove(CLASS_NAME_MAXIMIZED);
|
||||
if ((_a = this._parent) === null || _a === void 0 ? void 0 : _a.classList.contains(CLASS_NAME_WAS_COLLAPSED)) {
|
||||
this._parent.classList.remove(CLASS_NAME_WAS_COLLAPSED);
|
||||
}
|
||||
}
|
||||
}, 10);
|
||||
}
|
||||
(_a = this._element) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
|
||||
}
|
||||
toggleMaximize() {
|
||||
var _a;
|
||||
if ((_a = this._parent) === null || _a === void 0 ? void 0 : _a.classList.contains(CLASS_NAME_MAXIMIZED)) {
|
||||
this.minimize();
|
||||
return;
|
||||
}
|
||||
this.maximize();
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Data Api implementation
|
||||
* ====================================================
|
||||
*/
|
||||
onDOMContentLoaded(() => {
|
||||
const collapseBtn = document.querySelectorAll(SELECTOR_DATA_COLLAPSE);
|
||||
collapseBtn.forEach(btn => {
|
||||
btn.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
const target = event.target;
|
||||
const data = new CardWidget(target, Default);
|
||||
data.toggle();
|
||||
});
|
||||
});
|
||||
const removeBtn = document.querySelectorAll(SELECTOR_DATA_REMOVE);
|
||||
removeBtn.forEach(btn => {
|
||||
btn.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
const target = event.target;
|
||||
const data = new CardWidget(target, Default);
|
||||
data.remove();
|
||||
});
|
||||
});
|
||||
const maxBtn = document.querySelectorAll(SELECTOR_DATA_MAXIMIZE);
|
||||
maxBtn.forEach(btn => {
|
||||
btn.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
const target = event.target;
|
||||
const data = new CardWidget(target, Default);
|
||||
data.toggleMaximize();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
exports.CardWidget = CardWidget;
|
||||
exports.Layout = Layout;
|
||||
exports.PushMenu = PushMenu;
|
||||
exports.Treeview = Treeview;
|
||||
|
File diff suppressed because one or more lines are too long
2
public/v2/js/adminlte.min.js
vendored
2
public/v2/js/adminlte.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
48
resources/assets/v2/api/v1/accounts/get.js
Normal file
48
resources/assets/v2/api/v1/accounts/get.js
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* list.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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../boot/axios";
|
||||
|
||||
export default class Get {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param identifier
|
||||
* @param date
|
||||
* @returns {Promise<AxiosResponse<any>>}
|
||||
*/
|
||||
get(identifier, date) {
|
||||
let params = {date: date};
|
||||
if (!date) {
|
||||
return api.get('/api/v1/accounts/' + identifier);
|
||||
}
|
||||
return api.get('/api/v1/accounts/' + identifier, {params: params});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param identifier
|
||||
* @param page
|
||||
* @returns {Promise<AxiosResponse<any>>}
|
||||
*/
|
||||
transactions(identifier, page) {
|
||||
return api.get('/api/v1/accounts/' + identifier + '/transactions', {params: {page: page}});
|
||||
}
|
||||
}
|
30
resources/assets/v2/api/v1/chart/account/overview.js
Normal file
30
resources/assets/v2/api/v1/chart/account/overview.js
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
import {format} from "date-fns";
|
||||
|
||||
export default class Overview {
|
||||
overview(start, end) {
|
||||
let startStr = format(start, 'y-MM-dd');
|
||||
let endStr = format(end, 'y-MM-dd');
|
||||
return api.get('/api/v1/chart/account/overview', {params: {start: startStr, end: endStr}});
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../boot/axios";
|
||||
import {api} from "../../../boot/axios";
|
||||
|
||||
export default class Preferences {
|
||||
getByName(name) {
|
@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
|
||||
import {api} from "../../boot/axios.js";
|
||||
import {api} from "../../../boot/axios.js";
|
||||
|
||||
export default class Summary {
|
||||
get(start, end, code) {
|
30
resources/assets/v2/api/v2/chart/account/dashboard.js
Normal file
30
resources/assets/v2/api/v2/chart/account/dashboard.js
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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/account/dashboard', {params: {start: startStr, end: endStr}});
|
||||
}
|
||||
}
|
9
resources/assets/v2/bootstrap.js
vendored
9
resources/assets/v2/bootstrap.js
vendored
@ -9,6 +9,7 @@ import axios from 'axios';
|
||||
import store from "store";
|
||||
import observePlugin from 'store/plugins/observe';
|
||||
import Alpine from "alpinejs";
|
||||
import * as bootstrap from 'bootstrap'
|
||||
|
||||
// add plugin to store and put in window
|
||||
store.addPlugin(observePlugin);
|
||||
@ -33,6 +34,9 @@ Promise.all([
|
||||
store.set('end', range.end);
|
||||
}
|
||||
|
||||
// save local in window.__ something
|
||||
window.__localeId__ = values[3];
|
||||
|
||||
const event = new Event('firefly-iii-bootstrapped');
|
||||
document.dispatchEvent(event);
|
||||
window.bootstrapped = true;
|
||||
@ -41,10 +45,5 @@ Promise.all([
|
||||
window.axios = axios;
|
||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||
|
||||
// include popper js
|
||||
import '@popperjs/core';
|
||||
|
||||
// include bootstrap CSS
|
||||
import * as bootstrap from 'bootstrap'
|
||||
|
||||
window.Alpine = Alpine
|
||||
|
@ -21,8 +21,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';
|
||||
|
||||
const comps = {dates, boxes};
|
||||
const comps = {dates, boxes, accounts};
|
||||
|
||||
function loadPage(comps) {
|
||||
Object.keys(comps).forEach(comp => {
|
||||
|
@ -1,80 +1 @@
|
||||
import Summary from "./api/summary/index.js";
|
||||
import {format} from 'date-fns'
|
||||
import Alpine from "alpinejs";
|
||||
|
||||
//let amounts = [];
|
||||
|
||||
class IndexApp {
|
||||
|
||||
balanceBox = {foo: 'bar'};
|
||||
|
||||
constructor() {
|
||||
console.log('IndexApp constructor');
|
||||
}
|
||||
|
||||
init() {
|
||||
console.log('IndexApp init');
|
||||
this.loadBoxes();
|
||||
}
|
||||
|
||||
loadBoxes() {
|
||||
console.log('IndexApp loadBoxes');
|
||||
let getter = new Summary();
|
||||
let start = window.BasicStore.get('start');
|
||||
let end = window.BasicStore.get('end');
|
||||
|
||||
// check on NULL values:
|
||||
if (start !== null && end !== null) {
|
||||
start = new Date(start);
|
||||
end = new Date(end);
|
||||
}
|
||||
|
||||
getter.get(format(start, 'yyyy-MM-dd'), format(end, 'yyyy-MM-dd'), null).then((response) => {
|
||||
//
|
||||
console.log('IndexApp done!');
|
||||
console.log(response.data);
|
||||
document.querySelector('#balanceAmount').innerText = 'ok dan';
|
||||
//window.$refs.balanceAmount.text = 'bar!';
|
||||
for (const i in response.data) {
|
||||
if (response.data.hasOwnProperty(i)) {
|
||||
const current = response.data[i];
|
||||
if (i.startsWith('balance-in-')) {
|
||||
//amounts.push(current);
|
||||
console.log('Balance in: ', current);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
let index = new IndexApp();
|
||||
|
||||
document.addEventListener("AppReady", (e) => {
|
||||
index.init();
|
||||
}, false,);
|
||||
|
||||
if (window.BasicStore.isReady()) {
|
||||
index.init();
|
||||
}
|
||||
document.addEventListener('alpine:init', () => {
|
||||
Alpine.data('balanceBox', () => ({
|
||||
foo: 'barX'
|
||||
}))
|
||||
})
|
||||
|
||||
export function amounts() {
|
||||
return {
|
||||
amounts: ['bar', 'boo', 'baz'],
|
||||
add() {
|
||||
this.amounts.push('foo');
|
||||
},
|
||||
get() {
|
||||
return this.amounts[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.Alpine = Alpine
|
||||
Alpine.start()
|
||||
// NOT IN USE
|
||||
|
176
resources/assets/v2/pages/dashboard/accounts.js
Normal file
176
resources/assets/v2/pages/dashboard/accounts.js
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* accounts.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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import ApexCharts from "apexcharts";
|
||||
import {getVariable} from "../../store/get-variable.js";
|
||||
import Dashboard from "../../api/v2/chart/account/dashboard.js";
|
||||
import formatLocal from "../../util/format.js";
|
||||
import {format} from "date-fns";
|
||||
import formatMoney from "../../util/format-money.js";
|
||||
import Get from "../../api/v1/accounts/get.js";
|
||||
|
||||
// this is very ugly, but I have no better ideas at the moment to save the currency info
|
||||
// for each series.
|
||||
window.currencies = [];
|
||||
|
||||
export default () => ({
|
||||
loading: false,
|
||||
loadingAccounts: false,
|
||||
accountList: [],
|
||||
chart: null,
|
||||
loadChart() {
|
||||
if (this.loading) {
|
||||
return;
|
||||
}
|
||||
// load chart data
|
||||
this.loading = true;
|
||||
const dashboard = new Dashboard();
|
||||
dashboard.dashboard(new Date(window.store.get('start')), new Date(window.store.get('end')), null).then((response) => {
|
||||
|
||||
// chart options (may need to be centralized later on)
|
||||
window.currencies = [];
|
||||
let options = {
|
||||
legend: {show: false},
|
||||
chart: {
|
||||
height: 400,
|
||||
toolbar: {tools: {zoom: false, download: false, pan: false}}, type: 'line'
|
||||
}, series: [],
|
||||
settings: [],
|
||||
xaxis: {
|
||||
categories: [], labels: {
|
||||
formatter: function (value) {
|
||||
if (undefined === value) {
|
||||
return '';
|
||||
}
|
||||
const date = new Date(value);
|
||||
if (date instanceof Date && !isNaN(date)) {
|
||||
return formatLocal(date, 'PP');
|
||||
}
|
||||
console.error('Could not parse "' + value + '", return "".');
|
||||
return ':(';
|
||||
}
|
||||
}
|
||||
}, yaxis: {
|
||||
labels: {
|
||||
formatter: function (value, index) {
|
||||
if (undefined === value) {
|
||||
return value;
|
||||
}
|
||||
if (undefined === index) {
|
||||
return value;
|
||||
}
|
||||
if (typeof index === 'object') {
|
||||
index = index.seriesIndex;
|
||||
}
|
||||
//console.log(index);
|
||||
let currencyCode = window.currencies[index] ?? 'EUR';
|
||||
return formatMoney(value, currencyCode);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
// render data:
|
||||
for (let i = 0; i < response.data.length; i++) {
|
||||
if (response.data.hasOwnProperty(i)) {
|
||||
let current = response.data[i];
|
||||
let entry = [];
|
||||
window.currencies.push(current.currency_code);
|
||||
for (const [ii, value] of Object.entries(current.entries)) {
|
||||
entry.push({x: format(new Date(ii), 'yyyy-MM-dd'), y: parseFloat(value)});
|
||||
}
|
||||
options.series.push({name: current.label, data: entry});
|
||||
}
|
||||
}
|
||||
if (null !== this.chart) {
|
||||
// chart already in place, refresh:
|
||||
this.chart.updateOptions(options);
|
||||
}
|
||||
if (null === this.chart) {
|
||||
this.chart = new ApexCharts(document.querySelector("#account-chart"), options);
|
||||
this.chart.render();
|
||||
}
|
||||
this.loading = false;
|
||||
});
|
||||
}, loadAccounts() {
|
||||
if (this.loadingAccounts) {
|
||||
return;
|
||||
}
|
||||
this.loadingAccounts = true;
|
||||
const max = 10;
|
||||
Promise.all([getVariable('frontpageAccounts'),]).then((values) => {
|
||||
for (let i = 0; i < values[0].length; i++) {
|
||||
if (values[0].hasOwnProperty(i)) {
|
||||
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: [],
|
||||
};
|
||||
|
||||
// get groups for account:
|
||||
(new Get).transactions(current.id, 1).then((response) => {
|
||||
for (let ii = 0; ii < response.data.data.length; ii++) {
|
||||
if (ii >= max) {
|
||||
break;
|
||||
}
|
||||
let current = response.data.data[ii];
|
||||
let group = {
|
||||
title: null === current.attributes.group_title ? '' : current.attributes.group_title,
|
||||
id: current.id,
|
||||
transactions: [],
|
||||
};
|
||||
for (let iii = 0; iii < current.attributes.transactions.length; iii++) {
|
||||
let currentTransaction = current.attributes.transactions[iii];
|
||||
group.transactions.push({
|
||||
description: currentTransaction.description,
|
||||
id: current.id,
|
||||
amount: formatMoney(currentTransaction.amount, currentTransaction.currency_code),
|
||||
});
|
||||
}
|
||||
this.accountList[i].groups.push(group);
|
||||
}
|
||||
// will become false after the FIRST account is loaded.
|
||||
this.loadingAccounts = false;
|
||||
});
|
||||
}).then(() => {
|
||||
console.log(this.accountList);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
init() {
|
||||
console.log('init');
|
||||
Promise.all([getVariable('viewRange'),]).then((values) => {
|
||||
this.loadChart();
|
||||
this.loadAccounts();
|
||||
});
|
||||
window.store.observe('end', () => {
|
||||
this.loadChart();
|
||||
this.loadAccounts();
|
||||
});
|
||||
},
|
||||
});
|
@ -18,7 +18,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import Summary from "../../api/summary/index.js";
|
||||
import Summary from "../../api/v1/summary/index.js";
|
||||
import {format} from "date-fns";
|
||||
import {getVariable} from "../../store/get-variable.js";
|
||||
|
||||
@ -28,8 +28,12 @@ export default () => ({
|
||||
billBox: {paid: [], unpaid: []},
|
||||
leftBox: {left: [], perDay: []},
|
||||
netBox: {net: []},
|
||||
loading: false,
|
||||
loadBoxes() {
|
||||
console.log('loadboxes');
|
||||
if (this.loading) {
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
|
||||
// get stuff
|
||||
let getter = new Summary();
|
||||
@ -75,22 +79,17 @@ export default () => ({
|
||||
//console.log('Next up: ', current);
|
||||
}
|
||||
}
|
||||
this.loading = false;
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
// Getter
|
||||
init() {
|
||||
console.log('Now in boxes');
|
||||
Promise.all([
|
||||
getVariable('viewRange'),
|
||||
]).then((values) => {
|
||||
Promise.all([getVariable('viewRange'),]).then((values) => {
|
||||
this.loadBoxes();
|
||||
});
|
||||
window.store.observe('start', (newValue, oldValue) => {
|
||||
// this.loadBoxes();
|
||||
});
|
||||
window.store.observe('end', (newValue, oldValue) => {
|
||||
window.store.observe('end', () => {
|
||||
this.loadBoxes();
|
||||
});
|
||||
},
|
||||
|
@ -24,7 +24,7 @@ export default () => ({
|
||||
language: 'en-US',
|
||||
|
||||
init() {
|
||||
console.log('Dates init');
|
||||
// console.log('Dates init');
|
||||
|
||||
this.range = {
|
||||
start: new Date(window.store.get('start')),
|
||||
@ -68,7 +68,7 @@ export default () => ({
|
||||
|
||||
|
||||
buildDateRange() {
|
||||
console.log('Dates buildDateRange');
|
||||
// console.log('Dates buildDateRange');
|
||||
|
||||
// generate ranges
|
||||
let nextRange = this.getNextRange();
|
||||
@ -123,7 +123,7 @@ export default () => ({
|
||||
element.setAttribute('data-end', format(ytd.end, 'yyyy-MM-dd'));
|
||||
|
||||
// custom range.
|
||||
console.log('MainApp: buildDateRange end');
|
||||
// console.log('MainApp: buildDateRange end');
|
||||
},
|
||||
|
||||
getNextRange() {
|
||||
@ -161,12 +161,12 @@ export default () => ({
|
||||
|
||||
changeDateRange(e) {
|
||||
e.preventDefault();
|
||||
console.log('MainApp: changeDateRange');
|
||||
// console.log('MainApp: changeDateRange');
|
||||
let target = e.currentTarget;
|
||||
|
||||
let start = new Date(target.getAttribute('data-start'));
|
||||
let end = new Date(target.getAttribute('data-end'));
|
||||
console.log('MainApp: Change date range', start, end);
|
||||
// console.log('MainApp: Change date range', start, end);
|
||||
|
||||
window.store.set('start', start);
|
||||
window.store.set('end', end);
|
||||
|
@ -22,6 +22,8 @@
|
||||
// Variables
|
||||
//@import "variables";
|
||||
|
||||
$color-mode-type: media-query;
|
||||
|
||||
// Bootstrap
|
||||
//@import "~bootstrap-sass/assets/stylesheets/bootstrap";
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import Get from "../api/preferences/index.js";
|
||||
import Get from "../api/v1/preferences/index.js";
|
||||
|
||||
export function getVariable(name) {
|
||||
|
||||
@ -26,17 +26,17 @@ export function getVariable(name) {
|
||||
// to make things available quicker than if the store has to grab it through the API.
|
||||
// then again, it's not that slow.
|
||||
if (window.hasOwnProperty(name)) {
|
||||
console.log('Get from window');
|
||||
// console.log('Get from window');
|
||||
return Promise.resolve(window[name]);
|
||||
}
|
||||
// load from store2, if it's present.
|
||||
if (window.store.get(name)) {
|
||||
console.log('Get from store');
|
||||
// console.log('Get from store');
|
||||
return Promise.resolve(window.store.get(name));
|
||||
}
|
||||
let getter = (new Get);
|
||||
return getter.getByName(name).then((response) => {
|
||||
console.log('Get from API');
|
||||
// console.log('Get from API');
|
||||
return Promise.resolve(parseResponse(name, response));
|
||||
|
||||
});
|
||||
@ -45,7 +45,7 @@ export function getVariable(name) {
|
||||
function parseResponse(name, response) {
|
||||
let value = response.data.data.attributes.data;
|
||||
window.store.set(name, value);
|
||||
console.log('Store from API');
|
||||
// console.log('Store from API');
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ function getViewRange(viewRange, today) {
|
||||
let start;
|
||||
let end;
|
||||
|
||||
console.log('getViewRange: ' + viewRange);
|
||||
// console.log('getViewRange: ' + viewRange);
|
||||
|
||||
switch (viewRange) {
|
||||
case 'last365':
|
||||
@ -100,7 +100,6 @@ function getViewRange(viewRange, today) {
|
||||
end = endOfDay(end);
|
||||
break;
|
||||
}
|
||||
console.log('MainApp: setDatesFromViewRange done!');
|
||||
return {start: start, end: end};
|
||||
}
|
||||
|
||||
|
30
resources/assets/v2/util/format-money.js
Normal file
30
resources/assets/v2/util/format-money.js
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* format-money.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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {format} from "date-fns";
|
||||
|
||||
export default function (amount, currencyCode) {
|
||||
let locale = window.__localeId__.replace('_', '-');
|
||||
|
||||
return Intl.NumberFormat(locale, {
|
||||
style: 'currency',
|
||||
currency: currencyCode
|
||||
}).format(amount);
|
||||
}
|
@ -11,22 +11,113 @@
|
||||
<!-- row with account data -->
|
||||
<div class="row">
|
||||
<div class="col-xl-8 col-lg-12 col-sm-12 col-xs-12">
|
||||
Graph
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title"><a href="{{ route('accounts.index',['asset']) }}"
|
||||
title="{{ __('firefly.yourAccounts') }}">{{ __('firefly.yourAccounts') }}</a>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="account-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title"><a href="{{ route('accounts.index',['asset']) }}"
|
||||
title="{{ __('firefly.yourAccounts') }}">budget</a>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="budget-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title"><a href="{{ route('accounts.index',['asset']) }}"
|
||||
title="{{ __('firefly.yourAccounts') }}">cat</a>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="category-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-4 col-lg-12 col-sm-12 col-xs-12">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
Account1
|
||||
</div>
|
||||
<div class="col-12">
|
||||
Account2
|
||||
</div>
|
||||
<div class="col-12">
|
||||
Account3
|
||||
</div>
|
||||
<div class="col-12">
|
||||
Account4
|
||||
</div>
|
||||
<div class="row" x-data="accounts">
|
||||
<template x-for="account in accountList">
|
||||
<div class="col-12 mb-2">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">
|
||||
<a :href="'{{ route('accounts.show','') }}/' + account.id"
|
||||
x-text="account.name"></a>
|
||||
|
||||
<span class="small text-muted">(<span
|
||||
x-text="account.balance"></span>)</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<table class="table table-sm">
|
||||
<tbody>
|
||||
<template x-for="group in account.groups">
|
||||
<tr>
|
||||
<td>
|
||||
<template x-if="group.title">
|
||||
<span><a
|
||||
:href="'{{route('transactions.show', '') }}/' + group.id"
|
||||
x-text="group.title"></a><br/></span>
|
||||
</template>
|
||||
<template x-for="transaction in group.transactions">
|
||||
<span>
|
||||
<template x-if="group.title">
|
||||
<span>-
|
||||
<span
|
||||
x-text="transaction.description"></span><br>
|
||||
</span>
|
||||
</template>
|
||||
<template x-if="!group.title">
|
||||
<span><a
|
||||
:href="'{{route('transactions.show', '') }}/' + group.id"
|
||||
x-text="transaction.description"></a><br>
|
||||
</span>
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
</td>
|
||||
<td style="width:30%;" class="text-end">
|
||||
<template x-if="group.title">
|
||||
<span><br/></span>
|
||||
</template>
|
||||
<template x-for="transaction in group.transactions">
|
||||
<span>
|
||||
<span x-text="transaction.amount"></span><br>
|
||||
</span>
|
||||
</template>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ trans('config.html_language') }}">
|
||||
<!-- data-bs-theme="dark" -->
|
||||
<!--begin::Head-->
|
||||
@include('partials.layout.head')
|
||||
<!--end::Head-->
|
||||
@ -85,7 +86,7 @@
|
||||
{{ __('firefly.profile') }}
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a href="#" class="dropdown-item">
|
||||
<a href="{{ route('preferences.index') }}" class="dropdown-item">
|
||||
<i class="fa-solid fa-user-gear me-2"></i>
|
||||
{{ __('firefly.preferences') }}
|
||||
</a>
|
||||
|
@ -8,6 +8,51 @@
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="color-scheme" content="light dark">
|
||||
|
||||
<script type="text/javascript">
|
||||
/*!
|
||||
* Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
|
||||
* Copyright 2011-2023 The Bootstrap Authors
|
||||
* Licensed under the Creative Commons Attribution 3.0 Unported License.
|
||||
*/
|
||||
|
||||
(() => {
|
||||
'use strict'
|
||||
// todo store just happens to store in localStorage but if not, this would break.
|
||||
const getStoredTheme = () => JSON.parse(localStorage.getItem('darkMode'))
|
||||
const setStoredTheme = theme => localStorage.setItem('darkMode', theme)
|
||||
|
||||
const getPreferredTheme = () => {
|
||||
const storedTheme = getStoredTheme()
|
||||
if (storedTheme) {
|
||||
return storedTheme
|
||||
}
|
||||
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
||||
}
|
||||
|
||||
const setTheme = theme => {
|
||||
if (theme === 'browser' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
document.documentElement.setAttribute('data-bs-theme', 'dark')
|
||||
return;
|
||||
}
|
||||
if (theme === 'browser' && window.matchMedia('(prefers-color-scheme: light)').matches) {
|
||||
document.documentElement.setAttribute('data-bs-theme', 'light')
|
||||
return;
|
||||
}
|
||||
document.documentElement.setAttribute('data-bs-theme', theme)
|
||||
}
|
||||
|
||||
setTheme(getPreferredTheme())
|
||||
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
||||
const storedTheme = getStoredTheme()
|
||||
if (storedTheme !== 'light' && storedTheme !== 'dark') {
|
||||
setTheme(getPreferredTheme())
|
||||
}
|
||||
})
|
||||
})()
|
||||
</script>
|
||||
|
||||
<title>
|
||||
@if($subTitle)
|
||||
{{ $subTitle }} »
|
||||
@ -23,7 +68,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<!--begin::Fonts-->
|
||||
<link href="v4/css/fonts.css" rel="stylesheet">
|
||||
<link href="v2/css/fonts.css" rel="stylesheet">
|
||||
<!--end::Fonts-->
|
||||
|
||||
<!--begin::Third Party Plugin(OverlayScrollbars)-->
|
||||
@ -39,7 +84,7 @@
|
||||
--}}
|
||||
<!--end::Third Party Plugin(Bootstrap Icons)-->
|
||||
<!--begin::Required Plugin(AdminLTE)-->
|
||||
<link rel="stylesheet" href="v4/css/adminlte.css">
|
||||
<link rel="stylesheet" href="v2/css/adminlte.css">
|
||||
<!--end::Required Plugin(AdminLTE)-->
|
||||
@yield('vite')
|
||||
|
||||
|
@ -12,5 +12,5 @@
|
||||
crossorigin="anonymous"></script>
|
||||
--}}
|
||||
<!--end::Required Plugin(Bootstrap 5)--><!--begin::Required Plugin(AdminLTE)-->
|
||||
<script src="v4/js/adminlte.js"></script>
|
||||
<script src="v2/js/adminlte.js"></script>
|
||||
<!--end::Required Plugin(AdminLTE)-->
|
||||
|
@ -4,7 +4,7 @@
|
||||
<!--begin::Brand Link-->
|
||||
<a href="{{route('index') }}" class="brand-link">
|
||||
<!--begin::Brand Image-->
|
||||
<img src="v4/i/logo.png" alt="Firefly III Logo"
|
||||
<img src="v2/i/logo.png" alt="Firefly III Logo"
|
||||
class="brand-image opacity-75 shadow">
|
||||
<!--end::Brand Image-->
|
||||
<!--begin::Brand Text-->
|
||||
|
Loading…
Reference in New Issue
Block a user