Merge pull request #6911 from firefly-iii/v3-top-boxes

Clean up top boxes
This commit is contained in:
James Cole 2023-01-21 17:19:03 +01:00 committed by GitHub
commit fc0adfd375
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 954 additions and 850 deletions

View File

@ -239,7 +239,7 @@ class TransactionGroupTransformer extends AbstractTransformer
*/ */
private function stringFromArray(NullArrayObject $array, string $key, ?string $default): ?string private function stringFromArray(NullArrayObject $array, string $key, ?string $default): ?string
{ {
Log::debug(sprintf('%s: %s', $key, var_export($array[$key]))); //Log::debug(sprintf('%s: %s', $key, var_export($array[$key], true)));
if (null === $array[$key] && null === $default) { if (null === $array[$key] && null === $default) {
return null; return null;
} }

View File

@ -11,7 +11,7 @@
}, },
"dependencies": { "dependencies": {
"@popperjs/core": "^2.11.2", "@popperjs/core": "^2.11.2",
"@quasar/extras": "^1.15.9", "@quasar/extras": "^1.15.10",
"apexcharts": "^3.32.1", "apexcharts": "^3.32.1",
"axios": "^0.21.1", "axios": "^0.21.1",
"axios-cache-adapter": "^2.7.3", "axios-cache-adapter": "^2.7.3",
@ -26,7 +26,7 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/eslint-parser": "^7.13.14", "@babel/eslint-parser": "^7.13.14",
"@quasar/app-webpack": "^3.6.2", "@quasar/app-webpack": "^3.7.1",
"@types/node": "^12.20.21", "@types/node": "^12.20.21",
"@typescript-eslint/eslint-plugin": "^4.16.1", "@typescript-eslint/eslint-plugin": "^4.16.1",
"@typescript-eslint/parser": "^4.16.1", "@typescript-eslint/parser": "^4.16.1",

View File

@ -55,7 +55,7 @@ module.exports = configure(function (ctx) {
extras: [ extras: [
// 'ionicons-v4', // 'ionicons-v4',
// 'mdi-v5', // 'mdi-v5',
'fontawesome-v5', 'fontawesome-v6',
// 'eva-icons', // 'eva-icons',
// 'themify', // 'themify',
// 'line-awesome', // 'line-awesome',
@ -126,7 +126,7 @@ module.exports = configure(function (ctx) {
}, },
lang: 'en-US', // Quasar language pack lang: 'en-US', // Quasar language pack
iconSet: 'fontawesome-v5', iconSet: 'fontawesome-v6',
// For special cases outside of where the auto-import strategy can have an impact // For special cases outside of where the auto-import strategy can have an impact
// (like functional components as one of the examples), // (like functional components as one of the examples),

View File

@ -22,11 +22,10 @@
<!-- TODO most left? q-mr-sm --> <!-- TODO most left? q-mr-sm -->
<!-- TODO middle? dan q-mx-sm --> <!-- TODO middle? dan q-mx-sm -->
<!-- TODO right? dan q-ml-sm --> <!-- TODO right? dan q-ml-sm -->
<div class="q-mr-sm"> <q-card bordered flat class="fit">
<q-card bordered>
<q-item> <q-item>
<q-item-section> <q-item-section>
<q-item-label><strong>{{ $t('firefly.bills_to_pay') }}</strong></q-item-label> <q-item-label><strong>{{ $t('firefly.bills') }} </strong></q-item-label>
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-separator /> <q-separator />
@ -63,7 +62,6 @@
</q-card-section> </q-card-section>
</q-card-section> </q-card-section>
</q-card> </q-card>
</div>
</template> </template>
<script> <script>

View File

@ -22,8 +22,7 @@
<!-- TODO most left? q-mr-sm --> <!-- TODO most left? q-mr-sm -->
<!-- TODO middle? dan q-mx-sm --> <!-- TODO middle? dan q-mx-sm -->
<!-- TODO right? dan q-ml-sm --> <!-- TODO right? dan q-ml-sm -->
<div class="q-ml-sm"> <q-card bordered flat class="fit">
<q-card bordered>
<q-item> <q-item>
<q-item-section> <q-item-section>
<q-item-label><strong>{{ $t('firefly.net_worth') }}</strong></q-item-label> <q-item-label><strong>{{ $t('firefly.net_worth') }}</strong></q-item-label>
@ -47,7 +46,6 @@
</q-card-section> </q-card-section>
</q-card-section> </q-card-section>
</q-card> </q-card>
</div>
</template> </template>
<script> <script>

View File

@ -22,11 +22,10 @@
<!-- TODO most left? q-mr-sm --> <!-- TODO most left? q-mr-sm -->
<!-- TODO middle? dan q-mx-sm --> <!-- TODO middle? dan q-mx-sm -->
<!-- TODO right? dan q-ml-sm --> <!-- TODO right? dan q-ml-sm -->
<div class="q-mx-sm"> <q-card bordered flat>
<q-card bordered>
<q-item> <q-item>
<q-item-section> <q-item-section>
<q-item-label><strong>{{ $t('firefly.left_to_spend') }}</strong></q-item-label> <q-item-label><strong>{{ $t('firefly.left_to_spend') }} x</strong></q-item-label>
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-separator/> <q-separator/>
@ -66,7 +65,6 @@
</q-card-section> </q-card-section>
</q-card-section> </q-card-section>
</q-card> </q-card>
</div>
</template> </template>
<script> <script>

View File

@ -24,7 +24,6 @@
:columns="columns" :columns="columns"
:loading="loading" :loading="loading"
:rows="rows" :rows="rows"
:title="title"
class="q-ma-md" class="q-ma-md"
row-key="group_id" row-key="group_id"
@request="onRequest" @request="onRequest"

View File

@ -18,10 +18,24 @@
- along with this program. If not, see <https://www.gnu.org/licenses/>. - along with this program. If not, see <https://www.gnu.org/licenses/>.
--> -->
<!--
instructions for padding and margin
menu: top padding under top bar: q-pt-xs (padding top, xs)
page container: q-ma-xs (margin all, xs) AND q-mb-md to give the page content some space.
TODO main DIV always use q-ma-md for the main holder
TODO rows use a q-mb-sm to give them space
-->
<template> <template>
<q-layout view="hHh lpR fFf"> <q-layout view="hHh lpR fFf">
<q-header class="bg-primary text-white" elevated> <q-header reveal class="bg-primary text-white">
<q-toolbar> <q-toolbar>
<q-btn dense flat icon="fas fa-bars" round @click="toggleLeftDrawer"/> <q-btn dense flat icon="fas fa-bars" round @click="toggleLeftDrawer"/>
@ -101,7 +115,7 @@
<q-item-section>Currencies</q-item-section> <q-item-section>Currencies</q-item-section>
</q-item> </q-item>
<q-item :to="{ name: 'admin.index' }" clickable> <q-item :to="{ name: 'admin.index' }" clickable>
<q-item-section>Administration</q-item-section> <q-item-section>System settings</q-item-section>
</q-item> </q-item>
</q-list> </q-list>
</q-menu> </q-menu>
@ -119,9 +133,12 @@
<q-item :to="{ name: 'profile.index' }" clickable> <q-item :to="{ name: 'profile.index' }" clickable>
<q-item-section> Profile</q-item-section> <q-item-section> Profile</q-item-section>
</q-item> </q-item>
<q-item :to="{ name: 'profile.daa' }" clickable> <q-item :to="{ name: 'profile.data' }" clickable>
<q-item-section> Data management</q-item-section> <q-item-section> Data management</q-item-section>
</q-item> </q-item>
<q-item :to="{ name: 'administration.index' }" clickable>
<q-item-section>Administration management</q-item-section>
</q-item>
<q-item :to="{ name: 'preferences.index' }" clickable> <q-item :to="{ name: 'preferences.index' }" clickable>
<q-item-section>Preferences</q-item-section> <q-item-section>Preferences</q-item-section>
</q-item> </q-item>
@ -137,11 +154,11 @@
</q-btn> </q-btn>
</q-toolbar> </q-toolbar>
</q-header> </q-header>
<q-drawer v-model="leftDrawerOpen" bordered show-if-above side="left"> <q-drawer show-if-above v-model="leftDrawerOpen" side="left" bordered>
<q-scroll-area class="fit"> <q-scroll-area class="fit">
<div class="q-pa-md"> <div class="q-pt-xs">
<q-list> <q-list :dense="true">
<q-item v-ripple :to="{ name: 'index' }" clickable> <q-item v-ripple :to="{ name: 'index' }" clickable :dense="true">
<q-item-section avatar> <q-item-section avatar>
<q-icon name="fas fa-tachometer-alt"/> <q-icon name="fas fa-tachometer-alt"/>
</q-item-section> </q-item-section>
@ -149,7 +166,7 @@
Dashboard Dashboard
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item v-ripple :to="{ name: 'budgets.index' }" clickable> <q-item v-ripple :to="{ name: 'budgets.index' }" clickable :dense="true">
<q-item-section avatar> <q-item-section avatar>
<q-icon name="fas fa-chart-pie"/> <q-icon name="fas fa-chart-pie"/>
</q-item-section> </q-item-section>
@ -157,7 +174,7 @@
Budgets Budgets
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item v-ripple :to="{ name: 'subscriptions.index' }" clickable> <q-item v-ripple :to="{ name: 'subscriptions.index' }" clickable :dense="true">
<q-item-section avatar> <q-item-section avatar>
<q-icon name="far fa-calendar-alt"/> <q-icon name="far fa-calendar-alt"/>
</q-item-section> </q-item-section>
@ -165,7 +182,7 @@
Subscriptions Subscriptions
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item v-ripple :to="{ name: 'piggy-banks.index' }" clickable> <q-item v-ripple :to="{ name: 'piggy-banks.index' }" clickable :dense="true">
<q-item-section avatar> <q-item-section avatar>
<q-icon name="fas fa-piggy-bank"/> <q-icon name="fas fa-piggy-bank"/>
</q-item-section> </q-item-section>
@ -174,48 +191,55 @@
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-expansion-item <q-expansion-item :dense="true"
:default-opened="this.$route.name === 'transactions.index' || this.$route.name === 'transactions.show'" :default-opened="this.$route.name === 'transactions.index' || this.$route.name === 'transactions.show'"
expand-separator expand-separator
icon="fas fa-exchange-alt" icon="fas fa-exchange-alt"
label="Transactions" label="Transactions"
> >
<q-item v-ripple :inset-level="1" :to="{ name: 'transactions.index', params: {type: 'withdrawal'} }" <q-item :dense="true" v-ripple :inset-level="1" :to="{ name: 'transactions.index', params: {type: 'withdrawal'} }"
clickable> clickable>
<q-item-section> <q-item-section>
Withdrawals Withdrawals
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item v-ripple :inset-level="1" :to="{ name: 'transactions.index', params: {type: 'deposit'} }" <q-item :dense="true" v-ripple :inset-level="1" :to="{ name: 'transactions.index', params: {type: 'deposit'} }"
clickable> clickable>
<q-item-section> <q-item-section>
Deposits Deposits
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item v-ripple :inset-level="1" :to="{ name: 'transactions.index', params: {type: 'transfers'} }" <q-item :dense="true" v-ripple :inset-level="1" :to="{ name: 'transactions.index', params: {type: 'transfers'} }"
clickable> clickable>
<q-item-section> <q-item-section>
Transfers Transfers
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item :dense="true" v-ripple :inset-level="1" :to="{ name: 'transactions.index', params: {type: 'all'} }"
clickable>
<q-item-section>
All transactions
</q-item-section>
</q-item>
</q-expansion-item> </q-expansion-item>
<q-expansion-item <q-expansion-item :dense="true"
default-unopened default-unopened
expand-separator expand-separator
icon="fas fa-microchip" icon="fas fa-microchip"
label="Automation" label="Automation"
> >
<q-item v-ripple :inset-level="1" :to="{ name: 'rules.index' }" clickable> <q-item :dense="true" v-ripple :inset-level="1" :to="{ name: 'rules.index' }" clickable>
<q-item-section> <q-item-section>
Rules Rules
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item v-ripple :inset-level="1" :to="{ name: 'recurring.index' }" clickable> <q-item :dense="true" v-ripple :inset-level="1" :to="{ name: 'recurring.index' }" clickable>
<q-item-section> <q-item-section>
Recurring transactions Recurring transactions
</q-item-section> </q-item-section>
@ -223,18 +247,18 @@
</q-expansion-item> </q-expansion-item>
<q-expansion-item <q-expansion-item :dense="true"
:default-opened="this.$route.name === 'accounts.index' || this.$route.name === 'accounts.show'" :default-opened="this.$route.name === 'accounts.index' || this.$route.name === 'accounts.show'"
expand-separator expand-separator
icon="fas fa-credit-card" icon="fas fa-credit-card"
label="Accounts" label="Accounts"
> >
<q-item v-ripple :inset-level="1" :to="{ name: 'accounts.index', params: {type: 'asset'} }" clickable> <q-item :dense="true" v-ripple :inset-level="1" :to="{ name: 'accounts.index', params: {type: 'asset'} }" clickable>
<q-item-section> <q-item-section>
Asset accounts Asset accounts
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item v-ripple :inset-level="1" :to="{ name: 'accounts.index', params: {type: 'expense'} }" clickable> <q-item :dense="true" v-ripple :inset-level="1" :to="{ name: 'accounts.index', params: {type: 'expense'} }" clickable>
<q-item-section> <q-item-section>
Expense accounts Expense accounts
</q-item-section> </q-item-section>
@ -244,7 +268,7 @@
Revenue accounts Revenue accounts
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item v-ripple :inset-level="1" :to="{ name: 'accounts.index', params: {type: 'liabilities'} }" <q-item :dense="true" v-ripple :inset-level="1" :to="{ name: 'accounts.index', params: {type: 'liabilities'} }"
clickable> clickable>
<q-item-section> <q-item-section>
Liabilities Liabilities
@ -253,29 +277,29 @@
</q-expansion-item> </q-expansion-item>
<q-expansion-item <q-expansion-item :dense="true"
default-unopened default-unopened
expand-separator expand-separator
icon="fas fa-tags" icon="fas fa-tags"
label="Classification" label="Classification"
> >
<q-item v-ripple :inset-level="1" :to="{ name: 'categories.index' }" clickable> <q-item :dense="true" v-ripple :inset-level="1" :to="{ name: 'categories.index' }" clickable>
<q-item-section> <q-item-section>
Categories Categories
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item v-ripple :inset-level="1" :to="{ name: 'tags.index' }" clickable> <q-item :dense="true" v-ripple :inset-level="1" :to="{ name: 'tags.index' }" clickable>
<q-item-section> <q-item-section>
Tags Tags
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item v-ripple :inset-level="1" :to="{ name: 'groups.index'}" clickable> <q-item :dense="true" v-ripple :inset-level="1" :to="{ name: 'groups.index'}" clickable>
<q-item-section> <q-item-section>
Groups Groups
</q-item-section> </q-item-section>
</q-item> </q-item>
</q-expansion-item> </q-expansion-item>
<q-item v-ripple :to="{ name: 'reports.index'}" clickable> <q-item :dense="true" v-ripple :to="{ name: 'reports.index'}" clickable>
<q-item-section avatar> <q-item-section avatar>
<q-icon name="far fa-chart-bar"/> <q-icon name="far fa-chart-bar"/>
</q-item-section> </q-item-section>
@ -289,14 +313,15 @@
</q-drawer> </q-drawer>
<q-page-container> <q-page-container class="q-ma-xs">
<Alert></Alert> <Alert></Alert>
<!-- breadcrumb, page title? --> <!-- breadcrumb, page title? -->
<div class="q-ma-md"> <div class="q-mb-md">
<div class="row"> <div class="row">
<div class="col-6"> <div class="col-6">
<h4 class="q-ma-none q-pa-none">{{ $t($route.meta.pageTitle || 'firefly.welcome_back') }}</h4> <h4 class="q-ma-none q-pa-none">
<em class="fa-solid fa-fire"></em>
{{ $t($route.meta.pageTitle || 'firefly.welcome_back') }}</h4>
</div> </div>
<div class="col-6"> <div class="col-6">
<q-breadcrumbs align="right"> <q-breadcrumbs align="right">
@ -314,7 +339,7 @@
<q-footer class="bg-grey-8 text-white" elevated> <q-footer class="bg-grey-8 text-white" elevated>
<q-toolbar> <q-toolbar>
<div> <div>
<small>Firefly III v TODO &copy; James Cole, AGPL-3.0-or-later.</small> <small>Firefly III v v6.0.0-alpha.2 &copy; James Cole, AGPL-3.0-or-later.</small>
</div> </div>
</q-toolbar> </q-toolbar>
</q-footer> </q-footer>
@ -327,6 +352,7 @@
import {defineComponent, ref} from 'vue'; import {defineComponent, ref} from 'vue';
import DateRange from "../components/DateRange"; import DateRange from "../components/DateRange";
import Alert from '../components/Alert'; import Alert from '../components/Alert';
import {useQuasar} from "quasar";
export default defineComponent( export default defineComponent(
{ {
@ -339,7 +365,7 @@ export default defineComponent(
setup() { setup() {
const leftDrawerOpen = ref(true) const leftDrawerOpen = ref(true)
const search = ref('') const search = ref('')
const $q = useQuasar();
return { return {
search, search,
leftDrawerOpen, leftDrawerOpen,

View File

@ -0,0 +1,60 @@
<!--
- Index.vue
- 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/>.
-->
<template>
<div>
<div class="q-ma-md">
<div class="row q-mb-sm">
<div class="col">
<div class="q-mt-sm q-mr-sm">
<q-card bordered>
<q-item>
<q-item-section>
<q-item-label><strong>Financial administration</strong></q-item-label>
</q-item-section>
</q-item>
<q-separator/>
<q-card-section>
<p>
Bla bla bla
List of groups.
Edit members, edit group, delete group.
add new administration.
switch to new administration.
</p>
</q-card-section>
</q-card>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Index"
}
</script>
<style scoped>
</style>

View File

@ -1,207 +0,0 @@
<!--
- Boxes.vue
- Copyright (c) 2021 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/>.
-->
<template>
<div class="row">
<div class="col-4 q-pr-sm q-pr-sm">
<q-card bordered>
<q-card-section class="q-pt-xs">
<div class="text-overline">
{{ $t('firefly.bills_to_pay') }}
<span class="float-right">
<span class="text-grey-4 fas fa-redo-alt" style="cursor: pointer;" @click="triggerForcedUpgrade"></span>
</span>
</div>
</q-card-section>
<q-card-section class="q-pt-xs">
<span v-for="balance in prefBillsUnpaid">{{ balance.value_parsed }}</span>
<span v-for="(bill, index) in notPrefBillsUnpaid">
{{ bill.value_parsed }}<span v-if="index+1 !== notPrefBillsUnpaid.length">, </span>
</span>
</q-card-section>
</q-card>
</div>
<div class="col-4 q-pr-sm q-pl-sm">
<q-card bordered>
<q-card-section class="q-pt-xs">
<div class="text-overline">
{{ $t('firefly.left_to_spend') }}
<span class="float-right">
<span class="text-grey-4 fas fa-redo-alt" style="cursor: pointer;" @click="triggerForcedUpgrade"></span>
</span>
</div>
</q-card-section>
<q-card-section class="q-pt-xs">
<!-- left to spend in preferred currency -->
<span v-for="left in prefLeftToSpend" :title="left.sub_title">{{ left.value_parsed }}</span>
<span v-for="(left, index) in notPrefLeftToSpend">
{{ left.value_parsed }}<span v-if="index+1 !== notPrefLeftToSpend.length">, </span>
</span>
</q-card-section>
</q-card>
</div>
<div class="col-4 q-pl-sm">
<q-card bordered>
<q-card-section class="q-pt-xs">
<div class="text-overline">
{{ $t('firefly.net_worth') }}
<span class="float-right">
<span class="text-grey-4 fas fa-redo-alt" style="cursor: pointer;" @click="triggerForcedUpgrade"></span>
</span>
</div>
</q-card-section>
<q-card-section class="q-pt-xs">
<span v-for="nw in prefNetWorth" :title="nw.sub_title">{{ nw.value_parsed }}</span>
<span v-for="(nw, index) in notPrefNetWorth">
{{ nw.value_parsed }}<span v-if="index+1 !== notPrefNetWorth.length">, </span>
</span>
<span v-if="0===notPrefNetWorth.length">&nbsp;</span>
</q-card-section>
</q-card>
</div>
</div>
</template>
<script>
import Basic from "src/api/summary/basic";
import {useFireflyIIIStore} from '../../stores/fireflyiii'
export default {
name: 'Boxes',
computed: {
prefBillsUnpaid: function () {
return this.filterOnCurrency(this.billsUnpaid);
},
notPrefBillsUnpaid: function () {
return this.filterOnNotCurrency(this.billsUnpaid);
},
prefLeftToSpend: function () {
return this.filterOnCurrency(this.leftToSpend);
},
notPrefLeftToSpend: function () {
return this.filterOnNotCurrency(this.leftToSpend);
},
prefNetWorth: function () {
return this.filterOnCurrency(this.netWorth);
},
notPrefNetWorth: function () {
return this.filterOnNotCurrency(this.netWorth);
},
},
created() {
},
data() {
return {
summary: [],
billsPaid: [],
billsUnpaid: [],
leftToSpend: [],
netWorth: [],
range: {
start: null,
end: null,
},
store: null
}
},
mounted() {
this.store = useFireflyIIIStore();
if (null === this.range.start || null === this.range.end) {
// subscribe, then update:
this.store.$onAction(
({name, $store, args, after, onError,}) => {
after((result) => {
if (name === 'setRange') {
this.range = result;
this.triggerUpdate();
}
})
}
)
}
if (null !== this.store.getRange.start && null !== this.store.getRange.end) {
this.start = this.store.getRange.start;
this.end = this.store.getRange.end;
this.triggerUpdate();
}
},
methods: {
triggerForcedUpgrade: function () {
this.store.refreshCacheKey();
this.triggerUpdate();
},
triggerUpdate: function () {
if (null !== this.store.getRange.start && null !== this.store.getRange.end) {
const basic = new Basic;
basic.list({
start: this.store.getRange.start,
end: this.store.getRange.end
}, this.store.getCacheKey).then(data => {
this.netWorth = this.getKeyedEntries(data.data, 'net-worth-in-');
this.leftToSpend = this.getKeyedEntries(data.data, 'left-to-spend-in-');
this.billsPaid = this.getKeyedEntries(data.data, 'bills-paid-in-');
this.billsUnpaid = this.getKeyedEntries(data.data, 'bills-unpaid-in-');
});
}
},
getKeyedEntries(array, expected) {
let result = [];
for (const key in array) {
if (array.hasOwnProperty(key)) {
if (expected === key.substr(0, expected.length)) {
result.push(array[key]);
}
}
}
return result;
},
filterOnCurrency(array) {
let ret = [];
for (const key in array) {
if (array.hasOwnProperty(key)) {
if (array[key].currency_id === this.store.getCurrencyId) {
ret.push(array[key]);
}
}
}
// or just the first one:
if (0 === ret.length && array.hasOwnProperty(0)) {
ret.push(array[0]);
}
return ret;
},
filterOnNotCurrency(array) {
let ret = [];
for (const key in array) {
if (array.hasOwnProperty(key)) {
if (array[key].currency_id !== this.store.getCurrencyId) {
ret.push(array[key]);
}
}
}
return ret;
},
}
}
</script>

View File

@ -19,31 +19,29 @@
--> -->
<template> <template>
<!-- TODO main DIV always use q-ma-md for the main holder--> <div>
<!-- TODO rows use a q-mb-sm to give them space --> <div class="row">
<div class="q-ma-md"> <div class="col q-mr-sm">
<div class="row q-mb-sm">
<div class="col">
<BillInsightBox/> <BillInsightBox/>
</div> </div>
<div class="col"> <div class="col q-mx-sm">
<SpendInsightBox/> <SpendInsightBox/>
</div> </div>
<div class="col"> <div class="col q-ml-sm">
<NetWorthInsightBox/> <NetWorthInsightBox/>
</div> </div>
</div> </div>
<div class="row q-mb-sm"> <div class="row">
<div class="col"> <div class="col">
<AccountChart/> <AccountChart/>
</div> </div>
</div> </div>
<div class="row q-mb-sm"> <div class="row">
<div class="col"> <div class="col">
<TransactionLists/> <TransactionLists/>
</div> </div>
</div> </div>
<div class="row q-mb-sm"> <div class="row">
<div class="col"> <div class="col">
<BudgetBox/> <BudgetBox/>
</div> </div>
@ -51,7 +49,7 @@
Category box Category box
</div> </div>
</div> </div>
<div class="row q-mb-sm"> <div class="row">
<div class="col"> <div class="col">
Expense Box Expense Box
</div> </div>
@ -59,7 +57,7 @@
Revenue Box Revenue Box
</div> </div>
</div> </div>
<div class="row q-mb-sm"> <div class="row">
<div class="col"> <div class="col">
Piggy box Piggy box
</div> </div>

View File

@ -20,12 +20,99 @@
<template> <template>
<q-page> <q-page>
<div class="row q-mx-md q-mb-sm">
<!-- search box -->
<div class="col q-mr-sm">
<q-card bordered>
<q-card-section>
<div class="row items-center no-wrap">
<div class="col">
Search and filter
</div>
<div class="col-auto">
<q-btn color="grey" round flat dense
:icon="searchExpanded ? 'fas fa-chevron-up' : 'fas fa-chevron-down'" @click="searchExpanded = !searchExpanded">
</q-btn>
</div>
</div>
</q-card-section>
<q-slide-transition>
<div v-show="searchExpanded">
<q-separator />
<q-card-section>
Here be stuff
</q-card-section>
</div>
</q-slide-transition>
</q-card>
</div>
<!-- date and range box -->
<div class="col q-ml-sm">
<q-card bordered>
<q-card-section>
<div class="row items-center no-wrap">
<div class="col">
Dates and ranges
</div>
<div class="col-auto">
<q-btn color="grey" round flat dense
:icon="dateExpanded ? 'fas fa-chevron-up' : 'fas fa-chevron-down'" @click="dateExpanded = !dateExpanded">
</q-btn>
</div>
</div>
</q-card-section>
<q-slide-transition>
<div v-show="dateExpanded">
<q-separator />
<q-card-section>
Here be stuff
</q-card-section>
</div>
</q-slide-transition>
</q-card>
</div>
</div>
<div class="row q-mx-md">
<div class="col">
<q-card bordered>
<q-card-section>
<div class="row items-center no-wrap">
<div class="col">
Stats
</div>
<div class="col-auto">
<q-btn color="grey" round flat dense
:icon="statsExpanded ? 'fas fa-chevron-up' : 'fas fa-chevron-down'" @click="statsExpanded = !statsExpanded">
</q-btn>
</div>
</div>
</q-card-section>
<q-slide-transition>
<div v-show="statsExpanded">
<q-separator />
<q-card-section>
Here be stuff
</q-card-section>
</div>
</q-slide-transition>
</q-card>
</div>
</div>
<div class="row">
<div class="col">
<!-- insert LargeTable --> <!-- insert LargeTable -->
<LargeTable ref="table" <LargeTable ref="table"
:loading="loading" :loading="loading"
:page="page" :page="page"
:rows="rows" :rows="rows"
class="mb-5"
:rows-number="rowsNumber" :rows-number="rowsNumber"
:rows-per-page="rowsPerPage" :rows-per-page="rowsPerPage"
:title="$t('firefly.title_' + this.type)" :title="$t('firefly.title_' + this.type)"
@ -33,10 +120,14 @@
> >
</LargeTable> </LargeTable>
</div>
</div>
<div class="box">
<div class="row">
<p>&nbsp;</p> <p>&nbsp;</p>
<p>&nbsp;</p> <p>&nbsp;</p>
<p>&nbsp;</p> </div>
<p>&nbsp;</p> </div>
<q-page-sticky :offset="[18, 18]" position="bottom-right"> <q-page-sticky :offset="[18, 18]" position="bottom-right">
<q-fab <q-fab
color="green" color="green"
@ -47,12 +138,15 @@
square square
vertical-actions-align="right" vertical-actions-align="right"
> >
<q-fab-action :to="{ name: 'transactions.create', params: {type: 'transfer'} }" color="primary" icon="fas fa-exchange-alt" <q-fab-action :to="{ name: 'transactions.create', params: {type: 'transfer'} }" color="primary"
icon="fas fa-exchange-alt"
label="New transfer" square/> label="New transfer" square/>
<q-fab-action :to="{ name: 'transactions.create', params: {type: 'deposit'} }" color="primary" icon="fas fa-long-arrow-alt-right" <q-fab-action :to="{ name: 'transactions.create', params: {type: 'deposit'} }" color="primary"
icon="fas fa-long-arrow-alt-right"
label="New deposit" label="New deposit"
square/> square/>
<q-fab-action :to="{ name: 'transactions.create', params: {type: 'withdrawal'} }" color="primary" icon="fas fa-long-arrow-alt-left" <q-fab-action :to="{ name: 'transactions.create', params: {type: 'withdrawal'} }" color="primary"
icon="fas fa-long-arrow-alt-left"
label="New withdrawal" label="New withdrawal"
square/> square/>
@ -66,6 +160,7 @@
import List from "../../api/transactions/list"; import List from "../../api/transactions/list";
import LargeTable from "../../components/transactions/LargeTable"; import LargeTable from "../../components/transactions/LargeTable";
import Parser from "../../api/transactions/parser"; import Parser from "../../api/transactions/parser";
import {useFireflyIIIStore} from "stores/fireflyiii";
export default { export default {
name: 'Index', name: 'Index',
@ -92,27 +187,26 @@ export default {
columns: [ columns: [
{name: 'type', label: ' ', field: 'type', style: 'width: 30px'}, {name: 'type', label: ' ', field: 'type', style: 'width: 30px'},
{name: 'description', label: 'Description', field: 'description', align: 'left'}, {name: 'description', label: 'Description', field: 'description', align: 'left'},
{ {name: 'amount', label: 'Amount', field: 'amount'},
name: 'amount', label: 'Amount', field: 'amount' {name: 'date', label: 'Date', field: 'date', align: 'left',},
}, //{name: 'source', label: 'Source', field: 'source', align: 'left'},
{ //{name: 'destination', label: 'Destination', field: 'destination', align: 'left'},
name: 'date', label: 'Date', field: 'date', //{name: 'category', label: 'Category', field: 'category', align: 'left'},
align: 'left', //{name: 'budget', label: 'Budget', field: 'budget', align: 'left'},
},
{name: 'source', label: 'Source', field: 'source', align: 'left'},
{name: 'destination', label: 'Destination', field: 'destination', align: 'left'},
{name: 'category', label: 'Category', field: 'category', align: 'left'},
{name: 'budget', label: 'Budget', field: 'budget', align: 'left'},
{name: 'menu', label: ' ', field: 'menu', align: 'left'}, {name: 'menu', label: ' ', field: 'menu', align: 'left'},
], ],
type: 'withdrawal', type: 'withdrawal',
page: 1, page: 1,
rowsPerPage: 50, rowsPerPage: 50,
rowsNumber: 100, rowsNumber: 100,
store: null,
range: { range: {
start: null, start: null,
end: null end: null
} },
searchExpanded: false, // TODO store in cookie.
dateExpanded : false,
statsExpanded: false,
} }
}, },
computed: { computed: {
@ -120,6 +214,8 @@ export default {
}, },
created() { created() {
this.rowsPerPage = this.getListPageSize; this.rowsPerPage = this.getListPageSize;
this.store = useFireflyIIIStore();
}, },
mounted() { mounted() {
this.type = this.$route.params.type; this.type = this.$route.params.type;

View File

@ -900,6 +900,22 @@ const routes = [
} }
] ]
}, },
// financial administration
{
path: '/administrations',
component: () => import('layouts/MainLayout.vue'),
children: [
{
path: '',
component: () => import('pages/administration/Index.vue'),
name: 'administration.index',
meta: {
pageTitle: 'firefly.administration_index'
}
}
]
},
// profile // profile
{ {
path: '/profile', path: '/profile',
@ -946,17 +962,17 @@ const routes = [
] ]
}, },
// administration // administration (system settings)
{ {
path: '/admin', path: '/system',
component: () => import('layouts/MainLayout.vue'), component: () => import('layouts/MainLayout.vue'),
children: [ children: [
{ {
path: '', path: '',
component: () => import('pages/admin/Index.vue'), component: () => import('pages/system/Index.vue'),
name: 'admin.index', name: 'system.index',
meta: { meta: {
pageTitle: 'firefly.administration' pageTitle: 'firefly.system'
} }
} }
] ]

File diff suppressed because it is too large Load Diff

View File

@ -1347,6 +1347,9 @@ return [
'slack_webhook_url_help' => 'If you want Firefly III to notify you using Slack, enter the webhook URL here. Otherwise leave the field blank. If you are an admin, you need to set this URL in the administration as well.', 'slack_webhook_url_help' => 'If you want Firefly III to notify you using Slack, enter the webhook URL here. Otherwise leave the field blank. If you are an admin, you need to set this URL in the administration as well.',
'slack_url_label' => 'Slack "incoming webhook" URL', 'slack_url_label' => 'Slack "incoming webhook" URL',
// Financial administrations
'administration_index' => 'Financial administration',
// profile: // profile:
'purge_data_title' => 'Purge data from Firefly III', 'purge_data_title' => 'Purge data from Firefly III',
'purge_data_expl' => '"Purging" means "deleting that which is already deleted". In normal circumstances, Firefly III deletes nothing permanently. It just hides it. The button below deletes all of these previously "deleted" records FOREVER.', 'purge_data_expl' => '"Purging" means "deleting that which is already deleted". In normal circumstances, Firefly III deletes nothing permanently. It just hides it. The button below deletes all of these previously "deleted" records FOREVER.',