mirror of
https://github.com/crater-invoice/crater.git
synced 2026-02-09 20:32:40 -05:00
Merge branch 'master' of https://gitlab.com/mohit.panjvani/crater-web into fix-view-status-action
This commit is contained in:
@@ -98,7 +98,7 @@ export default {
|
||||
},
|
||||
password: {
|
||||
required,
|
||||
minLength: minLength(8)
|
||||
minLength: minLength(5)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
>
|
||||
<table-column :label="$t('dashboard.recent_invoices_card.due_on')" show="formattedDueDate" />
|
||||
<table-column :label="$t('dashboard.recent_invoices_card.customer')" show="user.name" />
|
||||
<table-column :label="$t('dashboard.recent_invoices_card.amount_due')" sort-as="due_amount">
|
||||
<table-column :label="$t('dashboard.recent_invoices_card.amount_due')" show="due_amount" sort-as="due_amount">
|
||||
<template slot-scope="row">
|
||||
<span>{{ $t('dashboard.recent_invoices_card.amount_due') }}</span>
|
||||
<div v-html="$utils.formatMoney(row.due_amount, row.user.currency)"/>
|
||||
@@ -242,7 +242,7 @@
|
||||
>
|
||||
<table-column :label="$t('dashboard.recent_estimate_card.date')" show="formattedExpiryDate" />
|
||||
<table-column :label="$t('dashboard.recent_estimate_card.customer')" show="user.name" />
|
||||
<table-column :label="$t('dashboard.recent_estimate_card.amount_due')" sort-as="total">
|
||||
<table-column :label="$t('dashboard.recent_estimate_card.amount_due')" show="total" sort-as="total">
|
||||
<template slot-scope="row">
|
||||
<span>{{ $t('dashboard.recent_estimate_card.amount_due') }}</span>
|
||||
<div v-html="$utils.formatMoney(row.total, row.user.currency)"/>
|
||||
|
||||
@@ -553,6 +553,8 @@ export default {
|
||||
if (response.data) {
|
||||
this.selectCustomer(response.data.estimate.user_id)
|
||||
this.newEstimate = response.data.estimate
|
||||
this.newEstimate.estimate_date = moment(response.data.estimate.estimate_date, 'YYYY-MM-DD').toString()
|
||||
this.newEstimate.expiry_date = moment(response.data.estimate.expiry_date, 'YYYY-MM-DD').toString()
|
||||
this.discountPerItem = response.data.discount_per_item
|
||||
this.taxPerItem = response.data.tax_per_item
|
||||
this.selectedCurrency = this.defaultCurrency
|
||||
|
||||
@@ -261,13 +261,13 @@
|
||||
{{ $t('estimates.send_estimate') }}
|
||||
</a>
|
||||
</v-dropdown-item>
|
||||
<v-dropdown-item v-if="row.status === 'DRAFT' || row.status === 'REJECTED'">
|
||||
<v-dropdown-item v-if="row.status !== 'ACCEPTED'">
|
||||
<a class="dropdown-item" href="#" @click.self="onMarkAsAccepted(row.id)">
|
||||
<font-awesome-icon icon="check-circle" class="dropdown-item-icon" />
|
||||
{{ $t('estimates.mark_as_accepted') }}
|
||||
</a>
|
||||
</v-dropdown-item>
|
||||
<v-dropdown-item v-if="row.status === 'ACCEPTED' || row.status === 'DRAFT'">
|
||||
<v-dropdown-item v-if="row.status !== 'REJECTED'">
|
||||
<a class="dropdown-item" href="#" @click.self="onMarkAsRejected(row.id)">
|
||||
<font-awesome-icon icon="times-circle" class="dropdown-item-icon" />
|
||||
{{ $t('estimates.mark_as_rejected') }}
|
||||
@@ -514,8 +514,8 @@ export default {
|
||||
icon: '/assets/icon/envelope-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true
|
||||
}).then(async (willDelete) => {
|
||||
if (willDelete) {
|
||||
}).then(async (willConvertInToinvoice) => {
|
||||
if (willConvertInToinvoice) {
|
||||
let res = await this.convertToInvoice(id)
|
||||
if (res.data) {
|
||||
window.toastr['success'](this.$t('estimates.conversion_message'))
|
||||
@@ -562,8 +562,8 @@ export default {
|
||||
icon: '/assets/icon/check-circle-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true
|
||||
}).then(async (willDelete) => {
|
||||
if (willDelete) {
|
||||
}).then(async (willMarkAsSent) => {
|
||||
if (willMarkAsSent) {
|
||||
const data = {
|
||||
id: id
|
||||
}
|
||||
@@ -582,8 +582,8 @@ export default {
|
||||
icon: '/assets/icon/paper-plane-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true
|
||||
}).then(async (sendEstimate) => {
|
||||
if (sendEstimate) {
|
||||
}).then(async (willSendEstimate) => {
|
||||
if (willSendEstimate) {
|
||||
const data = {
|
||||
id: id
|
||||
}
|
||||
|
||||
@@ -222,12 +222,22 @@ export default {
|
||||
return true
|
||||
},
|
||||
async onMarkAsSent () {
|
||||
this.isRequestOnGoing = true
|
||||
let response = await this.markAsSent({id: this.estimate.id})
|
||||
this.isRequestOnGoing = false
|
||||
if (response.data) {
|
||||
window.toastr['success'](this.$tc('estimates.mark_as_sent'))
|
||||
}
|
||||
swal({
|
||||
title: this.$t('general.are_you_sure'),
|
||||
text: this.$t('estimates.confirm_mark_as_sent'),
|
||||
icon: '/assets/icon/check-circle-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true
|
||||
}).then(async (willMarkAsSent) => {
|
||||
if (willMarkAsSent) {
|
||||
this.isRequestOnGoing = true
|
||||
let response = await this.markAsSent({id: this.estimate.id})
|
||||
this.isRequestOnGoing = false
|
||||
if (response.data) {
|
||||
window.toastr['success'](this.$tc('estimates.mark_as_sent'))
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
async removeEstimate (id) {
|
||||
this.selectEstimate([parseInt(id)])
|
||||
@@ -235,7 +245,7 @@ export default {
|
||||
swal({
|
||||
title: 'Deleted',
|
||||
text: 'you will not be able to recover this estimate!',
|
||||
icon: 'error',
|
||||
icon: '/assets/icon/trash-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true
|
||||
}).then(async (willDelete) => {
|
||||
|
||||
@@ -554,6 +554,8 @@ export default {
|
||||
if (response.data) {
|
||||
this.selectCustomer(response.data.invoice.user_id)
|
||||
this.newInvoice = response.data.invoice
|
||||
this.newInvoice.invoice_date = moment(response.data.invoice.invoice_date, 'YYYY-MM-DD').toString()
|
||||
this.newInvoice.due_date = moment(response.data.invoice.due_date, 'YYYY-MM-DD').toString()
|
||||
this.discountPerItem = response.data.discount_per_item
|
||||
this.taxPerItem = response.data.tax_per_item
|
||||
this.selectedCurrency = this.defaultCurrency
|
||||
|
||||
@@ -286,7 +286,7 @@ export default {
|
||||
swal({
|
||||
title: 'Deleted',
|
||||
text: 'you will not be able to recover this invoice!',
|
||||
icon: 'error',
|
||||
icon: '/assets/icon/trash-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true
|
||||
}).then(async (willDelete) => {
|
||||
|
||||
@@ -112,7 +112,8 @@ export default {
|
||||
{ name: 'kg', value: 'kg' },
|
||||
{ name: 'km', value: 'km' },
|
||||
{ name: 'lb', value: 'lb' },
|
||||
{ name: 'mg', value: 'mg' }
|
||||
{ name: 'mg', value: 'mg' },
|
||||
{ name: 'pc', value: 'pc' }
|
||||
],
|
||||
formData: {
|
||||
name: '',
|
||||
|
||||
@@ -245,7 +245,8 @@ export default {
|
||||
{ name: 'kg', value: 'kg' },
|
||||
{ name: 'km', value: 'km' },
|
||||
{ name: 'lb', value: 'lb' },
|
||||
{ name: 'mg', value: 'mg' }
|
||||
{ name: 'mg', value: 'mg' },
|
||||
{ name: 'pc', value: 'pc' }
|
||||
],
|
||||
isRequestOngoing: true,
|
||||
filtersApplied: false,
|
||||
|
||||
@@ -196,7 +196,14 @@ export default {
|
||||
return true
|
||||
},
|
||||
downloadReport () {
|
||||
this.url += '&download=true'
|
||||
if (!this.getReports()) {
|
||||
return false
|
||||
}
|
||||
if (navigator.appVersion.indexOf('Mac') !== -1) {
|
||||
this.url += '&download=true'
|
||||
} else {
|
||||
window.open(this.getReportUrl + '&download=true')
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
|
||||
}, 200)
|
||||
|
||||
@@ -200,7 +200,14 @@ export default {
|
||||
return true
|
||||
},
|
||||
downloadReport () {
|
||||
this.url += '&download=true'
|
||||
if (!this.getReports()) {
|
||||
return false
|
||||
}
|
||||
if (navigator.appVersion.indexOf('Mac') !== -1) {
|
||||
this.url += '&download=true'
|
||||
} else {
|
||||
window.open(this.getReportUrl + '&download=true')
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
|
||||
}, 200)
|
||||
|
||||
@@ -238,7 +238,14 @@ export default {
|
||||
return true
|
||||
},
|
||||
downloadReport () {
|
||||
this.url += '&download=true'
|
||||
if (!this.getReports()) {
|
||||
return false
|
||||
}
|
||||
if (navigator.appVersion.indexOf('Mac') !== -1) {
|
||||
this.url += '&download=true'
|
||||
} else {
|
||||
window.open(this.getReportUrl + '&download=true')
|
||||
}
|
||||
setTimeout(() => {
|
||||
if (this.selectedType === 'By Customer') {
|
||||
this.url = `${this.customerSiteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
|
||||
|
||||
@@ -189,14 +189,21 @@ export default {
|
||||
this.$v.formData.$touch()
|
||||
|
||||
if (this.$v.$invalid) {
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
|
||||
return true
|
||||
},
|
||||
downloadReport () {
|
||||
this.url += '&download=true'
|
||||
if (!this.getReports()) {
|
||||
return false
|
||||
}
|
||||
if (navigator.appVersion.indexOf('Mac') !== -1) {
|
||||
this.url += '&download=true'
|
||||
} else {
|
||||
window.open(this.url + '&download=true')
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
|
||||
}, 200)
|
||||
|
||||
@@ -66,8 +66,9 @@
|
||||
<base-input
|
||||
:invalid="$v.mailConfigData.mail_password.$error"
|
||||
v-model.trim="mailConfigData.mail_password"
|
||||
type="mail_password"
|
||||
type="password"
|
||||
name="name"
|
||||
show-password
|
||||
@input="$v.mailConfigData.mail_password.$touch()"
|
||||
/>
|
||||
<div v-if="$v.mailConfigData.mail_password.$error">
|
||||
@@ -141,12 +142,12 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
mailConfigData: {
|
||||
mail_driver: 'smtp',
|
||||
mail_host: 'mailtrap.io',
|
||||
mail_port: 2525,
|
||||
mail_username: 'cc3c64516febd4',
|
||||
mail_password: 'e6a0176301f587',
|
||||
mail_encryption: 'tls'
|
||||
mail_driver: '',
|
||||
mail_host: '',
|
||||
mail_port: null,
|
||||
mail_username: '',
|
||||
mail_password: '',
|
||||
mail_encryption: ''
|
||||
},
|
||||
loading: false,
|
||||
mail_drivers: []
|
||||
@@ -176,18 +177,22 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// this.getMailDrivers()
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
async getMailDrivers () {
|
||||
async loadData () {
|
||||
this.loading = true
|
||||
|
||||
let response = await window.axios.get('/api/admin/onboarding/environment/mail')
|
||||
let mailDrivers = await window.axios.get('/api/settings/environment/mail')
|
||||
let mailData = await window.axios.get('/api/settings/environment/mail-env')
|
||||
|
||||
if (response.data) {
|
||||
this.mail_drivers = response.data
|
||||
this.loading = false
|
||||
if (mailDrivers.data) {
|
||||
this.mail_drivers = mailDrivers.data
|
||||
}
|
||||
if (mailData.data) {
|
||||
this.mailConfigData = mailData.data
|
||||
}
|
||||
this.loading = false
|
||||
},
|
||||
async saveEmailConfig () {
|
||||
this.$v.mailConfigData.$touch()
|
||||
@@ -196,7 +201,7 @@ export default {
|
||||
}
|
||||
this.loading = true
|
||||
try {
|
||||
let response = await window.axios.post('/api/admin/onboarding/environment/mail', this.mailConfigData)
|
||||
let response = await window.axios.post('/api/settings/environment/mail', this.mailConfigData)
|
||||
if (response.data.success) {
|
||||
window.toastr['success'](this.$t('wizard.success.' + response.data.success))
|
||||
} else {
|
||||
|
||||
@@ -29,16 +29,9 @@
|
||||
>
|
||||
<table-column
|
||||
:sortable="true"
|
||||
:filterable="true"
|
||||
:label="$t('settings.tax_types.tax_name')"
|
||||
>
|
||||
<template slot-scope="row">
|
||||
<span>{{ $t('settings.tax_types.tax_name') }}</span>
|
||||
<span class="tax-name mt-3">
|
||||
{{ row.name }}
|
||||
</span>
|
||||
</template>
|
||||
</table-column>
|
||||
show="name"
|
||||
/>
|
||||
<table-column
|
||||
:sortable="true"
|
||||
:filterable="true"
|
||||
|
||||
55
resources/assets/js/views/settings/UpdateApp.vue
Normal file
55
resources/assets/js/views/settings/UpdateApp.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div class="setting-main-container">
|
||||
<div class="card setting-card">
|
||||
<div class="page-header">
|
||||
<h3 class="page-title">{{ $t('settings.update_app.title') }}</h3>
|
||||
<p class="page-sub-title">
|
||||
{{ $t('settings.update_app.description') }}
|
||||
</p>
|
||||
<base-button size="large" icon="sync-alt" color="theme" @click="onUpdateApp">
|
||||
{{ $t('settings.update_app.update') }}
|
||||
</base-button>
|
||||
<div v-if="isShowProgressBar" class="progress mt-4">
|
||||
<div
|
||||
:style="[{'width': progress+'%'}]"
|
||||
class="progress-bar progress-bar-striped progress-bar-animated"
|
||||
role="progressbar"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
isShowProgressBar: false,
|
||||
progress: 10,
|
||||
interval: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
methods: {
|
||||
onUpdateApp () {
|
||||
this.isShowProgressBar = true
|
||||
this.interval = setInterval(() => {
|
||||
if (this.progress >= 100) {
|
||||
clearInterval(this.interval)
|
||||
setTimeout(() => {
|
||||
this.isShowProgressBar = false
|
||||
}, 1000)
|
||||
}
|
||||
this.progress += 10
|
||||
}, 250)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -106,7 +106,7 @@ export default {
|
||||
email
|
||||
},
|
||||
password: {
|
||||
minLength: minLength(8)
|
||||
minLength: minLength(5)
|
||||
},
|
||||
confirm_password: {
|
||||
required: requiredIf('isRequired'),
|
||||
|
||||
@@ -74,6 +74,12 @@ export default {
|
||||
title: 'settings.menu_title.notifications',
|
||||
icon: 'bell',
|
||||
iconType: 'far'
|
||||
},
|
||||
{
|
||||
link: '/admin/settings/update-app',
|
||||
title: 'settings.menu_title.update_app',
|
||||
icon: 'sync-alt',
|
||||
iconType: 'fas'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -94,17 +94,27 @@
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">{{ $t('wizard.address') }}</label>
|
||||
<base-text-area
|
||||
:invalid="$v.companyData.address_street_1.$error"
|
||||
v-model.trim="companyData.address_street_1"
|
||||
:placeholder="$t('general.street_1')"
|
||||
name="billing_street1"
|
||||
rows="2"
|
||||
@input="$v.companyData.address_street_1.$touch()"
|
||||
/>
|
||||
<div v-if="$v.companyData.address_street_1.$error">
|
||||
<span v-if="!$v.companyData.address_street_1.maxLength" class="text-danger">{{ $t('validation.description_maxlength') }}</span>
|
||||
</div>
|
||||
<base-text-area
|
||||
:invalid="$v.companyData.address_street_2.$error"
|
||||
v-model="companyData.address_street_2"
|
||||
:placeholder="$t('general.street_2')"
|
||||
name="billing_street2"
|
||||
rows="2"
|
||||
@input="$v.companyData.address_street_2.$touch()"
|
||||
/>
|
||||
<div v-if="$v.companyData.address_street_2.$error">
|
||||
<span v-if="!$v.companyData.address_street_2.maxLength" class="text-danger">{{ $t('validation.description_maxlength') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="row">
|
||||
@@ -146,7 +156,7 @@ import MultiSelect from 'vue-multiselect'
|
||||
import AvatarCropper from 'vue-avatar-cropper'
|
||||
import { validationMixin } from 'vuelidate'
|
||||
import Ls from '../../services/ls'
|
||||
const { required, minLength, email } = require('vuelidate/lib/validators')
|
||||
const { required, minLength, email, maxLength } = require('vuelidate/lib/validators')
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -197,6 +207,12 @@ export default {
|
||||
},
|
||||
country_id: {
|
||||
required
|
||||
},
|
||||
address_street_1: {
|
||||
maxLength: maxLength(255)
|
||||
},
|
||||
address_street_2: {
|
||||
maxLength: maxLength(255)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -97,7 +97,6 @@
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">{{ $t('wizard.database.password') }}</label>
|
||||
<span class="text-danger"> *</span>
|
||||
<base-input
|
||||
v-model.trim="databaseData.database_password"
|
||||
type="password"
|
||||
@@ -154,7 +153,7 @@ export default {
|
||||
database_name: null,
|
||||
database_username: null,
|
||||
database_password: null,
|
||||
app_url: null
|
||||
app_url: window.location.origin
|
||||
},
|
||||
loading: false,
|
||||
connections: [
|
||||
@@ -207,8 +206,8 @@ export default {
|
||||
}
|
||||
this.loading = false
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
window.toastr['error']('Something went wrong')
|
||||
console.log(e.response)
|
||||
window.toastr['error'](e.response.data.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,8 @@
|
||||
<base-input
|
||||
:invalid="$v.mailConfigData.mail_password.$error"
|
||||
v-model.trim="mailConfigData.mail_password"
|
||||
type="mail_password"
|
||||
type="password"
|
||||
show-password
|
||||
name="name"
|
||||
@input="$v.mailConfigData.mail_password.$touch()"
|
||||
/>
|
||||
|
||||
@@ -67,8 +67,8 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
tab: 'step_1',
|
||||
step: 1
|
||||
tab: 'step_3',
|
||||
step: 3
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<base-button
|
||||
v-if="requirements"
|
||||
v-if="hasNext"
|
||||
:loading="loading"
|
||||
class="pull-right mt-4"
|
||||
icon="arrow-right"
|
||||
@@ -46,7 +46,7 @@
|
||||
{{ $t('wizard.continue') }}
|
||||
</base-button>
|
||||
<base-button
|
||||
v-else
|
||||
v-if="!requirements"
|
||||
:loading="loading"
|
||||
class="pull-right mt-4"
|
||||
color="theme"
|
||||
@@ -74,6 +74,20 @@ export default {
|
||||
isShow: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasNext () {
|
||||
if (this.requirements) {
|
||||
let isRequired = true
|
||||
for (const key in this.requirements) {
|
||||
if (!this.requirements[key]) {
|
||||
isRequired = false
|
||||
}
|
||||
}
|
||||
return this.requirements && this.phpSupportInfo.supported && isRequired
|
||||
}
|
||||
return false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
listToggle () {
|
||||
this.isShow = !this.isShow
|
||||
|
||||
@@ -108,7 +108,7 @@ export default {
|
||||
},
|
||||
password: {
|
||||
required,
|
||||
minLength: minLength(8)
|
||||
minLength: minLength(5)
|
||||
},
|
||||
confirm_password: {
|
||||
required: requiredIf('isRequired'),
|
||||
|
||||
Reference in New Issue
Block a user