Dateien nach "/" hochladen

main
macniel 2026-05-01 17:03:30 +02:00
commit 4a996f58a0
3 changed files with 396 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

349
index.js 100644
View File

@ -0,0 +1,349 @@
var gui = require('gui');
var fs = require('fs');
var rh = 14;
var sp = 4;
var y = sp;
let projectData = [
{
name: "Current",
entries: [
{
date: 1704067200000,
subject: '(Savings) Initial Deposit',
amount: -500,
targetAccount: "Savings"
},
{
date: 1704067200000,
subject: 'Salary',
amount: 2182.15
},
{
date: 1704153600000,
subject: 'Rent',
amount: -800
},
{
date: 1704240000000,
subject: 'Groceries',
amount: -24.19
}
],
},
{
name: "Savings",
entries: [
{
date: 1704067200000,
subject: 'Initial Deposit',
amount: 500
}
],
}
];
function getAccounts(data) {
const resultData = [];
for (let i = 0; i < data.length; i++) {
resultData.push(data[i].name);
}
return resultData
}
function toListViewEntries(entries, visibleCols) {
let cols = visibleCols;
return entries.map(e => {
const amount = parseFloat(e.amount);
const subject = ("" + e.subject).substr(0, cols - 20).padEnd(cols - 20, ' ');
const sum = ((amount >= 0 ? "+" : "") + amount.toFixed(2)).substr(0, 10).padStart(10, ' ');
const d = new Date(e.date);
const date = d.getDay().toString().padStart(2, '0') + "-" + (d.getMonth() + 1).toString().padStart(2, '0') + "-" + d.getFullYear();
let s = (date.substr(0, 10)) + " " + subject + " " + sum;
return s;
});
}
function getSummation(entries) {
return entries.reduce((sum, e) => sum + parseFloat(e.amount), 0);
}
function toDateByComponents(s) {
const parts = s.split("-");
if (parts.length !== 3) return null;
const day = parseInt(parts[0]);
const month = parseInt(parts[1]) - 1;
const year = parseInt(parts[2]);
if (isNaN(day) || isNaN(month) || isNaN(year)) return null;
return new Date(year, month, day).getTime();
}
function subWindow(data) {
let gadgets = [];
let removable = false;
const innerData = {
date: Date.now(),
subject: '',
amount: 0,
targetAccount: null
}
if (data) {
innerData.date = data.date;
innerData.subject = data.subject;
innerData.amount = data.amount;
innerData.targetAccount = data.targetAccount;
removable = true;
}
let d = new Date(innerData.date);
let formattedDate = d.getDay() + "-" + (d.getMonth() + 1) + "-" + d.getFullYear();
gadgets.push({
kind: 'string', id: 1, label: 'Subject:',
left: sp + 80, top: y, width: 400 - sp - 80 - sp, height: rh,
value: innerData.subject
});
gadgets.push({
kind: 'string', id: 2, label: 'Amount:',
left: sp + 80, top: sp + rh + sp, width: 100, height: rh,
value: innerData.amount.toFixed(2)
});
gadgets.push({
kind: 'string', id: 3, label: 'Date:',
left: sp + 80, top: sp + rh + sp + rh + sp, width: 150, height: rh,
value: formattedDate
});
gadgets.push({ kind: 'checkbox', id: 6, label: "Account:", left: sp + 80, top: sp + rh + sp + rh + sp + rh + sp + 2, width: rh, height: rh, value: 0 });
const accounts = getAccounts(projectData);
gadgets.push({ kind: 'cycle', id: 7, left: sp + 160 + rh + sp, top: sp + rh + sp + rh + sp + rh + sp, width: 120, height: rh, items: accounts, value: 0 });
gadgets.push({ kind: 'button', id: 4, left: sp + 80, top: sp + rh + sp + rh + sp + rh + sp + rh + sp, width: 80, label: "Save", height: rh });
gadgets.push({ kind: 'button', id: 5, left: sp + 80 + sp + 80, top: sp + rh + sp + rh + sp + rh + sp + rh + sp, width: 80, label: "Remove", height: rh });
let win = gui.createWindow({
title: 'Entry Details',
width: 400,
height: sp + rh + sp + rh + sp + rh + sp + rh + sp + rh + sp,
left: 30,
top: 30,
gadgets: gadgets
});
if (innerData.targetAccount) {
gui.set(win, 6, 1);
let i = -1;
for (i = 0; i < accounts.length; i++) {
if (accounts[i] === innerData.targetAccount) {
break;
}
}
gui.set(win, 7, i);
gui.setDisabled(win, 7, false);
} else {
gui.setDisabled(win, 7, true);
}
gui.setDisabled(win, 5, !removable);
while (true) {
var evt = gui.waitEvent(win);
if (!evt) continue;
if (evt.type === 'close') {
gui.closeWindow(win);
return null;
}
if (evt.type === 'gadgetup') {
if (evt.id === 6) {
gui.setDisabled(win, 7, !gui.get(win, 6));
}
if (evt.id === 4) {
innerData.subject = gui.get(win, 1);
innerData.amount = parseFloat(gui.get(win, 2));
innerData.date = toDateByComponents(gui.get(win, 3));
if (gui.get(win, 6)) {
const targetAccountIndex = gui.get(win, 7);
if (targetAccountIndex !== null && targetAccountIndex !== undefined) {
innerData.targetAccount = data[targetAccountIndex].name;
}
}
gui.closeWindow(win);
return innerData;
}
if (evt.id === 5) {
gui.closeWindow(win);
return -1;
}
}
}
}
function mainWindow() {
let gadgets = [];
const cycleId = 1;
const listViewId = 2;
const balanceId = 3;
const addButtonId = 4;
cols = 56;
gadgets.push({
kind: 'cycle', id: cycleId,
left: sp, top: y, width: 120, height: rh, border: false,
items: getAccounts(projectData), value: 0
});
gadgets.push({ kind: 'button', id: addButtonId, left: 500 - 80 - sp, top: y, width: 80, label: "+Transfer", height: rh });
gadgets.push({
kind: 'listview', id: listViewId, left: sp, top: y + rh + sp, width: 500 - sp - sp, height: 186,
flex: true,
items: toListViewEntries(projectData[0].entries, cols), value: 0
});
gadgets.push({
kind: 'text', id: balanceId, label: 'Balance:',
left: 100, top: y + rh + sp + 186, width: 400 - sp, height: rh,
value: getSummation(projectData[0].entries).toFixed(2)
});
var win = gui.createWindow({
title: 'Budget',
width: 500,
height: 14 + 4 + 4 + 200 + 4,
left: 20,
top: 15,
gadgets: gadgets
});
/* Set up menu bar */
gui.setMenu(win, [
{
title: 'Project',
items: [
{ label: 'New...', id: 101, key: 'N' },
{ label: 'Open...', id: 102, key: 'O' },
{ label: 'Save...', id: 103, key: 'S' },
{ label: '---' },
{ label: 'Quit', id: 199, key: 'Q' }
]
},
]);
let currentAccountIndex = 0;
function updateView() {
gui.set(win, listViewId, toListViewEntries(projectData[currentAccountIndex].entries, cols));
gui.set(win, balanceId, getSummation(projectData[currentAccountIndex].entries).toFixed(2));
}
function doNew() {
projectData = [
{
name: "Current",
entries: []
}
];
currentAccountIndex = 0;
gui.set(win, cycleId, getAccounts(projectData));
gui.set(win, cycleId, 0);
updateView();
}
function doOpen() {
var r = gui.fileRequest({ title: 'Open File', pattern: '#?.json' });
if (r) {
projectData = JSON.parse(fs.readFileSync(r.file));
}
}
function doSave() {
var r = gui.fileRequest({ title: 'Save File', pattern: '#?.json', save: true });
if (r) {
fs.writeFileSync(r.file, JSON.stringify(projectData));
}
}
while (true) {
var evt = gui.waitEvent(win);
if (!evt) continue;
if (evt.type === 'close') break;
if (evt.type === 'menu') {
if (evt.id === 101) doNew();
else if (evt.id === 102) doOpen();
else if (evt.id === 103) doSave();
else if (evt.id === 199) break;
}
if (evt.type === 'gadgetup') {
if (evt.id === cycleId) {
currentAccountIndex = evt.code;
updateView();
}
if (evt.id === listViewId) {
const entry = subWindow(projectData[currentAccountIndex].entries[evt.code]);
if (entry != null) {
if (entry === -1) {
projectData[currentAccountIndex].entries.splice(evt.code, 1);
} else {
projectData[currentAccountIndex].entries[evt.code] = entry;
}
if (entry.targetAccount) {
const targetAccount = projectData.find(d => d.name === entry.targetAccount);
if (targetAccount) {
targetAccount.entries.push({
date: entry.date,
subject: "(" + projectData[currentAccountIndex].name + ")" + entry.subject,
amount: -entry.amount
});
}
}
updateView();
}
}
if (evt.id === addButtonId) {
const entry = subWindow();
if (entry != null) {
projectData[currentAccountIndex].entries.push(entry);
if (entry.targetAccount) {
const targetAccount = projectData.find(d => d.name === entry.targetAccount);
if (targetAccount) {
targetAccount.entries.push({
date: entry.date,
subject: "(" + projectData[currentAccountIndex].name + ")" + entry.subject,
amount: -entry.amount
});
}
}
updateView();
}
}
}
};
gui.closeWindow(win);
}
mainWindow();

47
project.json 100644
View File

@ -0,0 +1,47 @@
[
{
"name": "Current",
"entries": [
{
"date": 1704067200000,
"subject": "(Savings) Initial Deposit",
"targetAccount": "Savings",
"amount": -500
},
{
"date": 1704067200000,
"subject": "Salary",
"amount": 2182.15000000000009
},
{
"date": 1704153600000,
"subject": "Rent",
"amount": -800
},
{
"date": 1704240000000,
"subject": "Groceries",
"amount": -24.19
},
{
"date": 1704240000000,
"subject": "Toiletries",
"amount": -12.95
}
]
},
{
"name": "Savings",
"entries": [
{
"date": 1704067200000,
"subject": "Initial Deposit",
"amount": 500
}
]
},
{
"name": "Portfolio",
"entries": []
}
]