mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-12-12 01:42:32 +00:00
Add list of transactions.
This commit is contained in:
148
resources/assets/v2/pages/transactions/index.js
Normal file
148
resources/assets/v2/pages/transactions/index.js
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* show.js
|
||||
* Copyright (c) 2024 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 '../../boot/bootstrap.js';
|
||||
import dates from "../shared/dates.js";
|
||||
import i18next from "i18next";
|
||||
import {format} from "date-fns";
|
||||
import formatMoney from "../../util/format-money.js";
|
||||
import Get from "../../api/v2/model/transaction/get.js";
|
||||
|
||||
|
||||
let index = function () {
|
||||
return {
|
||||
// notifications
|
||||
notifications: {
|
||||
error: {
|
||||
show: false, text: '', url: '',
|
||||
}, success: {
|
||||
show: false, text: '', url: '',
|
||||
}, wait: {
|
||||
show: false, text: '',
|
||||
|
||||
}
|
||||
},
|
||||
transactions: [],
|
||||
totalPages: 1,
|
||||
perPage: 50,
|
||||
page: 1,
|
||||
// available columns:
|
||||
tableColumns: {
|
||||
description: {
|
||||
enabled: true
|
||||
},
|
||||
source: {
|
||||
enabled: true
|
||||
},
|
||||
destination: {
|
||||
enabled: true
|
||||
},
|
||||
amount: {
|
||||
enabled: true
|
||||
},
|
||||
},
|
||||
|
||||
formatMoney(amount, currencyCode) {
|
||||
return formatMoney(amount, currencyCode);
|
||||
},
|
||||
format(date) {
|
||||
return format(date, i18next.t('config.date_time_fns'));
|
||||
},
|
||||
init() {
|
||||
this.notifications.wait.show = true;
|
||||
this.notifications.wait.text = i18next.t('firefly.wait_loading_data')
|
||||
// TODO need date range.
|
||||
// TODO handle page number
|
||||
this.getTransactions(this.page);
|
||||
},
|
||||
getTransactions(page) {
|
||||
let getter = new Get();
|
||||
|
||||
getter.list({page: page}).then(response => {
|
||||
this.parseTransactions(response.data.data)
|
||||
|
||||
// set meta data
|
||||
this.totalPages = response.data.meta.pagination.total_pages;
|
||||
this.perPage = response.data.meta.pagination.per_page;
|
||||
this.page = response.data.meta.pagination.current_page;
|
||||
}).catch(error => {
|
||||
// todo this is auto generated
|
||||
this.notifications.wait.show = false;
|
||||
this.notifications.error.show = true;
|
||||
this.notifications.error.text = error.response.data.message;
|
||||
});
|
||||
},
|
||||
parseTransactions(data) {
|
||||
// no parse, just save
|
||||
for (let i in data) {
|
||||
if (data.hasOwnProperty(i)) {
|
||||
let current = data[i];
|
||||
let isSplit = current.attributes.transactions.length > 1;
|
||||
let firstSplit = true;
|
||||
|
||||
// foreach on transactions, no matter how many.
|
||||
for (let ii in current.attributes.transactions) {
|
||||
if (current.attributes.transactions.hasOwnProperty(ii)) {
|
||||
let transaction = current.attributes.transactions[ii];
|
||||
transaction.split = isSplit;
|
||||
transaction.firstSplit = firstSplit;
|
||||
transaction.group_title = current.attributes.group_title;
|
||||
transaction.id = current.id;
|
||||
transaction.created_at = current.attributes.created_at;
|
||||
transaction.updated_at = current.attributes.updated_at;
|
||||
transaction.user = current.attributes.user;
|
||||
transaction.user_group = current.attributes.user_group;
|
||||
|
||||
// set firstSplit = false for next run if applicable.
|
||||
firstSplit = false;
|
||||
console.log(transaction);
|
||||
this.transactions.push(transaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// only now, disable wait thing.
|
||||
this.notifications.wait.show = false;
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
let comps = {index, dates};
|
||||
|
||||
function loadPage() {
|
||||
Object.keys(comps).forEach(comp => {
|
||||
console.log(`Loading page component "${comp}"`);
|
||||
let data = comps[comp]();
|
||||
Alpine.data(comp, () => data);
|
||||
});
|
||||
Alpine.start();
|
||||
}
|
||||
|
||||
// wait for load until bootstrapped event is received.
|
||||
document.addEventListener('firefly-iii-bootstrapped', () => {
|
||||
console.log('Loaded through event listener.');
|
||||
loadPage();
|
||||
});
|
||||
// or is bootstrapped before event is triggered.
|
||||
if (window.bootstrapped) {
|
||||
console.log('Loaded through window variable.');
|
||||
loadPage();
|
||||
}
|
||||
@@ -24,33 +24,30 @@ import ChainedBackend from "i18next-chained-backend";
|
||||
import HttpBackend from "i18next-http-backend";
|
||||
import LocalStorageBackend from "i18next-localstorage-backend";
|
||||
|
||||
|
||||
|
||||
|
||||
let loaded = false;
|
||||
|
||||
function loadTranslations(locale) {
|
||||
if (false === loaded) {
|
||||
const replacedLocale = locale.replace('-', '_');
|
||||
loaded = true;
|
||||
console.log(import.meta.env.MODE);
|
||||
const expireTime = import.meta.env.MODE === 'development' ? 1 : 7 * 24 * 60 * 60 * 1000;
|
||||
console.log('Will load language "'+replacedLocale+'"');
|
||||
return i18next
|
||||
.use(ChainedBackend)
|
||||
.init({
|
||||
fallbackLng: "en_US",
|
||||
load: 'languageOnly',
|
||||
fallbackLng: "en",
|
||||
lng: replacedLocale,
|
||||
debug: import.meta.env.MODE === 'development',
|
||||
// ... your i18next config
|
||||
backend: {
|
||||
backends: [
|
||||
LocalStorageBackend,
|
||||
HttpBackend
|
||||
],
|
||||
backendOptions: [{
|
||||
load: 'languageOnly',
|
||||
expirationTime: expireTime
|
||||
}, {
|
||||
// const response = await fetch(`./v2/i18n/${locale}.json`);
|
||||
loadPath: './v2/i18n/{{lng}}.json'
|
||||
}]
|
||||
}
|
||||
|
||||
167
resources/views/v2/transactions/index.blade.php
Normal file
167
resources/views/v2/transactions/index.blade.php
Normal file
@@ -0,0 +1,167 @@
|
||||
@extends('layout.v2')
|
||||
@section('vite')
|
||||
@vite(['resources/assets/v2/sass/app.scss', 'resources/assets/v2/pages/transactions/index.js'])
|
||||
@endsection
|
||||
@section('content')
|
||||
<div class="app-content">
|
||||
<div class="container-fluid" x-data="index">
|
||||
<x-messages></x-messages>
|
||||
<div class="row mb-3">
|
||||
<div class="col-xl-4 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Info</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
some chart
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-4 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Info</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
Same
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-4 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Info</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
Same
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
Nav
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-xl-10 col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Info</h3>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Icon
|
||||
</th>
|
||||
<template x-if="tableColumns.description.enabled">
|
||||
<th>Description</th>
|
||||
</template>
|
||||
<template x-if="tableColumns.source.enabled">
|
||||
<th>From</th>
|
||||
</template>
|
||||
<template x-if="tableColumns.destination.enabled">
|
||||
<th>To</th>
|
||||
</template>
|
||||
<template x-if="tableColumns.amount.enabled">
|
||||
<th>Amount</th>
|
||||
</template>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<template x-for="transaction in transactions">
|
||||
<tr>
|
||||
<td>
|
||||
<template x-if="'withdrawal' === transaction.type">
|
||||
<em class="fa fa-solid fa-arrow-left"
|
||||
title="TODO TRANSLATION"></em>
|
||||
</template>
|
||||
|
||||
<template x-if="'deposit' === transaction.type">
|
||||
<em class="fa-solid fa-arrow-right"
|
||||
:title="transaction.typeTranslated"></em>
|
||||
</template>
|
||||
|
||||
<template x-if="'transfer' === transaction.type">
|
||||
<em class="fa-solid fa-rotate"
|
||||
:title="transaction.typeTranslated"></em>
|
||||
</template>
|
||||
<template
|
||||
x-if="'transfer' !== transaction.type && 'deposit' !== transaction.type && 'withdrawal' !== transaction.type">
|
||||
<span>TODO missing ICON</span>
|
||||
</template>
|
||||
</td>
|
||||
<template x-if="tableColumns.description.enabled">
|
||||
<td>
|
||||
<template x-if="transaction.split">
|
||||
<span>I AM SPLIT</span>
|
||||
</template>
|
||||
<template x-if="transaction.split && transaction.firstSplit">
|
||||
<span>I AM FIRST SPLIT</span>
|
||||
</template>
|
||||
<a :href="'./transactions/show/' + transaction.id" x-text="transaction.description"></a>
|
||||
</td>
|
||||
</template>
|
||||
<template x-if="tableColumns.source.enabled">
|
||||
<td>
|
||||
<a :href="'./accounts/show/' + transaction.source_id"
|
||||
x-text="transaction.source_name"></a>
|
||||
</td>
|
||||
</template>
|
||||
<template x-if="tableColumns.destination.enabled">
|
||||
<td>
|
||||
<a :href="'./accounts/show/' + transaction.destination_id"
|
||||
x-text="transaction.destination_name"></a>
|
||||
</td>
|
||||
</template>
|
||||
<template x-if="tableColumns.amount.enabled">
|
||||
<td>
|
||||
|
||||
<template x-if="'withdrawal' === transaction.type">
|
||||
<span class="text-danger" x-text="formatMoney(transaction.amount*-1, transaction.currency_code)"></span>
|
||||
</template>
|
||||
|
||||
|
||||
<template x-if="'deposit' === transaction.type">
|
||||
<span class="text-success" x-text="formatMoney(transaction.amount, transaction.currency_code)"></span>
|
||||
</template>
|
||||
|
||||
<template x-if="'transfer' === transaction.type">
|
||||
<span class="text-info" x-text="formatMoney(transaction.amount, transaction.currency_code)"></span>
|
||||
</template>
|
||||
<template
|
||||
x-if="'transfer' !== transaction.type && 'deposit' !== transaction.type && 'withdrawal' !== transaction.type">
|
||||
<span>TODO PARSE MISSING AMOUNT</span>
|
||||
</template>
|
||||
</td>
|
||||
</template>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-2 col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Sidebar</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
I like sidebar
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
Nav
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
@@ -224,7 +224,7 @@
|
||||
</template>
|
||||
<tr>
|
||||
<th>recurring things</th>
|
||||
<td>meta</td>
|
||||
<td>TODO meta</td>
|
||||
</tr>
|
||||
<template x-if="entry.tags.length > 0">
|
||||
<tr>
|
||||
@@ -248,28 +248,28 @@
|
||||
</div>
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Transaction links</h3>
|
||||
<h3 class="card-title">Transaction links TODO</h3>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Piggy bank events.</h3>
|
||||
<h3 class="card-title">Piggy bank events TODO</h3>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Attachments</h3>
|
||||
<h3 class="card-title">Attachments TODO</h3>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Audit log entries</h3>
|
||||
<h3 class="card-title">Audit log entries TODO</h3>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user