Merge branch 'master' of github.com:akaunting/akaunting into 2.1-dev
# Conflicts: # app/Http/Controllers/Common/Items.php # resources/views/modules/item/documentation.blade.php # resources/views/modules/item/show.blade.php # resources/views/partials/admin/header.blade.php # resources/views/purchases/bills/show.blade.php # resources/views/purchases/vendors/show.blade.php # resources/views/sales/customers/show.blade.php # resources/views/sales/invoices/show.blade.php # resources/views/wizard/companies/edit.blade.php # resources/views/wizard/currencies/index.blade.php # resources/views/wizard/finish/index.blade.php # resources/views/wizard/taxes/index.blade.php
This commit is contained in:
@ -19,9 +19,12 @@
|
||||
|
||||
<el-carousel-item v-for="(screenshot, index) in screenshots" :key="index">
|
||||
<img class="d-block w-100 carousel-frame" height="365px" :src="screenshot.path_string" :alt="screenshot.alt_attribute">
|
||||
<div class="carousel-description py-2">
|
||||
<div class="carousel-description py-2" v-if="screenshot.description">
|
||||
{{ screenshot.description }}
|
||||
</div>
|
||||
<div class="carousel-description py-2" v-else>
|
||||
{{ name }}
|
||||
</div>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
|
201
resources/assets/js/components/AkauntingCountdown.vue
Normal file
201
resources/assets/js/components/AkauntingCountdown.vue
Normal file
@ -0,0 +1,201 @@
|
||||
<template>
|
||||
<div class="countdown">
|
||||
<section class="flex text-6xl justify-center content-center">
|
||||
<div class="days mr-2 relative">
|
||||
{{ displayDays}}
|
||||
<div class="label text-sm absolut bottom-0"> {{ textDays }} </div>
|
||||
</div>
|
||||
|
||||
<span class="leading-snug">:</span>
|
||||
|
||||
<div class="hours mx-2 relative">
|
||||
{{ displayHours }}
|
||||
<div class="label text-sm absolut bottom-0">{{ textHours }} </div>
|
||||
</div>
|
||||
|
||||
<span class="leading-snug">:</span>
|
||||
|
||||
<div class="minutes mx-2 relative">
|
||||
{{ displayMinutes }}
|
||||
<div class="label text-sm absolut bottom-0"> {{ textMinutes }} </div>
|
||||
</div>
|
||||
|
||||
<span class="leading-snug">:</span>
|
||||
|
||||
<div class="seconds ml-2 relative">
|
||||
{{ displaySeconds }}
|
||||
<div class="label text-sm absolut bottom-0"> {{ textSeconds }} </div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'akaunting-countdown',
|
||||
|
||||
props: {
|
||||
textDays: {
|
||||
type: String,
|
||||
default: 'days',
|
||||
description: "Modal header title"
|
||||
},
|
||||
|
||||
textHours: {
|
||||
type: String,
|
||||
default: 'hours',
|
||||
description: "Modal header title"
|
||||
},
|
||||
|
||||
textMinutes: {
|
||||
type: String,
|
||||
default: 'minutes',
|
||||
description: "Modal header title"
|
||||
},
|
||||
|
||||
textSeconds: {
|
||||
type: String,
|
||||
default: 'seconds',
|
||||
description: "Modal header title"
|
||||
},
|
||||
|
||||
year: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
description: "Modal header title"
|
||||
},
|
||||
month: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
description: "Modal header title"
|
||||
},
|
||||
date: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
description: "Input readonly status"
|
||||
},
|
||||
hour: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
description: "Input disabled status"
|
||||
},
|
||||
minute: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
description: "Input value defalut"
|
||||
},
|
||||
second: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
description: "Input model defalut"
|
||||
},
|
||||
millisecond: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
description: "Prepend icon (left)"
|
||||
}
|
||||
},
|
||||
|
||||
data:() => ({
|
||||
displayDays: 0,
|
||||
displayHours: 0,
|
||||
displayMinutes: 0,
|
||||
displaySeconds: 0,
|
||||
loaded: false,
|
||||
expired: false
|
||||
}),
|
||||
|
||||
computed: {
|
||||
_seconds: () => 1000,
|
||||
|
||||
_minutes() {
|
||||
return this._seconds * 60;
|
||||
},
|
||||
|
||||
_hours() {
|
||||
return this._minutes * 60;
|
||||
},
|
||||
|
||||
_days() {
|
||||
return this._hours * 24;
|
||||
},
|
||||
|
||||
end() {
|
||||
return new Date(
|
||||
this.year,
|
||||
this.month,
|
||||
this.date,
|
||||
this.hour,
|
||||
this.minute,
|
||||
this.second,
|
||||
this.millisecond
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.showRemainig();
|
||||
},
|
||||
|
||||
methods: {
|
||||
formatNum: num =>(num < 10 ? '0' + num : num),
|
||||
|
||||
showRemainig() {
|
||||
const timer = setInterval(() => {
|
||||
const now = new Date();
|
||||
|
||||
const distance = this.end.getTime() - now.getTime();
|
||||
|
||||
if (distance < 0) {
|
||||
clearInterval(timer);
|
||||
|
||||
this.expired = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const days = Math.floor(distance / this._days);
|
||||
const hours = Math.floor((distance % this._days) / this._hours);
|
||||
const minutes = Math.floor((distance % this._hours) / this._minutes);
|
||||
const seconds = Math.floor((distance % this._minutes) / this._seconds);
|
||||
|
||||
this.displayMinutes = this.formatNum(minutes);
|
||||
this.displaySeconds = this.formatNum(seconds);
|
||||
this.displayHours = this.formatNum(hours);
|
||||
this.displayDays = this.formatNum(days);
|
||||
|
||||
this.loaded = true;
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.countdown {
|
||||
text-align: justify;
|
||||
}
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
.justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
.content-center {
|
||||
align-content: center;
|
||||
}
|
||||
.seconds {
|
||||
max-width: 60px;
|
||||
}
|
||||
.leading-snug {
|
||||
line-height: 1.375;
|
||||
}
|
||||
.days, .hours, .minutes, .seconds {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
@ -6,7 +6,7 @@
|
||||
{'disabled': disabled},
|
||||
formClasses
|
||||
]"
|
||||
:error="formError"
|
||||
:footer-error="formError"
|
||||
:prependIcon="icon"
|
||||
:readonly="readonly"
|
||||
:disabled="disabled"
|
||||
|
@ -49,45 +49,64 @@
|
||||
|
||||
let editorRef = this.$refs.editor;
|
||||
let node = editorRef.children[0];
|
||||
|
||||
this.editor.on('text-change', () => {
|
||||
let html = node.innerHTML
|
||||
let html = node.innerHTML;
|
||||
|
||||
if (html === '<p><br></p>') {
|
||||
html = '';
|
||||
}
|
||||
this.content = html
|
||||
|
||||
this.content = html;
|
||||
|
||||
this.$emit('input', this.content);
|
||||
})
|
||||
},
|
||||
|
||||
pasteHTML () {
|
||||
if (!this.editor) {
|
||||
return
|
||||
}
|
||||
this.editor.pasteHTML(this.value)
|
||||
|
||||
this.editor.pasteHTML(this.value);
|
||||
},
|
||||
|
||||
randomString() {
|
||||
let text = "";
|
||||
let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
for (let i = 0; i < 5; i++)
|
||||
for (let i = 0; i < 5; i++) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
},
|
||||
|
||||
async mounted () {
|
||||
let Quill = await import('quill')
|
||||
Quill = Quill.default || Quill
|
||||
this.content = this.value;
|
||||
|
||||
let Quill = await import('quill');
|
||||
|
||||
Quill = Quill.default || Quill;
|
||||
|
||||
this.editorId = this.randomString();
|
||||
this.toolbarId = this.randomString();
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.initialize(Quill)
|
||||
});
|
||||
},
|
||||
|
||||
watch: {
|
||||
value (newVal) {
|
||||
if (newVal !== this.content) {
|
||||
this.pasteHTML(newVal);
|
||||
}
|
||||
},
|
||||
|
||||
content (newVal) {
|
||||
this.$emit('input', newVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
</div>
|
||||
<div class="modal-body pb-0" v-else>
|
||||
<form id="form-create" method="POST" action="#"/>
|
||||
|
||||
<component v-bind:is="component"></component>
|
||||
</div>
|
||||
</slot>
|
||||
@ -33,7 +34,11 @@
|
||||
{{ buttons.cancel.text }}
|
||||
</button>
|
||||
|
||||
<button :disabled="form.loading" type="button" class="btn button-submit" :class="buttons.confirm.class" @click="onSubmit">
|
||||
<a v-if="buttons.payment" :href="buttons.payment.url" class="btn btn-white" :class="buttons.payment.class">
|
||||
{{ buttons.payment.text }}
|
||||
</a>
|
||||
|
||||
<button :disabled="form.loading" type="button" class="btn button-submit" :class="buttons.confirm.class" @click="onSubmit">
|
||||
<div class="aka-loader"></div><span>{{ buttons.confirm.text }}</span>
|
||||
</button>
|
||||
</div>
|
||||
@ -139,10 +144,12 @@ export default {
|
||||
},
|
||||
|
||||
mounted() {
|
||||
let form_prefix = this._uid;
|
||||
|
||||
if (this.is_component) {
|
||||
this.component = Vue.component('add-new-component', (resolve, reject) => {
|
||||
resolve({
|
||||
template : '<div id="modal-add-new-form">' + this.message + '</div>',
|
||||
template : '<div id="modal-add-new-form-' + form_prefix + '">' + this.message + '</div>',
|
||||
|
||||
components: {
|
||||
AkauntingRadioGroup,
|
||||
@ -159,7 +166,7 @@ export default {
|
||||
},
|
||||
|
||||
mounted() {
|
||||
let form_id = document.getElementById('modal-add-new-form').children[0].id;
|
||||
let form_id = document.getElementById('modal-add-new-form-' + form_prefix).children[0].id;
|
||||
|
||||
this.form = new Form(form_id);
|
||||
},
|
||||
@ -217,7 +224,24 @@ export default {
|
||||
})
|
||||
.catch(error => {
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// Change bank account get money and currency rate
|
||||
async onChangePaymentAccount(account_id) {
|
||||
let payment_account = Promise.resolve(window.axios.get(url + '/banking/accounts/currency', {
|
||||
params: {
|
||||
account_id: account_id
|
||||
}
|
||||
}));
|
||||
|
||||
payment_account.then(response => {
|
||||
this.form.currency = response.data.currency_name;
|
||||
this.form.currency_code = response.data.currency_code;
|
||||
this.form.currency_rate = response.data.currency_rate;
|
||||
})
|
||||
.catch(error => {
|
||||
});
|
||||
},
|
||||
}
|
||||
})
|
||||
});
|
||||
|
@ -10,7 +10,7 @@
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<money :name="name" @input="input" :placeholder="placeholder" v-bind="money" :value="value" :disabled="disabled" :masked="masked" class="form-control"></money>
|
||||
<money :name="name" @input="input" :placeholder="placeholder" v-bind="money" :value="model" :disabled="disabled" :masked="masked" class="form-control"></money>
|
||||
</div>
|
||||
|
||||
<div class="invalid-feedback d-block" v-if="error" v-html="error"></div>
|
||||
@ -126,6 +126,8 @@ export default {
|
||||
},
|
||||
|
||||
mounted() {
|
||||
//this.model = this.value;
|
||||
|
||||
this.$emit('interface', this.model);
|
||||
},
|
||||
|
||||
@ -133,10 +135,15 @@ export default {
|
||||
change() {
|
||||
//this.$emit('change', this.model);
|
||||
//this.$emit('interface', this.model);
|
||||
|
||||
this.$emit('input', this.model);
|
||||
},
|
||||
|
||||
input(event) {
|
||||
this.model = event;
|
||||
|
||||
this.$emit('input', event);
|
||||
|
||||
//this.$emit('change', this.model);
|
||||
//this.$emit('interface', this.model);
|
||||
}
|
||||
@ -144,6 +151,10 @@ export default {
|
||||
|
||||
watch: {
|
||||
dynamicCurrency: function (currency) {
|
||||
if (!currency) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.money = {
|
||||
decimal: currency.decimal_mark,
|
||||
thousands: currency.thousands_separator,
|
||||
@ -153,9 +164,11 @@ export default {
|
||||
masked: this.masked
|
||||
};
|
||||
},
|
||||
|
||||
value: function (value) {
|
||||
this.model = value;
|
||||
},
|
||||
|
||||
model: function (model) {
|
||||
this.$emit('change', this.model);
|
||||
this.$emit('interface', this.model);
|
||||
|
@ -763,7 +763,7 @@
|
||||
|
||||
<span slot="infoBlock" class="badge badge-success badge-resize float-right" v-if="new_options[real_model]">{{ new_text }}</span>
|
||||
|
||||
<select :name="name" v-model="real_model" class="d-none">
|
||||
<select :name="name" :id="name" v-model="real_model" class="d-none">
|
||||
<option v-for="(label, value) in selectOptions" :key="value" :value="value">{{ label }}</option>
|
||||
</select>
|
||||
</span>
|
||||
@ -923,6 +923,7 @@ export default {
|
||||
add_new_html: '',
|
||||
form: {},
|
||||
new_options: false,
|
||||
couunt: 1,
|
||||
}
|
||||
},
|
||||
|
||||
@ -989,6 +990,24 @@ export default {
|
||||
|
||||
this.$emit('interface', this.real_model);
|
||||
this.$emit('change', this.real_model);
|
||||
|
||||
//this.$children[0].$children[0].$emit('keydown.native.tab');
|
||||
//this.$children[0].$children[0].handleMenuEnter();
|
||||
|
||||
this.$children[0].$children[0].visible = false;
|
||||
|
||||
/*
|
||||
this.$children[0].$children[0].setSoftFocus();
|
||||
if (this.$children[0].$children[0].visible) return;
|
||||
|
||||
let option = {};
|
||||
|
||||
option.value = this.real_model;
|
||||
|
||||
this.$children[0].$children[0].$nextTick(() => {
|
||||
this.$children[0].$children[0].scrollToOption(option);
|
||||
});
|
||||
*/
|
||||
},
|
||||
|
||||
async onAddItem() {
|
||||
@ -1180,7 +1199,17 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
this.change();
|
||||
if (this.real_model != value) {
|
||||
this.change();
|
||||
}
|
||||
|
||||
let e = $.Event('keyup');
|
||||
e.keyCode= 9; // tab
|
||||
$('#' + this.name).trigger(e);
|
||||
|
||||
let event = new window.KeyboardEvent('keydown', { keyCode: 9 }); // Tab key
|
||||
|
||||
window.dispatchEvent(event);
|
||||
},
|
||||
|
||||
value: function (value) {
|
||||
@ -1246,4 +1275,4 @@ export default {
|
||||
margin-right: 35px;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -12,7 +12,11 @@
|
||||
]"
|
||||
:error="formError">
|
||||
<el-select v-model="real_model" @input="change" disabled filterable v-if="disabled"
|
||||
:placeholder="placeholder">
|
||||
remote
|
||||
reserve-keyword
|
||||
:placeholder="placeholder"
|
||||
:remote-method="remoteMethod"
|
||||
:loading="loading">
|
||||
<div v-if="addNew.status && options.length != 0" class="el-select-dropdown__wrap" slot="empty">
|
||||
<p class="el-select-dropdown__empty">
|
||||
{{ noMatchingDataText }}
|
||||
@ -85,7 +89,11 @@
|
||||
</el-select>
|
||||
|
||||
<el-select v-model="real_model" @input="change" filterable v-if="!disabled && !multiple"
|
||||
:placeholder="placeholder">
|
||||
remote
|
||||
reserve-keyword
|
||||
:placeholder="placeholder"
|
||||
:remote-method="remoteMethod"
|
||||
:loading="loading">
|
||||
<div v-if="addNew.status && options.length != 0" class="el-select-dropdown__wrap" slot="empty">
|
||||
<p class="el-select-dropdown__empty">
|
||||
{{ noMatchingDataText }}
|
||||
@ -158,7 +166,11 @@
|
||||
</el-select>
|
||||
|
||||
<el-select v-model="real_model" @input="change" filterable v-if="!disabled && multiple && !collapse" multiple
|
||||
:placeholder="placeholder">
|
||||
remote
|
||||
reserve-keyword
|
||||
:placeholder="placeholder"
|
||||
:remote-method="remoteMethod"
|
||||
:loading="loading">
|
||||
<div v-if="addNew.status && options.length != 0" class="el-select-dropdown__wrap" slot="empty">
|
||||
<p class="el-select-dropdown__empty">
|
||||
{{ noMatchingDataText }}
|
||||
@ -231,7 +243,11 @@
|
||||
</el-select>
|
||||
|
||||
<el-select v-model="real_model" @input="change" filterable v-if="!disabled && multiple && collapse" multiple collapse-tags
|
||||
:placeholder="placeholder">
|
||||
remote
|
||||
reserve-keyword
|
||||
:placeholder="placeholder"
|
||||
:remote-method="remoteMethod"
|
||||
:loading="loading">
|
||||
<div v-if="addNew.status && options.length != 0" class="el-select-dropdown__wrap" slot="empty">
|
||||
<p class="el-select-dropdown__empty">
|
||||
{{ noMatchingDataText }}
|
||||
@ -464,14 +480,14 @@ export default {
|
||||
},
|
||||
value: {
|
||||
type: [String, Number, Array],
|
||||
default: null,
|
||||
default: '',
|
||||
description: "Selectbox selected value"
|
||||
},
|
||||
options: null,
|
||||
|
||||
model: {
|
||||
type: [String, Number],
|
||||
default: '',
|
||||
default: null,
|
||||
description: "Selectbox selected model"
|
||||
},
|
||||
|
||||
@ -582,10 +598,21 @@ export default {
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.real_model = this.value;
|
||||
if (this.multiple) {
|
||||
if (!this.value.length) {
|
||||
this.real_model = [];
|
||||
} else {
|
||||
let pre_value = [];
|
||||
|
||||
if (this.multiple && !this.real_model.length) {
|
||||
this.real_model = [];
|
||||
this.value.forEach(item => {
|
||||
pre_value.push(item.toString());
|
||||
});
|
||||
|
||||
this.real_model = pre_value;
|
||||
}
|
||||
|
||||
} else {
|
||||
this.real_model = this.value;
|
||||
}
|
||||
|
||||
this.$emit('interface', this.real_model);
|
||||
@ -593,6 +620,10 @@ export default {
|
||||
|
||||
methods: {
|
||||
remoteMethod(query) {
|
||||
if (document.getElementById('form-select-' + this.name)) {
|
||||
document.getElementById('form-select-' + this.name).getElementsByTagName("input")[0].readOnly = false;
|
||||
}
|
||||
|
||||
if (query !== '') {
|
||||
this.loading = true;
|
||||
|
||||
@ -634,21 +665,27 @@ export default {
|
||||
},
|
||||
|
||||
change() {
|
||||
if (typeof(this.real_model) === 'object') {
|
||||
if (typeof(this.real_model) === 'object' && !Array.isArray(this.real_model)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Array.isArray(this.real_model) && !this.real_model.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.$emit('interface', this.real_model);
|
||||
this.$emit('change', this.real_model);
|
||||
|
||||
this.selectOptions.forEach(item => {
|
||||
if (item.id == this.real_model) {
|
||||
this.$emit('label', item.name);
|
||||
this.$emit('option', item);
|
||||
if (Array.isArray(this.selectOptions)) {
|
||||
this.selectOptions.forEach(item => {
|
||||
if (item.id == this.real_model) {
|
||||
this.$emit('label', item.name);
|
||||
this.$emit('option', item);
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onPressEnter() {
|
||||
@ -871,9 +908,37 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
real_model: function (value) {
|
||||
if (this.multiple) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.real_model != value) {
|
||||
this.change();
|
||||
}
|
||||
|
||||
let e = $.Event('keyup');
|
||||
e.keyCode= 9; // tab
|
||||
$('#' + this.name).trigger(e);
|
||||
|
||||
let event = new window.KeyboardEvent('keydown', { keyCode: 9 }); // Tab key
|
||||
|
||||
window.dispatchEvent(event);
|
||||
},
|
||||
|
||||
value: function (value) {
|
||||
if (this.multiple) {
|
||||
this.real_model = value;
|
||||
if (Array.isArray(this.real_model) && !this.real_model.length) {
|
||||
this.real_model = value;
|
||||
} else {
|
||||
let pre_value = [];
|
||||
|
||||
value.forEach(item => {
|
||||
pre_value.push(item.toString());
|
||||
});
|
||||
|
||||
this.real_model = pre_value;
|
||||
}
|
||||
} else {
|
||||
//this.real_model = value.toString();
|
||||
this.real_model = value;
|
||||
|
@ -52,6 +52,11 @@
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
<slot name="error">
|
||||
<div v-if="footerError" class="invalid-feedback d-block"
|
||||
v-html="footerError">
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@ -84,6 +89,10 @@
|
||||
type: String,
|
||||
description: "Input error (below input)"
|
||||
},
|
||||
footerError: {
|
||||
type: String,
|
||||
description: "Input error (below input)"
|
||||
},
|
||||
successMessage: {
|
||||
type: String,
|
||||
description: "Input success message",
|
||||
|
Reference in New Issue
Block a user