mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-27 11:41:09 -04:00
Add New SweetAlert & Notification Components
This commit is contained in:
@ -34,14 +34,13 @@
|
||||
"lodash": "^4.17.13",
|
||||
"moment": "^2.29.1",
|
||||
"sweet-modal-vue": "^2.0.0",
|
||||
"sweetalert": "^2.1.2",
|
||||
"tailwindcss": "^2.0.1",
|
||||
"toastr": "^2.1.4",
|
||||
"v-tooltip": "^2.0.2",
|
||||
"vue": "^2.6.10",
|
||||
"vue-i18n": "^8.22.0",
|
||||
"vue-loader": "^15.9.3",
|
||||
"vue-router": "2.7.0",
|
||||
"vue-sweetalert2": "^4.2.1",
|
||||
"vue2-transitions": "^0.3.0",
|
||||
"vuedraggable": "^2.24.2",
|
||||
"vuelidate": "^0.6.2",
|
||||
|
||||
@ -8,7 +8,6 @@ import router from './router.js'
|
||||
import store from './store/index'
|
||||
import utils from './helpers/utilities'
|
||||
import i18n from './plugins/i18n'
|
||||
import swal from 'sweetalert'
|
||||
|
||||
require('./bootstrap')
|
||||
|
||||
@ -27,5 +26,4 @@ new Vue({
|
||||
router,
|
||||
store,
|
||||
i18n,
|
||||
swal,
|
||||
}).$mount('#app')
|
||||
|
||||
62
resources/assets/js/bootstrap.js
vendored
62
resources/assets/js/bootstrap.js
vendored
@ -8,6 +8,8 @@ import money from 'v-money'
|
||||
import VTooltip from 'v-tooltip'
|
||||
import Transitions from 'vue2-transitions'
|
||||
import SpaceWind from '@bytefury/spacewind'
|
||||
import swal from 'vue-sweetalert2'
|
||||
import 'sweetalert2/dist/sweetalert2.min.css'
|
||||
|
||||
/**
|
||||
* Theme
|
||||
@ -22,6 +24,33 @@ Vue.use(SpaceWind, { theme })
|
||||
|
||||
Vue.use(Vuelidate)
|
||||
|
||||
Vue.use(swal, {
|
||||
customClass: {
|
||||
container:
|
||||
'fixed z-50 inset-0 overflow-y-auto bg-black bg-opacity-25 flex justify-center min-h-screen items-center sm:p-0 swal2-container',
|
||||
popup:
|
||||
'flex items-center flex-col justify-center align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6',
|
||||
header: 'swal2-header',
|
||||
title: 'swal2-title',
|
||||
closeButton: '',
|
||||
icon: 'swal2-icon',
|
||||
image: '',
|
||||
content: 'swal2-content',
|
||||
input: '',
|
||||
inputLabel: '',
|
||||
validationMessage: '',
|
||||
actions: 'swal2-actions',
|
||||
confirmButton:
|
||||
'w-full inline-flex py-2 px-4 text-sm leading-5 rounded items-center justify-center text-white font-normal transition duration-150 ease-in-out border border-transparent focus:outline-none bg-primary-500 hover:bg-opacity-75 whitespace-nowrap',
|
||||
denyButton: '',
|
||||
cancelButton:
|
||||
'w-full inline-flex py-2 px-4 text-sm leading-5 rounded justify-center items-center focus:outline-none font-normal transition ease-in-out duration-150 border border-transparent border border-solid border-primary-500 text-primary-500 hover:bg-primary-200 shadow-inner whitespace-nowrap',
|
||||
loader: '',
|
||||
footer: '',
|
||||
},
|
||||
buttonsStyling: false,
|
||||
})
|
||||
|
||||
Vue.use(Transitions)
|
||||
|
||||
window._ = require('lodash')
|
||||
@ -89,10 +118,11 @@ global.axios.interceptors.response.use(undefined, function (err) {
|
||||
return true
|
||||
}
|
||||
if (!err.response) {
|
||||
window.toastr['error'](
|
||||
'Please check your internet connection or wait until servers are back online',
|
||||
'Network Error'
|
||||
)
|
||||
store.dispatch('notification/showNotification', {
|
||||
type: 'error',
|
||||
message:
|
||||
'Please check your internet connection or wait until servers are back online.',
|
||||
})
|
||||
} else {
|
||||
if (
|
||||
err.response.data &&
|
||||
@ -100,24 +130,30 @@ global.axios.interceptors.response.use(undefined, function (err) {
|
||||
err.response.data === ' Unauthorized.')
|
||||
) {
|
||||
// Unauthorized and log out
|
||||
window.toastr['error'](
|
||||
err.response.data.message ? err.response.data.message : 'Unauthorized'
|
||||
)
|
||||
store.dispatch('notification/showNotification', {
|
||||
type: 'error',
|
||||
message: err.response.data.message
|
||||
? err.response.data.message
|
||||
: 'Unauthorized',
|
||||
})
|
||||
store.dispatch('auth/logout', true)
|
||||
} else if (err.response.data.errors) {
|
||||
// Show a notification per error
|
||||
const errors = JSON.parse(JSON.stringify(err.response.data.errors))
|
||||
for (const i in errors) {
|
||||
window.toastr['error'](errors[i])
|
||||
store.dispatch('notification/showNotification', {
|
||||
type: 'error',
|
||||
message: errors[i],
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// Unknown error
|
||||
window.toastr['error'](
|
||||
err.response.data.message
|
||||
store.dispatch('notification/showNotification', {
|
||||
type: 'error',
|
||||
message: err.response.data.message
|
||||
? err.response.data.message
|
||||
: err.response.data || 'Unknown error occurred',
|
||||
'Error'
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
return Promise.reject(err)
|
||||
@ -126,8 +162,6 @@ global.axios.interceptors.response.use(undefined, function (err) {
|
||||
/**
|
||||
* Global plugins
|
||||
*/
|
||||
window.toastr = require('toastr')
|
||||
|
||||
Vue.use(VueRouter)
|
||||
Vue.use(Vuex)
|
||||
Vue.use(VTooltip)
|
||||
|
||||
147
resources/assets/js/components/base/BaseNotification.vue
Normal file
147
resources/assets/js/components/base/BaseNotification.vue
Normal file
@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<transition
|
||||
enter-class="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2 "
|
||||
enter-active-class="transition duration-300 ease-out transform"
|
||||
enter-to-class="duration-300 translate-y-0 opacity-100 sm:translate-x-0"
|
||||
leave-active-class="transition duration-100 ease-in"
|
||||
leave-class="duration-200 opacity-100"
|
||||
leave-to-class="duration-200 opacity-0"
|
||||
>
|
||||
<div
|
||||
v-if="notificationActive"
|
||||
class="fixed inset-0 z-50 flex items-end justify-center px-4 py-6 pointer-events-none sm:p-6 sm:items-start sm:justify-end"
|
||||
>
|
||||
<div
|
||||
:class="success || info ? 'bg-white' : 'bg-red-50'"
|
||||
class="w-full max-w-sm rounded-lg shadow-lg cursor-pointer pointer-events-auto"
|
||||
@click="hideNotification"
|
||||
>
|
||||
<div class="overflow-hidden rounded-lg shadow-xs">
|
||||
<div class="p-4">
|
||||
<div class="flex items-start">
|
||||
<div class="flex-shrink-0">
|
||||
<svg
|
||||
v-if="success"
|
||||
class="w-6 h-6 text-green-400"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
<exclamation-circle-icon
|
||||
v-if="info"
|
||||
class="w-6 h-6 text-blue-400"
|
||||
/>
|
||||
<svg
|
||||
v-if="error"
|
||||
class="w-6 h-6 text-red-400"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex-1 w-0 ml-3">
|
||||
<p
|
||||
:class="`text-sm leading-5 font-medium ${
|
||||
success || info ? 'text-gray-900' : 'text-red-800'
|
||||
}`"
|
||||
>
|
||||
{{
|
||||
notificationTitle ? notificationTitle : success ? 'Success!' : 'Error'
|
||||
}}
|
||||
</p>
|
||||
<p
|
||||
:class="`mt-1 text-sm leading-5 ${
|
||||
success || info ? 'text-gray-500' : 'text-red-700'
|
||||
}`"
|
||||
>
|
||||
{{
|
||||
notificationMessage
|
||||
? notificationMessage
|
||||
: success
|
||||
? 'Successful'
|
||||
: 'Somthing went wrong'
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-shrink-0">
|
||||
<button
|
||||
:class="
|
||||
success || info
|
||||
? ' text-gray-400 focus:text-gray-500'
|
||||
: 'text-red-400 focus:text-red-500'
|
||||
"
|
||||
class="inline-flex w-5 h-5 transition duration-150 ease-in-out focus:outline-none"
|
||||
@click="hideNotification"
|
||||
>
|
||||
<x-icon />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import { XIcon } from '@vue-hero-icons/outline'
|
||||
import { ExclamationCircleIcon } from '@vue-hero-icons/solid'
|
||||
export default {
|
||||
components: {
|
||||
XIcon,
|
||||
ExclamationCircleIcon,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hasFocus: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('notification', [
|
||||
'notificationActive',
|
||||
'notificationTitle',
|
||||
'notificationType',
|
||||
'notificationAutoHide',
|
||||
'notificationMessage',
|
||||
]),
|
||||
success() {
|
||||
return this.notificationType.toLowerCase() === 'success'
|
||||
},
|
||||
error() {
|
||||
return this.notificationType.toLowerCase() === 'error'
|
||||
},
|
||||
info() {
|
||||
return this.notificationType.toLowerCase() === 'info'
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
notificationActive(val) {
|
||||
if (val && this.notificationAutoHide) {
|
||||
window.setTimeout(this.hideNotification, 5000)
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (this.notificationActive && this.notificationAutoHide) {
|
||||
window.setTimeout(this.hideNotification, 5000)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('notification', ['showNotification', 'hideNotification']),
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -13,6 +13,7 @@ import NoteSelectPopup from './popup/NoteSelectPopup.vue'
|
||||
import BaseDatePicker from '../base/BaseDatePicker.vue'
|
||||
import BaseTimePicker from './BaseTimePicker.vue'
|
||||
import BasePage from './BasePage.vue'
|
||||
import BaseNotification from './BaseNotification.vue'
|
||||
|
||||
import GlobalSearch from '../GlobalSearch.vue'
|
||||
|
||||
@ -39,6 +40,7 @@ Vue.component('tax-select-popup', TaxSelectPopup)
|
||||
Vue.component('note-select-popup', NoteSelectPopup)
|
||||
|
||||
Vue.component('base-time-picker', BaseTimePicker)
|
||||
Vue.component('base-notification', BaseNotification)
|
||||
|
||||
Vue.component('dot-icon', DotIcon)
|
||||
Vue.component('save-icon', SaveIcon)
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
<div class="relative customer-modal">
|
||||
<base-loader
|
||||
v-if="isRequestOngoing"
|
||||
class="h-130"
|
||||
:show-bg-overlay="true"
|
||||
class="h-130"
|
||||
/>
|
||||
<form @submit.prevent="createNewBackup">
|
||||
<div class="p-6">
|
||||
@ -21,7 +21,7 @@
|
||||
:show-labels="false"
|
||||
:placeholder="$t('settings.backup.select_backup_type')"
|
||||
:allow-empty="false"
|
||||
:maxHeight="100"
|
||||
:max-height="100"
|
||||
/>
|
||||
</sw-input-group>
|
||||
<sw-input-group
|
||||
@ -38,11 +38,11 @@
|
||||
:show-labels="false"
|
||||
:placeholder="$t('settings.disk.select_disk')"
|
||||
:allow-empty="false"
|
||||
track-by="id"
|
||||
:preselect-first="true"
|
||||
:custom-label="getCustomLabel"
|
||||
:maxHeight="100"
|
||||
:max-height="100"
|
||||
:loading="isLoading"
|
||||
track-by="id"
|
||||
/>
|
||||
</sw-input-group>
|
||||
</div>
|
||||
@ -59,9 +59,9 @@
|
||||
</sw-button>
|
||||
<sw-button
|
||||
:loading="isCreateLoading"
|
||||
:disabled="isCreateLoading"
|
||||
variant="primary"
|
||||
type="submit"
|
||||
:disabled="isCreateLoading"
|
||||
>
|
||||
<save-icon v-if="!isCreateLoading" class="mr-2" />
|
||||
{{ $t('general.create') }}
|
||||
@ -140,6 +140,8 @@ export default {
|
||||
|
||||
...mapActions('modal', ['closeModal']),
|
||||
|
||||
...mapActions('notification', ['showNotification']),
|
||||
|
||||
getCustomLabel({ driver, name }) {
|
||||
return `${name} — [${driver}]`
|
||||
},
|
||||
@ -154,12 +156,18 @@ export default {
|
||||
this.isCreateLoading = true
|
||||
await this.createBackup(data)
|
||||
this.isCreateLoading = false
|
||||
window.toastr['success'](this.$t('settings.backup.created_message'))
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('settings.backup.created_message'),
|
||||
})
|
||||
this.refreshData ? this.refreshData() : ''
|
||||
this.cancelBackup()
|
||||
} catch (e) {
|
||||
this.isCreateLoading = false
|
||||
window.toastr['error'](e.response.data.message)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: e.response.data.message,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
>
|
||||
{{ $t('general.cancel') }}
|
||||
</sw-button>
|
||||
<sw-button variant="primary" type="submit" :loading="isLoading">
|
||||
<sw-button :loading="isLoading" variant="primary" type="submit">
|
||||
<save-icon v-if="!isLoading" class="mr-2" />
|
||||
{{ !isEdit ? $t('general.save') : $t('general.update') }}
|
||||
</sw-button>
|
||||
@ -135,6 +135,8 @@ export default {
|
||||
methods: {
|
||||
...mapActions('modal', ['closeModal']),
|
||||
...mapActions('category', ['addCategory', 'updateCategory']),
|
||||
...mapActions('notification', ['showNotification']),
|
||||
|
||||
resetFormData() {
|
||||
this.formData = {
|
||||
id: null,
|
||||
@ -159,13 +161,15 @@ export default {
|
||||
|
||||
if (response.data) {
|
||||
if (!this.isEdit) {
|
||||
window.toastr['success'](
|
||||
this.$t('settings.expense_category.created_message')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('settings.expense_category.created_message'),
|
||||
})
|
||||
} else {
|
||||
window.toastr['success'](
|
||||
this.$t('settings.expense_category.updated_message')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('settings.expense_category.updated_message'),
|
||||
})
|
||||
}
|
||||
window.hub.$emit('newCategory', response.data.category)
|
||||
this.refreshData ? this.refreshData() : ''
|
||||
@ -173,7 +177,10 @@ export default {
|
||||
this.isLoading = false
|
||||
return true
|
||||
}
|
||||
window.toastr['error'](response.data.error)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: response.data.error,
|
||||
})
|
||||
},
|
||||
async setData() {
|
||||
this.formData = {
|
||||
|
||||
@ -78,9 +78,9 @@
|
||||
/>
|
||||
</sw-input-group>
|
||||
<sw-input-group
|
||||
v-if="isDropdownSelected"
|
||||
:label="$t('settings.custom_fields.options')"
|
||||
class="mt-5"
|
||||
v-if="isDropdownSelected"
|
||||
horizontal
|
||||
>
|
||||
<option-create @onAdd="addNewOptions" />
|
||||
@ -92,28 +92,28 @@
|
||||
>
|
||||
<sw-input v-model="option.name" type="text" style="width: 90%" />
|
||||
<minus-circle-icon
|
||||
@click="removeOption(index)"
|
||||
class="ml-1 cursor-pointer icon text-danger"
|
||||
@click="removeOption(index)"
|
||||
/>
|
||||
</div>
|
||||
</sw-input-group>
|
||||
<sw-input-group
|
||||
v-if="formData.type"
|
||||
:label="$t('settings.custom_fields.default_value')"
|
||||
horizontal
|
||||
class="relative mt-5"
|
||||
v-if="formData.type"
|
||||
>
|
||||
<component
|
||||
:value="formData.default_answer"
|
||||
:is="formData.type + 'Type'"
|
||||
:options="formData.options"
|
||||
:defaultDateTime="formData.dateTimeValue"
|
||||
:default-date-time="formData.dateTimeValue"
|
||||
v-model="formData.default_answer"
|
||||
/>
|
||||
</sw-input-group>
|
||||
<sw-input-group
|
||||
:label="$t('settings.custom_fields.placeholder')"
|
||||
v-if="!isSwitchTypeSelected"
|
||||
:label="$t('settings.custom_fields.placeholder')"
|
||||
class="mt-5"
|
||||
horizontal
|
||||
>
|
||||
@ -376,6 +376,7 @@ export default {
|
||||
'fetchCustomField',
|
||||
]),
|
||||
...mapActions('modal', ['closeModal']),
|
||||
...mapActions('notification', ['showNotification']),
|
||||
resetFormData() {
|
||||
this.formData = {
|
||||
label: null,
|
||||
@ -433,9 +434,10 @@ export default {
|
||||
if (this.isEdit) {
|
||||
this.isLoading = true
|
||||
response = await this.updateCustomField(data)
|
||||
window.toastr['success'](
|
||||
this.$tc('settings.custom_fields.updated_message')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$tc('settings.custom_fields.updated_message'),
|
||||
})
|
||||
this.refreshData()
|
||||
this.closeCategoryModal()
|
||||
return true
|
||||
@ -444,7 +446,10 @@ export default {
|
||||
this.isLoading = true
|
||||
response = await this.addCustomField(data)
|
||||
|
||||
window.toastr['success'](this.$tc('settings.custom_fields.added_message'))
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$tc('settings.custom_fields.added_message'),
|
||||
})
|
||||
this.refreshData()
|
||||
this.closeCategoryModal()
|
||||
return true
|
||||
|
||||
@ -62,7 +62,7 @@
|
||||
:allow-empty="false"
|
||||
:show-labels="false"
|
||||
:placeholder="$t('customers.select_currency')"
|
||||
:maxHeight="200"
|
||||
:max-height="200"
|
||||
label="name"
|
||||
class="mt-1 md:mt-0"
|
||||
track-by="id"
|
||||
@ -343,7 +343,7 @@
|
||||
>
|
||||
{{ $t('general.cancel') }}
|
||||
</sw-button>
|
||||
<sw-button variant="primary" type="submit" :loading="isLoading">
|
||||
<sw-button :loading="isLoading" variant="primary" type="submit">
|
||||
<save-icon v-if="!isLoading" class="mr-2" />
|
||||
{{ $t('general.save') }}
|
||||
</sw-button>
|
||||
@ -444,6 +444,8 @@ export default {
|
||||
...mapGetters(['currencies', 'countries']),
|
||||
...mapGetters('company', ['defaultCurrency']),
|
||||
...mapGetters('modal', ['modalDataID', 'modalData', 'modalActive']),
|
||||
...mapActions('notification', ['showNotification']),
|
||||
|
||||
nameError() {
|
||||
if (!this.$v.formData.name.$error) {
|
||||
return ''
|
||||
@ -586,6 +588,7 @@ export default {
|
||||
'updateCustomer',
|
||||
]),
|
||||
...mapActions('modal', ['closeModal']),
|
||||
...mapActions('notification', ['showNotification']),
|
||||
resetData() {
|
||||
this.formData = {
|
||||
name: null,
|
||||
@ -700,9 +703,15 @@ export default {
|
||||
}
|
||||
if (response.data) {
|
||||
if (this.modalDataID) {
|
||||
window.toastr['success'](this.$tc('customers.updated_message'))
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$tc('customers.updated_message'),
|
||||
})
|
||||
} else {
|
||||
window.toastr['success'](this.$tc('customers.created_message'))
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$tc('customers.created_message'),
|
||||
})
|
||||
}
|
||||
|
||||
this.isLoading = false
|
||||
|
||||
@ -5,9 +5,9 @@
|
||||
:is="selected_disk"
|
||||
:loading="isLoading"
|
||||
:disks="getDiskDrivers"
|
||||
:is-edit="isEdit"
|
||||
@on-change-disk="(disk) => (selected_disk = disk.value)"
|
||||
@submit="createNewDisk"
|
||||
:is-edit="isEdit"
|
||||
>
|
||||
<template v-slot="slotProps">
|
||||
<div
|
||||
@ -16,15 +16,15 @@
|
||||
<sw-button
|
||||
class="mr-3 text-sm"
|
||||
variant="primary-outline"
|
||||
@click="closeDisk"
|
||||
type="button"
|
||||
@click="closeDisk"
|
||||
>
|
||||
{{ $t('general.cancel') }}
|
||||
</sw-button>
|
||||
<sw-button
|
||||
:loading="isRequestFire(slotProps)"
|
||||
variant="primary"
|
||||
:disabled="isRequestFire(slotProps)"
|
||||
variant="primary"
|
||||
type="submit"
|
||||
>
|
||||
<save-icon v-if="!isRequestFire(slotProps)" class="mr-2" />
|
||||
@ -96,6 +96,8 @@ export default {
|
||||
|
||||
...mapActions('modal', ['closeModal']),
|
||||
|
||||
...mapActions('notification', ['showNotification']),
|
||||
|
||||
isRequestFire(slotProps) {
|
||||
return slotProps && (slotProps.diskData.isLoading || this.isLoading)
|
||||
},
|
||||
@ -131,14 +133,21 @@ export default {
|
||||
this.refreshData()
|
||||
this.closeDisk()
|
||||
if (this.isEdit) {
|
||||
window.toastr['success'](this.$t('settings.disk.success_update'))
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('settings.disk.success_update'),
|
||||
})
|
||||
} else {
|
||||
window.toastr['success'](this.$t('settings.disk.success_create'))
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('settings.disk.success_create'),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
window.toastr['error'](
|
||||
this.$t('settings.disk.invalid_disk_credentials')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: this.$t('settings.disk.invalid_disk_credentials'),
|
||||
})
|
||||
}
|
||||
this.isLoading = false
|
||||
},
|
||||
|
||||
@ -251,6 +251,7 @@ export default {
|
||||
...mapActions('modal', ['closeModal', 'resetModalData']),
|
||||
...mapActions('item', ['addItem', 'updateItem', 'fetchItemUnits']),
|
||||
...mapActions('invoice', ['setItem']),
|
||||
...mapActions('notification', ['showNotification']),
|
||||
|
||||
resetFormData() {
|
||||
this.formData = {
|
||||
@ -304,7 +305,10 @@ export default {
|
||||
response = await this.addItem(data)
|
||||
}
|
||||
if (response.data) {
|
||||
window.toastr['success'](this.$tc('items.created_message'))
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$tc('items.created_message'),
|
||||
})
|
||||
this.setItem(response.data.item)
|
||||
|
||||
window.hub.$emit('newItem', response.data.item)
|
||||
@ -314,7 +318,10 @@ export default {
|
||||
this.closeModal()
|
||||
return true
|
||||
}
|
||||
window.toastr['error'](response.data.error)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: response.data.error,
|
||||
})
|
||||
},
|
||||
|
||||
closeItemModal() {
|
||||
|
||||
@ -97,6 +97,7 @@ export default {
|
||||
methods: {
|
||||
...mapActions('modal', ['closeModal', 'resetModalData']),
|
||||
...mapActions('item', ['addItemUnit', 'updateItemUnit', 'fatchItemUnit']),
|
||||
...mapActions('notification', ['showNotification']),
|
||||
resetFormData() {
|
||||
this.formData = {
|
||||
id: null,
|
||||
@ -123,13 +124,17 @@ export default {
|
||||
if (response.data) {
|
||||
this.isLoading = false
|
||||
if (!this.isEdit) {
|
||||
window.toastr['success'](
|
||||
this.$t('settings.customization.items.item_unit_added')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('settings.customization.items.item_unit_added'),
|
||||
})
|
||||
} else {
|
||||
window.toastr['success'](
|
||||
this.$t('settings.customization.items.item_unit_updated')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t(
|
||||
'settings.customization.items.item_unit_updated'
|
||||
),
|
||||
})
|
||||
}
|
||||
this.refreshData ? this.refreshData() : ''
|
||||
this.closeItemUnitModal()
|
||||
@ -137,7 +142,10 @@ export default {
|
||||
}
|
||||
} catch (error) {
|
||||
this.isLoading = false
|
||||
window.toastr['error'](response.data.error)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: response.data.error,
|
||||
})
|
||||
}
|
||||
},
|
||||
async setData() {
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
<div class="p-4 md:p-8">
|
||||
<sw-input-group
|
||||
:label="$t('general.to')"
|
||||
class="mt-3"
|
||||
:error="emailError"
|
||||
class="mt-3"
|
||||
variant="horizontal"
|
||||
required
|
||||
>
|
||||
@ -19,8 +19,8 @@
|
||||
</sw-input-group>
|
||||
<sw-input-group
|
||||
:label="$t('general.subject')"
|
||||
class="mt-3"
|
||||
:error="subjectError"
|
||||
class="mt-3"
|
||||
variant="horizontal"
|
||||
required
|
||||
>
|
||||
@ -33,8 +33,8 @@
|
||||
</sw-input-group>
|
||||
<sw-input-group
|
||||
:label="$t('general.message')"
|
||||
class="mt-3"
|
||||
:error="messageError"
|
||||
class="mt-3"
|
||||
variant="horizontal"
|
||||
required
|
||||
>
|
||||
@ -57,7 +57,7 @@
|
||||
>
|
||||
{{ $t('general.cancel') }}
|
||||
</sw-button>
|
||||
<sw-button variant="primary" type="submit" :loading="isLoading">
|
||||
<sw-button :loading="isLoading" variant="primary" type="submit">
|
||||
<paper-airplane-icon v-if="!isLoading" class="mr-2" />
|
||||
{{ !isEdit ? $t('general.send') : $t('general.update') }}
|
||||
</sw-button>
|
||||
@ -149,6 +149,7 @@ export default {
|
||||
methods: {
|
||||
...mapActions('modal', ['closeModal', 'resetModalData']),
|
||||
...mapActions('company', ['sendTestMail']),
|
||||
...mapActions('notification', ['showNotification']),
|
||||
resetFormData() {
|
||||
this.formData = {
|
||||
to: null,
|
||||
@ -169,18 +170,26 @@ export default {
|
||||
|
||||
if (response.data) {
|
||||
if (response.data.success) {
|
||||
window.toastr['success'](this.$tc('general.send_mail_successfully'))
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$tc('general.send_mail_successfully'),
|
||||
})
|
||||
this.closeTaxModal()
|
||||
this.isLoading = false
|
||||
return true
|
||||
}
|
||||
|
||||
window.toastr['error'](this.$tc('validation.something_went_wrong'))
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: this.$tc('validation.something_went_wrong'),
|
||||
})
|
||||
this.closeTaxModal()
|
||||
this.isLoading = false
|
||||
return true
|
||||
}
|
||||
window.toastr['error'](response.data.error)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: response.data.error,
|
||||
})
|
||||
},
|
||||
closeTaxModal() {
|
||||
this.resetModalData()
|
||||
|
||||
@ -147,6 +147,11 @@ export default {
|
||||
required,
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
noteType() {
|
||||
this.setFields()
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
this.setFields()
|
||||
if (this.modalDataID) {
|
||||
@ -158,14 +163,10 @@ export default {
|
||||
: (this.noteType = 'Invoice')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
noteType() {
|
||||
this.setFields()
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions('modal', ['closeModal', 'resetModalData']),
|
||||
...mapActions('notes', ['addNote', 'updateNote']),
|
||||
...mapActions('notification', ['showNotification']),
|
||||
...mapActions('invoice', {
|
||||
setInvoiceNote: 'selectNote',
|
||||
}),
|
||||
@ -222,15 +223,19 @@ export default {
|
||||
|
||||
let res = await this.updateNote(data)
|
||||
if (res.data) {
|
||||
window.toastr['success'](
|
||||
this.$t('settings.customization.notes.note_updated')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('settings.customization.notes.note_updated'),
|
||||
})
|
||||
|
||||
this.refreshData ? this.refreshData() : ''
|
||||
this.closeNoteModal()
|
||||
return true
|
||||
}
|
||||
window.toastr['error'](res.data.error)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: res.data.error,
|
||||
})
|
||||
} else {
|
||||
try {
|
||||
let data = {
|
||||
@ -243,9 +248,10 @@ export default {
|
||||
|
||||
if (response.data && response.data.note) {
|
||||
this.isLoading = false
|
||||
window.toastr['success'](
|
||||
this.$t('settings.customization.notes.note_added')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('settings.customization.notes.note_added'),
|
||||
})
|
||||
if (
|
||||
(this.$route.name === 'invoices.create' &&
|
||||
response.data.note.type === 'Invoice') ||
|
||||
@ -277,7 +283,10 @@ export default {
|
||||
this.closeNoteModal()
|
||||
return true
|
||||
}
|
||||
window.toastr['error'](response.data.error)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: response.data.error,
|
||||
})
|
||||
} catch (err) {
|
||||
if (err.response.data.errors.name) {
|
||||
this.isLoading = true
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
{{ $t('general.cancel') }}
|
||||
</sw-button>
|
||||
<sw-button :loading="isLoading" variant="primary" type="submit">
|
||||
<save-icon class="mr-2" v-if="!isLoading" />
|
||||
<save-icon v-if="!isLoading" class="mr-2" />
|
||||
{{ !isEdit ? $t('general.save') : $t('general.update') }}
|
||||
</sw-button>
|
||||
</div>
|
||||
@ -90,6 +90,7 @@ export default {
|
||||
methods: {
|
||||
...mapActions('modal', ['closeModal', 'resetModalData']),
|
||||
...mapActions('payment', ['addPaymentMode', 'updatePaymentMode']),
|
||||
...mapActions('notification', ['showNotification']),
|
||||
resetFormData() {
|
||||
this.formData = {
|
||||
id: null,
|
||||
@ -108,27 +109,39 @@ export default {
|
||||
if (this.isEdit) {
|
||||
response = await this.updatePaymentMode(this.formData)
|
||||
if (response.data) {
|
||||
window.toastr['success'](
|
||||
this.$t('settings.customization.payments.payment_mode_updated')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t(
|
||||
'settings.customization.payments.payment_mode_updated'
|
||||
),
|
||||
})
|
||||
this.refreshData ? this.refreshData() : ''
|
||||
this.closePaymentModeModal()
|
||||
return true
|
||||
}
|
||||
window.toastr['error'](response.data.error)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: response.data.error,
|
||||
})
|
||||
} else {
|
||||
try {
|
||||
response = await this.addPaymentMode(this.formData)
|
||||
if (response.data) {
|
||||
this.isLoading = false
|
||||
window.toastr['success'](
|
||||
this.$t('settings.customization.payments.payment_mode_added')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t(
|
||||
'settings.customization.payments.payment_mode_added'
|
||||
),
|
||||
})
|
||||
this.refreshData ? this.refreshData() : ''
|
||||
this.closePaymentModeModal()
|
||||
return true
|
||||
}
|
||||
window.toastr['error'](response.data.error)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: response.data.error,
|
||||
})
|
||||
} catch (err) {
|
||||
this.isLoading = false
|
||||
}
|
||||
|
||||
@ -61,8 +61,8 @@
|
||||
v-model="formData.body"
|
||||
:fields="estimateMailFields"
|
||||
:invalid="$v.formData.body.$error"
|
||||
@input="$v.formData.body.$touch()"
|
||||
class="mt-2"
|
||||
@input="$v.formData.body.$touch()"
|
||||
/>
|
||||
</sw-input-group>
|
||||
</div>
|
||||
@ -140,6 +140,7 @@ export default {
|
||||
computed: {
|
||||
...mapGetters('modal', ['modalDataID', 'modalData', 'modalActive']),
|
||||
...mapGetters('user', ['currentUser']),
|
||||
...mapActions('notification', ['showNotification']),
|
||||
getEmailUrl() {
|
||||
return this.url
|
||||
},
|
||||
@ -224,15 +225,31 @@ export default {
|
||||
if (this.$v.$invalid) {
|
||||
return true
|
||||
}
|
||||
swal({
|
||||
this.$swal({
|
||||
title: this.$t('general.are_you_sure'),
|
||||
text: this.$t('estimates.confirm_send_estimate'),
|
||||
icon: '/assets/icon/check-circle-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
}).then(async (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) => {
|
||||
try {
|
||||
if (value) {
|
||||
if (result.value) {
|
||||
let data = {
|
||||
...this.formData,
|
||||
id: this.modalDataID,
|
||||
@ -244,21 +261,26 @@ export default {
|
||||
this.closeModal()
|
||||
if (res.data.success) {
|
||||
this.isLoading = false
|
||||
window.toastr['success'](
|
||||
this.$tc('estimates.send_estimate_successfully')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$tc('estimates.send_estimate_successfully'),
|
||||
})
|
||||
return true
|
||||
}
|
||||
if (res.data.error === 'estimates.user_email_does_not_exist') {
|
||||
window.toastr['error'](
|
||||
this.$tc('estimates.user_email_does_not_exist')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: this.$tc('estimates.user_email_does_not_exist'),
|
||||
})
|
||||
return false
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.isLoading = false
|
||||
window.toastr['error'](this.$tc('estimates.something_went_wrong'))
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: this.$tc('estimates.something_went_wrong'),
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@ -55,8 +55,8 @@
|
||||
v-model="formData.body"
|
||||
:fields="InvoiceMailFields"
|
||||
:invalid="$v.formData.body.$error"
|
||||
@input="$v.formData.body.$touch()"
|
||||
class="mt-2"
|
||||
@input="$v.formData.body.$touch()"
|
||||
/>
|
||||
</sw-input-group>
|
||||
</div>
|
||||
@ -194,6 +194,8 @@ export default {
|
||||
|
||||
...mapActions('company', ['fetchCompanySettings', 'fetchMailConfig']),
|
||||
|
||||
...mapActions('notification', ['showNotification']),
|
||||
|
||||
async setInitialData() {
|
||||
let admin = await this.fetchMailConfig()
|
||||
|
||||
@ -220,15 +222,31 @@ export default {
|
||||
if (this.$v.$invalid) {
|
||||
return true
|
||||
}
|
||||
swal({
|
||||
this.$swal({
|
||||
title: this.$t('general.are_you_sure'),
|
||||
text: this.$t('invoices.confirm_send_invoice'),
|
||||
icon: '/assets/icon/check-circle-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
}).then(async (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) => {
|
||||
try {
|
||||
if (value) {
|
||||
if (result.value) {
|
||||
let data = {
|
||||
...this.formData,
|
||||
id: this.modalDataID,
|
||||
@ -239,21 +257,26 @@ export default {
|
||||
this.closeModal()
|
||||
if (res.data.success) {
|
||||
this.isLoading = false
|
||||
window.toastr['success'](
|
||||
this.$tc('invoices.send_invoice_successfully')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$tc('invoices.send_invoice_successfully'),
|
||||
})
|
||||
return true
|
||||
}
|
||||
if (res.data.error === 'invoices.user_email_does_not_exist') {
|
||||
window.toastr['error'](
|
||||
this.$tc('invoices.user_email_does_not_exist')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: this.$tc('invoices.user_email_does_not_exist'),
|
||||
})
|
||||
return false
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.isLoading = false
|
||||
window.toastr['error'](this.$tc('invoices.something_went_wrong'))
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: this.$tc('invoices.something_went_wrong'),
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
<div class="px-8 py-8 sm:p-6">
|
||||
<sw-input-group
|
||||
:label="$t('general.from')"
|
||||
:error="fromError"
|
||||
class="mb-4"
|
||||
variant="vertical"
|
||||
:error="fromError"
|
||||
required
|
||||
>
|
||||
<sw-input
|
||||
@ -25,8 +25,8 @@
|
||||
>
|
||||
<sw-input
|
||||
v-model="formData.to"
|
||||
type="text"
|
||||
:invalid="$v.formData.to.$error"
|
||||
type="text"
|
||||
@input="$v.formData.to.$touch()"
|
||||
/>
|
||||
</sw-input-group>
|
||||
@ -188,6 +188,8 @@ export default {
|
||||
|
||||
...mapActions('company', ['fetchCompanySettings', 'fetchMailConfig']),
|
||||
|
||||
...mapActions('notification', ['showNotification']),
|
||||
|
||||
async setInitialData() {
|
||||
let admin = await this.fetchMailConfig()
|
||||
|
||||
@ -216,15 +218,31 @@ export default {
|
||||
if (this.$v.$invalid) {
|
||||
return true
|
||||
}
|
||||
swal({
|
||||
this.$swal({
|
||||
title: this.$t('general.are_you_sure'),
|
||||
text: this.$t('payments.confirm_send_payment'),
|
||||
icon: '/assets/icon/check-circle-solid.svg',
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
}).then(async (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) => {
|
||||
try {
|
||||
if (value) {
|
||||
if (result.value) {
|
||||
let data = {
|
||||
...this.formData,
|
||||
id: this.modalDataID,
|
||||
@ -236,21 +254,26 @@ export default {
|
||||
this.closeModal()
|
||||
if (res.data.success) {
|
||||
this.isLoading = false
|
||||
window.toastr['success'](
|
||||
this.$tc('payments.send_payment_successfully')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$tc('payments.send_payment_successfully'),
|
||||
})
|
||||
return true
|
||||
}
|
||||
if (res.data.error === 'payments.user_email_does_not_exist') {
|
||||
window.toastr['error'](
|
||||
this.$tc('payments.user_email_does_not_exist')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: this.$tc('payments.user_email_does_not_exist'),
|
||||
})
|
||||
return false
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.isLoading = false
|
||||
window.toastr['error'](this.$tc('payments.something_went_wrong'))
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: this.$tc('payments.something_went_wrong'),
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@ -9,9 +9,9 @@
|
||||
:searchable="true"
|
||||
:allow-empty="false"
|
||||
:show-labels="false"
|
||||
:custom-label="getCustomLabel"
|
||||
class="mt-2"
|
||||
track-by="id"
|
||||
:custom-label="getCustomLabel"
|
||||
/>
|
||||
</sw-input-group>
|
||||
</div>
|
||||
@ -90,6 +90,8 @@ export default {
|
||||
|
||||
...mapActions('modal', ['closeModal']),
|
||||
|
||||
...mapActions('notification', ['showNotification']),
|
||||
|
||||
async loadData() {
|
||||
this.loading = true
|
||||
|
||||
@ -107,7 +109,10 @@ export default {
|
||||
if (response.data.success) {
|
||||
this.refreshData()
|
||||
this.closeDisk()
|
||||
window.toastr['success'](this.$t('settings.disk.success'))
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('settings.disk.success'),
|
||||
})
|
||||
}
|
||||
this.isLoading = true
|
||||
},
|
||||
|
||||
@ -69,7 +69,7 @@
|
||||
{{ $t('general.cancel') }}
|
||||
</sw-button>
|
||||
<sw-button :loading="isLoading" variant="primary" type="submit">
|
||||
<save-icon class="mr-2" v-if="!isLoading" />
|
||||
<save-icon v-if="!isLoading" class="mr-2" />
|
||||
{{ !isEdit ? $t('general.save') : $t('general.update') }}
|
||||
</sw-button>
|
||||
</div>
|
||||
@ -174,6 +174,7 @@ export default {
|
||||
methods: {
|
||||
...mapActions('modal', ['closeModal', 'resetModalData']),
|
||||
...mapActions('taxType', ['addTaxType', 'updateTaxType', 'fetchTaxType']),
|
||||
...mapActions('notification', ['showNotification']),
|
||||
resetFormData() {
|
||||
this.formData = {
|
||||
id: null,
|
||||
@ -198,13 +199,15 @@ export default {
|
||||
}
|
||||
if (response.data) {
|
||||
if (!this.isEdit) {
|
||||
window.toastr['success'](
|
||||
this.$t('settings.tax_types.created_message')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('settings.tax_types.created_message'),
|
||||
})
|
||||
} else {
|
||||
window.toastr['success'](
|
||||
this.$t('settings.tax_types.updated_message')
|
||||
)
|
||||
this.showNotification({
|
||||
type: 'success',
|
||||
message: this.$t('settings.tax_types.updated_message'),
|
||||
})
|
||||
}
|
||||
window.hub.$emit('newTax', response.data.taxType)
|
||||
this.refreshData ? this.refreshData() : ''
|
||||
@ -212,7 +215,10 @@ export default {
|
||||
this.isLoading = false
|
||||
return true
|
||||
}
|
||||
window.toastr['error'](response.data.error)
|
||||
this.showNotification({
|
||||
type: 'error',
|
||||
message: response.data.error,
|
||||
})
|
||||
},
|
||||
async setData() {
|
||||
this.formData = {
|
||||
|
||||
@ -26,6 +26,7 @@ import estimateTemplate from './modules/estimate-template'
|
||||
import invoiceTemplate from './modules/invoice-template'
|
||||
import search from './modules/search'
|
||||
import notes from './modules/notes'
|
||||
import notification from './modules/notification'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
@ -76,5 +77,6 @@ export default new Vuex.Store({
|
||||
invoiceTemplate,
|
||||
search,
|
||||
notes,
|
||||
notification,
|
||||
},
|
||||
})
|
||||
|
||||
@ -13,7 +13,6 @@ export const login = ({ commit }, data) => {
|
||||
commit('user/' + userTypes.RESET_CURRENT_USER, null, { root: true })
|
||||
commit(rootTypes.UPDATE_APP_LOADING_STATUS, false, { root: true })
|
||||
|
||||
window.toastr['success']('Login Successful')
|
||||
resolve(response)
|
||||
})
|
||||
.catch((err) => {
|
||||
@ -28,7 +27,7 @@ export const setLogoutFalse = ({ state, commit }) => {
|
||||
commit(types.SET_LOGOUT, false)
|
||||
}
|
||||
|
||||
export const logout = ({ state, commit }) => {
|
||||
export const logout = ({ state, commit, dispatch }) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (state.isLoggedOut) {
|
||||
resolve()
|
||||
@ -40,7 +39,14 @@ export const logout = ({ state, commit }) => {
|
||||
.get('/auth/logout')
|
||||
.then(() => {
|
||||
router.push('/login')
|
||||
window.toastr['success']('Logged out!', 'Success')
|
||||
dispatch(
|
||||
'notification/showNotification',
|
||||
{
|
||||
type: 'success',
|
||||
message: 'Logged out successfully.',
|
||||
},
|
||||
{ root: true }
|
||||
)
|
||||
})
|
||||
.catch((err) => {
|
||||
router.push('/login')
|
||||
|
||||
27
resources/assets/js/store/modules/notification/actions.js
Normal file
27
resources/assets/js/store/modules/notification/actions.js
Normal file
@ -0,0 +1,27 @@
|
||||
import * as types from './mutation-types'
|
||||
|
||||
export const showNotification = ({ commit, dispatch, state }, payload) => {
|
||||
commit(types.SHOW_NOTIFICATION, true)
|
||||
|
||||
if (payload.type) {
|
||||
commit(types.SET_NOTIFICATION_TYPE, payload.type)
|
||||
}
|
||||
if (payload.title) {
|
||||
commit(types.SET_TITLE, payload.title)
|
||||
}
|
||||
if (payload.autoHide) {
|
||||
commit(types.SET_AUTO_HIDE, payload.autoHide)
|
||||
}
|
||||
if (payload.message) {
|
||||
commit(types.SET_MESSAGE, payload.message)
|
||||
}
|
||||
}
|
||||
|
||||
export const hideNotification = ({ commit, dispatch, state }) => {
|
||||
commit(types.RESET_DATA)
|
||||
commit(types.HIDE_NOTIFICATION, false)
|
||||
}
|
||||
|
||||
export const resetNotificationData = ({ commit, dispatch, state }) => {
|
||||
commit(types.RESET_DATA)
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
export const notificationActive = (state) => state.active
|
||||
export const notificationTitle = (state) => state.title
|
||||
export const notificationMessage = (state) => state.message
|
||||
export const notificationAutoHide = (state) => state.autoHide
|
||||
export const notificationType = (state) => state.type
|
||||
23
resources/assets/js/store/modules/notification/index.js
Normal file
23
resources/assets/js/store/modules/notification/index.js
Normal file
@ -0,0 +1,23 @@
|
||||
import mutations from './mutations'
|
||||
import * as actions from './actions'
|
||||
import * as getters from './getters'
|
||||
|
||||
const initialState = {
|
||||
active: false,
|
||||
autoHide: true,
|
||||
title: '',
|
||||
message: '',
|
||||
type: '',
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
|
||||
state: initialState,
|
||||
|
||||
getters: getters,
|
||||
|
||||
actions: actions,
|
||||
|
||||
mutations: mutations,
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
export const SHOW_NOTIFICATION = 'SHOW_NOTIFICATION'
|
||||
export const HIDE_NOTIFICATION = 'HIDE_NOTIFICATION'
|
||||
export const SET_TITLE = 'SET_TITLE'
|
||||
export const SET_AUTO_HIDE = 'SET_AUTO_HIDE'
|
||||
export const SET_MESSAGE = 'SET_MESSAGE'
|
||||
export const SET_NOTIFICATION_TYPE = 'SET_NOTIFICATION_TYPE'
|
||||
export const RESET_DATA = 'RESET_DATA'
|
||||
33
resources/assets/js/store/modules/notification/mutations.js
Normal file
33
resources/assets/js/store/modules/notification/mutations.js
Normal file
@ -0,0 +1,33 @@
|
||||
import * as types from './mutation-types'
|
||||
|
||||
export default {
|
||||
[types.SHOW_NOTIFICATION](state, data) {
|
||||
state.active = data
|
||||
},
|
||||
|
||||
[types.HIDE_NOTIFICATION](state, data) {
|
||||
state.active = data
|
||||
},
|
||||
|
||||
[types.SET_TITLE](state, data) {
|
||||
state.title = data
|
||||
},
|
||||
|
||||
[types.SET_AUTO_HIDE](state, data) {
|
||||
state.autoHide = data
|
||||
},
|
||||
|
||||
[types.SET_MESSAGE](state, data) {
|
||||
state.message = data
|
||||
},
|
||||
|
||||
[types.SET_NOTIFICATION_TYPE](state, data) {
|
||||
state.type = data
|
||||
},
|
||||
|
||||
[types.RESET_DATA](state) {
|
||||
state.active = false
|
||||
state.description = ''
|
||||
state.title = ''
|
||||
},
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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'),
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -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'),
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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'),
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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"
|
||||
>
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -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 />
|
||||
|
||||
@ -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,
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
@ -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
|
||||
},
|
||||
},
|
||||
|
||||
@ -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'),
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@ -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'),
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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',
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -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'),
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@ -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'),
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@ -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'),
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@ -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'),
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@ -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'),
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 = ''
|
||||
|
||||
@ -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'
|
||||
),
|
||||
})
|
||||
// }
|
||||
},
|
||||
},
|
||||
|
||||
@ -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'
|
||||
),
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -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'
|
||||
),
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -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'),
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@ -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'
|
||||
),
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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',
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@ -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
|
||||
}
|
||||
})
|
||||
|
||||
@ -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')
|
||||
}
|
||||
},
|
||||
|
||||
@ -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
|
||||
|
||||
89
resources/assets/sass/crater.scss
vendored
89
resources/assets/sass/crater.scss
vendored
@ -5,11 +5,6 @@
|
||||
@tailwind utilities;
|
||||
|
||||
|
||||
// Plugins
|
||||
//----------------------------------
|
||||
|
||||
@import '../../../node_modules/toastr/toastr';
|
||||
|
||||
// Base Components
|
||||
//----------------------------------
|
||||
|
||||
@ -34,3 +29,87 @@
|
||||
right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.swal2-container .swal2-popup {
|
||||
transition-property: all !important;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1) !important;
|
||||
transition-duration: 150ms !important;
|
||||
transition-delay: 150ms !important;
|
||||
padding: 1.5rem !important;
|
||||
}
|
||||
|
||||
.swal2-actions {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
|
||||
gap: 0.75rem !important;
|
||||
margin-top: 1.5rem !important;
|
||||
width: 100% !important;
|
||||
flex-wrap: nowrap !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.swal2-content {
|
||||
text-align: center !important;
|
||||
font-size: 0.875rem !important;
|
||||
line-height: 1.25rem !important;
|
||||
color: #6b7280 !important;
|
||||
font-weight: 500 !important;
|
||||
margin-top: 0.5rem !important;
|
||||
}
|
||||
|
||||
.swal2-icon {
|
||||
height: 3rem !important;
|
||||
width: 3rem !important;
|
||||
border: none !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.swal2-header {
|
||||
display: flex !important;
|
||||
justify-content: center !important;
|
||||
align-items: center !important;
|
||||
}
|
||||
|
||||
.swal2-title {
|
||||
text-align: center !important;
|
||||
margin-top: 0.75 !important;
|
||||
font-weight: 500 !important;
|
||||
color: #111827 !important;
|
||||
font-size: 1.125rem !important;
|
||||
line-height: 1.75rem !important;
|
||||
margin-top: 1.25rem;
|
||||
}
|
||||
|
||||
.swal2-icon.swal2-error {
|
||||
background: #fed7d7 !important;
|
||||
border-radius: 9999px !important;
|
||||
}
|
||||
|
||||
.swal2-icon.swal2-success {
|
||||
background: #c6f6d5 !important;
|
||||
border-radius: 9999px !important;
|
||||
}
|
||||
|
||||
.swal2-icon.swal2-warning {
|
||||
background: #feebc8 !important;
|
||||
border-radius: 9999px !important;
|
||||
}
|
||||
|
||||
.swal2-icon.swal2-info {
|
||||
background: #bee3f8 !important;
|
||||
border-radius: 9999px !important;
|
||||
}
|
||||
|
||||
.swal2-icon.swal2-question {
|
||||
background: #edf2f7 !important;
|
||||
border-radius: 9999px !important;
|
||||
}
|
||||
|
||||
.swal2-icon-content {
|
||||
font-size: 2.75em !important;
|
||||
}
|
||||
|
||||
.swal2-title {
|
||||
margin: 0 !important;
|
||||
margin-top: 1.25rem !important;
|
||||
}
|
||||
|
||||
@ -10,7 +10,6 @@ module.exports = {
|
||||
'./node_modules/\\@bytefury/spacewind/src/**/*.vue',
|
||||
'./node_modules/\\@bytefury/spacewind/plugin/**/*.js',
|
||||
'flatpickr/**/*.js',
|
||||
'toastr/**/*.js',
|
||||
'./public/js/pace/**/*.js',
|
||||
],
|
||||
theme: {
|
||||
|
||||
Reference in New Issue
Block a user