Rebuild new layout.

This commit is contained in:
James Cole
2021-04-08 11:21:20 +02:00
parent 6160f99e92
commit 56dff7ea67
70 changed files with 2135 additions and 772 deletions

View File

@@ -3,6 +3,7 @@
"/public/js/accounts/index.js": "/public/js/accounts/index.js",
"/public/js/accounts/delete.js": "/public/js/accounts/delete.js",
"/public/js/accounts/show.js": "/public/js/accounts/show.js",
"/public/js/accounts/create.js": "/public/js/accounts/create.js",
"/public/js/transactions/create.js": "/public/js/transactions/create.js",
"/public/js/transactions/edit.js": "/public/js/transactions/edit.js",
"/public/js/transactions/index.js": "/public/js/transactions/index.js",

View File

@@ -17,9 +17,6 @@
* 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/>.
*/
// Firefly III colors (?)
$blue: #1E6581;
$green: #64B624;
$red: #CD5029;

View File

@@ -0,0 +1,95 @@
<!--
- AssetAccountRole.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="form-group">
<div class="text-xs d-none d-lg-block d-xl-block">
{{ $t('form.account_role') }}
</div>
<div class="input-group" v-if="loading">
<i class="fas fa-spinner fa-spin"></i>
</div>
<div class="input-group" v-if="!loading">
<select
ref="account_role"
v-model="account_role"
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
:title="$t('form.account_role')"
autocomplete="off"
name="account_role"
:disabled=disabled
>
<option v-for="role in this.roleList" :label="role.title" :value="role.slug">{{ role.title }}</option>
</select>
</div>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
</span>
</div>
</template>
<script>
export default {
name: "AssetAccountRole",
props: {
value: {},
errors: {},
disabled: {
type: Boolean,
default: false
},
},
data() {
return {
roleList: [],
account_role: this.value,
loading: false
}
},
methods: {
loadRoles: function () {
//
axios.get('./api/v1/configuration/firefly.accountRoles')
.then(response => {
let content = response.data.data.value;
for (let i in content) {
if (content.hasOwnProperty(i)) {
let current = content[i];
this.roleList.push({slug: current, title: this.$t('firefly.account_role_' + current)})
}
}
}
);
}
},
watch: {
account_role: function (value) {
this.$emit('set-field', {field: 'account_role', value: value});
},
},
created() {
this.loadRoles()
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,330 @@
<!--
- Create.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"/>
<form @submit="submitForm">
<div class="row">
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">
{{ $t('firefly.mandatoryFields') }}
</h3>
</div>
<div class="card-body">
<GenericTextInput :disabled="submitting" v-model="name" field-name="name" :errors="errors.name" :title="$t('form.name')"
v-on:set-field="storeField($event)"/>
<Currency :disabled="submitting" v-model="currency_id" :errors="errors.currency" v-on:set-field="storeField($event)"/>
<AssetAccountRole :disabled="submitting" v-if="'asset' === type" v-model="account_role" :errors="errors.account_role"
v-on:set-field="storeField($event)"/>
<LiabilityType :disabled="submitting" v-if="'liabilities' === type" v-model="liability_type" :errors="errors.liability_type"
v-on:set-field="storeField($event)"/>
<LiabilityDirection :disabled="submitting" v-if="'liabilities' === type" v-model="liability_direction" :errors="errors.liability_direction"
v-on:set-field="storeField($event)"/>
<GenericTextInput :disabled="submitting" v-if="'liabilities' === type" field-type="number" field-step="any" v-model="liability_amount"
field-name="liability_amount" :errors="errors.liability_amount" :title="$t('form.amount')" v-on:set-field="storeField($event)"/>
<GenericTextInput :disabled="submitting" v-if="'liabilities' === type" field-type="date" v-model="liability_date" field-name="liability_date"
:errors="errors.liability_date" :title="$t('form.date')" v-on:set-field="storeField($event)"/>
<Interest :disabled="submitting" v-if="'liabilities' === type" v-model="interest" :errors="errors.interest" v-on:set-field="storeField($event)"/>
<InterestPeriod :disabled="submitting" v-if="'liabilities' === type" v-model="interest_period" :errors="errors.interest_period"
v-on:set-field="storeField($event)"/>
</div>
</div>
</div>
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">
{{ $t('firefly.optionalFields') }}
</h3>
</div>
<div class="card-body">
<GenericTextInput :disabled="submitting" v-model="iban" field-name="iban" :errors="errors.iban" :title="$t('form.iban')"
v-on:set-field="storeField($event)"/>
<GenericTextInput :disabled="submitting" v-model="bic" field-name="bic" :errors="errors.bic" :title="$t('form.BIC')"
v-on:set-field="storeField($event)"/>
<GenericTextInput :disabled="submitting" v-model="account_number" field-name="account_number" :errors="errors.account_number"
:title="$t('form.account_number')" v-on:set-field="storeField($event)"/>
<GenericTextInput :disabled="submitting" v-if="'asset' === type" field-type="amount" v-model="virtual_balance" field-name="virtual_balance"
:errors="errors.virtual_balance" :title="$t('form.virtual_balance')" v-on:set-field="storeField($event)"/>
<GenericTextInput :disabled="submitting" v-if="'asset' === type" field-type="amount" v-model="opening_balance" field-name="opening_balance"
:errors="errors.opening_balance" :title="$t('form.opening_balance')" v-on:set-field="storeField($event)"/>
<GenericTextInput :disabled="submitting" v-if="'asset' === type" field-type="date" v-model="opening_balance_date"
field-name="opening_balance_date" :errors="errors.opening_balance_date" :title="$t('form.opening_balance_date')"
v-on:set-field="storeField($event)"/>
<GenericCheckbox :disabled="submitting" v-if="'asset' === type" :title="$t('form.include_net_worth')" field-name="include_net_worth"
v-model="include_net_worth" :errors="errors.include_net_worth" :description="$t('form.include_net_worth')"
v-on:set-field="storeField($event)"/>
<GenericCheckbox :disabled="submitting" :title="$t('form.active')" field-name="active"
v-model="active" :errors="errors.active" :description="$t('form.active')"
v-on:set-field="storeField($event)"/>
<GenericTextarea :disabled="submitting" field-name="notes" :title="$t('form.notes')" v-model="notes" :errors="errors.notes"
v-on:set-field="storeField($event)"/>
<GenericLocation :disabled="submitting" v-model="location" :title="$t('form.location')" :errors="errors.location"
v-on:set-field="storeField($event)"/>
<GenericAttachments :disabled="submitting" :title="$t('form.attachments')" field-name="attachments" :errors="errors.attachments"/>
</div>
</div>
</div>
</div>
</form>
<div class="row">
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12 offset-xl-6 offset-lg-6">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-lg-6 offset-lg-6">
<button :disabled=submitting type="button" @click="submitForm" class="btn btn-success btn-block">{{
$t('firefly.store_new_' + type + '_account')
}}
</button>
<div class="form-check">
<input id="createAnother" v-model="createAnother" class="form-check-input" type="checkbox">
<label class="form-check-label" for="createAnother">
<span class="small">{{ $t('firefly.create_another') }}</span>
</label>
</div>
<div class="form-check">
<input id="resetFormAfter" v-model="resetFormAfter" :disabled="!createAnother" class="form-check-input" type="checkbox">
<label class="form-check-label" for="resetFormAfter">
<span class="small">{{ $t('firefly.reset_after') }}</span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
const lodashClonedeep = require('lodash.clonedeep');
import Currency from "./Currency";
import AssetAccountRole from "./AssetAccountRole"
import LiabilityType from "./LiabilityType";
import LiabilityDirection from "./LiabilityDirection";
import Interest from "./Interest";
import InterestPeriod from "./InterestPeriod";
import GenericTextInput from "../form/GenericTextInput";
import GenericTextarea from "../form/GenericTextarea";
import GenericLocation from "../form/GenericLocation";
import GenericAttachments from "../form/GenericAttachments";
import GenericCheckbox from "../form/GenericCheckbox";
import Alert from '../partials/Alert';
export default {
name: "Create",
components: {
Currency, AssetAccountRole, LiabilityType, LiabilityDirection, Interest, InterestPeriod,
GenericTextInput, GenericTextarea, GenericLocation, GenericAttachments, GenericCheckbox, Alert
},
created() {
this.errors = lodashClonedeep(this.defaultErrors);
let pathName = window.location.pathname;
let parts = pathName.split('/');
this.type = parts[parts.length - 1];
},
data() {
return {
submitting: false,
successMessage: '',
errorMessage: '',
createAnother: false,
resetFormAfter: false,
returnedId: 0,
returnedTitle: '',
// info
name: '',
type: 'any',
currency_id: null,
// liabilities
liability_type: 'Loan',
liability_direction: 'debit',
liability_amount: null,
liability_date: null,
interest: null,
interest_period: 'monthly',
// optional fields
iban: null,
bic: null,
account_number: null,
virtual_balance: null,
opening_balance: null,
opening_balance_date: null,
include_net_worth: true,
active: true,
notes: null,
location: {},
account_role: 'defaultAsset',
errors: {},
defaultErrors: {
name: [],
currency: [],
account_role: [],
liability_type: [],
liability_direction: [],
liability_amount: [],
liability_date: [],
interest: [],
interest_period: [],
iban: [],
bic: [],
account_number: [],
virtual_balance: [],
opening_balance: [],
opening_balance_date: [],
include_net_worth: [],
notes: [],
location: [],
}
}
},
methods: {
storeField: function (payload) {
console.log(payload);
if ('location' === payload.field) {
if (true === payload.value.hasMarker) {
this.location = payload.value;
return;
}
this.location = {};
return;
}
this[payload.field] = payload.value;
},
submitForm: function (e) {
e.preventDefault();
this.submitting = true;
let submission = this.getSubmission();
console.log('Will submit:');
console.log(submission);
let url = './api/v1/accounts';
axios.post(url, submission)
.then(response => {
console.log('success!');
this.returnedId = parseInt(response.data.data.id);
this.returnedTitle = response.data.data.attributes.name;
this.successMessage = this.$t('firefly.stored_new_account_js', {ID: this.returnedId, name: this.returnedTitle});
// stay here is false?
if (false === this.createAnother) {
window.location.href = (window.previousURL ?? '/') + '?account_id=' + this.returnedId + '&message=created';
return;
}
this.submitting = false;
if (this.resetFormAfter) {
console.log('reset!');
this.name = '';
this.liability_type = 'Loan';
this.liability_direction = 'debit';
this.liability_amount = null;
this.liability_date = null;
this.interest = null;
this.interest_period = 'monthly';
this.iban = null;
this.bic = null;
this.account_number = null;
this.virtual_balance = null;
this.opening_balance = null;
this.opening_balance_date = null;
this.include_net_worth = true;
this.active = true;
this.notes = null;
this.location = {};
}
})
.catch(error => {
this.submitting = false;
this.parseErrors(error.response.data);
});
},
parseErrors: function (errors) {
this.errors = lodashClonedeep(this.defaultErrors);
console.log(errors);
for (let i in errors.errors) {
if (errors.errors.hasOwnProperty(i)) {
this.errors[i] = errors.errors[i];
}
}
},
getSubmission: function () {
let submission = {
"name": this.name,
"type": this.type,
"iban": this.iban,
"bic": this.bic,
"account_number": this.account_number,
"currency_id": this.currency_id,
"virtual_balance": this.virtual_balance,
"active": this.active,
"order": 31337,
"include_net_worth": this.include_net_worth,
"account_role": this.account_role,
"notes": this.notes,
};
if ('liabilities' === this.type) {
submission.liability_type = this.liability_type.toLowerCase();
submission.interest = this.interest;
submission.interest_period = this.interest_period;
submission.opening_balance = this.liability_amount;
submission.opening_balance_date = this.liability_date;
}
if (null !== this.opening_balance && null !== this.opening_balance_date && 'asset' === this.type) {
submission.opening_balance = this.opening_balance;
submission.opening_balance_date = this.opening_balance_date;
}
if ('asset' === this.type && 'ccAsset' === this.account_role) {
submission.credit_card_type = 'monthlyFull';
submission.monthly_payment_date = '2021-01-01';
}
if (Object.keys(this.location).length >= 3) {
submission.longitude = this.location.lng;
submission.latitude = this.location.lat;
submission.zoom_level = this.location.zoomLevel;
}
return submission;
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,115 @@
<!--
- Currency.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="form-group">
<div class="text-xs d-none d-lg-block d-xl-block">
{{ $t('form.currency_id') }}
</div>
<div class="input-group" v-if="loading">
<i class="fas fa-spinner fa-spin"></i>
</div>
<div class="input-group" v-if="!loading">
<select
ref="currency_id"
v-model="currency_id"
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
:title="$t('form.currency_id')"
autocomplete="off"
:disabled=disabled
name="currency_id"
>
<option v-for="currency in this.currencyList" :label="currency.name" :value="currency.id">{{ currency.name }}</option>
</select>
</div>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
</span>
</div>
</template>
<script>
export default {
name: "Currency",
props: {
value: {},
errors: {},
disabled: {
type: Boolean,
default: false
},
},
data() {
return {
loading: true,
currency_id: this.value,
currencyList: []
}
},
methods: {
loadCurrencies: function () {
this.loadCurrencyPage(1);
},
loadCurrencyPage: function (page) {
axios.get('./api/v1/currencies?page=' + page)
.then(response => {
let totalPages = parseInt(response.data.meta.pagination.total_pages);
let currentPage = parseInt(response.data.meta.pagination.current_page);
let currencies = response.data.data;
for (let i in currencies) {
if (currencies.hasOwnProperty(i)) {
let current = currencies[i];
if (true === current.attributes.default && (null === this.currency_id || typeof this.currency_id === 'undefined')) {
this.currency_id = parseInt(current.id);
}
if (false === current.attributes.enabled) {
continue;
}
let currency = {
id: parseInt(current.id),
name: current.attributes.name,
};
this.currencyList.push(currency);
}
}
if (currentPage < totalPages) {
this.loadCurrencyPage(currentPage++);
}
if (currentPage >= totalPages) {
this.loading = false;
}
}
);
}
},
watch: {
currency_id: function (value) {
this.$emit('set-field', {field: 'currency_id', value: value});
},
},
created() {
this.loadCurrencies()
}
}
</script>
<style scoped>
</style>

View File

@@ -47,7 +47,7 @@
:sort-desc.sync="sortDesc"
>
<template #cell(title)="data">
<a :href="'./accounts/show/' + data.item.id" :title="data.value">{{ data.value }}</a>
<a :class="false === data.item.active ? 'text-muted' : ''" :href="'./accounts/show/' + data.item.id" :title="data.value">{{ data.value }}</a>
</template>
<template #cell(number)="data">
<span v-if="null !== data.item.iban && null === data.item.account_number">{{ data.item.iban }}</span>

View File

@@ -0,0 +1,73 @@
<!--
- Interest.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="form-group">
<div class="text-xs d-none d-lg-block d-xl-block">
{{ $t('form.interest') }}
</div>
<div class="input-group">
<input
v-model="interest"
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
:placeholder="$t('form.interest')"
name="interest"
:disabled=disabled
type="number"
step="8"
/>
<div class="input-group-append">
<div class="input-group-text">%</div>
<button class="btn btn-outline-secondary" tabindex="-1" type="button"><i class="far fa-trash-alt"></i></button>
</div>
</div>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
</span>
</div>
</template>
<script>
export default {
name: "Interest",
props: {
value: {},
errors: {},
disabled: {
type: Boolean,
default: false
},
},
data() {
return {
interest: this.value
}
},
watch: {
interest: function (value) {
this.$emit('set-field', {field: 'interest', value: value});
},
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,96 @@
<!--
- InterestPeriod.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="form-group">
<div class="text-xs d-none d-lg-block d-xl-block">
{{ $t('form.interest_period') }}
</div>
<div class="input-group" v-if="loading">
<i class="fas fa-spinner fa-spin"></i>
</div>
<div class="input-group" v-if="!loading">
<select
ref="interest_period"
v-model="interest_period"
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
:title="$t('form.interest_period')"
autocomplete="off"
:disabled=disabled
name="interest_period"
>
<option v-for="period in this.periodList" :label="period.title" :value="period.slug">{{ period.title }}</option>
</select>
</div>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
</span>
</div>
</template>
<script>
export default {
name: "InterestPeriod",
props: {
value: {},
errors: {},
disabled: {
type: Boolean,
default: false
},
},
data() {
return {
periodList: [],
interest_period: this.value,
loading: true
}
},
methods: {
loadPeriods: function () {
//
axios.get('./api/v1/configuration/firefly.interest_periods')
.then(response => {
let content = response.data.data.value;
for (let i in content) {
if (content.hasOwnProperty(i)) {
let current = content[i];
this.periodList.push({slug: current, title: this.$t('firefly.interest_calc_' + current)})
}
}
this.loading = false;
}
);
}
},
watch: {
interest_period: function (value) {
this.$emit('set-field', {field: 'interest_period', value: value});
},
},
created() {
this.loadPeriods()
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,71 @@
<!--
- LiabilityAmount.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="form-group">
<div class="text-xs d-none d-lg-block d-xl-block">
{{ $t('form.amount') }}
</div>
<div class="input-group">
<input
v-model="amount"
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
:placeholder="$t('form.amount')"
name="liability_amount"
:disabled=disabled
type="number" step="any" min="0"
/>
<div class="input-group-append">
<button class="btn btn-outline-secondary" tabindex="-1" type="button"><i class="far fa-trash-alt"></i></button>
</div>
</div>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
</span>
</div>
</template>
<script>
export default {
name: "LiabilityAmount",
props: {
value: {},
errors: {},
disabled: {
type: Boolean,
default: false
},
},
data() {
return {
amount: this.value
}
},
watch: {
amount: function (value) {
this.$emit('set-field', {field: 'liability_amount', value: value});
},
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,71 @@
<!--
- LiabilityDate.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="form-group">
<div class="text-xs d-none d-lg-block d-xl-block">
{{ $t('form.date') }}
</div>
<div class="input-group">
<input
v-model="date"
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
:placeholder="$t('form.date')"
name="liability_date"
:disabled=disabled
type="date"
/>
<div class="input-group-append">
<button class="btn btn-outline-secondary" tabindex="-1" type="button"><i class="far fa-trash-alt"></i></button>
</div>
</div>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
</span>
</div>
</template>
<script>
export default {
name: "LiabilityDate",
props: {
value: {},
errors: {},
disabled: {
type: Boolean,
default: false
},
},
data() {
return {
date: this.value
}
},
watch: {
date: function (value) {
this.$emit('set-field', {field: 'liability_date', value: value});
},
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,76 @@
<!--
- LiabilityDirection.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="form-group">
<div class="text-xs d-none d-lg-block d-xl-block">
{{ $t('form.liability_direction') }}
</div>
<div class="input-group">
<select
ref="liability_type"
v-model="liability_direction"
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
:title="$t('form.liability_direction')"
autocomplete="off"
name="liability_direction"
:disabled=disabled
>
<option :label="$t('firefly.liability_direction_credit')" value="credit">{{ $t('firefly.liability_direction_credit') }}</option>
<option :label="$t('firefly.liability_direction_debit')" value="debit">{{ $t('firefly.liability_direction_debit') }}</option>
</select>
</div>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
</span>
</div>
</template>
<script>
export default {
name: "LiabilityDirection",
props: {
value: {},
errors: {},
disabled: {
type: Boolean,
default: false
},
},
data() {
return {
liability_direction: this.value
}
},
methods: {
},
watch: {
liability_direction: function (value) {
this.$emit('set-field', {field: 'liability_direction', value: value});
},
},
created() {
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,96 @@
<!--
- LiabilityType.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="form-group">
<div class="text-xs d-none d-lg-block d-xl-block">
{{ $t('form.liability_type') }}
</div>
<div class="input-group" v-if="loading">
<i class="fas fa-spinner fa-spin"></i>
</div>
<div class="input-group" v-if="!loading">
<select
ref="liability_type"
v-model="liability_type"
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
:title="$t('form.liability_type')"
autocomplete="off"
name="liability_type"
:disabled=disabled
>
<option v-for="type in this.typeList" :label="type.title" :value="type.slug">{{ type.title }}</option>
</select>
</div>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
</span>
</div>
</template>
<script>
export default {
name: "LiabilityType",
props: {
value: {},
errors: {},
disabled: {
type: Boolean,
default: false
},
},
data() {
return {
typeList: [],
liability_type: this.value,
loading: true
}
},
methods: {
loadRoles: function () {
//
axios.get('./api/v1/configuration/firefly.valid_liabilities')
.then(response => {
let content = response.data.data.value;
for (let i in content) {
if (content.hasOwnProperty(i)) {
let current = content[i];
this.typeList.push({slug: current, title: this.$t('firefly.account_type_' + current)})
}
}
this.loading = false;
}
);
}
},
watch: {
liability_type: function (value) {
this.$emit('set-field', {field: 'liability_type', value: value});
},
},
created() {
this.loadRoles()
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,82 @@
<!--
- GenericAttachments.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="form-group">
<div class="text-xs d-none d-lg-block d-xl-block">
{{ title }}
</div>
<div class="input-group">
<input
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
:placeholder="title"
:name="fieldName"
multiple
ref="att"
@change="selectedFile"
type="file"
:disabled=disabled
/>
</div>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
</span>
</div>
</template>
<script>
export default {
name: "GenericAttachments",
props: {
title: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
},
fieldName: {
type: String,
default: ''
},
errors: {
type: Array,
default: function () {
return [];
}
},
},
methods: {
selectedFile: function() {
this.$emit('selected-attachments');
},
},
data() {
return {
localValue: this.value
}
},
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,86 @@
<!--
- GenericTextInput.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="form-group">
<div class="text-xs d-none d-lg-block d-xl-block">
{{ title }}
</div>
<div class="input-group">
<div class="form-check">
<input class="form-check-input" :disabled=disabled type="checkbox" v-model="localValue" :id="fieldName">
<label class="form-check-label" :for="fieldName">
{{ description }}
</label>
</div>
</div>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
</span>
</div>
</template>
<script>
export default {
name: "GenericCheckbox",
props: {
title: {
type: String,
default: ''
},
description: {
type: String,
default: ''
},
value: {
type: Boolean,
default: false
},
fieldName: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
},
errors: {
type: Array,
default: function () {
return [];
}
},
},
data() {
return {
localValue: this.value
}
},
watch: {
localValue: function (value) {
this.$emit('set-field', {field: this.fieldName, value: value});
},
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,190 @@
<!--
- GenericLocation.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="form-group" v-if="enableExternalMap">
<div class="text-xs d-none d-lg-block d-xl-block">
{{ title }}
</div>
<div style="width:100%;height:300px;">
<LMap
ref="myMap"
:center="center"
:zoom="zoom" style="width:100%;height:300px;"
@ready="prepMap"
@update:zoom="zoomUpdated"
@update:center="centerUpdated"
@update:bounds="boundsUpdated"
>
<l-tile-layer :url="url"></l-tile-layer>
<l-marker :lat-lng="marker" :visible="hasMarker"></l-marker>
</LMap>
<span>
<button class="btn btn-default btn-xs" @click="clearLocation">{{ $t('firefly.clear_location') }}</button>
</span>
</div>
<p>&nbsp;</p>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
</span>
</div>
</template>
<script>
// If you need to reference 'L', such as in 'L.icon', then be sure to
// explicitly import 'leaflet' into your component
// import L from 'leaflet';
// OLD
// import {LMap, LMarker, LTileLayer} from 'vue2-leaflet';
// import 'leaflet/dist/leaflet.css';
//
// import L from 'leaflet';
//
// delete L.Icon.Default.prototype._getIconUrl;
//
// L.Icon.Default.mergeOptions({
// iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
// iconUrl: require('leaflet/dist/images/marker-icon.png'),
// shadowUrl: require('leaflet/dist/images/marker-shadow.png')
// });
import {LMap, LMarker, LTileLayer} from 'vue2-leaflet';
import 'leaflet/dist/leaflet.css';
export default {
name: "GenericLocation",
components: {LMap, LTileLayer, LMarker,},
props: {
title: {},
disabled: {
type: Boolean,
default: false
},
value: {
type: Object,
required: true,
default: function () {
return {
// some defaults here.
};
}
},
errors: {},
customFields: {},
},
data() {
return {
availableFields: this.customFields,
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
zoom: 3,
center: [0, 0],
bounds: null,
map: null,
enableExternalMap: false,
hasMarker: false,
marker: [0, 0],
}
},
created() {
// enable_external_map
this.verifyMapEnabled();
},
methods: {
verifyMapEnabled: function () {
axios.get('./api/v1/configuration/firefly.enable_external_map').then(response => {
this.enableExternalMap = response.data.data.value;
if (true === this.enableExternalMap) {
this.loadMap();
}
});
},
loadMap: function () {
if (null === this.value || typeof this.value === 'undefined' || 0 === Object.keys(this.value).length) {
axios.get('./api/v1/configuration/firefly.default_location').then(response => {
this.zoom = parseInt(response.data.data.value.zoom_level);
this.center =
[
parseFloat(response.data.data.value.latitude),
parseFloat(response.data.data.value.longitude),
]
;
});
return;
}
if (null !== this.value.zoom_level && null !== this.value.latitude && null !== this.value.longitude) {
this.zoom = this.value.zoom_level;
this.center = [
parseFloat(this.value.latitude),
parseFloat(this.value.longitude),
];
this.hasMarker = true;
}
},
prepMap: function () {
this.map = this.$refs.myMap.mapObject;
this.map.on('contextmenu', this.setObjectLocation);
this.map.on('zoomend', this.saveZoomLevel);
},
setObjectLocation: function (event) {
this.marker = [event.latlng.lat, event.latlng.lng];
this.hasMarker = true;
this.emitEvent();
},
saveZoomLevel: function () {
this.emitEvent();
},
clearLocation: function (e) {
e.preventDefault();
this.hasMarker = false;
this.emitEvent();
},
emitEvent() {
this.$emit('set-field', {
field: "location",
value: {
zoomLevel: this.zoom,
lat: this.marker[0],
lng: this.marker[1],
hasMarker: this.hasMarker
}
}
);
},
zoomUpdated(zoom) {
this.zoom = zoom;
},
centerUpdated(center) {
this.center = center;
},
boundsUpdated(bounds) {
this.bounds = bounds;
}
},
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,99 @@
<!--
- GenericTextInput.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="form-group">
<div class="text-xs d-none d-lg-block d-xl-block">
{{ title }}
</div>
<div class="input-group">
<input
v-model="localValue"
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
:placeholder="title"
:name="fieldName"
:type="fieldType"
:disabled=disabled
:step="fieldStep"
/>
<div class="input-group-append">
<button class="btn btn-outline-secondary" tabindex="-1" type="button"><i class="far fa-trash-alt"></i></button>
</div>
</div>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
</span>
</div>
</template>
<script>
export default {
name: "GenericTextInput",
props: {
title: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
},
value: {
type: String,
default: ''
},
fieldName: {
type: String,
default: ''
},
fieldType: {
type: String,
default: 'text'
},
fieldStep: {
type: String,
default: ''
},
errors: {
type: Array,
default: function () {
return [];
}
},
},
data() {
return {
localValue: this.value
}
},
watch: {
localValue: function (value) {
this.$emit('set-field', {field: this.fieldName, value: value});
},
value: function(value) {
this.localValue = value;
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,83 @@
<!--
- GenericTextarea.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="form-group">
<div class="text-xs d-none d-lg-block d-xl-block">
{{ title }}
</div>
<div class="input-group">
<textarea
v-model="localValue"
:class="errors.length > 0 ? 'form-control is-invalid' : 'form-control'"
:placeholder="title"
:disabled=disabled
:name="fieldName"
>{{ localValue }}</textarea>
</div>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>
</span>
</div>
</template>
<script>
export default {
name: "GenericTextarea",
props: {
title: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
},
value: {
type: String,
default: ''
},
fieldName: {
type: String,
default: ''
},
errors: {
type: Array,
default: function () {
return [];
}
},
},
data() {
return {
localValue: this.value
}
},
watch: {
localValue: function (value) {
this.$emit('set-field', {field: this.fieldName, value: value});
},
}
}
</script>
<style scoped>
</style>

View File

@@ -20,7 +20,7 @@
const lodashClonedeep = require('lodash.clonedeep');
import {getDefaultTransaction, getDefaultErrors} from '../../../shared/transactions';
import {getDefaultTransaction, getDefaultErrors} from '../../../../shared/transactions';
// initial state
const state = () => ({

View File

@@ -22,94 +22,96 @@
<div>
<alert :message="errorMessage" type="danger"/>
<alert :message="successMessage" type="success"/>
<SplitPills :transactions="transactions"/>
<div class="tab-content">
<SplitForm
v-for="(transaction, index) in this.transactions"
v-bind:key="index"
:allowed-opposing-types="allowedOpposingTypes"
:count="transactions.length"
:custom-fields="customFields"
:date="date"
:destination-allowed-types="destinationAllowedTypes"
:index="index"
:source-allowed-types="sourceAllowedTypes"
:submitted-transaction="submittedTransaction"
:time="time"
:transaction="transaction"
:transaction-type="transactionType"
v-on:uploaded-attachments="uploadedAttachment($event)"
v-on:set-marker-location="storeLocation($event)"
v-on:set-account="storeAccountValue($event)"
v-on:switch-accounts="switchAccounts($event)"
v-on:set-date="storeDate($event)"
v-on:set-time="storeTime($event)"
v-on:set-field="storeField($event)"
v-on:remove-transaction="removeTransaction($event)"
v-on:set-dest-types="setDestinationAllowedTypes($event)"
v-on:set-src-types="setSourceAllowedTypes($event)"
<form @submit="submitTransaction">
<SplitPills :transactions="transactions"/>
<div class="tab-content">
<!-- v-on:switch-accounts="switchAccounts($event)" -->
<!-- :allowed-opposing-types="allowedOpposingTypes" -->
<SplitForm
v-for="(transaction, index) in this.transactions"
v-bind:key="index"
:count="transactions.length"
:custom-fields="customFields"
:date="date"
:destination-allowed-types="destinationAllowedTypes"
:index="index"
:source-allowed-types="sourceAllowedTypes"
:submitted-transaction="submittedTransaction"
:time="time"
:transaction="transaction"
:transaction-type="transactionType"
v-on:uploaded-attachments="uploadedAttachment($event)"
v-on:set-marker-location="storeLocation($event)"
v-on:set-account="storeAccountValue($event)"
v-on:set-date="storeDate($event)"
v-on:set-time="storeTime($event)"
v-on:set-field="storeField($event)"
v-on:remove-transaction="removeTransaction($event)"
v-on:set-dest-types="setDestinationAllowedTypes($event)"
v-on:set-src-types="setSourceAllowedTypes($event)"
/>
</div>
/>
</div>
<div class="row">
<!-- group title -->
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
<div v-if="transactions.length > 1" class="card">
<div class="card-body">
<div class="row">
<div class="col">
<TransactionGroupTitle v-model="this.groupTitle" :errors="this.groupTitleErrors" v-on:set-group-title="storeGroupTitle($event)"/>
<div class="row">
<!-- group title -->
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
<div v-if="transactions.length > 1" class="card">
<div class="card-body">
<div class="row">
<div class="col">
<TransactionGroupTitle v-model="this.groupTitle" :errors="this.groupTitleErrors" v-on:set-group-title="storeGroupTitle($event)"/>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
<!-- buttons -->
<div class="card card-primary">
<div class="card-body">
<div class="row">
<div class="col">
<div class="text-xs d-none d-lg-block d-xl-block">
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
<!-- buttons -->
<div class="card card-primary">
<div class="card-body">
<div class="row">
<div class="col">
<div class="text-xs d-none d-lg-block d-xl-block">
&nbsp;
</div>
<button class="btn btn-outline-primary btn-block" @click="addTransaction"><i class="far fa-clone"></i> {{ $t('firefly.add_another_split') }}
</button>
</div>
<div class="col">
<div class="text-xs d-none d-lg-block d-xl-block">
&nbsp;
</div>
<button :disabled="!enableSubmit" class="btn btn-success btn-block" @click="submitTransaction">
<span v-if="enableSubmit"><i class="far fa-save"></i> {{ $t('firefly.store_transaction') }}</span>
<span v-if="!enableSubmit"><i class="fas fa-spinner fa-spin"></i></span>
</button>
</div>
</div>
<div class="row">
<div class="col">
&nbsp;
</div>
<button class="btn btn-outline-primary btn-block" @click="addTransaction"><i class="far fa-clone"></i> {{ $t('firefly.add_another_split') }}
</button>
</div>
<div class="col">
<div class="text-xs d-none d-lg-block d-xl-block">
&nbsp;
</div>
<button :disabled="!enableSubmit" class="btn btn-success btn-block" @click="submitTransaction">
<span v-if="enableSubmit"><i class="far fa-save"></i> {{ $t('firefly.store_transaction') }}</span>
<span v-if="!enableSubmit"><i class="fas fa-spinner fa-spin"></i></span>
</button>
</div>
</div>
<div class="row">
<div class="col">
&nbsp;
</div>
<div class="col">
<div class="form-check">
<input id="createAnother" v-model="createAnother" class="form-check-input" type="checkbox">
<label class="form-check-label" for="createAnother">
<span class="small">{{ $t('firefly.create_another') }}</span>
</label>
</div>
<div class="form-check">
<input id="resetFormAfter" v-model="resetFormAfter" :disabled="!createAnother" class="form-check-input" type="checkbox">
<label class="form-check-label" for="resetFormAfter">
<span class="small">{{ $t('firefly.reset_after') }}</span>
</label>
<div class="col">
<div class="form-check">
<input id="createAnother" v-model="createAnother" class="form-check-input" type="checkbox">
<label class="form-check-label" for="createAnother">
<span class="small">{{ $t('firefly.create_another') }}</span>
</label>
</div>
<div class="form-check">
<input id="resetFormAfter" v-model="resetFormAfter" :disabled="!createAnother" class="form-check-input" type="checkbox">
<label class="form-check-label" for="resetFormAfter">
<span class="small">{{ $t('firefly.reset_after') }}</span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</template>
@@ -119,7 +121,7 @@ import Alert from '../partials/Alert';
import SplitPills from "./SplitPills";
import TransactionGroupTitle from "./TransactionGroupTitle";
import SplitForm from "./SplitForm";
import {toW3CString} from '../shared/transactions';
import {toW3CString} from '../../shared/transactions';
const {mapState, mapGetters, mapActions, mapMutations} = createNamespacedHelpers('transactions/create')
@@ -135,7 +137,15 @@ export default {
* Grab some stuff from the API, add the first transaction.
*/
created() {
this.getAllowedOpposingTypes();
// set transaction type:
let pathName = window.location.pathname;
let parts = pathName.split('/');
let type = parts[parts.length - 1];
console.log('Set transaction type to ' + type);
this.setTransactionType(type[0].toUpperCase() + type.substring(1));
//this.getAllowedOpposingTypes();
this.getExpectedSourceTypes();
this.getAccountToTransaction();
this.getCustomFields();
this.addTransaction();
@@ -291,7 +301,8 @@ export default {
* Actually submit the transaction to Firefly III. This is a fairly complex beast of a thing because multiple things
* need to happen in the right order.
*/
submitTransaction: function () {
submitTransaction: function (event) {
event.preventDefault();
// console.log('submitTransaction()');
// disable the submit button:
this.enableSubmit = false;
@@ -398,7 +409,7 @@ export default {
this.updateField({index: payload.index, field: payload.direction + '_account_currency_code', value: payload.currency_code});
this.updateField({index: payload.index, field: payload.direction + '_account_currency_symbol', value: payload.currency_symbol});
this.calculateTransactionType(payload.index);
//this.calculateTransactionType(payload.index);
},
storeField: function (payload) {
this.updateField(payload);
@@ -414,60 +425,60 @@ export default {
this.setGroupTitle({groupTitle: value});
},
/**
* Calculate the transaction type based on what's currently in the store.
*/
calculateTransactionType: function (index) {
//console.log('calculateTransactionType(' + index + ')');
if (0 === index) {
let source = this.transactions[0].source_account_type;
let dest = this.transactions[0].destination_account_type;
if (null === source || null === dest) {
//console.log('transactionType any');
this.setTransactionType('any');
//this.$store.commit('setTransactionType', 'any');
//console.log('calculateTransactionType: either type is NULL so no dice.');
return;
}
if ('' === source || '' === dest) {
//console.log('transactionType any');
this.setTransactionType('any');
//this.$store.commit('setTransactionType', 'any');
//console.log('calculateTransactionType: either type is empty so no dice.');
return;
}
// ok so type is set on both:
let expectedDestinationTypes = this.accountToTransaction[source];
if ('undefined' !== typeof expectedDestinationTypes) {
let transactionType = expectedDestinationTypes[dest];
if ('undefined' !== typeof expectedDestinationTypes[dest]) {
//console.log('Found a type: ' + transactionType);
this.setTransactionType(transactionType);
//this.$store.commit('setTransactionType', transactionType);
//console.log('calculateTransactionType: ' + source + ' --> ' + dest + ' = ' + transactionType);
return;
}
}
//console.log('Found no type for ' + source + ' --> ' + dest);
if ('Asset account' !== source) {
//console.log('Drop ID from destination.');
this.updateField({index: 0, field: 'destination_account_id', value: null});
//console.log('calculateTransactionType: drop ID from destination.');
// source.id =null
// context.commit('updateField', {field: 'source_account',index: })
// context.state.transactions[0].source_account.id = null;
}
if ('Asset account' !== dest) {
//console.log('Drop ID from source.');
this.updateField({index: 0, field: 'source_account_id', value: null});
//console.log('calculateTransactionType: drop ID from source.');
//context.state.transactions[0].destination_account.id = null;
}
//console.log('calculateTransactionType: fallback, type to any.');
this.setTransactionType('any');
//this.$store.commit('setTransactionType', 'any');
}
},
// /**
// * Calculate the transaction type based on what's currently in the store.
// */
// calculateTransactionType: function (index) {
// //console.log('calculateTransactionType(' + index + ')');
// if (0 === index) {
// let source = this.transactions[0].source_account_type;
// let dest = this.transactions[0].destination_account_type;
// if (null === source || null === dest) {
// //console.log('transactionType any');
// this.setTransactionType('any');
// //this.$store.commit('setTransactionType', 'any');
// //console.log('calculateTransactionType: either type is NULL so no dice.');
// return;
// }
// if ('' === source || '' === dest) {
// //console.log('transactionType any');
// this.setTransactionType('any');
// //this.$store.commit('setTransactionType', 'any');
// //console.log('calculateTransactionType: either type is empty so no dice.');
// return;
// }
// // ok so type is set on both:
// let expectedDestinationTypes = this.accountToTransaction[source];
// if ('undefined' !== typeof expectedDestinationTypes) {
// let transactionType = expectedDestinationTypes[dest];
// if ('undefined' !== typeof expectedDestinationTypes[dest]) {
// //console.log('Found a type: ' + transactionType);
// this.setTransactionType(transactionType);
// //this.$store.commit('setTransactionType', transactionType);
// //console.log('calculateTransactionType: ' + source + ' --> ' + dest + ' = ' + transactionType);
// return;
// }
// }
// //console.log('Found no type for ' + source + ' --> ' + dest);
// if ('Asset account' !== source) {
// //console.log('Drop ID from destination.');
// this.updateField({index: 0, field: 'destination_account_id', value: null});
// //console.log('calculateTransactionType: drop ID from destination.');
// // source.id =null
// // context.commit('updateField', {field: 'source_account',index: })
// // context.state.transactions[0].source_account.id = null;
// }
// if ('Asset account' !== dest) {
// //console.log('Drop ID from source.');
// this.updateField({index: 0, field: 'source_account_id', value: null});
// //console.log('calculateTransactionType: drop ID from source.');
// //context.state.transactions[0].destination_account.id = null;
// }
// //console.log('calculateTransactionType: fallback, type to any.');
// this.setTransactionType('any');
// //this.$store.commit('setTransactionType', 'any');
// }
// },
/**
* Submit transaction links.
*/
@@ -669,25 +680,25 @@ export default {
},
switchAccounts: function (index) {
// console.log('user wants to switch Accounts');
let origSourceId = this.transactions[index].source_account_id;
let origSourceName = this.transactions[index].source_account_name;
let origSourceType = this.transactions[index].source_account_type;
let origDestId = this.transactions[index].destination_account_id;
let origDestName = this.transactions[index].destination_account_name;
let origDestType = this.transactions[index].destination_account_type;
this.updateField({index: 0, field: 'source_account_id', value: origDestId});
this.updateField({index: 0, field: 'source_account_name', value: origDestName});
this.updateField({index: 0, field: 'source_account_type', value: origDestType});
this.updateField({index: 0, field: 'destination_account_id', value: origSourceId});
this.updateField({index: 0, field: 'destination_account_name', value: origSourceName});
this.updateField({index: 0, field: 'destination_account_type', value: origSourceType});
this.calculateTransactionType(0);
},
// switchAccounts: function (index) {
// // console.log('user wants to switch Accounts');
// let origSourceId = this.transactions[index].source_account_id;
// let origSourceName = this.transactions[index].source_account_name;
// let origSourceType = this.transactions[index].source_account_type;
//
// let origDestId = this.transactions[index].destination_account_id;
// let origDestName = this.transactions[index].destination_account_name;
// let origDestType = this.transactions[index].destination_account_type;
//
// this.updateField({index: 0, field: 'source_account_id', value: origDestId});
// this.updateField({index: 0, field: 'source_account_name', value: origDestName});
// this.updateField({index: 0, field: 'source_account_type', value: origDestType});
//
// this.updateField({index: 0, field: 'destination_account_id', value: origSourceId});
// this.updateField({index: 0, field: 'destination_account_name', value: origSourceName});
// this.updateField({index: 0, field: 'destination_account_type', value: origSourceType});
// this.calculateTransactionType(0);
// },
/**
@@ -703,19 +714,34 @@ export default {
) {
let theDate = new Date(this.date);
// update time in date object.
theDate.setHours(this.time.getHours());
theDate.setMinutes(this.time.getMinutes());
theDate.setSeconds(this.time.getSeconds());
//theDate.setHours(this.time.getHours());
//theDate.setMinutes(this.time.getMinutes());
//theDate.setSeconds(this.time.getSeconds());
dateStr = toW3CString(theDate);
}
console.log('Date is now ' + dateStr);
console.log(dateStr);
// console.log('dateStr = ' + dateStr);
if ('' === array.destination_account_name) {
array.destination_account_name = null;
}
if (0 === array.destination_account_id) {
array.destination_account_name = null;
}
if ('' === array.source_account_name) {
array.source_account_name = null;
}
if (0 === array.source_account_id) {
array.source_account_id = null;
}
let currentSplit = {
// basic
description: array.description,
date: dateStr,
type: this.transactionType,
type: this.transactionType.toLowerCase(),
// account
source_id: array.source_account_id ?? null,
@@ -761,10 +787,10 @@ export default {
if (array.tags.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) {
// array.tags
let current = array.tags[i];
if(typeof current === 'object' && null !== current) {
if (typeof current === 'object' && null !== current) {
currentSplit.tags.push(current.text);
}
if(typeof current === 'string') {
if (typeof current === 'string') {
currentSplit.tags.push(current);
}
}
@@ -788,17 +814,17 @@ export default {
}
// do transaction type
let transactionType;
let firstSource;
let firstDestination;
// let transactionType;
// let firstSource;
// let firstDestination;
// get transaction type from first transaction
transactionType = this.transactionType ? this.transactionType.toLowerCase() : 'any';
//transactionType = this.transactionType ? this.transactionType.toLowerCase() : 'any';
//console.log('Transaction type is now ' + transactionType);
// if the transaction type is invalid, might just be that we can deduce it from
// the presence of a source or destination account
firstSource = this.transactions[0].source_account_type;
firstDestination = this.transactions[0].destination_account_type;
//firstSource = this.transactions[0].source_account_type;
//firstDestination = this.transactions[0].destination_account_type;
//console.log(this.transactions[0].source_account);
//console.log(this.transactions[0].destination_account);
//console.log('Type of first source is ' + firstSource);
@@ -806,15 +832,15 @@ export default {
// default to source:
currentSplit.currency_id = array.source_account_currency_id;
if ('any' === transactionType && ['asset', 'Asset account', 'Loan', 'Debt', 'Mortgage'].includes(firstSource)) {
transactionType = 'withdrawal';
}
// if ('any' === transactionType && ['asset', 'Asset account', 'Loan', 'Debt', 'Mortgage'].includes(firstSource)) {
// transactionType = 'withdrawal';
// }
if ('any' === transactionType && ['asset', 'Asset account', 'Loan', 'Debt', 'Mortgage'].includes(firstDestination)) {
transactionType = 'deposit';
if ('Deposit' === this.transactionType) {
// transactionType = 'deposit';
currentSplit.currency_id = array.destination_account_currency_id;
}
currentSplit.type = transactionType;
//currentSplit.type = transactionType;
//console.log('Final type is ' + transactionType);
let links = [];
@@ -833,6 +859,21 @@ export default {
}
}
currentSplit.links = links;
if (null === currentSplit.source_id) {
delete currentSplit.source_id;
}
if (null === currentSplit.source_name) {
delete currentSplit.source_name;
}
if (null === currentSplit.destination_id) {
delete currentSplit.destination_id;
}
if (null === currentSplit.destination_name) {
delete currentSplit.destination_name;
}
console.log('Current split is: ');
console.log(currentSplit);
// return it.
return currentSplit;
@@ -843,9 +884,21 @@ export default {
getAllowedOpposingTypes: function () {
axios.get('./api/v1/configuration/firefly.allowed_opposing_types')
.then(response => {
console.log('opposing types things.');
console.log(response.data.data.value);
this.allowedOpposingTypes = response.data.data.value;
});
},
getExpectedSourceTypes: function() {
axios.get('./api/v1/configuration/firefly.expected_source_types')
.then(response => {
console.log('getExpectedSourceTypes.');
this.sourceAllowedTypes = response.data.data.value.source[this.transactionType];
this.destinationAllowedTypes = response.data.data.value.destination[this.transactionType];
//this.allowedOpposingTypes = response.data.data.value;
});
},
/**
* Get API value.
*/

View File

@@ -23,88 +23,90 @@
<Alert :message="errorMessage" type="danger"/>
<Alert :message="successMessage" type="success"/>
<Alert :message="warningMessage" type="warning"/>
<SplitPills :transactions="transactions"/>
<form @submit="submitTransaction">
<SplitPills :transactions="transactions"/>
<div class="tab-content">
<SplitForm
v-for="(transaction, index) in this.transactions"
v-bind:key="index"
:count="transactions.length"
:transaction="transaction"
:allowed-opposing-types="allowedOpposingTypes"
:custom-fields="customFields"
:date="date"
:time="time"
:index="index"
:transaction-type="transactionType"
:destination-allowed-types="destinationAllowedTypes"
:source-allowed-types="sourceAllowedTypes"
:allow-switch="false"
:submitted-transaction="submittedTransaction"
v-on:uploaded-attachments="uploadedAttachment($event)"
v-on:set-marker-location="storeLocation($event)"
v-on:set-account="storeAccountValue($event)"
v-on:set-date="storeDate($event)"
v-on:set-time="storeTime($event)"
v-on:set-field="storeField($event)"
v-on:remove-transaction="removeTransaction($event)"
v-on:selected-attachments="selectedAttachments($event)"
/>
</div>
<div class="tab-content">
<SplitForm
v-for="(transaction, index) in this.transactions"
v-bind:key="index"
:count="transactions.length"
:transaction="transaction"
:allowed-opposing-types="allowedOpposingTypes"
:custom-fields="customFields"
:date="date"
:time="time"
:index="index"
:transaction-type="transactionType"
:destination-allowed-types="destinationAllowedTypes"
:source-allowed-types="sourceAllowedTypes"
:allow-switch="false"
:submitted-transaction="submittedTransaction"
v-on:uploaded-attachments="uploadedAttachment($event)"
v-on:set-marker-location="storeLocation($event)"
v-on:set-account="storeAccountValue($event)"
v-on:set-date="storeDate($event)"
v-on:set-time="storeTime($event)"
v-on:set-field="storeField($event)"
v-on:remove-transaction="removeTransaction($event)"
v-on:selected-attachments="selectedAttachments($event)"
/>
</div>
<!-- bottom buttons etc -->
<div class="row">
<!-- group title -->
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
<div v-if="transactions.length > 1" class="card">
<div class="card-body">
<div class="row">
<div class="col">
<TransactionGroupTitle v-model="this.groupTitle" :errors="this.groupTitleErrors" v-on:set-group-title="storeGroupTitle($event)"/>
<!-- bottom buttons etc -->
<div class="row">
<!-- group title -->
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
<div v-if="transactions.length > 1" class="card">
<div class="card-body">
<div class="row">
<div class="col">
<TransactionGroupTitle v-model="this.groupTitle" :errors="this.groupTitleErrors" v-on:set-group-title="storeGroupTitle($event)"/>
</div>
</div>
</div>
</div>
</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">
<div class="col">
<div class="text-xs d-none d-lg-block d-xl-block">
<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">
<div class="col">
<div class="text-xs d-none d-lg-block d-xl-block">
&nbsp;
</div>
<button class="btn btn-outline-primary btn-block" @click="addTransaction"><i class="far fa-clone"></i> {{ $t('firefly.add_another_split') }}
</button>
</div>
<div class="col">
<div class="text-xs d-none d-lg-block d-xl-block">
&nbsp;
</div>
<button :disabled="!enableSubmit" class="btn btn-info btn-block" @click="submitTransaction">
<span v-if="enableSubmit"><i class="far fa-save"></i> {{ $t('firefly.update_transaction') }}</span>
<span v-if="!enableSubmit"><i class="fas fa-spinner fa-spin"></i></span>
</button>
</div>
</div>
<div class="row">
<div class="col">
&nbsp;
</div>
<button class="btn btn-outline-primary btn-block" @click="addTransaction"><i class="far fa-clone"></i> {{ $t('firefly.add_another_split') }}
</button>
</div>
<div class="col">
<div class="text-xs d-none d-lg-block d-xl-block">
&nbsp;
</div>
<button :disabled="!enableSubmit" class="btn btn-info btn-block" @click="submitTransaction">
<span v-if="enableSubmit"><i class="far fa-save"></i> {{ $t('firefly.update_transaction') }}</span>
<span v-if="!enableSubmit"><i class="fas fa-spinner fa-spin"></i></span>
</button>
</div>
</div>
<div class="row">
<div class="col">
&nbsp;
</div>
<div class="col">
<div class="form-check">
<input id="stayHere" v-model="stayHere" class="form-check-input" type="checkbox">
<label class="form-check-label" for="stayHere">
<span class="small">{{ $t('firefly.after_update_create_another') }}</span>
</label>
<div class="col">
<div class="form-check">
<input id="stayHere" v-model="stayHere" class="form-check-input" type="checkbox">
<label class="form-check-label" for="stayHere">
<span class="small">{{ $t('firefly.after_update_create_another') }}</span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</template>
@@ -114,7 +116,7 @@ import Alert from '../partials/Alert';
import SplitPills from "./SplitPills";
import SplitForm from "./SplitForm";
import TransactionGroupTitle from "./TransactionGroupTitle";
import {getDefaultErrors, getDefaultTransaction, toW3CString} from '../shared/transactions';
import {getDefaultErrors, getDefaultTransaction, toW3CString} from '../../shared/transactions';
export default {
name: "Edit",
@@ -463,7 +465,7 @@ export default {
let newTransactionCount = this.transactions.length;
console.log('Found ' + this.transactions.length + ' split(s).');
if(newTransactionCount > 1 && typeof submission.group_title === 'undefined' && (null === this.originalGroupTitle || '' === this.originalGroupTitle)) {
if (newTransactionCount > 1 && typeof submission.group_title === 'undefined' && (null === this.originalGroupTitle || '' === this.originalGroupTitle)) {
submission.group_title = this.transactions[0].description;
}

View File

@@ -51,7 +51,6 @@
<TransactionAccount
v-model="sourceAccount"
v-on="$listeners"
:allowed-opposing-types="allowedOpposingTypes"
:destination-allowed-types="destinationAllowedTypes"
:errors="transaction.errors.source"
:index="index"
@@ -76,7 +75,6 @@
<TransactionAccount
v-model="destinationAccount"
v-on="$listeners"
:allowed-opposing-types="allowedOpposingTypes"
:destination-allowed-types="destinationAllowedTypes"
:errors="transaction.errors.destination"
:index="index"
@@ -369,11 +367,6 @@ export default {
required: false,
default: []
},
allowedOpposingTypes: {
type: Object,
required: false,
default: {}
},
// allow switch?
allowSwitch: {
type: Boolean,
@@ -382,11 +375,6 @@ export default {
}
},
// watch: {
// allowedOpposingTypes: function() {
// console.log('SplitForm noticed change in allowedOpposingTypes');
// }
// },
methods: {
removeTransaction: function () {
// console.log('Will remove transaction ' + this.index);

View File

@@ -26,9 +26,11 @@
</span>
<span v-if="'any' === this.transactionType" class="text-muted">&nbsp;</span>
</div>
<!--
<div class="btn-group d-flex">
<button class="btn btn-light" @click="switchAccounts">&harr;</button>
</div>
-->
</div>
</template>
@@ -37,9 +39,9 @@ export default {
name: "SwitchAccount",
props: ['index', 'transactionType'],
methods: {
switchAccounts() {
this.$emit('switch-accounts', this.index);
}
// switchAccounts() {
// this.$emit('switch-accounts', this.index);
// }
}
}
</script>

View File

@@ -92,10 +92,6 @@ export default {
type: Array,
default: () => ([])
},
allowedOpposingTypes: {
type: Object,
default: () => ({})
},
transactionType: {
type: String,
default: 'any'
@@ -161,9 +157,6 @@ export default {
}
},
watch: {
// allowedOpposingTypes: function () {
// console.log(this.direction + ' account noticed change in allowedOpposingTypes');
// },
sourceAllowedTypes: function (value) {
// console.log(this.direction + ' account noticed change in sourceAllowedTypes');
// console.log(value);
@@ -193,7 +186,15 @@ export default {
this.accountName = this.account.name_with_balance;
},
accountName: function (value) {
if('source' === this.direction && 'Deposit' !== this.transactionType) {
return;
}
if('destination' === this.direction && 'Withdrawal' !== this.transactionType) {
return;
}
if (false === this.selectedAccountTrigger) {
console.log('User submitted manual thing.');
// console.log('Save to change name!');
this.$emit('set-account',
{
@@ -212,22 +213,6 @@ export default {
}
this.selectedAccountTrigger = false;
},
account: function (value) {
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.$emit('set-dest-types', opposingAccounts);
}
if ('destination' === this.direction) {
this.$emit('set-src-types', opposingAccounts);
}
},
value: function (value) {
// console.log('Index ' + this.index + ' nwAct: ', value);
// console.log(this.direction + ' account overruled by external forces.');

View File

@@ -31,7 +31,6 @@
:title="$t('firefly.bill')"
autocomplete="off"
name="bill_id[]"
v-on:submit.prevent
>
<option v-for="bill in this.billList" :label="bill.name" :value="bill.id">{{ bill.name }}</option>

View File

@@ -31,7 +31,6 @@
:title="$t('firefly.budget')"
autocomplete="off"
name="budget_id[]"
v-on:submit.prevent
>
<option v-for="budget in this.budgetList" :label="budget.name" :value="budget.id">{{ budget.name }}</option>
</select>

View File

@@ -35,7 +35,6 @@
class="form-control"
type="date"
@change="setFieldValue($event, name)"
v-on:submit.prevent
>
</div>
</div>

View File

@@ -35,6 +35,7 @@
name="date[]"
type="date"
>
<!--
<input
ref="time"
v-model="timeStr"
@@ -46,6 +47,7 @@
name="time[]"
type="time"
>
-->
</div>
<span v-if="errors.length > 0">
<span v-for="error in errors" class="text-danger small">{{ error }}<br/></span>

View File

@@ -31,7 +31,6 @@
:title="$t('firefly.piggy_bank')"
autocomplete="off"
name="piggy_bank_id[]"
v-on:submit.prevent
>
<option v-for="piggy in this.piggyList" :label="piggy.name_with_balance" :value="piggy.id">{{ piggy.name_with_balance }}</option>

36
frontend/src/pages/accounts/create.js vendored Normal file
View File

@@ -0,0 +1,36 @@
/*
* create.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/>.
*/
require('../../bootstrap');
import Create from "../../components/accounts/Create";
// i18n
let i18n = require('../../i18n');
let props = {};
new Vue({
i18n,
render(createElement) {
return createElement(Create, {props: props});
}
}).$mount('#accounts_create');

View File

@@ -25,12 +25,14 @@ import store from "../../components/store";
import {BPagination, BTable} from 'bootstrap-vue';
import Calendar from "../../components/dashboard/Calendar";
import IndexOptions from "../../components/accounts/IndexOptions";
//import Vuex from "vuex";
// i18n
let i18n = require('../../i18n');
let props = {};
// TODO: long lists are slow to load. Fix this.
// TODO add interest for liabilities
Vue.component('b-table', BTable);
Vue.component('b-pagination', BPagination);
//Vue.use(Vuex);

View File

@@ -43,6 +43,8 @@ import store from '../components/store';
* vue, uiv and vuei18n are in app_vue.js
*/
// TODO pretty sure not all categories, budgets and other objects are picked up because they're paginated.
require('../bootstrap');
require('chart.js');

View File

@@ -28,6 +28,12 @@ Vue.config.productionTip = false;
// i18n
let i18n = require('../../i18n');
// TODO take transaction type from URL. Simplifies a lot of code.
// TODO make sure the enter button works.
// TODO add preferences in sidebar
// TODO If I change the date box at all even if you just type over it with the current date, it posts back a day.
// TODO Cash accounts do not work
let props = {};
new Vue({
i18n,

View File

@@ -35,6 +35,9 @@ const mix = require('laravel-mix');
// production
// require('laravel-mix-bundle-analyzer');
mix.webpackConfig({
stats: {
children: true
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.runtime.common.js'
@@ -50,7 +53,7 @@ mix.js('src/pages/dashboard.js', 'public/js').vue({version: 2});
mix.js('src/pages/accounts/index.js', 'public/js/accounts').vue({version: 2});
mix.js('src/pages/accounts/delete.js', 'public/js/accounts').vue({version: 2});
mix.js('src/pages/accounts/show.js', 'public/js/accounts').vue({version: 2});
mix.js('src/pages/accounts/create.js', 'public/js/accounts').vue({version: 2});
// transactions.
mix.js('src/pages/transactions/create.js', 'public/js/transactions').vue({version: 2});

View File

@@ -942,16 +942,16 @@
chokidar "^2.1.2"
"@types/chart.js@^2.7.55":
version "2.9.31"
resolved "https://registry.yarnpkg.com/@types/chart.js/-/chart.js-2.9.31.tgz#e8ebc7ed18eb0e5114c69bd46ef8e0037c89d39d"
integrity sha512-hzS6phN/kx3jClk3iYqEHNnYIRSi4RZrIGJ8CDLjgatpHoftCezvC44uqB3o3OUm9ftU1m7sHG8+RLyPTlACrA==
version "2.9.32"
resolved "https://registry.yarnpkg.com/@types/chart.js/-/chart.js-2.9.32.tgz#b17d9a8c41ad348183a2ce041ebdeef892998251"
integrity sha512-d45JiRQwEOlZiKwukjqmqpbqbYzUX2yrXdH9qVn6kXpPDsTYCo6YbfFOlnUaJ8S/DhJwbBJiLsMjKpW5oP8B2A==
dependencies:
moment "^2.10.2"
"@types/clean-css@^4.2.2":
version "4.2.3"
resolved "https://registry.yarnpkg.com/@types/clean-css/-/clean-css-4.2.3.tgz#12c13cc815f5e793014ee002c6324455907d851c"
integrity sha512-ET0ldU/vpXecy5vO8JRIhtJWSrk1vzXdJcp3Bjf8bARZynl6vfkhEKY/A7njfNIRlmyTGuVFuqnD6I3tOGdXpQ==
version "4.2.4"
resolved "https://registry.yarnpkg.com/@types/clean-css/-/clean-css-4.2.4.tgz#4fe4705c384e6ec9ee8454bc3d49089f38dc038a"
integrity sha512-x8xEbfTtcv5uyQDrBXKg9Beo5QhTPqO4vM0uq4iU27/nhyRRWNEMKHjxvAb0WDvp2Mnt4Sw0jKmIi5yQF/k2Ag==
dependencies:
"@types/node" "*"
source-map "^0.6.0"
@@ -1449,9 +1449,9 @@ anymatch@^2.0.0:
normalize-path "^2.1.1"
anymatch@~3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142"
integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==
version "3.1.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
dependencies:
normalize-path "^3.0.0"
picomatch "^2.0.4"
@@ -1483,11 +1483,6 @@ arr-union@^3.1.0:
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
array-filter@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83"
integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
@@ -1584,13 +1579,6 @@ autoprefixer@^10.0.1:
normalize-range "^0.1.2"
postcss-value-parser "^4.1.0"
available-typed-arrays@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5"
integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==
dependencies:
array-filter "^1.0.0"
axios@^0.21:
version "0.21.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
@@ -1648,9 +1636,9 @@ babel-runtime@^6.26.0:
regenerator-runtime "^0.11.0"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
base64-js@0.0.8:
version "0.0.8"
@@ -2061,9 +2049,9 @@ caniuse-api@^3.0.0:
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001181, caniuse-lite@^1.0.30001196:
version "1.0.30001207"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001207.tgz#364d47d35a3007e528f69adb6fecb07c2bb2cc50"
integrity sha512-UPQZdmAsyp2qfCTiMU/zqGSWOYaY9F9LL61V8f+8MrubsaDGpaHD9HRV/EWZGULZn0Hxu48SKzI5DgFwTvHuYw==
version "1.0.30001208"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001208.tgz#a999014a35cebd4f98c405930a057a0d75352eb9"
integrity sha512-OE5UE4+nBOro8Dyvv0lfx+SRtfVIOM9uhKqFmJeUbGriqhhStgp1A0OyBpgy3OUF8AhYCT+PVwPC1gMl2ZcQMA==
chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2"
@@ -2444,9 +2432,9 @@ copy-descriptor@^0.1.0:
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
core-js-compat@^3.8.1, core-js-compat@^3.9.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.10.0.tgz#3600dc72869673c110215ee7a005a8609dea0fe1"
integrity sha512-9yVewub2MXNYyGvuLnMHcN1k9RkvB7/ofktpeKTIaASyB88YYqGzUnu0ywMMhJrDHOMiTjSHWGzR+i7Wb9Z1kQ==
version "3.10.1"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.10.1.tgz#62183a3a77ceeffcc420d907a3e6fc67d9b27f1c"
integrity sha512-ZHQTdTPkqvw2CeHiZC970NNJcnwzT6YIueDMASKt+p3WbZsLXOcoD392SkcWhkC0wBBHhlfhqGKKsNCQUozYtg==
dependencies:
browserslist "^4.16.3"
semver "7.0.0"
@@ -2457,9 +2445,9 @@ core-js@^2.4.0:
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
core-js@^3.6.5:
version "3.10.0"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.10.0.tgz#9a020547c8b6879f929306949e31496bbe2ae9b3"
integrity sha512-MQx/7TLgmmDVamSyfE+O+5BHvG1aUGj/gHhLn1wVtm2B5u1eVIPvh7vkfjwWKNCjrTJB8+He99IntSQ1qP+vYQ==
version "3.10.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.10.1.tgz#e683963978b6806dcc6c0a4a8bd4ab0bdaf3f21a"
integrity sha512-pwCxEXnj27XG47mu7SXAwhLP3L5CrlvCB91ANUkIz40P27kUcvNfSdvyZJ9CLHiVoKSp+TTChMQMSKQEH/IQxA==
core-util-is@~1.0.0:
version "1.0.2"
@@ -2636,10 +2624,10 @@ cssesc@^3.0.0:
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
cssnano-preset-default@^4.0.7:
version "4.0.7"
resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76"
integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==
cssnano-preset-default@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz#920622b1fc1e95a34e8838203f1397a504f2d3ff"
integrity sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==
dependencies:
css-declaration-sorter "^4.0.1"
cssnano-util-raw-cache "^4.0.1"
@@ -2669,7 +2657,7 @@ cssnano-preset-default@^4.0.7:
postcss-ordered-values "^4.1.2"
postcss-reduce-initial "^4.0.3"
postcss-reduce-transforms "^4.0.2"
postcss-svgo "^4.0.2"
postcss-svgo "^4.0.3"
postcss-unique-selectors "^4.0.1"
cssnano-util-get-arguments@^4.0.0:
@@ -2695,12 +2683,12 @@ cssnano-util-same-parent@^4.0.0:
integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==
cssnano@^4.1.10:
version "4.1.10"
resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2"
integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==
version "4.1.11"
resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.11.tgz#c7b5f5b81da269cb1fd982cb960c1200910c9a99"
integrity sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==
dependencies:
cosmiconfig "^5.0.0"
cssnano-preset-default "^4.0.7"
cssnano-preset-default "^4.0.8"
is-resolvable "^1.0.0"
postcss "^7.0.0"
@@ -2966,9 +2954,9 @@ date-fns-tz@^1.0.12:
integrity sha512-mD26WkejWz842RggjFrKsY6ehGgyBQSJ209mn83/vsjhgQ5WbdVvBzJ0CuosnGdklDxOvOppQ/wn1UgvTOPKPw==
date-fns@^2.8.1:
version "2.19.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.19.0.tgz#65193348635a28d5d916c43ec7ce6fbd145059e1"
integrity sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg==
version "2.20.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.20.0.tgz#df00ba9177fbea22d88010b5844ecc91e9e03ceb"
integrity sha512-nmA7y6aDH5+fknfJ0G77HQzUSfTPpq4ifq+c9blP9d+X9zs3kNjxC+t3pcbBMGTp262a6PJB3RVjLlxIgoMI+Q==
daterangepicker@^3.1.0:
version "3.1.0"
@@ -2990,7 +2978,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
dependencies:
ms "2.0.0"
debug@^3.1.1, debug@^3.2.6:
debug@^3.1.1:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
@@ -3251,9 +3239,9 @@ ekko-lightbox@^5.3.0:
integrity sha512-mbacwySuVD3Ad6F2hTkjSTvJt59bcVv2l/TmBerp4xZnLak8tPtA4AScUn4DL42c1ksTiAO6sGhJZ52P/1Qgew==
electron-to-chromium@^1.3.649:
version "1.3.707"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.707.tgz#71386d0ceca6727835c33ba31f507f6824d18c35"
integrity sha512-BqddgxNPrcWnbDdJw7SzXVzPmp+oiyjVrc7tkQVaznPGSS9SKZatw6qxoP857M+HbOyyqJQwYQtsuFIMSTNSZA==
version "1.3.710"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.710.tgz#b33d316e5d6de92b916e766d8a478d19796ffe11"
integrity sha512-b3r0E2o4yc7mNmBeJviejF1rEx49PUBi+2NPa7jHEX3arkAXnVgLhR0YmV8oi6/Qf3HH2a8xzQmCjHNH0IpXWQ==
elliptic@^6.5.3:
version "6.5.4"
@@ -3309,9 +3297,9 @@ entities@^2.0.0:
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
envinfo@^7.7.3:
version "7.7.4"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.7.4.tgz#c6311cdd38a0e86808c1c9343f667e4267c4a320"
integrity sha512-TQXTYFVVwwluWSFis6K2XKxgrD22jEv0FTuLCQI+OjH7rn93+iY0fSSFM5lrSxFY+H1+B0/cvvlamr3UsBivdQ==
version "7.8.1"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475"
integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==
error-ex@^1.3.1:
version "1.3.2"
@@ -3320,7 +3308,7 @@ error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2:
es-abstract@^1.17.2, es-abstract@^1.18.0-next.2:
version "1.18.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4"
integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==
@@ -3539,13 +3527,6 @@ events@^3.0.0, events@^3.2.0:
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
eventsource@^1.0.7:
version "1.1.0"
resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.0.tgz#00e8ca7c92109e94b0ddf32dac677d841028cfaf"
integrity sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==
dependencies:
original "^1.0.0"
evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
@@ -3827,11 +3808,6 @@ for-in@^1.0.2:
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=
foreach@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k=
forwarded@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
@@ -4128,12 +4104,7 @@ hsla-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38"
integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg=
html-comment-regex@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7"
integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==
html-entities@^2.1.1:
html-entities@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488"
integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==
@@ -4213,7 +4184,7 @@ http-parser-js@>=0.5.1:
resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9"
integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==
http-proxy-middleware@^1.0.6:
http-proxy-middleware@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-1.1.0.tgz#b896b2cc6836019af4a4f2d5f7b21b99c77ea13f"
integrity sha512-OnjU5vyVgcZVe2AjLJyMrk8YLNOC2lspCHirB5ldM+B/dwEfZ5bgVTrFyzE9R7xRWAP/i/FXtvIqKjTNEZBhBg==
@@ -4421,6 +4392,11 @@ ipaddr.js@1.9.1, ipaddr.js@^1.9.1:
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
ipaddr.js@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.0.tgz#77ccccc8063ae71ab65c55f21b090698e763fc6e"
integrity sha512-S54H9mIj0rbxRIyrDMEuuER86LdlgUg9FSeZ8duQb6CUG2iRrA36MYVQBSprTF/ZeAwvyQ5mDGuNvIPM0BIl3w==
is-absolute-url@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6"
@@ -4560,9 +4536,9 @@ is-directory@^0.3.1:
integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=
is-docker@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156"
integrity sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.0.tgz#b037c8815281edaad6c2562648a5f5f18839d5f7"
integrity sha512-K4GwB4i/HzhAzwP/XSlspzRdFTI9N8OxJOyOU7Y5Rz+p+WBokXWVWblaJeBkggthmoSV0OoGTH5thJNvplpkvQ==
is-extendable@^0.1.0, is-extendable@^0.1.1:
version "0.1.1"
@@ -4586,11 +4562,6 @@ is-fullwidth-code-point@^3.0.0:
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
is-generator-function@^1.0.7:
version "1.0.8"
resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.8.tgz#dfb5c2b120e02b0a8d9d2c6806cd5621aa922f7b"
integrity sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==
is-glob@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
@@ -4684,13 +4655,6 @@ is-string@^1.0.5:
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6"
integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==
is-svg@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75"
integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==
dependencies:
html-comment-regex "^1.1.0"
is-symbol@^1.0.2, is-symbol@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937"
@@ -4698,17 +4662,6 @@ is-symbol@^1.0.2, is-symbol@^1.0.3:
dependencies:
has-symbols "^1.0.1"
is-typed-array@^1.1.3:
version "1.1.5"
resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e"
integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==
dependencies:
available-typed-arrays "^1.0.2"
call-bind "^1.0.2"
es-abstract "^1.18.0-next.2"
foreach "^2.0.5"
has-symbols "^1.0.1"
is-windows@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
@@ -4842,11 +4795,6 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json3@^3.3.3:
version "3.3.3"
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
json5@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
@@ -5279,9 +5227,9 @@ mimic-fn@^3.1.0:
integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==
mini-css-extract-plugin@^1.1.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.4.0.tgz#c8e571c4b6d63afa56c47260343adf623349c473"
integrity sha512-DyQr5DhXXARKZoc4kwvCvD95kh69dUupfuKOmBUqZ4kBTmRaRZcU32lYu3cLd6nEGXhQ1l7LzZ3F/CjItaY6VQ==
version "1.4.1"
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.4.1.tgz#975e27c1d0bd8e052972415f47c79cea5ed37548"
integrity sha512-COAGbpAsU0ioFzj+/RRfO5Qv177L1Z/XAx2EmCF33b8GDDqKygMffBTws2lit8iaPdrbKEY5P+zsseBUCREZWQ==
dependencies:
loader-utils "^2.0.0"
schema-utils "^3.0.0"
@@ -5637,13 +5585,6 @@ optionator@^0.8.1:
type-check "~0.3.2"
word-wrap "~1.2.3"
original@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f"
integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==
dependencies:
url-parse "^1.4.3"
os-browserify@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
@@ -5704,7 +5645,7 @@ p-pipe@^3.0.0:
resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-3.1.0.tgz#48b57c922aa2e1af6a6404cb7c6bf0eb9cc8e60e"
integrity sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==
p-retry@^4.4.0:
p-retry@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.5.0.tgz#6685336b3672f9ee8174d3769a660cb5e488521d"
integrity sha512-5Hwh4aVQSu6BEP+w2zKlVXtFAaYQe1qWuVADSgoeVlLjwe/Q/AMSoRR4MDeaAfu8llT+YNbEijWu/YF3m6avkg==
@@ -6201,12 +6142,11 @@ postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4:
uniq "^1.0.1"
util-deprecate "^1.0.2"
postcss-svgo@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258"
integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==
postcss-svgo@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.3.tgz#343a2cdbac9505d416243d496f724f38894c941e"
integrity sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==
dependencies:
is-svg "^3.0.0"
postcss "^7.0.0"
postcss-value-parser "^3.0.0"
svgo "^1.0.0"
@@ -6342,11 +6282,6 @@ querystring@0.2.0:
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
querystringify@^2.1.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@@ -6528,9 +6463,9 @@ remove-trailing-separator@^1.0.1:
integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8=
repeat-element@^1.1.2:
version "1.1.3"
resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce"
integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==
version "1.1.4"
resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9"
integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==
repeat-string@^1.6.1:
version "1.6.1"
@@ -6950,18 +6885,6 @@ snapdragon@^0.8.1:
source-map-resolve "^0.5.0"
use "^3.1.0"
sockjs-client@^1.5.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.1.tgz#256908f6d5adfb94dabbdbd02c66362cca0f9ea6"
integrity sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ==
dependencies:
debug "^3.2.6"
eventsource "^1.0.7"
faye-websocket "^0.11.3"
inherits "^2.0.4"
json3 "^3.3.3"
url-parse "^1.5.1"
sockjs@^0.3.21:
version "0.3.21"
resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417"
@@ -7264,9 +7187,9 @@ svgo@^1.0.0:
util.promisify "~1.0.0"
sweetalert2@^10.15.6:
version "10.15.7"
resolved "https://registry.yarnpkg.com/sweetalert2/-/sweetalert2-10.15.7.tgz#ad4c8f08432952d3283adbaa9a309c534f5a863d"
integrity sha512-imY0MR03NGefPcGzSYjWYz1GMIlniusEBXilswvKrHD/GMiTxA5jnsdjtK2IoRyXfEaqV7GWt6DM4YVjAZU8gw==
version "10.16.0"
resolved "https://registry.yarnpkg.com/sweetalert2/-/sweetalert2-10.16.0.tgz#33d527af90689baab1078bf447b1986b796d4c75"
integrity sha512-qJp4nIpx0MPDnAdY6MurwH/mAovfCzWo07hFoQ41C46XGLpNkxiqBbJDNdhGfMFwbDY1e9jfttNFxe5IsrkEtA==
tapable@^2.1.1, tapable@^2.2.0:
version "2.2.0"
@@ -7414,9 +7337,9 @@ tslib@^1.9.0:
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2.0.3:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
version "2.2.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c"
integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==
tty-browserify@0.0.0:
version "0.0.0"
@@ -7588,14 +7511,6 @@ urix@^0.1.0:
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
url-parse@^1.4.3, url-parse@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b"
integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==
dependencies:
querystringify "^2.1.1"
requires-port "^1.0.0"
url@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
@@ -7638,18 +7553,6 @@ util@^0.11.0:
dependencies:
inherits "2.0.3"
util@^0.12.3:
version "0.12.3"
resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888"
integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==
dependencies:
inherits "^2.0.3"
is-arguments "^1.0.4"
is-generator-function "^1.0.7"
is-typed-array "^1.1.3"
safe-buffer "^5.1.2"
which-typed-array "^1.1.2"
utils-merge@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
@@ -7750,9 +7653,9 @@ vue-template-es2015-compiler@^1.9.0:
integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
vue-typeahead-bootstrap@^2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/vue-typeahead-bootstrap/-/vue-typeahead-bootstrap-2.8.0.tgz#ff14c7cf63b56972c7df6b01443c447e60535730"
integrity sha512-GCGY6ASqlf/JSyWrmvWM1BAZsTUjuh2xjLb0YXXSbhb2/71b0YZHyVrLs7pv8A9swjnLv4t63ijwBlj+C6iEQg==
version "2.11.0"
resolved "https://registry.yarnpkg.com/vue-typeahead-bootstrap/-/vue-typeahead-bootstrap-2.11.0.tgz#075efef9a69206836520f01f796936026fc49281"
integrity sha512-BLwO8c7xkivqVQlx36c84kz+zfuXnhHDlnGhgxI75RRtNFp7DKQQn+5Xf5dV5mEvpOM9af49ajBffDddKAX1IQ==
dependencies:
lodash "^4.17.20"
resize-observer-polyfill "^1.5.0"
@@ -7821,9 +7724,9 @@ webpack-dev-middleware@^4.1.0:
schema-utils "^3.0.0"
webpack-dev-server@^4.0.0-beta.0:
version "4.0.0-beta.1"
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.0.0-beta.1.tgz#6feb4ff7a3bbc6a60f624f74b15065c60a6e864f"
integrity sha512-rPSAfz1VKQDQ2kmRbOamc0mX+T7kfqi9acvHic1YYctHWfKKvtovwLm9sA48GdLiYb8Ynop79zdT3CUoFiT7YQ==
version "4.0.0-beta.2"
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.0.0-beta.2.tgz#0364a5756544da9c077da829016817703db4d5ed"
integrity sha512-kbUAjQg1FLtCoIZ0NdcTZWRBVT1EDajBSvGAiAqQPJxBjsr0N3FQ57kJ/4SrIZPyAajn8kcHctwFsTKPwme1tQ==
dependencies:
ansi-html "^0.0.7"
bonjour "^3.5.0"
@@ -7834,24 +7737,22 @@ webpack-dev-server@^4.0.0-beta.0:
express "^4.17.1"
find-cache-dir "^3.3.1"
graceful-fs "^4.2.6"
html-entities "^2.1.1"
http-proxy-middleware "^1.0.6"
html-entities "^2.3.2"
http-proxy-middleware "^1.1.0"
internal-ip "^6.2.0"
ipaddr.js "^1.9.1"
ipaddr.js "^2.0.0"
is-absolute-url "^3.0.3"
killable "^1.0.1"
open "^7.4.2"
p-retry "^4.4.0"
p-retry "^4.5.0"
portfinder "^1.0.28"
schema-utils "^3.0.0"
selfsigned "^1.10.8"
serve-index "^1.9.1"
sockjs "^0.3.21"
sockjs-client "^1.5.0"
spdy "^4.0.2"
strip-ansi "^6.0.0"
url "^0.11.0"
util "^0.12.3"
webpack-dev-middleware "^4.1.0"
ws "^7.4.4"
@@ -7888,9 +7789,9 @@ webpack-sources@^2.1.1:
source-map "^0.6.1"
webpack@^5.25.1, webpack@^5.30.0:
version "5.30.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.30.0.tgz#07d87c182a060e0c2491062f3dc0edc85a29d884"
integrity sha512-Zr9NIri5yzpfmaMea2lSMV1UygbW0zQsSlGLMgKUm63ACXg6alhd1u4v5UBSBjzYKXJN6BNMGVM7w165e7NxYA==
version "5.31.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.31.0.tgz#fab61d0be896feca4af87bdad5c18815c0d63455"
integrity sha512-3fUfZT/FUuThWSSyL32Fsh7weUUfYP/Fjc/cGSbla5KiSo0GtI1JMssCRUopJTvmLjrw05R2q7rlLtiKdSzkzQ==
dependencies:
"@types/eslint-scope" "^3.7.0"
"@types/estree" "^0.0.46"
@@ -7955,19 +7856,6 @@ which-boxed-primitive@^1.0.2:
is-string "^1.0.5"
is-symbol "^1.0.3"
which-typed-array@^1.1.2:
version "1.1.4"
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff"
integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==
dependencies:
available-typed-arrays "^1.0.2"
call-bind "^1.0.0"
es-abstract "^1.18.0-next.1"
foreach "^2.0.5"
function-bind "^1.1.1"
has-symbols "^1.0.1"
is-typed-array "^1.1.3"
which@^2.0.1, which@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
@@ -8017,9 +7905,9 @@ xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.1:
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
y18n@^5.0.5:
version "5.0.6"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.6.tgz#8236b05cfc5af6a409f41326a4847c68989bb04f"
integrity sha512-PlVX4Y0lDTN6E2V4ES2tEdyvXkeKzxa8c/vo0pxPr/TqbztddTP0yn7zZylIyiAuxerqj0Q5GhpJ1YJCP8LaZQ==
version "5.0.8"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
yallist@^2.1.2:
version "2.1.2"