Add New SweetAlert & Notification Components

This commit is contained in:
Aman Upadhyay
2021-04-09 12:35:50 +00:00
committed by Mohit Panjwani
parent 3f7db2793f
commit c3d3e5e35f
78 changed files with 2295 additions and 984 deletions

View File

@ -45,9 +45,8 @@
</template>
<script type="text/babel">
import { async } from 'q'
const { required, email } = require('vuelidate/lib/validators')
import { mapActions } from 'vuex'
export default {
data() {
return {
@ -67,6 +66,7 @@ export default {
},
},
methods: {
...mapActions('notification', ['showNotification']),
async validateBeforeSubmit(e) {
this.$v.formData.$touch()
if (!this.$v.formData.$invalid) {
@ -78,7 +78,10 @@ export default {
)
if (res.data) {
toastr['success']('Mail sent successfuly!', 'Success')
this.showNotification({
type: 'success',
message: 'Mail sent successfuly!',
})
}
this.isSent = true

View File

@ -145,6 +145,7 @@ export default {
},
methods: {
...mapActions('auth', ['login']),
...mapActions('notification', ['showNotification']),
async validateBeforeSubmit() {
axios.defaults.withCredentials = true
@ -158,6 +159,10 @@ export default {
try {
await this.login(this.loginData)
this.$router.push('/admin/dashboard')
this.showNotification({
type: 'success',
message: 'Logged in successfully.',
})
this.isLoading = false
} catch (error) {
this.isLoading = false

View File

@ -92,6 +92,7 @@ const {
sameAs,
minLength,
} = require('vuelidate/lib/validators')
import { mapActions } from 'vuex'
export default {
data() {
@ -120,6 +121,7 @@ export default {
},
},
methods: {
...mapActions('notification', ['showNotification']),
async validateBeforeSubmit(e) {
this.$v.formData.$touch()
@ -135,18 +137,18 @@ export default {
let res = await axios.post('/api/v1/auth/reset/password', data)
this.isLoading = false
if (res.data) {
toastr['success'](
this.$t('login.password_reset_successfully'),
'Success'
)
this.showNotification({
type: 'success',
message: this.$t('login.password_reset_successfully'),
})
this.$router.push('/login')
}
} catch (err) {
if (err.response && err.response.status === 403) {
toastr['error'](
err.response.data,
this.$t('validation.email_incorrect')
)
this.showNotification({
type: 'error',
message: this.$t('validation.email_incorrect'),
})
this.isLoading = false
}
}

View File

@ -1,26 +1,26 @@
<template>
<base-page class="customer-create">
<form v-if="!initLoad" @submit.prevent="submitCustomerData">
<sw-page-header class="mb-5" :title="pageTitle">
<sw-page-header :title="pageTitle" class="mb-5">
<sw-breadcrumb slot="breadcrumbs">
<sw-breadcrumb-item
to="/admin/dashboard"
:title="$t('general.home')"
to="/admin/dashboard"
/>
<sw-breadcrumb-item
to="/admin/customers"
:title="$tc('customers.customer', 2)"
to="/admin/customers"
/>
<sw-breadcrumb-item
v-if="$route.name === 'customers.edit'"
to="#"
:title="$t('customers.edit_customer')"
to="#"
active
/>
<sw-breadcrumb-item
v-else
to="#"
:title="$t('customers.new_customer')"
to="#"
active
/>
</sw-breadcrumb>
@ -56,8 +56,8 @@
>
<sw-input-group
:label="$t('customers.display_name')"
class="md:col-span-3"
:error="displayNameError"
class="md:col-span-3"
required
>
<sw-input
@ -85,8 +85,8 @@
<sw-input-group
:label="$t('customers.email')"
class="md:col-span-3"
:error="emailError"
class="md:col-span-3"
>
<sw-input
:invalid="$v.formData.email.$error"
@ -243,8 +243,8 @@
<sw-input-group :label="$t('customers.zip_code')">
<sw-input
tabindex="14"
v-model.trim="billing.zip"
tabindex="14"
type="text"
name="zip"
/>
@ -406,16 +406,16 @@
class="grid col-span-5 lg:col-span-4 gap-y-6 gap-x-4 md:grid-cols-6"
>
<sw-input-group
class="md:col-span-3"
v-for="(field, index) in customFields"
:label="field.label"
:required="field.is_required ? true : false"
:key="index"
class="md:col-span-3"
>
<component
:type="field.type.label"
:field="field"
:isEdit="isEdit"
:is-edit="isEdit"
:is="field.type + 'Field'"
:invalid-fields="invalidFields"
:tabindex="23 + index"
@ -694,7 +694,7 @@ export default {
'updateCustomer',
'fetchViewCustomer',
]),
...mapActions('notification', ['showNotification']),
...mapActions('customFields', ['fetchCustomFields']),
currencyNameWithCode({ name, code }) {
@ -786,10 +786,16 @@ export default {
this.$router.push(
`/admin/customers/${response.data.customer.id}/view`
)
window.toastr['success'](this.$t('customers.updated_message'))
this.showNotification({
type: 'success',
message: this.$t('customers.updated_message'),
})
}
if (response.data.error) {
window.toastr['error'](this.$t('validation.email_already_taken'))
this.showNotification({
type: 'error',
message: this.$t('validation.email_already_taken'),
})
}
} else {
response = await this.addCustomer(this.formData)
@ -797,7 +803,10 @@ export default {
this.$router.push(
`/admin/customers/${response.data.customer.id}/view`
)
window.toastr['success'](this.$t('customers.created_message'))
this.showNotification({
type: 'success',
message: this.$t('customers.created_message'),
})
}
}
@ -806,7 +815,10 @@ export default {
} catch (error) {
this.isLoading = false
if (err.response.data.errors.email) {
window.toastr['error'](this.$t('validation.email_already_taken'))
this.showNotification({
type: 'error',
message: this.$t('validation.email_already_taken'),
})
}
}
},

View File

@ -195,7 +195,11 @@
<template slot-scope="row">
<span>{{ $t('customers.contact_name') }}</span>
<span>
{{ row.contact_name ? row.contact_name : $t('customers.no_contact_name') }}
{{
row.contact_name
? row.contact_name
: $t('customers.no_contact_name')
}}
</span>
</template>
</sw-table-column>
@ -354,6 +358,7 @@ export default {
'deleteMultipleCustomers',
'setSelectAllState',
]),
...mapActions('notification', ['showNotification']),
refreshTable() {
this.$refs.table.refresh()
},
@ -398,43 +403,60 @@ export default {
},
async removeCustomer(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('customers.confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.deleteCustomer({ ids: [id] })
if (res.data.success) {
window.toastr['success'](this.$tc('customers.deleted_message', 1))
this.showNotification({
type: 'success',
message: this.$tc('customers.deleted_message', 1),
})
this.$refs.table.refresh()
return true
}
window.toastr['error'](res.data.message)
this.showNotification({
type: 'error',
message: this.$tc(res.data.message),
})
return true
}
})
},
async removeMultipleCustomers() {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('customers.confirm_delete', 2),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let request = await this.deleteMultipleCustomers()
if (request.data.success) {
window.toastr['success'](this.$tc('customers.deleted_message', 2))
this.showNotification({
type: 'success',
message: this.$tc('customers.deleted_message', 2),
})
this.refreshTable()
} else if (request.data.error) {
window.toastr['error'](request.data.message)
this.showNotification({
type: 'error',
message: request.data.message,
})
}
}
})

View File

@ -3,8 +3,8 @@
<sw-page-header :title="pageTitle">
<template slot="actions">
<sw-button
tag-name="router-link"
:to="`/admin/customers/${$route.params.id}/edit`"
tag-name="router-link"
class="mr-3"
variant="primary-outline"
>
@ -15,29 +15,29 @@
{{ $t('customers.new_transaction') }}
</sw-button>
<sw-dropdown-item
tag-name="router-link"
:to="`/admin/estimates/create?customer=${$route.params.id}`"
tag-name="router-link"
>
<document-icon class="h-5 mr-3 text-gray-600" />
{{ $t('estimates.new_estimate') }}
</sw-dropdown-item>
<sw-dropdown-item
tag-name="router-link"
:to="`/admin/invoices/create?customer=${$route.params.id}`"
tag-name="router-link"
>
<document-text-icon class="h-5 mr-3 text-gray-600" />
{{ $t('invoices.new_invoice') }}
</sw-dropdown-item>
<sw-dropdown-item
tag-name="router-link"
:to="`/admin/payments/create?customer=${$route.params.id}`"
tag-name="router-link"
>
<credit-card-icon class="h-5 mr-3 text-gray-600" />
{{ $t('payments.new_payment') }}
</sw-dropdown-item>
<sw-dropdown-item
tag-name="router-link"
:to="`/admin/expenses/create?customer=${$route.params.id}`"
tag-name="router-link"
>
<calculator-icon class="h-5 mr-3 text-gray-600" />
{{ $t('expenses.new_expense') }}
@ -112,25 +112,48 @@ export default {
'selectCustomer',
'deleteMultipleCustomers',
]),
...mapActions('notification', ['showNotification']),
async removeCustomer(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('customers.confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
class="w-6 h-6"
focusable="false"
data-prefix="fas"
data-icon="trash"
class="svg-inline--fa fa-trash fa-w-14"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512"
>
<path
fill="#55547A"
d="M432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM53.2 467a48 48 0 0 0 47.9 45h245.8a48 48 0 0 0 47.9-45L416 128H32z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let data = [id]
this.selectCustomer(data)
let res = await this.deleteMultipleCustomers()
if (res.data.success) {
window.toastr['success'](this.$tc('customers.deleted_message'))
this.showNotification({
type: 'success',
message: this.$tc('customers.deleted_message'),
})
this.$router.push('/admin/customers')
return true
} else if (request.data.error) {
window.toastr['error'](res.data.message)
this.showNotification({
type: 'error',
message: res.data.message,
})
}
}
})

View File

@ -98,16 +98,16 @@
<sw-dropdown slot-scope="row">
<dot-icon slot="activator" />
<sw-dropdown-item
tag-name="router-link"
:to="`invoices/${row.id}/edit`"
tag-name="router-link"
>
<pencil-icon class="h-5 mr-3 text-gray-600" />
{{ $t('general.edit') }}
</sw-dropdown-item>
<sw-dropdown-item
tag-name="router-link"
:to="`invoices/${row.id}/view`"
tag-name="router-link"
>
<eye-icon class="h-5 mr-3 text-gray-600" />
{{ $t('invoices.view') }}
@ -227,16 +227,16 @@
<dot-icon slot="activator" />
<sw-dropdown-item
tag-name="router-link"
:to="`estimates/${row.id}/edit`"
tag-name="router-link"
>
<pencil-icon class="h-5 mr-3 text-gray-600" />
{{ $t('general.edit') }}
</sw-dropdown-item>
<sw-dropdown-item
tag-name="router-link"
:to="`estimates/${row.id}/view`"
tag-name="router-link"
>
<eye-icon class="h-5 mr-3 text-gray-600" />
{{ $t('general.view') }}
@ -350,6 +350,8 @@ export default {
'convertToInvoice',
]),
...mapActions('notification', ['showNotification']),
...mapActions('estimate', {
sendEstimateEmail: 'sendEmail',
markEstimateAsSent: 'markAsSent',
@ -362,25 +364,32 @@ export default {
async removeEstimate(id) {
this.id = id
window
.swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('estimates.confirm_delete', 1),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
})
.then(async (willDelete) => {
if (willDelete) {
let res = await this.deleteEstimate({ ids: [this.id] })
if (res.data.success) {
window.toastr['success'](this.$tc('estimates.deleted_message', 1))
this.refreshEstTable()
} else if (res.data.error) {
window.toastr['error'](res.data.message)
}
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('estimates.confirm_delete', 1),
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.deleteEstimate({ ids: [this.id] })
if (res.data.success) {
this.showToaster({
type: 'success',
message: this.$tc('estimates.deleted_message', 1),
})
this.refreshEstTable()
} else if (res.data.error) {
this.showToaster({
type: 'error',
message: res.data.message,
})
}
})
}
})
},
refreshInvTable() {
@ -392,229 +401,355 @@ export default {
},
async convertInToinvoice(id) {
window
.swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_conversion'),
icon: '/assets/icon/file-alt-solid.svg',
buttons: true,
dangerMode: true,
})
.then(async (willDelete) => {
if (willDelete) {
let res = await this.convertToInvoice(id)
this.selectAllField = false
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_conversion'),
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
viewBox="0 0 384 512"
class="w-6 h-6"
data-prefix="fas"
data-icon="file-alt"
class="svg-inline--fa fa-file-alt fa-w-12"
role="img"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill="#55547A"
d="M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm64 236c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-64c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-72v8c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm96-114.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.convertToInvoice(id)
this.selectAllField = false
if (res.data) {
window.toastr['success'](this.$t('estimates.conversion_message'))
this.$router.push(`invoices/${res.data.invoice.id}/edit`)
} else if (res.data.error) {
window.toastr['error'](res.data.message)
}
if (res.data) {
this.showToaster({
type: 'success',
message: this.$t('estimates.conversion_message'),
})
this.$router.push(`invoices/${res.data.invoice.id}/edit`)
} else if (res.data.error) {
this.showToaster({
type: 'error',
message: res.data.message,
})
}
})
}
})
},
async onMarkAsSent(id) {
window
.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) {
const data = {
id: id,
status: 'SENT',
}
let response = await this.markEstimateAsSent(data)
this.refreshEstTable()
if (response.data) {
window.toastr['success'](
this.$tc('estimates.mark_as_sent_successfully')
)
}
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_mark_as_sent'),
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
class="w-6 h-6"
focusable="false"
data-prefix="fas"
data-icon="check-circle"
class="svg-inline--fa fa-check-circle fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#55547A"
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
const data = {
id: id,
status: 'SENT',
}
})
let response = await this.markEstimateAsSent(data)
this.refreshEstTable()
if (response.data) {
this.showToaster({
type: 'success',
message: this.$tc('estimates.mark_as_sent_successfully'),
})
}
}
})
},
async removeInvoice(id) {
this.id = id
window
.swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('invoices.confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
})
.then(async (willDelete) => {
if (willDelete) {
let res = await this.deleteInvoice({ ids: [this.id] })
if (res.data.success) {
window.toastr['success'](this.$tc('invoices.deleted_message'))
this.refreshInvTable()
} else if (res.data.error) {
window.toastr['error'](res.data.message)
}
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('invoices.confirm_delete'),
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.deleteInvoice({ ids: [this.id] })
if (res.data.success) {
this.showToaster({
type: 'success',
message: this.$tc('invoices.deleted_message'),
})
this.refreshInvTable()
} else if (res.data.error) {
this.showToaster({
type: 'error',
message: res.data.message,
})
}
})
}
})
},
async sendInvoice(id) {
window
.swal({
title: this.$t('general.are_you_sure'),
text: this.$t('invoices.confirm_send'),
icon: '/assets/icon/paper-plane-solid.svg',
buttons: true,
dangerMode: true,
})
.then(async (willSendInvoice) => {
if (willSendInvoice) {
const data = {
id: id,
}
let response = await this.sendEmail(data)
this.refreshInvTable()
if (response.data.success) {
window.toastr['success'](
this.$tc('invoices.send_invoice_successfully')
)
return true
}
if (response.data.error === 'user_email_does_not_exist') {
window.toastr['error'](
this.$tc('invoices.user_email_does_not_exist')
)
return false
}
window.toastr['error'](this.$tc('invoices.something_went_wrong'))
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('invoices.confirm_send'),
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
focusable="false"
class="w-6 h-6"
data-prefix="fas"
data-icon="paper-plane"
class="svg-inline--fa fa-paper-plane fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#55547A"
d="M476 3.2L12.5 270.6c-18.1 10.4-15.8 35.6 2.2 43.2L121 358.4l287.3-253.2c5.5-4.9 13.3 2.6 8.6 8.3L176 407v80.5c0 23.6 28.5 32.9 42.5 15.8L282 426l124.6 52.2c14.2 6 30.4-2.9 33-18.2l72-432C515 7.8 493.3-6.8 476 3.2z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
const data = {
id: id,
}
})
let response = await this.sendEmail(data)
this.refreshInvTable()
if (response.data.success) {
this.showToaster({
type: 'success',
message: this.$tc('invoices.send_invoice_successfully'),
})
return true
}
if (response.data.error === 'user_email_does_not_exist') {
this.showToaster({
type: 'error',
message: this.$tc('invoices.user_email_does_not_exist'),
})
return false
}
this.showToaster({
type: 'error',
message: this.$tc('invoices.something_went_wrong'),
})
}
})
},
async sentInvoice(id) {
window
.swal({
title: this.$t('general.are_you_sure'),
text: this.$t('invoices.invoice_mark_as_sent'),
icon: '/assets/icon/check-circle-solid.svg',
buttons: true,
dangerMode: true,
})
.then(async (willMarkAsSend) => {
if (willMarkAsSend) {
const data = {
id: id,
status: 'SENT',
}
let response = await this.markAsSent(data)
this.refreshInvTable()
if (response.data) {
window.toastr['success'](
this.$tc('invoices.mark_as_sent_successfully')
)
}
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('invoices.invoice_mark_as_sent'),
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
class="w-6 h-6"
focusable="false"
data-prefix="fas"
data-icon="check-circle"
class="svg-inline--fa fa-check-circle fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#55547A"
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
const data = {
id: id,
status: 'SENT',
}
})
let response = await this.markAsSent(data)
this.refreshInvTable()
if (response.data) {
this.showToaster({
type: 'success',
message: this.$tc('invoices.mark_as_sent_successfully'),
})
}
}
})
},
async onMarkAsAccepted(id) {
window
.swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_mark_as_accepted'),
icon: '/assets/icon/check-circle-solid.svg',
buttons: true,
dangerMode: true,
})
.then(async (markedAsRejected) => {
if (markedAsRejected) {
const data = {
id: id,
}
let response = await this.markAsAccepted(data)
this.refreshEstTable()
if (response.data) {
this.refreshEstTable()
window.toastr['success'](
this.$tc('estimates.marked_as_accepted_message')
)
}
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_mark_as_accepted'),
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
class="w-6 h-6"
focusable="false"
data-prefix="fas"
data-icon="check-circle"
class="svg-inline--fa fa-check-circle fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#55547A"
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
const data = {
id: id,
}
})
let response = await this.markAsAccepted(data)
this.refreshEstTable()
if (response.data) {
this.refreshEstTable()
this.showToaster({
type: 'success',
message: this.$tc('estimates.marked_as_accepted_message'),
})
}
}
})
},
async onMarkAsRejected(id) {
window
.swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_mark_as_rejected'),
icon: '/assets/icon/times-circle-solid.svg',
buttons: true,
dangerMode: true,
})
.then(async (markedAsRejected) => {
if (markedAsRejected) {
const data = {
id: id,
}
let response = await this.markAsRejected(data)
this.refreshEstTable()
if (response.data) {
this.refreshEstTable()
window.toastr['success'](
this.$tc('estimates.marked_as_rejected_message')
)
}
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_mark_as_rejected'),
icon: 'error',
iconHtml: `<svg
aria-hidden="true"
class="w-6 h-6"
focusable="false"
data-prefix="fas"
data-icon="check-circle"
class="svg-inline--fa fa-check-circle fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#DC2626"
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
const data = {
id: id,
}
})
let response = await this.markAsRejected(data)
this.refreshEstTable()
if (response.data) {
this.refreshEstTable()
this.showToaster({
type: 'success',
message: this.$tc('estimates.marked_as_rejected_message'),
})
}
}
})
},
async sendEstimate(id) {
window
.swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_send_estimate'),
icon: '/assets/icon/paper-plane-solid.svg',
buttons: true,
dangerMode: true,
})
.then(async (willSendEstimate) => {
if (willSendEstimate) {
const data = {
id: id,
}
let response = await this.sendEstimateEmail(data)
this.refreshEstTable()
if (response.data.success) {
window.toastr['success'](
this.$tc('estimates.send_estimate_successfully')
)
return true
}
if (response.data.error === 'user_email_does_not_exist') {
window.toastr['error'](
this.$tc('estimates.user_email_does_not_exist')
)
return true
}
window.toastr['error'](this.$tc('estimates.something_went_wrong'))
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_send_estimate'),
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
focusable="false"
class="w-6 h-6"
data-prefix="fas"
data-icon="paper-plane"
class="svg-inline--fa fa-paper-plane fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#55547A"
d="M476 3.2L12.5 270.6c-18.1 10.4-15.8 35.6 2.2 43.2L121 358.4l287.3-253.2c5.5-4.9 13.3 2.6 8.6 8.3L176 407v80.5c0 23.6 28.5 32.9 42.5 15.8L282 426l124.6 52.2c14.2 6 30.4-2.9 33-18.2l72-432C515 7.8 493.3-6.8 476 3.2z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
const data = {
id: id,
}
})
let response = await this.sendEstimateEmail(data)
this.refreshEstTable()
if (response.data.success) {
this.showToaster({
type: 'success',
message: this.$tc('estimates.send_estimate_successfully'),
})
return true
}
if (response.data.error === 'user_email_does_not_exist') {
this.showToaster({
type: 'error',
message: this.$tc('estimates.user_email_does_not_exist'),
})
return true
}
this.showToaster({
type: 'error',
message: this.$tc('estimates.something_went_wrong'),
})
}
})
},
},
}

View File

@ -720,6 +720,8 @@ export default {
...mapActions('customFields', ['fetchCustomFields']),
...mapActions('notification', ['showNotification']),
selectFixed() {
if (this.newEstimate.discount_type === 'fixed') {
return
@ -921,7 +923,10 @@ export default {
.then((res) => {
if (res.data) {
this.$router.push(`/admin/estimates/${res.data.estimate.id}/view`)
window.toastr['success'](this.$t('estimates.created_message'))
this.showNotification({
type: 'success',
message: this.$t('estimates.created_message'),
})
}
this.isLoading = false
@ -937,7 +942,10 @@ export default {
this.isLoading = false
if (res.data) {
this.$router.push(`/admin/estimates/${res.data.estimate.id}/view`)
window.toastr['success'](this.$t('estimates.updated_message'))
this.showNotification({
type: 'success',
message: this.$t('estimates.updated_message'),
})
}
})
.catch((err) => {

View File

@ -2,11 +2,11 @@
<base-page>
<sw-page-header :title="$t('estimates.title')">
<sw-breadcrumb slot="breadcrumbs">
<sw-breadcrumb-item to="dashboard" :title="$t('general.home')" />
<sw-breadcrumb-item :title="$t('general.home')" to="dashboard" />
<sw-breadcrumb-item
to="#"
:title="$tc('estimates.estimate', 2)"
to="#"
active
/>
</sw-breadcrumb>
@ -277,12 +277,12 @@
>
<template slot-scope="row">
<span> {{ $t('estimates.action') }} </span>
<sw-dropdown containerClass="w-56">
<sw-dropdown container-class="w-56">
<dot-icon slot="activator" />
<sw-dropdown-item
tag-name="router-link"
:to="`estimates/${row.id}/edit`"
tag-name="router-link"
>
<pencil-icon class="h-5 mr-3 text-gray-600" />
{{ $t('general.edit') }}
@ -294,8 +294,8 @@
</sw-dropdown-item>
<sw-dropdown-item
tag-name="router-link"
:to="`estimates/${row.id}/view`"
tag-name="router-link"
>
<eye-icon class="h-5 mr-3 text-gray-600" />
{{ $t('general.view') }}
@ -481,6 +481,8 @@ export default {
...mapActions('modal', ['openModal']),
...mapActions('notification', ['showNotification']),
refreshTable() {
this.$refs.table.refresh()
},
@ -536,14 +538,30 @@ export default {
},
async onMarkAsAccepted(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_mark_as_accepted'),
icon: '/assets/icon/check-circle-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (markedAsRejected) => {
if (markedAsRejected) {
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
class="w-6 h-6"
focusable="false"
data-prefix="fas"
data-icon="check-circle"
class="svg-inline--fa fa-check-circle fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#55547A"
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
const data = {
id: id,
status: 'ACCEPTED',
@ -553,23 +571,40 @@ export default {
if (response.data) {
this.$refs.table.refresh()
window.toastr['success'](
this.$tc('estimates.marked_as_accepted_message')
)
this.showNotification({
type: 'success',
message: this.$tc('estimates.marked_as_accepted_message'),
})
}
}
})
},
async onMarkAsRejected(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_mark_as_rejected'),
icon: '/assets/icon/times-circle-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (markedAsRejected) => {
if (markedAsRejected) {
icon: 'error',
iconHtml: `<svg
aria-hidden="true"
focusable="false"
class="w-6 h-6"
data-prefix="fas"
data-icon="times-circle"
class="svg-inline--fa fa-times-circle fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#DC2626"
d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
const data = {
id: id,
status: 'REJECTED',
@ -579,9 +614,10 @@ export default {
if (response.data) {
this.$refs.table.refresh()
window.toastr['success'](
this.$tc('estimates.marked_as_rejected_message')
)
this.showNotification({
type: 'success',
message: this.$tc('estimates.marked_as_rejected_message'),
})
}
}
})
@ -624,65 +660,104 @@ export default {
async removeEstimate(id) {
this.id = id
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('estimates.confirm_delete', 1),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.deleteEstimate({ ids: [this.id] })
if (res.data.success) {
this.$refs.table.refresh()
this.resetSelectedEstimates()
window.toastr['success'](this.$tc('estimates.deleted_message', 1))
this.showNotification({
type: 'success',
message: this.$tc('estimates.deleted_message', 1),
})
} else if (res.data.error) {
window.toastr['error'](res.data.message)
this.showNotification({
type: 'error',
message: res.data.message,
})
}
}
})
},
async convertInToinvoice(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_conversion'),
icon: '/assets/icon/file-alt-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willConvertInToinvoice) => {
if (willConvertInToinvoice) {
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
viewBox="0 0 384 512"
class="w-6 h-6"
data-prefix="fas"
data-icon="file-alt"
class="svg-inline--fa fa-file-alt fa-w-12"
role="img"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill="#55547A"
d="M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm64 236c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-64c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-72v8c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm96-114.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.convertToInvoice(id)
if (res.data) {
window.toastr['success'](this.$t('estimates.conversion_message'))
this.showNotification({
type: 'success',
message: this.$t('estimates.conversion_message'),
})
this.$router.push(`invoices/${res.data.invoice.id}/edit`)
} else if (res.data.error) {
window.toastr['error'](res.data.message)
this.showNotification({
type: 'error',
message: res.data.message,
})
}
}
})
},
async removeMultipleEstimates() {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('estimates.confirm_delete', 2),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.deleteMultipleEstimates()
if (res.data.success) {
this.$refs.table.refresh()
this.resetSelectedEstimates()
window.toastr['success'](this.$tc('estimates.deleted_message', 2))
this.showNotification({
type: 'success',
message: this.$tc('estimates.deleted_message', 2),
})
} else if (res.data.error) {
window.toastr['error'](res.data.message)
this.showNotification({
type: 'error',
message: res.data.message,
})
}
}
})
@ -699,14 +774,30 @@ export default {
},
async onMarkAsSent(id) {
swal({
this.$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) {
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
class="w-6 h-6"
focusable="false"
data-prefix="fas"
data-icon="check-circle"
class="svg-inline--fa fa-check-circle fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#55547A"
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
const data = {
id: id,
status: 'SENT',
@ -716,9 +807,10 @@ export default {
this.refreshTable()
if (response.data) {
window.toastr['success'](
this.$tc('estimates.mark_as_sent_successfully')
)
this.showNotification({
type: 'success',
message: this.$tc('estimates.mark_as_sent_successfully'),
})
}
}
})

View File

@ -310,6 +310,8 @@ export default {
...mapActions('modal', ['openModal']),
...mapActions('notification', ['showNotification']),
hasActiveUrl(id) {
return this.$route.params.id == id
},
@ -342,8 +344,10 @@ export default {
let pdfUrl = `${window.location.origin}/estimates/pdf/${this.estimate.unique_hash}`
let response = this.$utils.copyTextToClipboard(pdfUrl)
window.toastr['success'](this.$tc('general.copied_pdf_url_clipboard'))
this.showNotification({
type: 'success',
message: this.$tc('general.copied_pdf_url_clipboard'),
})
},
async onSearched() {
let data = ''
@ -386,30 +390,45 @@ export default {
return true
},
async onMarkAsSent() {
window
.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 (value) => {
if (value) {
this.isMarkAsSent = true
let response = await this.markAsSent({
id: this.estimate.id,
status: 'SENT',
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('estimates.confirm_mark_as_sent'),
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
class="w-6 h-6"
focusable="false"
data-prefix="fas"
data-icon="check-circle"
class="svg-inline--fa fa-check-circle fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#55547A"
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
this.isMarkAsSent = true
let response = await this.markAsSent({
id: this.estimate.id,
status: 'SENT',
})
this.isMarkAsSent = false
if (response.data) {
this.estimate.status = 'SENT'
this.showToaster({
type: 'success',
message: this.$tc('estimates.mark_as_sent_successfully'),
})
this.isMarkAsSent = false
if (response.data) {
this.estimate.status = 'SENT'
window.toastr['success'](
this.$tc('estimates.mark_as_sent_successfully')
)
}
}
})
}
})
},
async onSendEstimate(id) {
this.openModal({
@ -423,29 +442,38 @@ export default {
let pdfUrl = `${window.location.origin}/estimates/pdf/${this.estimate.unique_hash}`
let response = this.$utils.copyTextToClipboard(pdfUrl)
window.toastr['success'](this.$tc('general.copied_pdf_url_clipboard'))
this.showNotification({
type: 'success',
message: this.$tc('general.copied_pdf_url_clipboard'),
})
},
async removeEstimate(id) {
window
.swal({
title: this.$t('general.are_you_sure'),
text: 'you will not be able to recover this estimate!',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
})
.then(async (value) => {
if (value) {
let request = await this.deleteEstimate({ ids: [id] })
if (request.data.success) {
window.toastr['success'](this.$tc('estimates.deleted_message', 1))
this.$router.push('/admin/estimates')
} else if (request.data.error) {
window.toastr['error'](request.data.message)
}
this.$swal({
title: this.$t('general.are_you_sure'),
text: 'you will not be able to recover this estimate!',
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let request = await this.deleteEstimate({ ids: [id] })
if (request.data.success) {
this.showToaster({
type: 'success',
message: this.$tc('estimates.deleted_message', 1),
})
this.$router.push('/admin/estimates')
} else if (request.data.error) {
this.showToaster({
type: 'error',
message: request.data.message,
})
}
})
}
})
},
},
}

View File

@ -417,6 +417,8 @@ export default {
...mapActions('customer', ['fetchCustomers']),
...mapActions('notification', ['showNotification']),
openCategoryModal() {
this.openModal({
title: this.$t('settings.expense_category.add_category'),
@ -532,22 +534,34 @@ export default {
if (response.data.success) {
this.isLoading = false
window.toastr['success'](this.$t('expenses.updated_message'))
this.showNotification({
type: 'success',
message: this.$t('expenses.updated_message'),
})
this.$router.push('/admin/expenses')
return true
}
window.toastr['error'](response.data.error)
this.showNotification({
type: 'error',
message: response.data.error,
})
} else {
this.isLoading = true
let response = await this.addExpense(data)
this.isLoading = false
if (response.data.success) {
window.toastr['success'](this.$t('expenses.created_message'))
this.showNotification({
type: 'success',
message: this.$t('expenses.created_message'),
})
this.$router.push('/admin/expenses')
return true
}
window.toastr['success'](response.data.success)
this.showNotification({
type: 'success',
message: response.data.success,
})
}
},
},

View File

@ -3,9 +3,9 @@
<!-- Page Header -->
<sw-page-header :title="$t('expenses.title')">
<sw-breadcrumb slot="breadcrumbs">
<sw-breadcrumb-item to="dashboard" :title="$t('general.home')" />
<sw-breadcrumb-item :title="$t('general.home')" to="dashboard" />
<sw-breadcrumb-item to="#" :title="$tc('expenses.expense', 2)" active />
<sw-breadcrumb-item :title="$tc('expenses.expense', 2)" to="#" active />
</sw-breadcrumb>
<template slot="actions">
@ -208,7 +208,9 @@
>
<template slot-scope="row">
<span>{{ $t('expenses.customer') }}</span>
<span> {{ row.user_name ? row.user_name : $t('expenses.not_selected') }} </span>
<span>
{{ row.user_name ? row.user_name : $t('expenses.not_selected') }}
</span>
</template>
</sw-table-column>
@ -248,8 +250,8 @@
<dot-icon slot="activator" />
<sw-dropdown-item
tag-name="router-link"
:to="`expenses/${row.id}/edit`"
tag-name="router-link"
>
<pencil-icon class="h-5 mr-3 text-gray-600" />
{{ $t('general.edit') }}
@ -374,6 +376,8 @@ export default {
...mapActions('category', ['fetchCategories']),
...mapActions('notification', ['showNotification']),
async fetchData({ page, filter, sort }) {
let data = {
user_id: this.filters.user ? this.filters.user.id : null,
@ -454,43 +458,61 @@ export default {
},
async removeExpense(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('expenses.confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.deleteExpense({ ids: [id] })
if (res.data.success) {
window.toastr['success'](this.$tc('expenses.deleted_message', 1))
this.showNotification({
type: 'success',
message: this.$tc('expenses.deleted_message', 1),
})
this.refreshTable()
return true
} else if (res.data.error) {
window.toastr['error'](res.data.message)
this.showNotification({
type: 'success',
message: res.data.message,
})
}
}
})
},
async removeMultipleExpenses() {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('expenses.confirm_delete', 2),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let request = await this.deleteMultipleExpenses()
if (request.data.success) {
window.toastr['success'](this.$tc('expenses.deleted_message', 2))
this.showNotification({
type: 'success',
message: this.$tc('expenses.deleted_message', 2),
})
this.$refs.table.refresh()
} else if (request.data.error) {
window.toastr['error'](request.data.message)
this.showNotification({
type: 'error',
message: request.data.message,
})
}
}
})

View File

@ -722,6 +722,8 @@ export default {
...mapActions('customFields', ['fetchCustomFields']),
...mapActions('notification', ['showNotification']),
selectFixed() {
if (this.newInvoice.discount_type === 'fixed') {
return
@ -918,8 +920,10 @@ export default {
.then((res) => {
if (res.data) {
this.$router.push(`/admin/invoices/${res.data.invoice.id}/view`)
window.toastr['success'](this.$t('invoices.created_message'))
this.showNotification({
type: 'success',
message: this.$t('invoices.created_message'),
})
}
this.isLoading = false
@ -935,13 +939,17 @@ export default {
this.isLoading = false
if (res.data.success) {
this.$router.push(`/admin/invoices/${res.data.invoice.id}/view`)
window.toastr['success'](this.$t('invoices.updated_message'))
this.showNotification({
type: 'success',
message: this.$t('invoices.updated_message'),
})
}
if (res.data.error === 'invalid_due_amount') {
window.toastr['error'](
this.$t('invoices.invalid_due_amount_message')
)
this.showNotification({
type: 'error',
message: this.$t('invoices.invalid_due_amount_message'),
})
}
})
.catch((err) => {

View File

@ -2,8 +2,8 @@
<base-page>
<sw-page-header :title="$t('invoices.title')">
<sw-breadcrumb slot="breadcrumbs">
<sw-breadcrumb-item to="dashboard" :title="$t('general.home')" />
<sw-breadcrumb-item to="#" :title="$tc('invoices.invoice', 2)" active />
<sw-breadcrumb-item :title="$t('general.home')" to="dashboard" />
<sw-breadcrumb-item :title="$tc('invoices.invoice', 2)" to="#" active />
</sw-breadcrumb>
<template slot="actions">
@ -93,8 +93,8 @@
<label
class="absolute text-sm leading-snug text-black cursor-pointer"
@click="clearFilter"
style="top: 10px; right: 15px"
@click="clearFilter"
>{{ $t('general.clear_all') }}</label
>
</sw-filter-wrapper>
@ -258,7 +258,9 @@
:bg-color="$utils.getBadgeStatusColor(row.status).bgColor"
:color="$utils.getBadgeStatusColor(row.status).color"
>
{{ $utils.getStatusTranslation(row.paid_status.replace('_', ' ')) }}
{{
$utils.getStatusTranslation(row.paid_status.replace('_', ' '))
}}
</sw-badge>
</template>
</sw-table-column>
@ -289,16 +291,16 @@
<dot-icon slot="activator" />
<sw-dropdown-item
tag-name="router-link"
:to="`invoices/${row.id}/edit`"
tag-name="router-link"
>
<pencil-icon class="h-5 mr-3 text-gray-600" />
{{ $t('general.edit') }}
</sw-dropdown-item>
<sw-dropdown-item
tag-name="router-link"
:to="`invoices/${row.id}/view`"
tag-name="router-link"
>
<eye-icon class="h-5 mr-3 text-gray-600" />
{{ $t('invoices.view') }}
@ -334,8 +336,8 @@
row.status === 'VIEWED' ||
row.status === 'OVERDUE'
"
tag-name="router-link"
:to="`/admin/payments/${row.id}/create`"
tag-name="router-link"
>
<credit-card-icon class="h-5 mr-3 text-gray-600" />
{{ $t('payments.record_payment') }}
@ -510,6 +512,8 @@ export default {
...mapActions('modal', ['openModal']),
...mapActions('notification', ['showNotification']),
async sendInvoice(invoice) {
this.openModal({
title: this.$t('invoices.send_invoice'),
@ -521,14 +525,30 @@ export default {
},
async markInvoiceAsSent(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('invoices.invoice_mark_as_sent'),
icon: '/assets/icon/check-circle-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (value) => {
if (value) {
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
class="w-6 h-6"
focusable="false"
data-prefix="fas"
data-icon="check-circle"
class="svg-inline--fa fa-check-circle fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#55547A"
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
const data = {
id: id,
status: 'SENT',
@ -536,29 +556,49 @@ export default {
let response = await this.markAsSent(data)
this.refreshTable()
if (response.data) {
window.toastr['success'](
this.$tc('invoices.mark_as_sent_successfully')
)
this.showNotification({
type: 'success',
message: this.$tc('invoices.mark_as_sent_successfully'),
})
}
}
})
},
async onCloneInvoice(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('invoices.confirm_clone'),
icon: '/assets/icon/check-circle-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (value) => {
if (value) {
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
class="w-6 h-6"
focusable="false"
data-prefix="fas"
data-icon="check-circle"
class="svg-inline--fa fa-check-circle fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#55547A"
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let response = await this.cloneInvoice({ id })
this.refreshTable()
if (response.data) {
window.toastr['success'](this.$tc('invoices.cloned_successfully'))
this.showNotification({
type: 'success',
message: this.$tc('invoices.cloned_successfully'),
})
this.$router.push(
`/admin/invoices/${response.data.invoice.id}/edit`
)
@ -665,31 +705,43 @@ export default {
async removeInvoice(id) {
this.id = id
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('invoices.confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (value) => {
if (value) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.deleteInvoice({ ids: [id] })
if (res.data.success) {
window.toastr['success'](this.$tc('invoices.deleted_message'))
this.showNotification({
type: 'success',
message: this.$tc('invoices.deleted_message'),
})
this.$refs.table.refresh()
return true
}
if (res.data.error === 'payment_attached') {
window.toastr['error'](
this.$t('invoices.payment_attached_message'),
this.$t('general.action_failed')
)
this.showNotification({
type: 'error',
message:
(this.$t('invoices.payment_attached_message'),
this.$t('general.action_failed')),
})
return true
}
window.toastr['error'](res.data.error)
this.showNotification({
type: 'error',
message: res.data.error,
})
return true
}
this.resetSelectedInvoices()
@ -697,30 +749,41 @@ export default {
},
async removeMultipleInvoices() {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('invoices.confirm_delete', 2),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (value) => {
if (value) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.deleteMultipleInvoices()
if (res.data.error === 'payment_attached') {
window.toastr['error'](
this.$t('invoices.payment_attached_message'),
this.$t('general.action_failed')
)
this.showNotification({
type: 'error',
message:
(this.$t('invoices.payment_attached_message'),
this.$t('general.action_failed')),
})
return true
}
if (res.data) {
this.$refs.table.refresh()
this.resetSelectedInvoices()
window.toastr['success'](this.$tc('invoices.deleted_message', 2))
this.showNotification({
type: 'success',
message: this.$tc('invoices.deleted_message', 2),
})
} else if (res.data.error) {
window.toastr['error'](res.data.message)
this.showNotification({
type: 'error',
message: res.data.message,
})
}
}
})

View File

@ -323,6 +323,7 @@ export default {
]),
...mapActions('modal', ['openModal']),
...mapActions('notification', ['showNotification']),
hasActiveUrl(id) {
return this.$route.params.id == id
@ -393,30 +394,45 @@ export default {
return true
},
async onMarkAsSent() {
window
.swal({
title: this.$t('general.are_you_sure'),
text: this.$t('invoices.invoice_mark_as_sent'),
icon: '/assets/icon/check-circle-solid.svg',
buttons: true,
dangerMode: true,
})
.then(async (value) => {
if (value) {
this.isMarkingAsSent = true
let response = await this.markAsSent({
id: this.invoice.id,
status: 'SENT',
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('invoices.invoice_mark_as_sent'),
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
class="w-6 h-6"
focusable="false"
data-prefix="fas"
data-icon="check-circle"
class="svg-inline--fa fa-check-circle fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#55547A"
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
this.isMarkingAsSent = true
let response = await this.markAsSent({
id: this.invoice.id,
status: 'SENT',
})
this.isMarkingAsSent = false
if (response.data) {
this.invoice.status = 'SENT'
this.showToaster({
type: 'success',
message: this.$tc('invoices.marked_as_sent_message'),
})
this.isMarkingAsSent = false
if (response.data) {
this.invoice.status = 'SENT'
window.toastr['success'](
this.$tc('invoices.marked_as_sent_message')
)
}
}
})
}
})
},
async onSendInvoice() {
this.openModal({
@ -430,29 +446,38 @@ export default {
let pdfUrl = `${window.location.origin}/invoices/pdf/${this.invoice.unique_hash}`
let response = this.$utils.copyTextToClipboard(pdfUrl)
window.toastr['success'](this.$t('general.copied_pdf_url_clipboard'))
this.showNotification({
type: 'success',
message: this.$t('general.copied_pdf_url_clipboard'),
})
},
async removeInvoice(id) {
window
.swal({
title: this.$t('general.are_you_sure'),
text: 'you will not be able to recover this invoice!',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
})
.then(async (value) => {
if (value) {
let request = await this.deleteInvoice({ ids: [id] })
if (request.data.success) {
window.toastr['success'](this.$tc('invoices.deleted_message', 1))
this.$router.push('/admin/invoices')
} else if (request.data.error) {
window.toastr['error'](request.data.message)
}
this.$swal({
title: this.$t('general.are_you_sure'),
text: 'you will not be able to recover this invoice!',
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let request = await this.deleteInvoice({ ids: [id] })
if (request.data.success) {
this.showToaster({
type: 'success',
message: this.$tc('invoices.deleted_message', 1),
})
this.$router.push('/admin/invoices')
} else if (request.data.error) {
this.showToaster({
type: 'error',
message: request.data.message,
})
}
})
}
})
},
},
}

View File

@ -312,6 +312,8 @@ export default {
...mapActions('modal', ['openModal']),
...mapActions('notification', ['showNotification']),
async setTaxPerItem() {
let response = await this.fetchCompanySettings(['tax_per_item'])
@ -385,15 +387,24 @@ export default {
this.isLoading = false
if (!this.isEdit) {
window.toastr['success'](this.$tc('items.created_message'))
this.showNotification({
type: 'success',
message: this.$tc('items.created_message'),
})
this.$router.push('/admin/items')
return true
} else {
window.toastr['success'](this.$tc('items.updated_message'))
this.showNotification({
type: 'success',
message: this.$tc('items.updated_message'),
})
this.$router.push('/admin/items')
return true
}
window.toastr['error'](response.data.error)
this.showNotification({
type: 'error',
message: response.data.error,
})
}
},

View File

@ -348,6 +348,8 @@ export default {
'fetchItemUnits',
]),
...mapActions('notification', ['showNotification']),
refreshTable() {
this.$refs.table.refresh()
},
@ -397,52 +399,71 @@ export default {
async removeItems(id) {
this.id = id
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('items.confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.deleteItem({ ids: [id] })
if (res.data.success) {
window.toastr['success'](this.$tc('items.deleted_message', 1))
this.showNotification({
type: 'success',
message: this.$tc('items.deleted_message'),
})
this.$refs.table.refresh()
return true
}
if (res.data.error === 'item_attached') {
window.toastr['error'](
this.$tc('items.item_attached_message'),
this.$t('general.action_failed')
)
this.showNotification({
type: 'error',
message:
(this.$tc('items.item_attached_message'),
this.$t('general.action_failed')),
})
return true
}
window.toastr['error'](res.data.message)
this.showNotification({
type: 'error',
message: res.data.message,
})
return true
}
})
},
async removeMultipleItems() {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('items.confirm_delete', 2),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.deleteMultipleItems()
if (res.data.success || res.data.items) {
window.toastr['success'](this.$tc('items.deleted_message', 2))
this.showNotification({
type: 'success',
message: this.$tc('items.deleted_message', 2),
})
this.$refs.table.refresh()
} else if (res.data.error) {
window.toastr['error'](res.data.message)
this.showNotification({
type: 'error',
message: res.data.message,
})
}
}
})

View File

@ -1,6 +1,7 @@
<template>
<div v-if="isAppLoaded" class="h-full">
<base-modal />
<base-notification />
<site-header />
<div class="flex h-screen pt-16 pb-10 overflow-hidden">
<site-sidebar />
@ -20,6 +21,7 @@ import SiteSidebar from './partials/TheSiteSidebar.vue'
import BaseModal from '../../components/base/modal/BaseModal'
import { RefreshIcon } from '@vue-hero-icons/solid'
import { mapActions, mapGetters } from 'vuex'
import BaseNotification from '../../components/base/BaseNotification.vue'
export default {
components: {
@ -28,6 +30,7 @@ export default {
SiteFooter,
BaseModal,
RefreshIcon,
BaseNotification,
},
computed: {

View File

@ -1,5 +1,6 @@
<template>
<div class="grid h-full grid-cols-12 overflow-y-hidden bg-gray-100">
<base-notification />
<div
class="flex items-center justify-center w-full max-w-sm col-span-12 p-4 mx-auto text-gray-900 md:p-8 md:col-span-6 lg:col-span-4 flex-2 md:pb-48 md:pt-40"
>

View File

@ -423,6 +423,8 @@ export default {
...mapActions('customer', ['fetchCustomers']),
...mapActions('notification', ['showNotification']),
invoiceWithAmount({ invoice_number, due_amount }) {
return `${invoice_number} (${this.$utils.formatGraphMoney(
due_amount,
@ -561,25 +563,38 @@ export default {
this.$router.push(
`/admin/payments/${response.data.payment.id}/view`
)
window.toastr['success'](this.$t('payments.updated_message'))
this.showNotification({
type: 'success',
message: this.$t('payments.updated_message'),
})
return true
}
if (response.data.error === 'invalid_amount') {
window.toastr['error'](this.$t('invalid_amount_message'))
this.showNotification({
type: 'error',
message: this.$t('invalid_amount_message'),
})
return false
}
window.toastr['error'](response.data.error)
this.showNotification({
type: 'error',
message: response.data.error,
})
} catch (err) {
this.isLoading = false
if (err.response.data.errors.payment_number) {
window.toastr['error'](err.response.data.errors.payment_number)
this.showNotification({
type: 'error',
message: err.response.data.errors.payment_number,
})
return true
}
window.toastr['error'](err.response.data.message)
this.showNotification({
type: 'error',
message: err.response.data.message,
})
}
} else {
let data = {
@ -599,26 +614,39 @@ export default {
this.$router.push(
`/admin/payments/${response.data.payment.id}/view`
)
window.toastr['success'](this.$t('payments.created_message'))
this.showNotification({
type: 'success',
message: this.$t('payments.created_message'),
})
this.isLoading = true
return true
}
if (response.data.error === 'invalid_amount') {
window.toastr['error'](this.$t('invalid_amount_message'))
this.showNotification({
type: 'error',
message: this.$t('invalid_amount_message'),
})
return false
}
window.toastr['error'](response.data.error)
this.showNotification({
type: 'error',
message: response.data.error,
})
} catch (err) {
this.isLoading = false
if (err.response.data.errors.payment_number) {
window.toastr['error'](err.response.data.errors.payment_number)
this.showNotification({
type: 'error',
message: err.response.data.errors.payment_number,
})
return true
}
window.toastr['error'](err.response.data.message)
this.showNotification({
type: 'error',
message: err.response.data.message,
})
}
}
},

View File

@ -2,8 +2,8 @@
<base-page class="payments">
<sw-page-header :title="$t('payments.title')">
<sw-breadcrumb slot="breadcrumbs">
<sw-breadcrumb-item to="dashboard" :title="$t('general.home')" />
<sw-breadcrumb-item to="#" :title="$tc('payments.payment', 2)" active />
<sw-breadcrumb-item :title="$t('general.home')" to="dashboard" />
<sw-breadcrumb-item :title="$tc('payments.payment', 2)" to="#" active />
</sw-breadcrumb>
<template slot="actions">
@ -202,7 +202,11 @@
<template slot-scope="row">
<span>{{ $t('payments.payment_mode') }}</span>
<span>
{{ row.payment_mode ? row.payment_mode : $t('payments.not_selected') }}
{{
row.payment_mode
? row.payment_mode
: $t('payments.not_selected')
}}
</span>
</template>
</sw-table-column>
@ -216,7 +220,11 @@
<template slot-scope="row">
<span>{{ $t('invoices.invoice_number') }}</span>
<span>
{{ row.invoice_number ? row.invoice_number : $t('payments.no_invoice') }}
{{
row.invoice_number
? row.invoice_number
: $t('payments.no_invoice')
}}
</span>
</template>
</sw-table-column>
@ -239,16 +247,16 @@
<dot-icon slot="activator" />
<sw-dropdown-item
tag-name="router-link"
:to="`payments/${row.id}/edit`"
tag-name="router-link"
>
<pencil-icon class="h-5 mr-3 text-gray-600" />
{{ $t('general.edit') }}
</sw-dropdown-item>
<sw-dropdown-item
tag-name="router-link"
:to="`payments/${row.id}/view`"
tag-name="router-link"
>
<eye-icon class="h-5 mr-3 text-gray-600" />
{{ $t('general.view') }}
@ -371,6 +379,8 @@ export default {
'fetchPaymentModes',
]),
...mapActions('notification', ['showNotification']),
async fetchData({ page, filter, sort }) {
let data = {
customer_id: this.filters.customer ? this.filters.customer.id : '',
@ -433,43 +443,60 @@ export default {
},
async removePayment(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('payments.confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.deletePayment({ ids: [id] })
if (res.data.success) {
window.toastr['success'](this.$tc('payments.deleted_message', 1))
this.showNotification({
type: 'success',
message: this.$tc('payments.deleted_message', 1),
})
this.$refs.table.refresh()
return true
}
window.toastr['error'](res.data.message)
this.showNotification({
type: 'error',
message: res.data.message,
})
return true
}
})
},
async removeMultiplePayments() {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('payments.confirm_delete', 2),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let request = await this.deleteMultiplePayments()
if (request.data.success) {
window.toastr['success'](this.$tc('payments.deleted_message', 2))
this.showNotification({
type: 'success',
message: this.$tc('payments.deleted_message', 2),
})
this.$refs.table.refresh()
} else if (request.data.error) {
window.toastr['error'](request.data.message)
this.showNotification({
type: 'error',
message: request.data.message,
})
}
}
})

View File

@ -282,6 +282,7 @@ export default {
'searchPayment',
]),
...mapActions('modal', ['openModal']),
...mapActions('notification', ['showNotification']),
hasActiveUrl(id) {
return this.$route.params.id == id
@ -364,30 +365,39 @@ export default {
let pdfUrl = `${window.location.origin}/payments/pdf/${this.payment.unique_hash}`
let response = this.$utils.copyTextToClipboard(pdfUrl)
window.toastr['success'](this.$t('general.copied_pdf_url_clipboard'))
this.showNotification({
type: 'success',
message: this.$t('general.copied_pdf_url_clipboard'),
})
},
async removePayment(id) {
this.id = id
window
.swal({
title: this.$t('general.are_you_sure'),
text: 'you will not be able to recover this payment!',
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
})
.then(async (value) => {
if (value) {
let request = await this.deletePayment({ ids: [id] })
if (request.data.success) {
window.toastr['success'](this.$tc('payments.deleted_message', 1))
this.$router.push('/admin/payments')
} else if (request.data.error) {
window.toastr['error'](request.data.message)
}
this.$swal({
title: this.$t('general.are_you_sure'),
text: 'you will not be able to recover this payment!',
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let request = await this.deletePayment({ ids: [id] })
if (request.data.success) {
this.showToaster({
type: 'success',
message: this.$tc('payments.deleted_message', 1),
})
this.$router.push('/admin/payments')
} else if (request.data.error) {
this.showToaster({
type: 'error',
message: request.data.message,
})
}
})
}
})
},
},
}

View File

@ -58,8 +58,8 @@
:options="reportTypes"
:allow-empty="false"
:show-labels="false"
class="mt-2"
:placeholder="$t('reports.sales.report_type')"
class="mt-2"
@input="getInitialReport"
/>
</sw-input-group>
@ -79,7 +79,7 @@
class="hidden w-full h-screen border-gray-100 border-solid rounded md:flex"
/>
<a
class="flex items-center justify-center h-10 px-5 py-1 text-sm font-medium leading-none text-center text-white whitespace-nowrap rounded md:hidden bg-primary-500"
class="flex items-center justify-center h-10 px-5 py-1 text-sm font-medium leading-none text-center text-white rounded whitespace-nowrap md:hidden bg-primary-500"
@click="viewReportsPDF"
>
<document-text-icon />

View File

@ -33,18 +33,18 @@
:show-labels="false"
:placeholder="$t('settings.disk.select_disk')"
:allow-empty="false"
:custom-label="getCustomLabel"
track-by="id"
label="name"
:custom-label="getCustomLabel"
@select="refreshTable"
/>
</sw-input-group>
</div>
<sw-table-component
ref="table"
variant="gray"
:show-filter="false"
:data="fetchBackupsData"
variant="gray"
>
<sw-table-column :label="$t('settings.backup.path')" show="path">
<template slot-scope="row">
@ -119,6 +119,8 @@ export default {
...mapActions('modal', ['openModal']),
...mapActions('notification', ['showNotification']),
getCustomLabel({ driver, name }) {
if (!name) {
return
@ -127,14 +129,17 @@ export default {
},
async onRemoveBackup(backup) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('settings.backup.backup_confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (value) => {
if (value) {
icon: 'question',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let data = {
disk: this.filters.selected_disk.driver,
file_disk_id: this.filters.selected_disk.id,
@ -142,7 +147,10 @@ export default {
}
let response = await this.removeBackup(data)
if (response.data.success) {
window.toastr['success'](this.$t('settings.backup.deleted_message'))
this.showNotification({
type: 'success',
message: this.$t('settings.backup.deleted_message'),
})
this.$refs.table.refresh()
return true
}
@ -170,9 +178,10 @@ export default {
let response = await this.fetchBackups(data)
if (response.data.error) {
window.toastr['error'](
this.$t('settings.backup.' + response.data.error)
)
this.showNotification({
type: 'error',
message: this.$t('settings.backup.' + response.data.error),
})
}
this.isRequestOngoing = false
@ -225,7 +234,10 @@ export default {
})
.catch((e) => {
this.isRequestOngoing = false
window.toastr['error'](e.response.data.message)
this.showNotification({
type: 'error',
message: e.response.data.message,
})
})
},
},

View File

@ -1,5 +1,5 @@
<template>
<form @submit.prevent="updateCompanyData" class="relative h-full">
<form class="relative h-full" @submit.prevent="updateCompanyData">
<base-loader v-if="isRequestOnGoing" :show-bg-overlay="true" />
<sw-card variant="setting-card">
<template slot="header">
@ -41,8 +41,8 @@
</div>
<sw-avatar
trigger="#logo-box"
:preview-avatar="previewLogo"
trigger="#logo-box"
@changed="onChange"
@uploadHandler="onUploadHandler"
@handleUploadError="onHandleUploadError"
@ -74,8 +74,8 @@
<sw-input-group :label="$tc('settings.company_info.phone')">
<sw-input
v-model="formData.phone"
class="mt-2"
:placeholder="$t('settings.company_info.phone')"
class="mt-2"
/>
</sw-input-group>
@ -153,9 +153,9 @@
</div>
<sw-button
class="mt-4"
:loading="isLoading"
:disabled="isLoading"
class="mt-4"
variant="primary"
>
<save-icon v-if="!isLoading" class="mr-2 -ml-1" />
@ -269,13 +269,17 @@ export default {
methods: {
...mapActions('company', ['updateCompany', 'updateCompanyLogo']),
...mapActions('user', ['fetchCurrentUser']),
...mapActions('notification', ['showNotification']),
onUploadHandler(cropper) {
this.previewLogo = cropper
.getCroppedCanvas()
.toDataURL(this.cropperOutputMime)
},
onHandleUploadError() {
window.toastr['error']('Oops! Something went wrong...')
this.showNotification({
type: 'error',
message: 'Oops! Something went wrong...',
})
},
onChange(file) {
this.cropperOutputMime = file.type
@ -322,13 +326,17 @@ export default {
await this.updateCompanyLogo(logoData)
}
this.isLoading = false
window.toastr['success'](
this.$t('settings.company_info.updated_message')
)
this.showNotification({
type: 'success',
message: this.$t('settings.company_info.updated_message'),
})
return true
}
this.isLoading = false
window.toastr['error'](response.data.error)
this.showNotification({
type: 'error',
message: response.data.error,
})
return true
},
},

View File

@ -23,9 +23,9 @@
<sw-table-component
ref="table"
variant="gray"
:show-filter="false"
:data="fetchData"
variant="gray"
>
<sw-table-column
:sortable="true"
@ -118,6 +118,8 @@ export default {
...mapActions('modal', ['openModal']),
...mapActions('notification', ['showNotification']),
async fetchData({ page, filter, sort }) {
let data = {
orderByField: sort.fieldName || 'created_at',
@ -138,26 +140,31 @@ export default {
},
async removeCustomField(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('settings.custom_fields.custom_field_confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (value) => {
if (value) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let response = await this.deleteCustomFields(id)
if (response.data.success) {
window.toastr['success'](
this.$t('settings.custom_fields.deleted_message')
)
this.showNotification({
type: 'success',
message: this.$t('settings.custom_fields.deleted_message'),
})
this.id = null
this.$refs.table.refresh()
return true
}
window.toastr['error'](
this.$t('settings.custom_fields.already_in_use')
)
this.showNotification({
type: 'error',
message: this.$t('settings.custom_fields.already_in_use'),
})
}
})
},

View File

@ -110,6 +110,8 @@ export default {
'deleteCategory',
]),
...mapActions('notification', ['showNotification']),
async fetchData({ page, filter, sort }) {
let data = {
orderByField: sort.fieldName || 'created_at',
@ -132,26 +134,31 @@ export default {
},
async removeExpenseCategory(id, index) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('settings.expense_category.confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'question',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>s`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let response = await this.deleteCategory(id)
if (response.data.success) {
window.toastr['success'](
this.$tc('settings.expense_category.deleted_message')
)
this.showNotification({
type: 'success',
message: this.$tc('settings.expense_category.deleted_message'),
})
this.id = null
this.$refs.table.refresh()
return true
}
window.toastr['error'](
this.$t('settings.expense_category.already_in_use')
)
this.showNotification({
type: 'error',
message: this.$t('settings.expense_category.already_in_use'),
})
}
})
},

View File

@ -27,9 +27,9 @@
<sw-table-component
ref="table"
variant="gray"
:show-filter="false"
:data="fetchData"
variant="gray"
table-class="table tax-table"
class="mt-0 mb-3"
>
@ -173,6 +173,8 @@ export default {
...mapActions('company', ['updateCompanySettings', 'fetchCompanySettings']),
...mapActions('notification', ['showNotification']),
async fetchData({ page, filter, sort }) {
let data = {
orderByField: sort.fieldName || 'created_at',
@ -243,20 +245,39 @@ export default {
let response = await this.updateCompanySettings(data)
if (response.data.success) {
window.toastr['success'](this.$t('general.setting_updated'))
this.showNotification({
type: 'success',
message: this.$t('general.setting_updated'),
})
}
this.$refs.table.refresh()
},
async setDefaultDiskData(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('settings.disk.set_default_disk_confirm'),
icon: '/assets/icon/check-circle-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (value) => {
if (value) {
icon: 'question',
iconHtml: `<svg
aria-hidden="true"
class="w-6 h-6"
focusable="false"
data-prefix="fas"
data-icon="check-circle"
class="svg-inline--fa fa-check-circle fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
fill="#55547A"
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
></path>
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
this.loading = true
let data = {
set_as_default: true,
@ -266,26 +287,33 @@ export default {
if (response.data.success) {
this.refreshTable()
window.toastr['success'](
this.$t('settings.disk.success_set_default_disk')
)
this.showNotification({
type: 'success',
message: this.$t('settings.disk.success_set_default_disk'),
})
}
}
})
},
async removeDisk(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('settings.disk.confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (value) => {
if (value) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let response = await this.deleteFileDisk(id)
if (response.data.success) {
window.toastr['success'](this.$t('settings.disk.deleted_message'))
this.showNotification({
type: 'success',
message: this.$t('settings.disk.deleted_message'),
})
this.refreshTable()
return true
}

View File

@ -76,6 +76,7 @@ export default {
'fetchMailConfig',
'updateMailConfig',
]),
...mapActions('notification', ['showNotification']),
async loadData() {
this.isRequestOnGoing = true
@ -100,17 +101,22 @@ export default {
let response = await this.updateMailConfig(mailConfigData)
if (response.data.success) {
this.isLoading = false
window.toastr['success'](
this.$t('wizard.success.' + response.data.success)
)
this.showNotification({
type: 'success',
message: this.$t('wizard.success.' + response.data.success),
})
} else {
window.toastr['error'](
this.$t('wizard.errors.' + response.data.error)
)
this.showNotification({
type: 'error',
message: this.$t('wizard.errors.' + response.data.error),
})
}
return true
} catch (e) {
window.toastr['error']('Something went wrong')
this.showNotification({
type: 'error',
message: 'Something went wrong',
})
}
},

View File

@ -27,9 +27,9 @@
<sw-table-component
ref="table"
variant="gray"
:show-filter="false"
:data="fetchData"
variant="gray"
>
<sw-table-column
:label="$t('settings.customization.notes.name')"
@ -93,6 +93,8 @@ export default {
...mapActions('notes', ['fetchNotes', 'deleteNote']),
...mapActions('notification', ['showNotification']),
async fetchData({ page, filter, sort }) {
let data = {
orderByField: sort.fieldName || 'created_at',
@ -112,26 +114,31 @@ export default {
}
},
removeNote(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('settings.customization.notes.note_confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (value) => {
if (value) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let response = await this.deleteNote(id)
if (response.data.success) {
window.toastr['success'](
this.$t('settings.customization.notes.deleted_message')
)
this.showNotification({
type: 'success',
message: this.$t('settings.customization.notes.deleted_message'),
})
this.$refs.table.refresh()
return true
}
window.toastr['error'](
this.$t('settings.customization.notes.already_in_use')
)
this.showNotification({
type: 'error',
message: this.$t('settings.customization.notes.already_in_use'),
})
}
})
},

View File

@ -133,6 +133,7 @@ export default {
},
methods: {
...mapActions('company', ['fetchCompanySettings', 'updateCompanySettings']),
...mapActions('notification', ['showNotification']),
async fetchData() {
this.isRequestOnGoing = true
@ -176,9 +177,10 @@ export default {
if (response.data.success) {
this.isLoading = false
window.toastr['success'](
this.$tc('settings.notification.email_save_message')
)
this.showNotification({
type: 'success',
message: this.$tc('settings.notification.email_save_message'),
})
}
},
@ -199,7 +201,10 @@ export default {
let response = await this.updateCompanySettings(data)
if (response.data.success) {
window.toastr['success'](this.$tc('general.setting_updated'))
this.showNotification({
type: 'success',
message: this.$tc('general.setting_updated'),
})
}
},
@ -220,7 +225,10 @@ export default {
let response = await this.updateCompanySettings(data)
if (response.data) {
window.toastr['success'](this.$tc('general.setting_updated'))
this.showNotification({
type: 'success',
message: this.$tc('general.setting_updated'),
})
}
},
},

View File

@ -22,9 +22,9 @@
<sw-table-component
ref="table"
variant="gray"
:show-filter="false"
:data="fetchData"
variant="gray"
>
<sw-table-column
:label="$t('settings.customization.payments.mode_name')"
@ -79,6 +79,8 @@ export default {
...mapActions('payment', ['deletePaymentMode', 'fetchPaymentModes']),
...mapActions('notification', ['showNotification']),
async fetchData({ page, filter, sort }) {
let data = {
orderByField: sort.fieldName || 'created_at',
@ -117,29 +119,36 @@ export default {
},
removePaymentMode(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t(
'settings.customization.payments.payment_mode_confirm_delete'
),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (value) => {
if (value) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let response = await this.deletePaymentMode(id)
if (response.data.success) {
window.toastr['success'](
this.$t('settings.customization.payments.deleted_message')
)
this.showNotification({
type: 'success',
message: this.$t(
'settings.customization.payments.deleted_message'
),
})
this.id = null
this.$refs.table.refresh()
return true
}
window.toastr['error'](
this.$t('settings.customization.payments.already_in_use')
)
this.showNotification({
type: 'error',
message: this.$t('settings.customization.payments.already_in_use'),
})
}
})
},

View File

@ -1,5 +1,5 @@
<template>
<form action="" @submit.prevent="updatePreferencesData" class="relative">
<form action="" class="relative" @submit.prevent="updatePreferencesData">
<base-loader v-if="isRequestOnGoing" :show-bg-overlay="true" />
<sw-card variant="setting-card">
<template slot="header">
@ -113,11 +113,11 @@
</div>
<sw-button
:disabled="isLoading"
:loading="isLoading"
class="mt-6"
variant="primary"
type="submit"
:disabled="isLoading"
:loading="isLoading"
>
<save-icon v-if="!isLoading" class="mr-2 -ml-1" />
{{ $tc('settings.company_info.save') }}
@ -267,6 +267,8 @@ export default {
'fetchTimeZones',
]),
...mapActions('notification', ['showNotification']),
currencyNameWithCode({ name, code }) {
return `${code} - ${name}`
},
@ -340,12 +342,16 @@ export default {
this.isLoading = false
// window.i18n.locale = this.formData.language.code
this.setDefaultCurrency(this.formData.currency)
window.toastr['success'](
this.$t('settings.preferences.updated_message')
)
this.showNotification({
type: 'success',
message: this.$t('settings.preferences.updated_message'),
})
return true
}
window.toastr['error'](response.data.error)
this.showNotification({
type: 'error',
message: response.data.error,
})
return true
},
@ -357,7 +363,10 @@ export default {
}
let response = await this.updateCompanySettings(data)
if (response.data.success) {
window.toastr['success'](this.$t('general.setting_updated'))
this.showNotification({
type: 'success',
message: this.$t('general.setting_updated'),
})
}
},
},

View File

@ -160,6 +160,8 @@ export default {
]),
...mapActions('company', ['fetchCompanySettings', 'updateCompanySettings']),
...mapActions('notification', ['showNotification']),
async fetchData({ page, filter, sort }) {
let data = {
orderByField: sort.fieldName || 'created_at',
@ -194,28 +196,38 @@ export default {
}
let response = await this.updateCompanySettings(data)
if (response.data) {
window.toastr['success'](this.$t('general.setting_updated'))
this.showNotification({
type: 'success',
message: this.$t('general.setting_updated'),
})
}
},
async removeTax(id, index) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('settings.tax_types.confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (value) => {
if (value) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let response = await this.deleteTaxType(id)
if (response.data.success) {
window.toastr['success'](
this.$t('settings.tax_types.deleted_message')
)
this.showNotification({
type: 'success',
message: this.$t('settings.tax_types.deleted_message'),
})
this.$refs.table.refresh()
return true
}
window.toastr['error'](this.$t('settings.tax_types.already_in_use'))
this.showNotification({
type: 'error',
message: this.$t('settings.tax_types.already_in_use'),
})
}
})
},

View File

@ -58,9 +58,9 @@
</label>
<table class="w-1/2 mt-2 border-2 border-gray-200 table-fixed">
<tr
class="p-2 border-2 border-gray-200"
v-for="(ext, i) in requiredExtentions"
:key="i"
class="p-2 border-2 border-gray-200"
>
<td width="70%" class="p-2 text-sm truncate">
{{ i }}
@ -106,8 +106,8 @@
<!-- -->
<ul v-if="isUpdating" class="w-full p-0 list-none">
<li
class="flex justify-between w-full py-3 border-b border-gray-200 border-solid last:border-b-0"
v-for="step in updateSteps"
class="flex justify-between w-full py-3 border-b border-gray-200 border-solid last:border-b-0"
>
<p class="m-0 text-sm leading-8">{{ $t(step.translationKey) }}</p>
<div class="flex flex-row items-center">
@ -115,8 +115,8 @@
{{ step.time }}
</span>
<span
class="block py-1 text-sm text-center uppercase rounded-full"
:class="statusClass(step)"
class="block py-1 text-sm text-center uppercase rounded-full"
style="width: 88px"
>
{{ getStatus(step) }}
@ -130,7 +130,7 @@
<script>
import LoadingIcon from '../../components/icon/LoadingIcon'
import { mapActions } from 'vuex'
export default {
components: {
LoadingIcon,
@ -228,6 +228,8 @@ export default {
},
methods: {
...mapActions('notification', ['showNotification']),
getStatus(step) {
if (step.started && step.completed) {
return 'finished'
@ -266,7 +268,11 @@ export default {
this.isCheckingforUpdate = false
if (!response.data.version) {
window.toastr['info'](this.$t('settings.update_app.latest_message'))
this.showNotification({
title: 'Info!',
type: 'info',
message: this.$t('settings.update_app.latest_message'),
})
return
}
@ -283,16 +289,21 @@ export default {
} catch (e) {
this.isUpdateAvailable = false
this.isCheckingforUpdate = false
window.toastr['error']('Something went wrong')
this.showNotification({
type: 'error',
message: 'Something went wrong',
})
}
},
async onUpdateApp() {
let path = null
if (!this.allowToUpdate) {
window.toastr['error'](
'Your current configuration does not match the update requirements. Please try again after all the requirements are fulfilled. '
)
this.showNotification({
type: 'error',
message:
'Your current configuration does not match the update requirements. Please try again after all the requirements are fulfilled.',
})
return true
}
for (let index = 0; index < this.updateSteps.length; index++) {
@ -321,9 +332,10 @@ export default {
currentStep.translationKey == 'settings.update_app.finishing_update'
) {
this.isUpdating = false
window.toastr['success'](
this.$t('settings.update_app.update_success')
)
this.showNotification({
type: 'success',
message: this.$t('settings.update_app.update_success'),
})
setTimeout(() => {
location.reload()
@ -332,7 +344,10 @@ export default {
} catch (error) {
currentStep.started = false
currentStep.completed = true
window.toastr['error'](this.$t('validation.something_went_wrong'))
this.showNotification({
type: 'error',
message: this.$t('validation.something_went_wrong'),
})
this.onUpdateFailed(currentStep.translationKey)
return false
}
@ -341,7 +356,7 @@ export default {
onUpdateFailed(translationKey) {
let stepName = this.$t(translationKey)
swal({
this.$swal({
title: this.$t('settings.update_app.update_failed'),
text: this.$tc('settings.update_app.update_failed_text', stepName, {
step: stepName,

View File

@ -264,6 +264,8 @@ export default {
...mapActions(['fetchLanguages']),
...mapActions('notification', ['showNotification']),
onUploadHandler(cropper) {
this.previewAvatar = cropper
.getCroppedCanvas()
@ -271,7 +273,10 @@ export default {
},
onHandleUploadError() {
window.toastr['error']('Oops! Something went wrong...')
this.showNotification({
type: 'error',
message: 'Oops! Something went wrong...',
})
},
onChange(file) {
@ -348,10 +353,10 @@ export default {
this.uploadAvatar(avatarData)
}
window.toastr['success'](
this.$t('settings.account_settings.updated_message')
)
this.showNotification({
type: 'success',
message: this.$t('settings.account_settings.updated_message'),
})
this.formData.password = ''
this.formData.confirm_password = ''

View File

@ -56,6 +56,7 @@
</transition>
</template>
<script>
import { mapActions } from 'vuex'
export default {
data() {
return {
@ -134,13 +135,17 @@ export default {
},
methods: {
...mapActions('notification', ['showNotification']),
async updateAddressSetting() {
let data = { type: 'ADDRESSES', ...this.addresses, large: true }
// if (this.updateSetting(data)) {
window.toastr['success'](
this.$t('settings.customization.addresses.address_setting_updated')
)
this.showNotification({
type: 'success',
message: this.$t(
'settings.customization.addresses.address_setting_updated'
),
})
// }
},
},

View File

@ -107,9 +107,7 @@
</div>
<div class="ml-4">
<p class="p-0 mb-1 text-base leading-snug text-black">
{{
$t('settings.customization.estimates.estimate_email_attachment')
}}
{{ $t('settings.customization.estimates.estimate_email_attachment') }}
</p>
<p
@ -117,7 +115,9 @@
style="max-width: 480px"
>
{{
$t('settings.customization.estimates.estimate_email_attachment_setting_description')
$t(
'settings.customization.estimates.estimate_email_attachment_setting_description'
)
}}
</p>
</div>
@ -126,7 +126,7 @@
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
import { mapActions } from 'vuex'
const { required, maxLength, alpha } = require('vuelidate/lib/validators')
export default {
@ -244,7 +244,7 @@ export default {
methods: {
...mapActions('company', ['updateCompanySettings']),
...mapActions('notification', ['showNotification']),
async setEstimateSetting() {
let data = {
settings: {
@ -254,7 +254,10 @@ export default {
}
let response = await this.updateCompanySettings(data)
if (response.data) {
window.toastr['success'](this.$t('general.setting_updated'))
this.showNotification({
type: 'success',
message: this.$t('general.setting_updated'),
})
}
},
@ -286,9 +289,12 @@ export default {
}
if (this.updateSetting(data)) {
window.toastr['success'](
this.$t('settings.customization.estimates.estimate_setting_updated')
)
this.showNotification({
type: 'success',
message: this.$t(
'settings.customization.estimates.estimate_setting_updated'
),
})
}
},

View File

@ -113,9 +113,7 @@
<div class="ml-4">
<p class="p-0 mb-1 text-base leading-snug text-black">
{{
$t('settings.customization.invoices.invoice_email_attachment')
}}
{{ $t('settings.customization.invoices.invoice_email_attachment') }}
</p>
<p
@ -123,7 +121,9 @@
style="max-width: 480px"
>
{{
$t('settings.customization.invoices.invoice_email_attachment_setting_description')
$t(
'settings.customization.invoices.invoice_email_attachment_setting_description'
)
}}
</p>
</div>
@ -240,6 +240,7 @@ export default {
methods: {
...mapActions('company', ['updateCompanySettings']),
...mapActions('notification', ['showNotification']),
async setInvoiceSetting() {
let data = {
@ -252,7 +253,10 @@ export default {
let response = await this.updateCompanySettings(data)
if (response.data) {
window.toastr['success'](this.$t('general.setting_updated'))
this.showNotification({
type: 'success',
message: this.$t('general.setting_updated'),
})
}
},
@ -283,9 +287,12 @@ export default {
}
if (this.updateSetting(data)) {
window.toastr['success'](
this.$t('settings.customization.invoices.invoice_setting_updated')
)
this.showNotification({
type: 'success',
message: this.$t(
'settings.customization.invoices.invoice_setting_updated'
),
})
}
},

View File

@ -9,9 +9,9 @@
<sw-table-component
ref="table"
variant="gray"
:data="fetchData"
:show-filter="false"
variant="gray"
>
<sw-table-column
:sortable="true"
@ -66,6 +66,8 @@ export default {
...mapActions('item', ['deleteItemUnit', 'fetchItemUnits']),
...mapActions('notification', ['showNotification']),
async fetchData({ page, filter, sort }) {
let data = {
orderByField: sort.fieldName || 'created_at',
@ -104,26 +106,31 @@ export default {
},
async removeItemUnit(id) {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$t('settings.customization.items.item_unit_confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (value) => {
if (value) {
icon: 'question',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let response = await this.deleteItemUnit(id)
if (response.data.success) {
window.toastr['success'](
this.$t('settings.customization.items.deleted_message')
)
this.showNotification({
type: 'success',
message: this.$t('settings.customization.items.deleted_message'),
})
this.$refs.table.refresh()
return true
}
window.toastr['error'](
this.$t('settings.customization.items.already_in_use')
)
this.showNotification({
type: 'error',
message: this.$t('settings.customization.items.already_in_use'),
})
}
})
},

View File

@ -102,9 +102,7 @@
<div class="ml-4">
<p class="p-0 mb-1 text-base leading-snug text-black">
{{
$t('settings.customization.payments.payment_email_attachment')
}}
{{ $t('settings.customization.payments.payment_email_attachment') }}
</p>
<p
@ -112,7 +110,9 @@
style="max-width: 480px"
>
{{
$t('settings.customization.payments.payment_email_attachment_setting_description')
$t(
'settings.customization.payments.payment_email_attachment_setting_description'
)
}}
</p>
</div>
@ -228,6 +228,8 @@ export default {
...mapActions('company', ['updateCompanySettings']),
...mapActions('notification', ['showNotification']),
changeToUppercase(currentTab) {
if (currentTab === 'PAYMENTS') {
this.payments.payment_prefix = this.payments.payment_prefix.toUpperCase()
@ -244,7 +246,10 @@ export default {
}
let response = await this.updateCompanySettings(data)
if (response.data) {
window.toastr['success'](this.$t('general.setting_updated'))
this.showNotification({
type: 'success',
message: this.$t('general.setting_updated'),
})
}
},
@ -266,9 +271,12 @@ export default {
}
if (this.updateSetting(data)) {
window.toastr['success'](
this.$t('settings.customization.payments.payment_setting_updated')
)
this.showNotification({
type: 'success',
message: this.$t(
'settings.customization.payments.payment_setting_updated'
),
})
}
},

View File

@ -1,19 +1,19 @@
<template>
<base-page v-if="isSuperAdmin" class="item-create">
<sw-page-header class="mb-3" :title="pageTitle">
<sw-page-header :title="pageTitle" class="mb-3">
<sw-breadcrumb slot="breadcrumbs">
<sw-breadcrumb-item to="/admin/dashboard" :title="$t('general.home')" />
<sw-breadcrumb-item to="/admin/users" :title="$tc('users.user', 2)" />
<sw-breadcrumb-item :title="$t('general.home')" to="/admin/dashboard" />
<sw-breadcrumb-item :title="$tc('users.user', 2)" to="/admin/users" />
<sw-breadcrumb-item
v-if="$route.name === 'users.edit'"
to="#"
:title="$t('users.edit_user')"
to="#"
active
/>
<sw-breadcrumb-item
v-else
to="#"
:title="$t('users.new_user')"
to="#"
active
/>
</sw-breadcrumb>
@ -43,8 +43,8 @@
<sw-input-group
:label="$t('users.email')"
class="mt-4"
:error="emailError"
class="mt-4"
required
>
<sw-input
@ -229,6 +229,8 @@ export default {
methods: {
...mapActions('users', ['addUser', 'fetchUser', 'updateUser']),
...mapActions('notification', ['showNotification']),
async loadEditData() {
let response = await this.fetchUser(this.$route.params.id)
@ -251,12 +253,18 @@ export default {
response = await this.updateUser(this.formData)
let data
if (response.data.success) {
window.toastr['success'](this.$tc('users.updated_message'))
this.showNotification({
type: 'success',
message: this.$tc('users.updated_message'),
})
this.$router.push('/admin/users')
this.isLoading = false
}
if (response.data.error) {
window.toastr['error'](this.$t('validation.email_already_taken'))
this.showNotification({
type: 'error',
message: this.$t('validation.email_already_taken'),
})
}
} else {
response = await this.addUser(this.formData)
@ -264,7 +272,10 @@ export default {
if (response.data.success) {
this.isLoading = false
if (!this.isEdit) {
window.toastr['success'](this.$tc('users.created_message'))
this.showNotification({
type: 'success',
message: this.$tc('users.created_message'),
})
this.$router.push('/admin/users')
return true
}

View File

@ -2,8 +2,8 @@
<base-page v-if="isSuperAdmin" class="items">
<sw-page-header :title="$t('users.title')">
<sw-breadcrumb slot="breadcrumbs">
<sw-breadcrumb-item to="dashboard" :title="$t('general.home')" />
<sw-breadcrumb-item to="#" :title="$tc('users.title', 2)" active />
<sw-breadcrumb-item :title="$t('general.home')" to="dashboard" />
<sw-breadcrumb-item :title="$tc('users.title', 2)" to="#" active />
</sw-breadcrumb>
<template slot="actions">
@ -91,7 +91,7 @@
</sw-button>
</sw-empty-table-placeholder>
<div class="relative table-container" v-show="!showEmptyScreen">
<div v-show="!showEmptyScreen" class="relative table-container">
<div
class="relative flex items-center justify-between h-10 mt-5 list-none border-b-2 border-gray-200 border-solid"
>
@ -209,8 +209,8 @@
<dot-icon slot="activator" />
<sw-dropdown-item
tag-name="router-link"
:to="`users/${row.id}/edit`"
tag-name="router-link"
>
<pencil-icon class="h-5 mr-3 text-gray-600" />
{{ $t('general.edit') }}
@ -302,17 +302,17 @@ export default {
},
},
},
created() {
if (!this.isSuperAdmin) {
this.$router.push('/admin/dashboard')
}
},
watch: {
filters: {
handler: 'setFilters',
deep: true,
},
},
created() {
if (!this.isSuperAdmin) {
this.$router.push('/admin/dashboard')
}
},
destroyed() {
if (this.selectAllField) {
@ -330,6 +330,8 @@ export default {
'setSelectAllState',
]),
...mapActions('notification', ['showNotification']),
refreshTable() {
this.$refs.table.refresh()
},
@ -384,52 +386,71 @@ export default {
let user = []
user.push(id)
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('users.confirm_delete'),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.deleteUser(user)
if (res.data.success) {
window.toastr['success'](this.$tc('users.deleted_message', 1))
this.showNotification({
type: 'success',
message: this.$tc('users.deleted_message', 1),
})
this.$refs.table.refresh()
return true
}
if (res.data.error === 'user_attached') {
window.toastr['error'](
this.$tc('users.user_attached_message'),
this.$t('general.action_failed')
)
this.showNotification({
type: 'error',
message:
(this.$tc('users.user_attached_message'),
this.$t('general.action_failed')),
})
return true
}
window.toastr['error'](res.data.message)
this.showNotification({
type: 'error',
message: res.data.message,
})
return true
}
})
},
async removeMultipleUsers() {
swal({
this.$swal({
title: this.$t('general.are_you_sure'),
text: this.$tc('users.confirm_delete', 2),
icon: '/assets/icon/trash-solid.svg',
buttons: true,
dangerMode: true,
}).then(async (willDelete) => {
if (willDelete) {
icon: 'error',
iconHtml: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-red-600"fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>`,
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
let res = await this.deleteMultipleUsers()
if (res.data.success || res.data.users) {
window.toastr['success'](this.$tc('users.deleted_message', 2))
this.showNotification({
type: 'success',
message: this.$tc('users.deleted_message', 2),
})
this.$refs.table.refresh()
} else if (res.data.error) {
window.toastr['error'](res.data.message)
this.showNotification({
type: 'error',
message: res.data.message,
})
}
}
})

View File

@ -33,8 +33,8 @@
</div>
<sw-avatar
trigger="#logo-box"
:preview-avatar="previewLogo"
trigger="#logo-box"
@changed="onChange"
@uploadHandler="onUploadHandler"
@handleUploadError="onHandleUploadError"
@ -156,7 +156,7 @@ const { required, maxLength } = require('vuelidate/lib/validators')
export default {
components: {
CloudUploadIcon
CloudUploadIcon,
},
data() {
return {
@ -197,12 +197,6 @@ export default {
},
},
},
watch: {
country({ id }) {
this.companyData.country_id = id
return true
},
},
computed: {
companyNameError() {
if (!this.$v.companyData.name.$error) {
@ -241,12 +235,18 @@ export default {
}
},
},
watch: {
country({ id }) {
this.companyData.country_id = id
return true
},
},
mounted() {
this.fetchCountries()
},
methods: {
...mapActions('company', ['setSelectedCompany']),
...mapActions('notification', ['showNotification']),
onUploadHandler(cropper) {
this.previewLogo = cropper
.getCroppedCanvas()
@ -254,7 +254,10 @@ export default {
},
onHandleUploadError() {
window.toastr['error']('Oops! Something went wrong...')
this.showNotification({
type: 'error',
message: 'Oops! Something went wrong...',
})
},
onChange(file) {

View File

@ -21,7 +21,7 @@ import Mysql from './database/MysqlDatabase'
import Pgsql from './database/PgsqlDatabase'
import Sqlite from './database/SqliteDatabase'
import Sqlsrv from './database/SqlsrvDatabase'
import { mapActions } from 'vuex'
export default {
components: {
Mysql,
@ -44,6 +44,7 @@ export default {
this.getDatabaseConfig(this.database_connection)
},
methods: {
...mapActions('notification', ['showNotification']),
async getDatabaseConfig(connection) {
this.isLoading = this.isFetching = true
@ -80,20 +81,28 @@ export default {
this.$emit('next', 3)
window.toastr['success'](
this.$t('wizard.success.' + response.data.success)
)
this.showNotification({
type: 'success',
message: this.$t('wizard.success.' + response.data.success),
})
return true
} else if (response.data.error) {
window.toastr['error'](
this.$t('wizard.errors.' + response.data.error)
)
this.showNotification({
type: 'error',
message: this.$t('wizard.errors.' + response.data.error),
})
} else if (response.data.error_message) {
window.toastr['error'](response.data.error_message)
this.showNotification({
type: 'error',
message: response.data.error_message,
})
}
} catch (e) {
window.toastr['error'](e.response.data.message)
this.showNotification({
type: 'error',
message: e.response.data.message,
})
} finally {
this.isLoading = this.isFetching = false
}

View File

@ -24,7 +24,7 @@ import Smtp from './mail-driver/SmtpMailDriver'
import Mailgun from './mail-driver/MailgunMailDriver'
import Ses from './mail-driver/SesMailDriver'
import Basic from './mail-driver/BasicMailDriver'
import { mapActions } from 'vuex'
export default {
components: {
Smtp,
@ -48,6 +48,7 @@ export default {
this.getMailDrivers()
},
methods: {
...mapActions('notification', ['showNotification']),
async getMailDrivers() {
this.isLoading = this.isFetching = true
@ -67,19 +68,24 @@ export default {
)
if (response.data.success) {
this.$emit('next', 4)
window.toastr['success'](
this.$t('wizard.success.' + response.data.success)
)
this.showNotification({
type: 'success',
message: this.$t('wizard.success.' + response.data.success),
})
} else {
window.toastr['error'](
this.$t('wizard.errors.' + response.data.error)
)
this.showNotification({
type: 'error',
message: this.$t('wizard.errors.' + response.data.error),
})
}
this.isLoading = this.isFetching = false
return true
} catch (e) {
this.isLoading = this.isFetching = false
window.toastr['error']('Something went wrong')
this.showNotification({
type: 'error',
message: 'Something went wrong',
})
}
},
},

View File

@ -75,14 +75,14 @@ export default {
let self = this
if (this.errors) {
swal({
this.$swal({
title: this.$t('wizard.permissions.permission_confirm_title'),
text: this.$t('wizard.permissions.permission_confirm_desc'),
icon: 'warning',
buttons: true,
dangerMode: true,
}).then(async (willConfirm) => {
if (willConfirm) {
showCancelButton: true,
showConfirmButton: true,
}).then(async (result) => {
if (result.value) {
self.isLoading = this.isFetching = false
}
})

View File

@ -211,6 +211,7 @@ export default {
},
methods: {
...mapActions('company', ['updateCompanySettings', 'setSelectedCompany']),
...mapActions('notification', ['showNotification']),
...mapActions([
'fetchLanguages',
'fetchCurrencies',
@ -288,7 +289,10 @@ export default {
if (response.data) {
this.$emit('next', 'COMPLETED')
window.toastr['success']('Login Successful')
this.showNotification({
type: 'success',
message: 'Login Successful',
})
this.$router.push('/admin/dashboard')
}
},

View File

@ -208,13 +208,17 @@ export default {
},
methods: {
...mapActions('user', ['uploadAvatar']),
...mapActions('notification', ['showNotification']),
onUploadHandler(cropper) {
this.previewAvatar = cropper
.getCroppedCanvas()
.toDataURL(this.cropperOutputMime)
},
onHandleUploadError() {
window.toastr['error']('Oops! Something went wrong...')
this.showNotification({
type: 'error',
message: 'Oops! Something went wrong...',
})
},
onChange(file) {
this.cropperOutputMime = file.type