diff --git a/web/package.json b/web/package.json
index 895aade..2f82f7c 100644
--- a/web/package.json
+++ b/web/package.json
@@ -11,6 +11,7 @@
"@mdi/font": "5.9.55",
"@vueuse/core": "^7.6.1",
"autoprefixer": "^10.4.2",
+ "file-saver": "^2.0.5",
"pinia": "^2.0.11",
"postcss": "^8.4.6",
"tailwindcss": "^3.0.18",
@@ -18,6 +19,7 @@
"vue-router": "^4.0.12"
},
"devDependencies": {
+ "@types/file-saver": "^2.0.5",
"@vitejs/plugin-vue": "^2.0.0",
"@vue/cli-plugin-babel": "5.0.0-beta.7",
"@vue/cli-plugin-typescript": "~4.5.0",
diff --git a/web/src/pages/Budgeting.vue b/web/src/pages/Budgeting.vue
index bf00f8c..3ffb2c1 100644
--- a/web/src/pages/Budgeting.vue
+++ b/web/src/pages/Budgeting.vue
@@ -1,5 +1,5 @@
@@ -78,8 +90,8 @@ onMounted(() => {
Available |
- {{ group }}
-
+ {{ (getGroupState(group) ? "−" : "+") + " " + group.Name }}
+
{{ category.Name }} |
|
|
diff --git a/web/src/pages/Settings.vue b/web/src/pages/Settings.vue
index 6550a11..fc41a14 100644
--- a/web/src/pages/Settings.vue
+++ b/web/src/pages/Settings.vue
@@ -6,6 +6,7 @@ import { useBudgetsStore } from "../stores/budget";
import { useSessionStore } from "../stores/session";
import Card from "../components/Card.vue";
import Button from "../components/Button.vue";
+import { saveAs } from 'file-saver';
const transactionsFile = ref(undefined);
const assignmentsFile = ref(undefined);
@@ -15,6 +16,10 @@ onMounted(() => {
useSessionStore().setTitle("Settings");
});
+const budgetStore = useBudgetsStore();
+const CurrentBudgetID = computed(() => budgetStore.CurrentBudgetID);
+const CurrentBudgetName = computed(() => budgetStore.CurrentBudgetName);
+
function gotAssignments(e: Event) {
const input = (e.target);
if (input.files != null)
@@ -26,19 +31,17 @@ function gotTransactions(e: Event) {
transactionsFile.value = input.files[0];
};
function deleteBudget() {
- const currentBudgetID = useBudgetsStore().CurrentBudgetID;
- if (currentBudgetID == null)
+ if (CurrentBudgetID.value == null)
return;
- DELETE("/budget/" + currentBudgetID);
+ DELETE("/budget/" + CurrentBudgetID.value);
const budgetStore = useSessionStore();
- budgetStore.Budgets.delete(currentBudgetID);
+ budgetStore.Budgets.delete(CurrentBudgetID.value);
useRouter().push("/")
};
function clearBudget() {
- const currentBudgetID = useBudgetsStore().CurrentBudgetID;
- POST("/budget/" + currentBudgetID + "/settings/clear", null)
+ POST("/budget/" + CurrentBudgetID.value + "/settings/clear", null)
};
function cleanNegative() {
// Fix all historic negative category-balances
@@ -53,6 +56,22 @@ function ynabImport() {
const budgetStore = useBudgetsStore();
budgetStore.ImportYNAB(formData);
};
+function ynabExport() {
+ const timeStamp = new Date().toISOString();
+ POST("/budget/"+CurrentBudgetID.value+"/export/ynab/assignments", "")
+ .then(x => x.text())
+ .then(x => {
+ var blob = new Blob([x], {type: "text/plain;charset=utf-8"});
+ saveAs(blob, timeStamp + " " + CurrentBudgetName.value + " - Budget.tsv");
+ })
+ POST("/budget/"+CurrentBudgetID.value+"/export/ynab/transactions", "")
+ .then(x => x.text())
+ .then(x => {
+ var blob = new Blob([x], {type: "text/plain;charset=utf-8"});
+ saveAs(blob, timeStamp + " " + CurrentBudgetName.value + " - Transactions.tsv");
+ })
+}
+
@@ -94,6 +113,13 @@ function ynabImport() {
+
+ Export as YNAB TSV
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/stores/budget-account.ts b/web/src/stores/budget-account.ts
index c612c0d..1f0f3d2 100644
--- a/web/src/stores/budget-account.ts
+++ b/web/src/stores/budget-account.ts
@@ -67,7 +67,10 @@ export const useAccountStore = defineStore("budget/account", {
let prev = undefined;
for (const category of categories) {
if(category.Group != prev)
- categoryGroups.push(category.Group);
+ categoryGroups.push({
+ Name: category.Group,
+ Expand: category.Group != "Hidden Categories",
+ });
prev = category.Group;
}
return categoryGroups;
diff --git a/web/yarn.lock b/web/yarn.lock
index dea9627..f5071c9 100644
--- a/web/yarn.lock
+++ b/web/yarn.lock
@@ -1141,6 +1141,11 @@
"@types/qs" "*"
"@types/serve-static" "*"
+"@types/file-saver@^2.0.5":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@types/file-saver/-/file-saver-2.0.5.tgz#9ee342a5d1314bb0928375424a2f162f97c310c7"
+ integrity sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==
+
"@types/glob@^7.1.1":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
@@ -4137,6 +4142,11 @@ figures@^2.0.0:
dependencies:
escape-string-regexp "^1.0.5"
+file-saver@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-2.0.5.tgz#d61cfe2ce059f414d899e9dd6d4107ee25670c38"
+ integrity sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==
+
file-uri-to-path@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"