mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-12 15:35:15 +00:00
Split components for future recycling.
This commit is contained in:
@@ -18,5 +18,7 @@
|
||||
"/public/js/register.js": "/public/js/register.js",
|
||||
"/public/js/register.js.map": "/public/js/register.js.map",
|
||||
"/public/js/transactions/create.js": "/public/js/transactions/create.js",
|
||||
"/public/js/transactions/create.js.map": "/public/js/transactions/create.js.map"
|
||||
"/public/js/transactions/create.js.map": "/public/js/transactions/create.js.map",
|
||||
"/public/js/transactions/edit.js": "/public/js/transactions/edit.js",
|
||||
"/public/js/transactions/edit.js.map": "/public/js/transactions/edit.js.map"
|
||||
}
|
||||
|
37
frontend/src/components/partials/Alert.vue
Normal file
37
frontend/src/components/partials/Alert.vue
Normal file
@@ -0,0 +1,37 @@
|
||||
<!--
|
||||
- Alert.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="'alert alert-' + type + ' alert-dismissible'" v-if="message.length > 0">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h5>
|
||||
<i v-if="'danger' === type" class="icon fas fa-ban"></i>
|
||||
<i v-if="'success' === type" class="icon fas fa-thumbs-up"></i>
|
||||
<span v-if="'danger' === type">{{ $t("firefly.flash_error") }}</span>
|
||||
<span v-if="'success' === type">{{ $t("firefly.flash_success") }}</span>
|
||||
</h5>
|
||||
<span v-html="message"></span>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "Alert",
|
||||
props: ['message', 'type']
|
||||
}
|
||||
</script>
|
4
frontend/src/components/store/index.js
vendored
4
frontend/src/components/store/index.js
vendored
@@ -21,6 +21,7 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex, {createLogger} from 'vuex'
|
||||
import transactions_create from './modules/transactions/create';
|
||||
import transactions_edit from './modules/transactions/edit';
|
||||
import dashboard_index from './modules/dashboard/index';
|
||||
|
||||
Vue.use(Vuex)
|
||||
@@ -32,7 +33,8 @@ export default new Vuex.Store(
|
||||
transactions: {
|
||||
namespaced: true,
|
||||
modules: {
|
||||
create: transactions_create
|
||||
create: transactions_create,
|
||||
edit: transactions_edit
|
||||
}
|
||||
},
|
||||
dashboard: {
|
||||
|
43
frontend/src/components/store/modules/transactions/edit.js
vendored
Normal file
43
frontend/src/components/store/modules/transactions/edit.js
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* edit.js
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
// initial state
|
||||
const state = () => ({});
|
||||
|
||||
|
||||
// getters
|
||||
const getters = {
|
||||
};
|
||||
|
||||
// actions
|
||||
const actions = {
|
||||
};
|
||||
|
||||
// mutations
|
||||
const mutations = {
|
||||
};
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations
|
||||
}
|
@@ -20,230 +20,21 @@
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="alert alert-danger alert-dismissible" v-if="errorMessage.length > 0">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h5><i class="icon fas fa-ban"></i> {{ $t("firefly.flash_error") }}</h5>
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
|
||||
<div class="alert alert-success alert-dismissible" v-if="successMessage.length > 0">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h5><i class="icon fas fa-thumbs-up"></i> {{ $t("firefly.flash_success") }}</h5>
|
||||
<span v-html="successMessage"></span>
|
||||
</div>
|
||||
|
||||
<div class="row" v-if="transactions.length > 1">
|
||||
<div class="col">
|
||||
<!-- tabs -->
|
||||
<ul class="nav nav-pills ml-auto p-2">
|
||||
<li v-for="(transaction, index) in this.transactions" class="nav-item"><a :class="'nav-link' + (0===index ? ' active' : '')" :href="'#split_' + index"
|
||||
data-toggle="tab">
|
||||
<span v-if="'' !== transaction.description">{{ transaction.description }}</span>
|
||||
<span v-if="'' === transaction.description">Split {{ index + 1 }}</span>
|
||||
</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<alert :message="errorMessage" type="danger"/>
|
||||
<alert :message="successMessage" type="success"/>
|
||||
<SplitPills :transactions="transactions" />
|
||||
<div class="tab-content">
|
||||
<div v-for="(transaction, index) in this.transactions" :class="'tab-pane' + (0===index ? ' active' : '')" :id="'split_' + index">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">
|
||||
{{ $t('firefly.basic_journal_information') }}
|
||||
<span v-if="transactions.length > 1">({{ index + 1 }} / {{ transactions.length }}) </span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- start of body -->
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<TransactionDescription
|
||||
v-model="transaction.description"
|
||||
:index="index"
|
||||
:errors="transaction.errors.description"
|
||||
></TransactionDescription>
|
||||
</div>
|
||||
</div>
|
||||
<!-- source and destination -->
|
||||
<div class="row">
|
||||
<div class="col-xl-5 col-lg-5 col-md-10 col-sm-12 col-xs-12">
|
||||
<!-- SOURCE -->
|
||||
<TransactionAccount
|
||||
v-model="transaction.source_account"
|
||||
direction="source"
|
||||
:index="index"
|
||||
:errors="transaction.errors.source"
|
||||
/>
|
||||
</div>
|
||||
<!-- switcharoo! -->
|
||||
<div class="col-xl-2 col-lg-2 col-md-2 col-sm-12 text-center d-none d-sm-block">
|
||||
<SwitchAccount v-if="0 === index"
|
||||
:index="index"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- destination -->
|
||||
<div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-xs-12">
|
||||
<!-- DESTINATION -->
|
||||
<TransactionAccount
|
||||
v-model="transaction.destination_account"
|
||||
direction="destination"
|
||||
:index="index"
|
||||
:errors="transaction.errors.destination"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- amount -->
|
||||
<div class="row">
|
||||
<div class="col-xl-5 col-lg-5 col-md-10 col-sm-12 col-xs-12">
|
||||
<!-- AMOUNT -->
|
||||
<TransactionAmount :index="index" :errors="transaction.errors.amount"/>
|
||||
<!--
|
||||
|
||||
-->
|
||||
</div>
|
||||
<div class="col-xl-2 col-lg-2 col-md-2 col-sm-12 text-center d-none d-sm-block">
|
||||
<TransactionForeignCurrency :index="index"/>
|
||||
</div>
|
||||
<div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-xs-12">
|
||||
<TransactionForeignAmount :index="index" :errors="transaction.errors.foreign_amount"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- dates -->
|
||||
<div class="row">
|
||||
<div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-xs-12">
|
||||
<TransactionDate
|
||||
:index="index"
|
||||
:errors="transaction.errors.date"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-xs-12 offset-xl-2 offset-lg-2">
|
||||
<TransactionCustomDates :index="index" :enabled-dates="customDateFields" :errors="transaction.errors.custom_dates"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- end of body -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end of basic card -->
|
||||
|
||||
<!-- card for meta -->
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">
|
||||
{{ $t('firefly.transaction_journal_meta') }}
|
||||
<span v-if="transactions.length > 1">({{ index + 1 }} / {{ transactions.length }}) </span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- start of body -->
|
||||
<!-- meta -->
|
||||
<div class="row">
|
||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
<TransactionBudget
|
||||
v-model="transaction.budget_id"
|
||||
:index="index"
|
||||
:errors="transaction.errors.budget"
|
||||
v-if="!('Transfer' === transactionType || 'Deposit' === transactionType)"
|
||||
/>
|
||||
<TransactionCategory
|
||||
v-model="transaction.category"
|
||||
:index="index"
|
||||
:errors="transaction.errors.category"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
<TransactionBill
|
||||
v-model="transaction.bill_id"
|
||||
:index="index"
|
||||
:errors="transaction.errors.bill"
|
||||
v-if="!('Transfer' === transactionType || 'Deposit' === transactionType)"
|
||||
/>
|
||||
<TransactionTags
|
||||
:index="index"
|
||||
v-model="transaction.tags"
|
||||
:errors="transaction.errors.tags"
|
||||
/>
|
||||
<TransactionPiggyBank
|
||||
:index="index"
|
||||
v-model="transaction.piggy_bank_id"
|
||||
:errors="transaction.errors.piggy_bank"
|
||||
v-if="!('Withdrawal' === transactionType || 'Deposit' === transactionType)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end card for meta -->
|
||||
<!-- card for extra -->
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">
|
||||
{{ $t('firefly.transaction_journal_meta') }}
|
||||
<span v-if="transactions.length > 1">({{ index + 1 }} / {{ transactions.length }}) </span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- start of body -->
|
||||
<div class="row">
|
||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
|
||||
<TransactionInternalReference
|
||||
:index="index"
|
||||
v-model="transaction.internal_reference"
|
||||
:errors="transaction.errors.internal_reference"
|
||||
/>
|
||||
|
||||
<TransactionExternalUrl
|
||||
:index="index"
|
||||
v-model="transaction.external_url"
|
||||
:errors="transaction.errors.external_url"
|
||||
/>
|
||||
<TransactionNotes
|
||||
:index="index"
|
||||
v-model="transaction.notes"
|
||||
:errors="transaction.errors.notes"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
|
||||
<TransactionAttachments
|
||||
:index="index"
|
||||
ref="attachments"
|
||||
:transaction_journal_id="transaction.transaction_journal_id"
|
||||
:submitted_transaction="submittedTransaction"
|
||||
v-model="transaction.attachments"
|
||||
v-on:uploaded-attachments="uploadedAttachment($event)"
|
||||
/>
|
||||
|
||||
<TransactionLinks :index="index"
|
||||
v-model="transaction.links"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- end of body -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end card for extra -->
|
||||
<!-- end of card -->
|
||||
</div>
|
||||
<SplitForm
|
||||
v-for="(transaction, index) in this.transactions"
|
||||
v-bind:key="index"
|
||||
:transaction="transaction"
|
||||
:index="index"
|
||||
:count="transactions.length"
|
||||
:submitted-transaction="submittedTransaction"
|
||||
v-on:uploaded-attachments="uploadedAttachment($event)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<!-- group title -->
|
||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
@@ -258,6 +49,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
<!-- buttons -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
@@ -306,45 +98,20 @@
|
||||
|
||||
<script>
|
||||
import {createNamespacedHelpers} from 'vuex'
|
||||
|
||||
import TransactionDescription from "./TransactionDescription";
|
||||
import TransactionDate from "./TransactionDate";
|
||||
import TransactionBudget from "./TransactionBudget";
|
||||
import TransactionAccount from "./TransactionAccount";
|
||||
import SwitchAccount from "./SwitchAccount";
|
||||
import TransactionAmount from "./TransactionAmount";
|
||||
import TransactionForeignAmount from "./TransactionForeignAmount";
|
||||
import TransactionForeignCurrency from "./TransactionForeignCurrency";
|
||||
import TransactionCustomDates from "./TransactionCustomDates";
|
||||
import TransactionCategory from "./TransactionCategory";
|
||||
import TransactionBill from "./TransactionBill";
|
||||
import TransactionTags from "./TransactionTags";
|
||||
import TransactionPiggyBank from "./TransactionPiggyBank";
|
||||
import TransactionInternalReference from "./TransactionInternalReference";
|
||||
import TransactionExternalUrl from "./TransactionExternalUrl";
|
||||
import TransactionNotes from "./TransactionNotes";
|
||||
import TransactionLinks from "./TransactionLinks";
|
||||
import TransactionAttachments from "./TransactionAttachments";
|
||||
import Alert from '../partials/Alert';
|
||||
import SplitPills from "./SplitPills";
|
||||
import TransactionGroupTitle from "./TransactionGroupTitle";
|
||||
import SplitForm from "./SplitForm";
|
||||
|
||||
const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers('transactions/create')
|
||||
|
||||
export default {
|
||||
name: "Create",
|
||||
components: {
|
||||
TransactionAttachments,
|
||||
TransactionNotes,
|
||||
TransactionExternalUrl,
|
||||
SplitForm,
|
||||
Alert,
|
||||
SplitPills,
|
||||
TransactionGroupTitle,
|
||||
TransactionInternalReference,
|
||||
TransactionPiggyBank,
|
||||
TransactionTags,
|
||||
TransactionLinks,
|
||||
TransactionBill,
|
||||
TransactionCategory,
|
||||
TransactionCustomDates,
|
||||
TransactionForeignCurrency,
|
||||
TransactionForeignAmount, TransactionAmount, SwitchAccount, TransactionAccount, TransactionBudget, TransactionDescription, TransactionDate
|
||||
},
|
||||
created() {
|
||||
this.storeAllowedOpposingTypes();
|
||||
@@ -386,8 +153,8 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'transactionType', // -> this.someGetter
|
||||
'transactions', // -> this.someOtherGetter
|
||||
'transactionType',
|
||||
'transactions',
|
||||
'customDateFields',
|
||||
'date',
|
||||
'groupTitle'
|
||||
@@ -465,12 +232,24 @@ export default {
|
||||
* forwarded.
|
||||
*/
|
||||
finalizeSubmit() {
|
||||
// console.log('finalizeSubmit (' + this.submittedTransaction + ', ' + this.submittedAttachments + ', ' + this.submittedLinks + ')');
|
||||
console.log('finalizeSubmit (' + this.submittedTransaction + ', ' + this.submittedAttachments + ', ' + this.submittedLinks + ')');
|
||||
if (this.submittedTransaction && this.submittedAttachments && this.submittedLinks) {
|
||||
console.log('all true');
|
||||
console.log('createAnother = ' + this.createAnother);
|
||||
console.log('inError = ' + this.inError);
|
||||
if (false === this.createAnother && false === this.inError) {
|
||||
console.log('redirect');
|
||||
window.location.href = (window.previousURL ?? '/') + '?transaction_group_id=' + this.returnedGroupId + '&message=created';
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (false === this.inError) {
|
||||
// show message:
|
||||
this.errorMessage = '';
|
||||
this.successMessage = this.$t('firefly.transaction_stored_link', {ID: this.returnedGroupId, title: this.returnedGroupTitle});
|
||||
}
|
||||
|
||||
// enable flags:
|
||||
this.enableSubmit = true;
|
||||
this.submittedTransaction = false;
|
||||
@@ -478,9 +257,6 @@ export default {
|
||||
this.submittedAttachments = false;
|
||||
this.inError = false;
|
||||
|
||||
// show message:
|
||||
this.errorMessage = '';
|
||||
this.successMessage = this.$t('firefly.transaction_stored_link', {ID: this.returnedGroupId, title: this.returnedGroupTitle});
|
||||
|
||||
// reset attachments (always do this)
|
||||
for (let i in this.transactions) {
|
||||
@@ -509,9 +285,9 @@ export default {
|
||||
* need to happen in the right order.
|
||||
*/
|
||||
submitTransaction: function () {
|
||||
console.log('submitTransaction()');
|
||||
// disable the submit button:
|
||||
this.enableSubmit = false;
|
||||
// console.log('enable submit = false');
|
||||
|
||||
// convert the data so its ready to be submitted:
|
||||
const url = './api/v1/transactions';
|
||||
@@ -520,6 +296,7 @@ export default {
|
||||
// POST the transaction.
|
||||
axios.post(url, data)
|
||||
.then(response => {
|
||||
console.log('Response is OK!');
|
||||
// report the transaction is submitted.
|
||||
this.submittedTransaction = true;
|
||||
|
||||
@@ -557,7 +334,7 @@ export default {
|
||||
* The ID is set via the store.
|
||||
*/
|
||||
submitAttachments: function (data, response) {
|
||||
// console.log('submitAttachments');
|
||||
console.log('submitAttachments()');
|
||||
let result = response.data.data.attributes.transactions
|
||||
for (let i in data.transactions) {
|
||||
if (data.transactions.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
||||
@@ -575,7 +352,7 @@ export default {
|
||||
* Once the number of components matches the number of splits we know all attachments have been uploaded.
|
||||
*/
|
||||
uploadedAttachment: function (journalId) {
|
||||
// console.log('Triggered uploadedAttachment(' + journalId + ')');
|
||||
console.log('Triggered uploadedAttachment(' + journalId + ')');
|
||||
let key = 'str' + journalId;
|
||||
this.submittedAttCount[key] = 1;
|
||||
let count = Object.keys(this.submittedAttCount).length;
|
||||
@@ -586,6 +363,7 @@ export default {
|
||||
},
|
||||
|
||||
submitTransactionLinks(data, response) {
|
||||
console.log('submitTransactionLinks()');
|
||||
let promises = [];
|
||||
let result = response.data.data.attributes.transactions;
|
||||
let total = 0;
|
||||
|
43
frontend/src/components/transactions/Edit.vue
Normal file
43
frontend/src/components/transactions/Edit.vue
Normal file
@@ -0,0 +1,43 @@
|
||||
<!--
|
||||
- Edit.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>
|
||||
<alert :message="errorMessage" type="danger"/>
|
||||
<alert :message="successMessage" type="success"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Edit",
|
||||
data() {
|
||||
return {
|
||||
successMessage: '',
|
||||
errorMessage: '',
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
282
frontend/src/components/transactions/SplitForm.vue
Normal file
282
frontend/src/components/transactions/SplitForm.vue
Normal file
@@ -0,0 +1,282 @@
|
||||
<!--
|
||||
- SplitForm.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="'tab-pane' + (0===index ? ' active' : '')" :id="'split_' + index">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">
|
||||
{{ $t('firefly.basic_journal_information') }}
|
||||
<span v-if="count > 1">({{ index + 1 }} / {{ count }}) </span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- start of body -->
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<TransactionDescription
|
||||
v-model="transaction.description"
|
||||
:index="index"
|
||||
:errors="transaction.errors.description"
|
||||
></TransactionDescription>
|
||||
</div>
|
||||
</div>
|
||||
<!-- source and destination -->
|
||||
<div class="row">
|
||||
<div class="col-xl-5 col-lg-5 col-md-10 col-sm-12 col-xs-12">
|
||||
<!-- SOURCE -->
|
||||
<TransactionAccount
|
||||
v-model="transaction.source_account"
|
||||
direction="source"
|
||||
:index="index"
|
||||
:errors="transaction.errors.source"
|
||||
/>
|
||||
</div>
|
||||
<!-- switcharoo! -->
|
||||
<div class="col-xl-2 col-lg-2 col-md-2 col-sm-12 text-center d-none d-sm-block">
|
||||
<SwitchAccount v-if="0 === index"
|
||||
:index="index"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- destination -->
|
||||
<div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-xs-12">
|
||||
<!-- DESTINATION -->
|
||||
<TransactionAccount
|
||||
v-model="transaction.destination_account"
|
||||
direction="destination"
|
||||
:index="index"
|
||||
:errors="transaction.errors.destination"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- amount -->
|
||||
<div class="row">
|
||||
<div class="col-xl-5 col-lg-5 col-md-10 col-sm-12 col-xs-12">
|
||||
<!-- AMOUNT -->
|
||||
<TransactionAmount :index="index" :errors="transaction.errors.amount"/>
|
||||
<!--
|
||||
|
||||
-->
|
||||
</div>
|
||||
<div class="col-xl-2 col-lg-2 col-md-2 col-sm-12 text-center d-none d-sm-block">
|
||||
<TransactionForeignCurrency :index="index"/>
|
||||
</div>
|
||||
<div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-xs-12">
|
||||
<TransactionForeignAmount :index="index" :errors="transaction.errors.foreign_amount"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- dates -->
|
||||
<div class="row">
|
||||
<div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-xs-12">
|
||||
<TransactionDate
|
||||
:index="index"
|
||||
:errors="transaction.errors.date"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-xs-12 offset-xl-2 offset-lg-2">
|
||||
<TransactionCustomDates
|
||||
:index="index"
|
||||
:errors="transaction.errors.custom_dates"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- end of body -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end of basic card -->
|
||||
|
||||
<!-- card for meta -->
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">
|
||||
{{ $t('firefly.transaction_journal_meta') }}
|
||||
<span v-if="count > 1">({{ index + 1 }} / {{ count }}) </span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- start of body -->
|
||||
<!-- meta -->
|
||||
<div class="row">
|
||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
<TransactionBudget
|
||||
v-model="transaction.budget_id"
|
||||
:index="index"
|
||||
:errors="transaction.errors.budget"
|
||||
v-if="!('Transfer' === transactionType || 'Deposit' === transactionType)"
|
||||
/>
|
||||
<TransactionCategory
|
||||
v-model="transaction.category"
|
||||
:index="index"
|
||||
:errors="transaction.errors.category"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
<TransactionBill
|
||||
v-model="transaction.bill_id"
|
||||
:index="index"
|
||||
:errors="transaction.errors.bill"
|
||||
v-if="!('Transfer' === transactionType || 'Deposit' === transactionType)"
|
||||
/>
|
||||
<TransactionTags
|
||||
:index="index"
|
||||
v-model="transaction.tags"
|
||||
:errors="transaction.errors.tags"
|
||||
/>
|
||||
<TransactionPiggyBank
|
||||
:index="index"
|
||||
v-model="transaction.piggy_bank_id"
|
||||
:errors="transaction.errors.piggy_bank"
|
||||
v-if="!('Withdrawal' === transactionType || 'Deposit' === transactionType)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end card for meta -->
|
||||
<!-- card for extra -->
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">
|
||||
{{ $t('firefly.transaction_journal_meta') }}
|
||||
<span v-if="count > 1">({{ index + 1 }} / {{ count }}) </span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- start of body -->
|
||||
<div class="row">
|
||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
|
||||
<TransactionInternalReference
|
||||
:index="index"
|
||||
v-model="transaction.internal_reference"
|
||||
:errors="transaction.errors.internal_reference"
|
||||
/>
|
||||
|
||||
<TransactionExternalUrl
|
||||
:index="index"
|
||||
v-model="transaction.external_url"
|
||||
:errors="transaction.errors.external_url"
|
||||
/>
|
||||
<TransactionNotes
|
||||
:index="index"
|
||||
v-model="transaction.notes"
|
||||
:errors="transaction.errors.notes"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
|
||||
<TransactionAttachments
|
||||
:index="index"
|
||||
ref="attachments"
|
||||
v-on="$listeners"
|
||||
:transaction_journal_id="transaction.transaction_journal_id"
|
||||
:submitted_transaction="submittedTransaction"
|
||||
v-model="transaction.attachments"
|
||||
/>
|
||||
|
||||
<TransactionLinks :index="index" v-model="transaction.links" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- end of body -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end card for extra -->
|
||||
<!-- end of card -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import TransactionDescription from "./TransactionDescription";
|
||||
import TransactionDate from "./TransactionDate";
|
||||
import TransactionBudget from "./TransactionBudget";
|
||||
import TransactionAccount from "./TransactionAccount";
|
||||
import SwitchAccount from "./SwitchAccount";
|
||||
import TransactionAmount from "./TransactionAmount";
|
||||
import TransactionForeignAmount from "./TransactionForeignAmount";
|
||||
import TransactionForeignCurrency from "./TransactionForeignCurrency";
|
||||
import TransactionCustomDates from "./TransactionCustomDates";
|
||||
import TransactionCategory from "./TransactionCategory";
|
||||
import TransactionBill from "./TransactionBill";
|
||||
import TransactionTags from "./TransactionTags";
|
||||
import TransactionPiggyBank from "./TransactionPiggyBank";
|
||||
import TransactionInternalReference from "./TransactionInternalReference";
|
||||
import TransactionExternalUrl from "./TransactionExternalUrl";
|
||||
import TransactionNotes from "./TransactionNotes";
|
||||
import TransactionLinks from "./TransactionLinks";
|
||||
import TransactionAttachments from "./TransactionAttachments";
|
||||
import SplitPills from "./SplitPills";
|
||||
import {createNamespacedHelpers} from "vuex";
|
||||
|
||||
const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers('transactions/create')
|
||||
|
||||
export default {
|
||||
name: "SplitForm",
|
||||
props: [
|
||||
'transaction',
|
||||
'split',
|
||||
'count',
|
||||
'index',
|
||||
'submittedTransaction' // need to know if transaction is submitted.
|
||||
],
|
||||
computed: {
|
||||
...mapGetters(['transactionType',])
|
||||
},
|
||||
components: {
|
||||
SplitPills,
|
||||
TransactionAttachments,
|
||||
TransactionNotes,
|
||||
TransactionExternalUrl,
|
||||
TransactionInternalReference,
|
||||
TransactionPiggyBank,
|
||||
TransactionTags,
|
||||
TransactionLinks,
|
||||
TransactionBill,
|
||||
TransactionCategory,
|
||||
TransactionCustomDates,
|
||||
TransactionForeignCurrency,
|
||||
TransactionForeignAmount,
|
||||
TransactionAmount,
|
||||
SwitchAccount,
|
||||
TransactionAccount,
|
||||
TransactionBudget,
|
||||
TransactionDescription,
|
||||
TransactionDate
|
||||
},
|
||||
}
|
||||
</script>
|
41
frontend/src/components/transactions/SplitPills.vue
Normal file
41
frontend/src/components/transactions/SplitPills.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<!--
|
||||
- SplitPills.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" v-if="transactions.length > 1">
|
||||
<div class="col">
|
||||
<!-- tabs -->
|
||||
<ul class="nav nav-pills ml-auto p-2">
|
||||
<li v-for="(transaction, index) in this.transactions" class="nav-item"><a :class="'nav-link' + (0===index ? ' active' : '')" :href="'#split_' + index"
|
||||
data-toggle="tab">
|
||||
<span v-if="'' !== transaction.description">{{ transaction.description }}</span>
|
||||
<span v-if="'' === transaction.description">Split {{ index + 1 }}</span>
|
||||
</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "SplitPills",
|
||||
props: ['transactions']
|
||||
}
|
||||
</script>
|
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
<vue-typeahead-bootstrap
|
||||
v-if="visible"
|
||||
v-model="value.name"
|
||||
v-model="accountName"
|
||||
:data="accounts"
|
||||
:showOnFocus=true
|
||||
:inputClass="errors.length > 0 ? 'is-invalid' : ''"
|
||||
@@ -73,7 +73,9 @@ export default {
|
||||
accounts: [],
|
||||
accountTypes: [],
|
||||
initialSet: [],
|
||||
selectedAccount: {}
|
||||
selectedAccount: {},
|
||||
account: this.value,
|
||||
accountName: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -97,7 +99,8 @@ export default {
|
||||
},
|
||||
clearAccount: function () {
|
||||
this.accounts = this.initialSet;
|
||||
this.value = {name: ''};
|
||||
this.account = {name: ''};
|
||||
this.accountName = '';
|
||||
},
|
||||
lookupAccount: debounce(function () {
|
||||
if (0 === this.accountTypes.length) {
|
||||
@@ -106,11 +109,12 @@ export default {
|
||||
}
|
||||
|
||||
// update autocomplete URL:
|
||||
axios.get(this.getACURL(this.accountTypes, this.value.name))
|
||||
axios.get(this.getACURL(this.accountTypes, this.account.name))
|
||||
.then(response => {
|
||||
this.accounts = response.data;
|
||||
})
|
||||
}, 300),
|
||||
|
||||
createInitialSet: function () {
|
||||
let types = this.sourceAllowedTypes;
|
||||
if ('destination' === this.direction) {
|
||||
@@ -119,7 +123,6 @@ export default {
|
||||
|
||||
axios.get(this.getACURL(types, ''))
|
||||
.then(response => {
|
||||
// console.log('initial set of accounts. ' + this.direction);
|
||||
this.accounts = response.data;
|
||||
this.initialSet = response.data;
|
||||
});
|
||||
@@ -127,10 +130,10 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
selectedAccount: function (value) {
|
||||
this.value = value;
|
||||
this.value.name = this.value.name_with_balance;
|
||||
this.accountName = this.account.name_with_balance;
|
||||
this.account = value;
|
||||
},
|
||||
value: function (value) {
|
||||
account: function (value) {
|
||||
this.updateField({field: this.accountKey, index: this.index, value: value});
|
||||
// set the opposing account allowed set.
|
||||
let opposingAccounts = [];
|
||||
@@ -150,60 +153,10 @@ export default {
|
||||
|
||||
this.calcTransactionType();
|
||||
},
|
||||
// account: function (value) {
|
||||
// //this.value.name = value;
|
||||
// //console.log('watch account in direction ' + this.direction + ' change to "' + value + '"');
|
||||
// // this.account = value ? value.name_with_balance : null;
|
||||
// // // console.log('this.account (' + this.direction + ') = "' + this.account + '"');
|
||||
// //
|
||||
// //
|
||||
// // // set the opposing account allowed set.
|
||||
// // // console.log('opposing:');
|
||||
// // let opposingAccounts = [];
|
||||
// // let type = value.type ? value.type : 'no_type';
|
||||
// // if ('undefined' !== typeof this.allowedOpposingTypes[this.direction]) {
|
||||
// // if ('undefined' !== typeof this.allowedOpposingTypes[this.direction][type]) {
|
||||
// // opposingAccounts = this.allowedOpposingTypes[this.direction][type];
|
||||
// // }
|
||||
// // }
|
||||
// //
|
||||
// // if ('source' === this.direction) {
|
||||
// // this.setDestinationAllowedTypes(opposingAccounts);
|
||||
// // }
|
||||
// // if ('destination' === this.direction) {
|
||||
// // this.setSourceAllowedTypes(opposingAccounts);
|
||||
// // }
|
||||
//
|
||||
//
|
||||
// //
|
||||
// // this.calcTransactionType();
|
||||
//
|
||||
//
|
||||
// }
|
||||
|
||||
// selectedAccount: function (value) {
|
||||
|
||||
// },
|
||||
// sourceAllowedTypes: function (value) {
|
||||
// if ('source' === this.direction) {
|
||||
// // console.log('do update initial set in direction ' + this.direction + ' because allowed types changed');
|
||||
// // update initial set:
|
||||
// this.createInitialSet();
|
||||
// }
|
||||
// },
|
||||
// destinationAllowedTypes: function (value) {
|
||||
// if ('destination' === this.direction) {
|
||||
// // console.log('do update initial set in direction ' + this.direction + ' because allowed types changed');
|
||||
// // update initial set:
|
||||
// this.createInitialSet();
|
||||
// }
|
||||
// }
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'transactionType',
|
||||
'transactions',
|
||||
'defaultTransaction',
|
||||
'sourceAllowedTypes',
|
||||
'destinationAllowedTypes',
|
||||
'allowedOpposingTypes'
|
||||
@@ -228,20 +181,6 @@ export default {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// selectedAccount: {
|
||||
// get() {
|
||||
// return this.transactions[this.index][this.accountKey];
|
||||
// },
|
||||
// set(value) {
|
||||
// // console.log('set selectedAccount for ' + this.direction);
|
||||
// // console.log(value);
|
||||
// this.updateField({field: this.accountKey, index: this.index, value: value});
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@@ -41,7 +41,7 @@ export default {
|
||||
props: ['transaction_journal_id'],
|
||||
watch: {
|
||||
transaction_journal_id: function (value) {
|
||||
// console.log('transaction_journal_id changed to ' + value);
|
||||
console.log('transaction_journal_id changed to ' + value);
|
||||
// do upload!
|
||||
if (0 !== value) {
|
||||
this.doUpload();
|
||||
@@ -50,7 +50,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
doUpload: function () {
|
||||
// console.log('Now in doUpload() for ' + this.$refs.att.files.length + ' files.');
|
||||
console.log('Now in doUpload() for ' + this.$refs.att.files.length + ' files.');
|
||||
for (let i in this.$refs.att.files) {
|
||||
if (this.$refs.att.files.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
||||
let current = this.$refs.att.files[i];
|
||||
@@ -73,7 +73,7 @@ export default {
|
||||
.post(uploadUri, new Blob([evt.target.result]))
|
||||
.then(attachmentResponse => {
|
||||
// TODO feedback etc.
|
||||
// console.log('Uploaded a file.');
|
||||
console.log('Uploaded a file. Emit event!');
|
||||
// console.log(attachmentResponse);
|
||||
theParent.$emit('uploaded-attachments', this.transaction_journal_id);
|
||||
});
|
||||
@@ -84,7 +84,7 @@ export default {
|
||||
}
|
||||
}
|
||||
if (0 === this.$refs.att.files.length) {
|
||||
// console.log('No files to upload.');
|
||||
console.log('No files to upload. Emit event!');
|
||||
this.$emit('uploaded-attachments', this.transaction_journal_id);
|
||||
}
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@
|
||||
<select
|
||||
ref="bill"
|
||||
:title="$t('firefly.bill')"
|
||||
v-model="value"
|
||||
v-model="bill"
|
||||
autocomplete="off"
|
||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
||||
name="bill_id[]"
|
||||
@@ -54,7 +54,8 @@ export default {
|
||||
name: "TransactionBill",
|
||||
data() {
|
||||
return {
|
||||
billList: []
|
||||
billList: [],
|
||||
bill: this.value
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -97,7 +98,7 @@ export default {
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
value: function (value) {
|
||||
bill: function (value) {
|
||||
this.updateField({field: 'bill_id', index: this.index, value: value});
|
||||
}
|
||||
},
|
||||
|
@@ -27,7 +27,7 @@
|
||||
<select
|
||||
ref="budget"
|
||||
:title="$t('firefly.budget')"
|
||||
v-model="value"
|
||||
v-model="budget"
|
||||
autocomplete="off"
|
||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
||||
name="budget_id[]"
|
||||
@@ -53,7 +53,8 @@ export default {
|
||||
name: "TransactionBudget",
|
||||
data() {
|
||||
return {
|
||||
budgetList: []
|
||||
budgetList: [],
|
||||
budget: this.value
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -96,7 +97,7 @@ export default {
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
value: function (value) {
|
||||
budget: function (value) {
|
||||
this.updateField({field: 'budget_id', index: this.index, value: value});
|
||||
}
|
||||
},
|
||||
|
@@ -26,7 +26,7 @@
|
||||
|
||||
<vue-typeahead-bootstrap
|
||||
inputName="category[]"
|
||||
v-model="value"
|
||||
v-model="category"
|
||||
:data="categories"
|
||||
:placeholder="$t('firefly.category')"
|
||||
:showOnFocus=true
|
||||
@@ -63,7 +63,8 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
categories: [],
|
||||
initialSet: []
|
||||
initialSet: [],
|
||||
category: this.value
|
||||
}
|
||||
},
|
||||
|
||||
@@ -84,7 +85,7 @@ export default {
|
||||
],
|
||||
),
|
||||
clearCategory: function () {
|
||||
this.value = null;
|
||||
this.category = null;
|
||||
},
|
||||
getACURL: function (query) {
|
||||
// update autocomplete URL:
|
||||
@@ -99,7 +100,7 @@ export default {
|
||||
}, 300)
|
||||
},
|
||||
watch: {
|
||||
value: function (value) {
|
||||
category: function (value) {
|
||||
this.updateField({field: 'category', index: this.index, value: value});
|
||||
}
|
||||
},
|
||||
@@ -115,7 +116,7 @@ export default {
|
||||
return this.categories[this.index].name;
|
||||
},
|
||||
set(value) {
|
||||
this.value = value.name;
|
||||
this.category = value.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -49,28 +49,47 @@ import {createNamespacedHelpers} from "vuex";
|
||||
const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers('transactions/create')
|
||||
export default {
|
||||
name: "TransactionCustomDates",
|
||||
props: ['enabledDates', 'index', 'errors'],
|
||||
props: ['index', 'errors'],
|
||||
data() {
|
||||
return {
|
||||
enabledDates: {},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getCustomDates();
|
||||
},
|
||||
methods: {
|
||||
...mapGetters(
|
||||
[
|
||||
'transactions'
|
||||
]
|
||||
),
|
||||
...mapMutations(
|
||||
[
|
||||
'updateField',
|
||||
],
|
||||
...mapGetters(['transactions']),
|
||||
...mapMutations(['updateField',],
|
||||
),
|
||||
getFieldValue(field) {
|
||||
return this.transactions()[parseInt(this.index)][field] ?? '';
|
||||
},
|
||||
setFieldValue(event, field) {
|
||||
this.updateField({index: this.index, field: field, value: event.target.value});
|
||||
}
|
||||
},
|
||||
getCustomDates: function () {
|
||||
axios.get('./api/v1/preferences/transaction_journal_optional_fields').then(response => {
|
||||
let fields = response.data.data.attributes.data;
|
||||
let allDateFields = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date'];
|
||||
let selectedDateFields = {
|
||||
interest_date: false,
|
||||
book_date: false,
|
||||
process_date: false,
|
||||
due_date: false,
|
||||
payment_date: false,
|
||||
invoice_date: false,
|
||||
};
|
||||
for (let key in fields) {
|
||||
if (fields.hasOwnProperty(key)) {
|
||||
if (-1 !== allDateFields.indexOf(key)) {
|
||||
selectedDateFields[key] = fields[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
this.enabledDates = selectedDateFields;
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@@ -22,7 +22,7 @@
|
||||
<div class="form-group">
|
||||
<vue-typeahead-bootstrap
|
||||
inputName="description[]"
|
||||
v-model="value"
|
||||
v-model="description"
|
||||
:data="descriptions"
|
||||
:placeholder="$t('firefly.description')"
|
||||
:showOnFocus=true
|
||||
@@ -59,7 +59,8 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
descriptions: [],
|
||||
initialSet: []
|
||||
initialSet: [],
|
||||
description: this.value
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -77,7 +78,7 @@ export default {
|
||||
],
|
||||
),
|
||||
clearDescription: function () {
|
||||
this.value = '';
|
||||
this.description = '';
|
||||
},
|
||||
getACURL: function (query) {
|
||||
// update autocomplete URL:
|
||||
@@ -92,7 +93,7 @@ export default {
|
||||
}, 300)
|
||||
},
|
||||
watch: {
|
||||
value: function (value) {
|
||||
description: function (value) {
|
||||
this.updateField({field: 'description', index: this.index, value: value});
|
||||
}
|
||||
},
|
||||
|
@@ -28,7 +28,7 @@
|
||||
type="url"
|
||||
name="external_url[]"
|
||||
:placeholder="$t('firefly.external_url')"
|
||||
v-model="value"
|
||||
v-model="url"
|
||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
||||
/>
|
||||
<div class="input-group-append">
|
||||
@@ -46,6 +46,11 @@ const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers
|
||||
export default {
|
||||
props: ['index', 'value', 'errors'],
|
||||
name: "TransactionExternalUrl",
|
||||
data() {
|
||||
return {
|
||||
url: this.value
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(
|
||||
[
|
||||
@@ -54,7 +59,7 @@ export default {
|
||||
),
|
||||
},
|
||||
watch: {
|
||||
value: function (value) {
|
||||
url: function (value) {
|
||||
this.updateField({field: 'external_url', index: this.index, value: value});
|
||||
}
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@
|
||||
</div>
|
||||
<vue-typeahead-bootstrap
|
||||
inputName="group_title"
|
||||
v-model="value"
|
||||
v-model="title"
|
||||
:data="descriptions"
|
||||
:placeholder="$t('firefly.split_transaction_title')"
|
||||
:showOnFocus=true
|
||||
@@ -61,7 +61,8 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
descriptions: [],
|
||||
initialSet: []
|
||||
initialSet: [],
|
||||
title: this.value
|
||||
}
|
||||
},
|
||||
|
||||
@@ -73,7 +74,7 @@ export default {
|
||||
});
|
||||
},
|
||||
watch: {
|
||||
value: function (value) {
|
||||
title: function (value) {
|
||||
//console.log('set');
|
||||
this.setGroupTitle({groupTitle: value});
|
||||
}
|
||||
@@ -91,7 +92,7 @@ export default {
|
||||
),
|
||||
clearDescription: function () {
|
||||
this.setGroupTitle({groupTitle: ''});
|
||||
this.value = '';
|
||||
this.title = '';
|
||||
},
|
||||
getACURL: function (query) {
|
||||
// update autocomplete URL:
|
||||
@@ -99,7 +100,7 @@ export default {
|
||||
},
|
||||
lookupDescription: debounce(function () {
|
||||
// update autocomplete URL:
|
||||
axios.get(this.getACURL(this.value))
|
||||
axios.get(this.getACURL(this.title))
|
||||
.then(response => {
|
||||
this.descriptions = response.data;
|
||||
})
|
||||
|
@@ -27,7 +27,7 @@
|
||||
<input
|
||||
type="text"
|
||||
name="internal_reference[]"
|
||||
v-model="value"
|
||||
v-model="reference"
|
||||
:placeholder="$t('firefly.internal_reference')"
|
||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
||||
/>
|
||||
@@ -46,6 +46,11 @@ const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers
|
||||
export default {
|
||||
props: ['index', 'value', 'errors'],
|
||||
name: "TransactionInternalReference",
|
||||
data() {
|
||||
return {
|
||||
reference: this.value
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(
|
||||
[
|
||||
@@ -54,13 +59,9 @@ export default {
|
||||
),
|
||||
},
|
||||
watch: {
|
||||
value: function (value) {
|
||||
reference: function (value) {
|
||||
this.updateField({field: 'internal_reference', index: this.index, value: value});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@@ -26,11 +26,11 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<p v-if="value.length === 0">
|
||||
<p v-if="links.length === 0">
|
||||
<button data-toggle="modal" data-target="#linkModal" class="btn btn-default btn-xs"><i class="fas fa-plus"></i> Add transaction link</button>
|
||||
</p>
|
||||
<ul class="list-group" v-if="value.length > 0">
|
||||
<li class="list-group-item" v-for="transaction in value">
|
||||
<ul class="list-group" v-if="links.length > 0">
|
||||
<li class="list-group-item" v-for="transaction in links">
|
||||
<em>{{ getTextForLinkType(transaction.link_type_id) }}</em>
|
||||
<a :href='"./transaction/show/" + transaction.transaction_group_id'>{{ transaction.description }}</a>
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="form-text" v-if="value.length > 0">
|
||||
<div class="form-text" v-if="links.length > 0">
|
||||
<button data-toggle="modal" data-target="#linkModal" class="btn btn-default"><i class="fas fa-plus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -184,6 +184,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {createNamespacedHelpers} from 'vuex'
|
||||
|
||||
const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers('transactions/create')
|
||||
|
||||
const lodashClonedeep = require('lodash.clonedeep');
|
||||
// TODO error handling
|
||||
export default {
|
||||
props: ['index', 'value', 'errors'],
|
||||
@@ -195,27 +200,31 @@ export default {
|
||||
locale: 'en-US',
|
||||
linkTypes: [],
|
||||
query: '',
|
||||
searching: false
|
||||
searching: false,
|
||||
links: [],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.locale = localStorage.locale ?? 'en-US';
|
||||
this.links = lodashClonedeep(this.value);
|
||||
this.getLinkTypes();
|
||||
},
|
||||
watch: {
|
||||
value: function (value) {
|
||||
//console.log('Selected transactions is now:');
|
||||
//console.log(value);
|
||||
links: function (value) {
|
||||
this.updateField({index: this.index, field: 'links', value: lodashClonedeep(value)});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(
|
||||
[
|
||||
'updateField',
|
||||
],
|
||||
),
|
||||
getTextForLinkType: function (linkTypeId) {
|
||||
let parts = linkTypeId.split('-');
|
||||
for (let i in this.linkTypes) {
|
||||
if (this.linkTypes.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
||||
let current = this.linkTypes[i];
|
||||
//console.log(parts);
|
||||
//console.log(current);
|
||||
if (parts[0] === current.id && parts[1] === current.direction) {
|
||||
return current.type;
|
||||
}
|
||||
@@ -246,27 +255,27 @@ export default {
|
||||
}
|
||||
},
|
||||
updateSelected(journalId, linkTypeId) {
|
||||
for (let i in this.value) {
|
||||
if (this.value.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
||||
let current = this.value[i];
|
||||
for (let i in this.links) {
|
||||
if (this.links.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
||||
let current = this.links[i];
|
||||
if (parseInt(current.transaction_journal_id) === journalId) {
|
||||
this.value[i].link_type_id = linkTypeId;
|
||||
this.links[i].link_type_id = linkTypeId;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
addToSelected(journal) {
|
||||
const result = this.value.find(({transaction_journal_id}) => transaction_journal_id === journal.transaction_journal_id);
|
||||
let result = this.links.find(({transaction_journal_id}) => transaction_journal_id === journal.transaction_journal_id);
|
||||
if (typeof result === 'undefined') {
|
||||
this.value.push(journal);
|
||||
this.links.push(journal);
|
||||
}
|
||||
},
|
||||
removeFromSelected(journal) {
|
||||
for (let i in this.value) {
|
||||
if (this.value.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
||||
let current = this.value[i];
|
||||
for (let i in this.links) {
|
||||
if (this.links.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
||||
let current = this.links[i];
|
||||
if (current.transaction_journal_id === journal.transaction_journal_id) {
|
||||
this.value.splice(parseInt(i), 1);
|
||||
this.links.splice(parseInt(i), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -330,9 +339,9 @@ export default {
|
||||
this.searching = false;
|
||||
},
|
||||
getJournalLinkType: function (journalId) {
|
||||
for (let i in this.value) {
|
||||
if (this.value.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
||||
let current = this.value[i];
|
||||
for (let i in this.links) {
|
||||
if (this.links.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
||||
let current = this.links[i];
|
||||
if (current.transaction_journal_id === journalId) {
|
||||
return current.link_type_id;
|
||||
}
|
||||
@@ -341,9 +350,9 @@ export default {
|
||||
return '1-inward';
|
||||
},
|
||||
isJournalSelected: function (journalId) {
|
||||
for (let i in this.value) {
|
||||
if (this.value.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
||||
let current = this.value[i];
|
||||
for (let i in this.links) {
|
||||
if (this.links.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
|
||||
let current = this.links[i];
|
||||
if (current.transaction_journal_id === journalId) {
|
||||
return true;
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<textarea
|
||||
v-model="value"
|
||||
v-model="notes"
|
||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
||||
:placeholder="$t('firefly.notes')"
|
||||
></textarea>
|
||||
@@ -43,6 +43,11 @@ const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers
|
||||
export default {
|
||||
props: ['index', 'value', 'errors'],
|
||||
name: "TransactionNotes",
|
||||
data() {
|
||||
return {
|
||||
notes: this.value
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(
|
||||
[
|
||||
@@ -51,7 +56,7 @@ export default {
|
||||
),
|
||||
},
|
||||
watch: {
|
||||
value: function (value) {
|
||||
notes: function (value) {
|
||||
this.updateField({field: 'notes', index: this.index, value: value});
|
||||
}
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@
|
||||
<select
|
||||
ref="piggy_bank_id"
|
||||
:title="$t('firefly.piggy_bank')"
|
||||
v-model="value"
|
||||
v-model="piggy_bank_id"
|
||||
autocomplete="off"
|
||||
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
|
||||
name="piggy_bank_id[]"
|
||||
@@ -54,7 +54,8 @@ export default {
|
||||
name: "TransactionPiggyBank",
|
||||
data() {
|
||||
return {
|
||||
piggyList: []
|
||||
piggyList: [],
|
||||
piggy_bank_id: this.value
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -97,7 +98,7 @@ export default {
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
value: function (value) {
|
||||
piggy_bank_id: function (value) {
|
||||
this.updateField({field: 'piggy_bank_id', index: this.index, value: value});
|
||||
}
|
||||
},
|
||||
|
@@ -59,14 +59,13 @@ export default {
|
||||
debounce: null,
|
||||
tags: [],
|
||||
currentTag: '',
|
||||
updateTags: true // the idea is that this is always true, except when the tags-function sets the value.
|
||||
updateTags: true, // the idea is that this is always true, except when the tags-function sets the value.
|
||||
tagList: this.value
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
'currentTag': 'initItems',
|
||||
value: function (value) {
|
||||
//console.log('watch: value');
|
||||
//console.log(value);
|
||||
tagList: function (value) {
|
||||
this.updateField({field: 'tags', index: this.index, value: value});
|
||||
this.updateTags = false;
|
||||
this.tags = value;
|
||||
@@ -81,7 +80,7 @@ export default {
|
||||
shortList.push({text: value[key].text});
|
||||
}
|
||||
}
|
||||
this.value = shortList;
|
||||
this.tagList = shortList;
|
||||
}
|
||||
this.updateTags = true;
|
||||
}
|
||||
|
42
frontend/src/pages/transactions/edit.js
vendored
Normal file
42
frontend/src/pages/transactions/edit.js
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* edit.js
|
||||
* Copyright (c) 2020 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 store from "../../components/store";
|
||||
import Edit from "../../components/transactions/Edit";
|
||||
import Vue from "vue";
|
||||
|
||||
require('../../bootstrap');
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
// i18n
|
||||
let i18n = require('../../i18n');
|
||||
|
||||
let props = {};
|
||||
new Vue({
|
||||
i18n,
|
||||
store,
|
||||
render(createElement) {
|
||||
return createElement(Edit, {props: props});
|
||||
},
|
||||
beforeCreate() {
|
||||
this.$store.commit('initialiseStore');
|
||||
this.$store.dispatch('updateCurrencyPreference');
|
||||
},
|
||||
}).$mount('#transactions_edit');
|
1
frontend/webpack.mix.js
vendored
1
frontend/webpack.mix.js
vendored
@@ -62,6 +62,7 @@ mix
|
||||
|
||||
// transactions.
|
||||
.js('src/pages/transactions/create.js', 'public/js/transactions')
|
||||
.js('src/pages/transactions/edit.js', 'public/js/transactions')
|
||||
// register page
|
||||
.js('src/pages/register.js', 'public/js')
|
||||
|
||||
|
Reference in New Issue
Block a user