v6 update

This commit is contained in:
Mohit Panjwani
2022-01-10 16:06:17 +05:30
parent b770e6277f
commit bdea879273
722 changed files with 19047 additions and 9186 deletions

View File

@ -0,0 +1,99 @@
<template>
<BaseDropdown>
<template #activator>
<BaseIcon name="DotsHorizontalIcon" class="h-5 text-gray-500" />
</template>
<!-- edit customField -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.EDIT_CUSTOM_FIELDS)"
@click="editCustomField(row.id)"
>
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
<!-- delete customField -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.DELETE_CUSTOM_FIELDS)"
@click="removeCustomField(row.id)"
>
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useDialogStore } from '@/scripts/stores/dialog'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useI18n } from 'vue-i18n'
import { useCustomFieldStore } from '@/scripts/admin/stores/custom-field'
import { useRoute, useRouter } from 'vue-router'
import { inject } from 'vue'
import { useUserStore } from '@/scripts/admin/stores/user'
import { useModalStore } from '@/scripts/stores/modal'
import abilities from '@/scripts/admin/stub/abilities'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
loadData: {
type: Function,
default: null,
},
})
const dialogStore = useDialogStore()
const notificationStore = useNotificationStore()
const { t } = useI18n()
const customFieldStore = useCustomFieldStore()
const route = useRoute()
const userStore = useUserStore()
const modalStore = useModalStore()
const $utils = inject('utils')
async function editCustomField(id) {
await customFieldStore.fetchCustomField(id)
modalStore.openModal({
title: t('settings.custom_fields.edit_custom_field'),
componentName: 'CustomFieldModal',
size: 'sm',
data: id,
refreshData: props.loadData,
})
}
async function removeCustomField(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('settings.custom_fields.custom_field_confirm_delete'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'danger',
hideNoButton: false,
size: 'lg',
})
.then(async (res) => {
if (res) {
await customFieldStore.deleteCustomFields(id)
props.loadData && props.loadData()
}
})
}
</script>

View File

@ -0,0 +1,113 @@
<template>
<BaseDropdown :content-loading="customerStore.isFetchingViewData">
<template #activator>
<BaseButton v-if="route.name === 'customers.view'" variant="primary">
<BaseIcon name="DotsHorizontalIcon" class="h-5 text-white" />
</BaseButton>
<BaseIcon v-else name="DotsHorizontalIcon" class="h-5 text-gray-500" />
</template>
<!-- Edit Customer -->
<router-link
v-if="userStore.hasAbilities(abilities.EDIT_CUSTOMER)"
:to="`/admin/customers/${row.id}/edit`"
>
<BaseDropdownItem>
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
</router-link>
<!-- View Customer -->
<router-link
v-if="
route.name !== 'customers.view' &&
userStore.hasAbilities(abilities.VIEW_CUSTOMER)
"
:to="`customers/${row.id}/view`"
>
<BaseDropdownItem>
<BaseIcon
name="EyeIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.view') }}
</BaseDropdownItem>
</router-link>
<!-- Delete Customer -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.DELETE_CUSTOMER)"
@click="removeCustomer(row.id)"
>
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useCustomerStore } from '@/scripts/admin/stores/customer'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useDialogStore } from '@/scripts/stores/dialog'
import { useModalStore } from '@/scripts/stores/modal'
import { useI18n } from 'vue-i18n'
import { useRoute, useRouter } from 'vue-router'
import { useUserStore } from '@/scripts/admin/stores/user'
import { inject } from 'vue'
import abilities from '@/scripts/admin/stub/abilities'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
loadData: {
type: Function,
default: () => {},
},
})
const customerStore = useCustomerStore()
const notificationStore = useNotificationStore()
const dialogStore = useDialogStore()
const userStore = useUserStore()
const { t } = useI18n()
const route = useRoute()
const router = useRouter()
const utils = inject('utils')
function removeCustomer(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('customers.confirm_delete', 1),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'danger',
hideNoButton: false,
size: 'lg',
})
.then((res) => {
if (res) {
customerStore.deleteCustomer({ ids: [id] }).then((response) => {
if (response.data.success) {
props.loadData && props.loadData()
return true
}
})
}
})
}
</script>

View File

@ -0,0 +1,337 @@
<template>
<BaseDropdown>
<template #activator>
<BaseButton v-if="route.name === 'estimates.view'" variant="primary">
<BaseIcon name="DotsHorizontalIcon" class="text-white" />
</BaseButton>
<BaseIcon v-else class="text-gray-500" name="DotsHorizontalIcon" />
</template>
<!-- Copy PDF url -->
<BaseDropdownItem
v-if="route.name === 'estimates.view'"
@click="copyPdfUrl"
>
<BaseIcon
name="LinkIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.copy_pdf_url') }}
</BaseDropdownItem>
<!-- Edit Estimate -->
<router-link
v-if="userStore.hasAbilities(abilities.EDIT_ESTIMATE)"
:to="`/admin/estimates/${row.id}/edit`"
>
<BaseDropdownItem>
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
</router-link>
<!-- Delete Estimate -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.DELETE_ESTIMATE)"
@click="removeEstimate(row.id)"
>
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
<!-- View Estimate -->
<router-link
v-if="
route.name !== 'estimates.view' &&
userStore.hasAbilities(abilities.VIEW_ESTIMATE)
"
:to="`estimates/${row.id}/view`"
>
<BaseDropdownItem>
<BaseIcon
name="EyeIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.view') }}
</BaseDropdownItem>
</router-link>
<!-- Convert into Invoice -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.CREATE_INVOICE)"
@click="convertInToinvoice(row.id)"
>
<BaseIcon
name="DocumentTextIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('estimates.convert_to_invoice') }}
</BaseDropdownItem>
<!-- Mark as sent -->
<BaseDropdownItem
v-if="
row.status !== 'SENT' &&
route.name !== 'estimates.view' &&
userStore.hasAbilities(abilities.SEND_ESTIMATE)
"
@click="onMarkAsSent(row.id)"
>
<BaseIcon
name="CheckCircleIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('estimates.mark_as_sent') }}
</BaseDropdownItem>
<!-- Send Estimate -->
<BaseDropdownItem
v-if="
row.status !== 'SENT' &&
route.name !== 'estimates.view' &&
userStore.hasAbilities(abilities.SEND_ESTIMATE)
"
@click="sendEstimate(row)"
>
<BaseIcon
name="PaperAirplaneIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('estimates.send_estimate') }}
</BaseDropdownItem>
<!-- Resend Estimate -->
<BaseDropdownItem v-if="canResendEstimate(row)" @click="sendEstimate(row)">
<BaseIcon
name="PaperAirplaneIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('estimates.resend_estimate') }}
</BaseDropdownItem>
<!-- Mark as Accepted -->
<BaseDropdownItem
v-if="
row.status !== 'ACCEPTED' &&
userStore.hasAbilities(abilities.EDIT_ESTIMATE)
"
@click="onMarkAsAccepted(row.id)"
>
<BaseIcon
name="CheckCircleIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('estimates.mark_as_accepted') }}
</BaseDropdownItem>
<!-- Mark as Rejected -->
<BaseDropdownItem
v-if="
row.status !== 'REJECTED' &&
userStore.hasAbilities(abilities.EDIT_ESTIMATE)
"
@click="onMarkAsRejected(row.id)"
>
<BaseIcon
name="XCircleIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('estimates.mark_as_rejected') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useEstimateStore } from '@/scripts/admin/stores/estimate'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useModalStore } from '@/scripts/stores/modal'
import { useI18n } from 'vue-i18n'
import { useRoute, useRouter } from 'vue-router'
import { useDialogStore } from '@/scripts/stores/dialog'
import { inject } from 'vue'
import { useUserStore } from '@/scripts/admin/stores/user'
import abilities from '@/scripts/admin/stub/abilities'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
})
const utils = inject('utils')
const estimateStore = useEstimateStore()
const modalStore = useModalStore()
const notificationStore = useNotificationStore()
const dialogStore = useDialogStore()
const userStore = useUserStore()
const { t } = useI18n()
const route = useRoute()
const router = useRouter()
async function removeEstimate(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('estimates.confirm_delete'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'danger',
hideNoButton: false,
size: 'lg',
})
.then((res) => {
id = id
if (res) {
estimateStore.deleteEstimate({ ids: [id] }).then((res) => {
if (res) {
props.table && props.table.refresh()
if (res.data) {
router.push('/admin/estimates')
}
estimateStore.$patch((state) => {
state.selectedEstimates = []
state.selectAllField = false
})
}
})
}
})
}
function convertInToinvoice(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('estimates.confirm_conversion'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'primary',
hideNoButton: false,
size: 'lg',
})
.then((res) => {
if (res) {
estimateStore.convertToInvoice(id).then((res) => {
if (res.data) {
router.push(`/admin/invoices/${res.data.data.id}/edit`)
}
})
}
})
}
async function onMarkAsSent(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('estimates.confirm_mark_as_sent'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'primary',
hideNoButton: false,
size: 'lg',
})
.then((response) => {
const data = {
id: id,
status: 'SENT',
}
if (response) {
estimateStore.markAsSent(data).then((response) => {
props.table && props.table.refresh()
})
}
})
}
function canResendEstimate(row) {
return (
(row.status == 'SENT' || row.status == 'VIEWED') &&
route.name !== 'estimates.view' &&
userStore.hasAbilities(abilities.SEND_ESTIMATE)
)
}
async function sendEstimate(estimate) {
modalStore.openModal({
title: t('estimates.send_estimate'),
componentName: 'SendEstimateModal',
id: estimate.id,
data: estimate,
variant: 'lg',
})
}
async function onMarkAsAccepted(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('estimates.confirm_mark_as_accepted'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'primary',
hideNoButton: false,
size: 'lg',
})
.then((response) => {
const data = {
id: id,
status: 'ACCEPTED',
}
if (response) {
estimateStore.markAsAccepted(data).then((response) => {
props.table && props.table.refresh()
})
}
})
}
async function onMarkAsRejected(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('estimates.confirm_mark_as_rejected'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'primary',
hideNoButton: false,
size: 'lg',
})
.then((response) => {
const data = {
id: id,
status: 'REJECTED',
}
if (response) {
estimateStore.markAsRejected(data).then((response) => {
props.table && props.table.refresh()
})
}
})
}
function copyPdfUrl() {
let pdfUrl = `${window.location.origin}/estimates/pdf/${props.row.unique_hash}`
let response = utils.copyTextToClipboard(pdfUrl)
notificationStore.showNotification({
type: 'success',
message: t('general.copied_pdf_url_clipboard'),
})
}
</script>

View File

@ -0,0 +1,105 @@
<template>
<BaseDropdown>
<template #activator>
<BaseButton
v-if="route.name === 'expenseCategorys.view'"
variant="primary"
>
<BaseIcon name="DotsHorizontalIcon" class="h-5 text-white" />
</BaseButton>
<BaseIcon v-else name="DotsHorizontalIcon" class="h-5 text-gray-500" />
</template>
<!-- edit expenseCategory -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.EDIT_EXPENSE)"
@click="editExpenseCategory(row.id)"
>
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
<!-- delete expenseCategory -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.DELETE_EXPENSE)"
@click="removeExpenseCategory(row.id)"
>
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useDialogStore } from '@/scripts/stores/dialog'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useI18n } from 'vue-i18n'
import { useCategoryStore } from '@/scripts/admin/stores/category'
import { useRoute, useRouter } from 'vue-router'
import { inject } from 'vue'
import { useUserStore } from '@/scripts/admin/stores/user'
import { useModalStore } from '@/scripts/stores/modal'
import abilities from '@/scripts/admin/stub/abilities'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
loadData: {
type: Function,
default: null,
},
})
const dialogStore = useDialogStore()
const notificationStore = useNotificationStore()
const { t } = useI18n()
const expenseCategoryStore = useCategoryStore()
const route = useRoute()
const userStore = useUserStore()
const modalStore = useModalStore()
const $utils = inject('utils')
function editExpenseCategory(data) {
expenseCategoryStore.fetchCategory(data)
modalStore.openModal({
title: t('settings.expense_category.edit_category'),
componentName: 'CategoryModal',
refreshData: props.loadData,
size: 'sm',
})
}
function removeExpenseCategory(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('settings.expense_category.confirm_delete'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'danger',
hideNoButton: false,
size: 'lg',
})
.then(async () => {
let response = await expenseCategoryStore.deleteCategory(id)
if (response.data.success) {
props.loadData && props.loadData()
return true
}
props.loadData && props.loadData()
})
}
</script>

View File

@ -0,0 +1,94 @@
<template>
<BaseDropdown>
<template #activator>
<BaseButton v-if="route.name === 'expenses.view'" variant="primary">
<BaseIcon name="DotsHorizontalIcon" class="h-5 text-white" />
</BaseButton>
<BaseIcon v-else name="DotsHorizontalIcon" class="h-5 text-gray-500" />
</template>
<!-- edit expense -->
<router-link
v-if="userStore.hasAbilities(abilities.EDIT_EXPENSE)"
:to="`/admin/expenses/${row.id}/edit`"
>
<BaseDropdownItem>
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
</router-link>
<!-- delete expense -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.DELETE_EXPENSE)"
@click="removeExpense(row.id)"
>
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useDialogStore } from '@/scripts/stores/dialog'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useI18n } from 'vue-i18n'
import { useExpenseStore } from '@/scripts/admin/stores/expense'
import { useRoute, useRouter } from 'vue-router'
import { inject } from 'vue'
import { useUserStore } from '@/scripts/admin/stores/user'
import abilities from '@/scripts/admin/stub/abilities'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
loadData: {
type: Function,
default: null,
},
})
const dialogStore = useDialogStore()
const notificationStore = useNotificationStore()
const { t } = useI18n()
const expenseStore = useExpenseStore()
const route = useRoute()
const router = useRouter()
const userStore = useUserStore()
const $utils = inject('utils')
function removeExpense(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('expenses.confirm_delete', 1),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'danger',
size: 'lg',
hideNoButton: false,
})
.then((res) => {
if (res) {
expenseStore.deleteExpense({ ids: [id] }).then((res) => {
if (res) {
props.loadData && props.loadData()
}
})
}
})
}
</script>

View File

@ -0,0 +1,261 @@
<template>
<BaseDropdown>
<template #activator>
<BaseButton v-if="route.name === 'invoices.view'" variant="primary">
<BaseIcon name="DotsHorizontalIcon" class="h-5 text-white" />
</BaseButton>
<BaseIcon v-else name="DotsHorizontalIcon" class="h-5 text-gray-500" />
</template>
<!-- Edit Invoice -->
<router-link
v-if="userStore.hasAbilities(abilities.EDIT_INVOICE)"
:to="`/admin/invoices/${row.id}/edit`"
>
<BaseDropdownItem v-show="row.allow_edit">
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
</router-link>
<!-- Copy PDF url -->
<BaseDropdownItem v-if="route.name === 'invoices.view'" @click="copyPdfUrl">
<BaseIcon
name="LinkIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.copy_pdf_url') }}
</BaseDropdownItem>
<!-- View Invoice -->
<router-link
v-if="
route.name !== 'invoices.view' &&
userStore.hasAbilities(abilities.VIEW_INVOICE)
"
:to="`/admin/invoices/${row.id}/view`"
>
<BaseDropdownItem>
<BaseIcon
name="EyeIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.view') }}
</BaseDropdownItem>
</router-link>
<!-- Send Invoice Mail -->
<BaseDropdownItem v-if="canSendInvoice(row)" @click="sendInvoice(row)">
<BaseIcon
name="PaperAirplaneIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('invoices.send_invoice') }}
</BaseDropdownItem>
<!-- Resend Invoice -->
<BaseDropdownItem v-if="canReSendInvoice(row)" @click="sendInvoice(row)">
<BaseIcon
name="PaperAirplaneIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('invoices.resend_invoice') }}
</BaseDropdownItem>
<!-- Record payment -->
<router-link :to="`/admin/payments/${row.id}/create`">
<BaseDropdownItem
v-if="row.status == 'SENT' && route.name !== 'invoices.view'"
>
<BaseIcon
name="CreditCardIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('invoices.record_payment') }}
</BaseDropdownItem>
</router-link>
<!-- Mark as sent Invoice -->
<BaseDropdownItem v-if="canSendInvoice(row)" @click="onMarkAsSent(row.id)">
<BaseIcon
name="CheckCircleIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('invoices.mark_as_sent') }}
</BaseDropdownItem>
<!-- Clone Invoice into new invoice -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.CREATE_INVOICE)"
@click="cloneInvoiceData(row)"
>
<BaseIcon
name="DocumentTextIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('invoices.clone_invoice') }}
</BaseDropdownItem>
<!-- Delete Invoice -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.DELETE_INVOICE)"
@click="removeInvoice(row.id)"
>
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useInvoiceStore } from '@/scripts/admin/stores/invoice'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useDialogStore } from '@/scripts/stores/dialog'
import { useModalStore } from '@/scripts/stores/modal'
import { useI18n } from 'vue-i18n'
import { useRoute, useRouter } from 'vue-router'
import { useUserStore } from '@/scripts/admin/stores/user'
import { inject } from 'vue'
import abilities from '@/scripts/admin/stub/abilities'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
loadData: {
type: Function,
default: () => {},
},
})
const invoiceStore = useInvoiceStore()
const modalStore = useModalStore()
const notificationStore = useNotificationStore()
const dialogStore = useDialogStore()
const userStore = useUserStore()
const { t } = useI18n()
const route = useRoute()
const router = useRouter()
const utils = inject('utils')
function canReSendInvoice(row) {
return (
(row.status == 'SENT' || row.status == 'VIEWED') &&
userStore.hasAbilities(abilities.SEND_INVOICE)
)
}
function canSendInvoice(row) {
return (
row.status == 'DRAFT' &&
route.name !== 'invoices.view' &&
userStore.hasAbilities(abilities.SEND_INVOICE)
)
}
async function removeInvoice(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('invoices.confirm_delete'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'danger',
hideNoButton: false,
size: 'lg',
})
.then((res) => {
id = id
if (res) {
invoiceStore.deleteInvoice({ ids: [id] }).then((res) => {
if (res.data.success) {
router.push('/admin/invoices')
props.table && props.table.refresh()
invoiceStore.$patch((state) => {
state.selectedInvoices = []
state.selectAllField = false
})
}
})
}
})
}
async function cloneInvoiceData(data) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('invoices.confirm_clone'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'primary',
hideNoButton: false,
size: 'lg',
})
.then((res) => {
if (res) {
invoiceStore.cloneInvoice(data).then((res) => {
router.push(`/admin/invoices/${res.data.data.id}/edit`)
})
}
})
}
async function onMarkAsSent(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('invoices.invoice_mark_as_sent'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'primary',
hideNoButton: false,
size: 'lg',
})
.then((response) => {
const data = {
id: id,
status: 'SENT',
}
if (response) {
invoiceStore.markAsSent(data).then((response) => {
props.table && props.table.refresh()
})
}
})
}
async function sendInvoice(invoice) {
modalStore.openModal({
title: t('invoices.send_invoice'),
componentName: 'SendInvoiceModal',
id: invoice.id,
data: invoice,
variant: 'sm',
})
}
function copyPdfUrl() {
let pdfUrl = `${window.location.origin}/invoices/pdf/${props.row.unique_hash}`
utils.copyTextToClipboard(pdfUrl)
notificationStore.showNotification({
type: 'success',
message: t('general.copied_pdf_url_clipboard'),
})
}
</script>

View File

@ -0,0 +1,96 @@
<template>
<BaseDropdown>
<template #activator>
<BaseButton v-if="route.name === 'items.view'" variant="primary">
<BaseIcon name="DotsHorizontalIcon" class="h-5 text-white" />
</BaseButton>
<BaseIcon v-else name="DotsHorizontalIcon" class="h-5 text-gray-500" />
</template>
<!-- edit item -->
<router-link
v-if="userStore.hasAbilities(abilities.EDIT_ITEM)"
:to="`/admin/items/${row.id}/edit`"
>
<BaseDropdownItem>
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
</router-link>
<!-- delete item -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.DELETE_ITEM)"
@click="removeItem(row.id)"
>
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useDialogStore } from '@/scripts/stores/dialog'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useI18n } from 'vue-i18n'
import { useItemStore } from '@/scripts/admin/stores/item'
import { useRoute, useRouter } from 'vue-router'
import { inject } from 'vue'
import { useUserStore } from '@/scripts/admin/stores/user'
import abilities from '@/scripts/admin/stub/abilities'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
loadData: {
type: Function,
default: null,
},
})
const dialogStore = useDialogStore()
const notificationStore = useNotificationStore()
const { t } = useI18n()
const itemStore = useItemStore()
const route = useRoute()
const router = useRouter()
const userStore = useUserStore()
const $utils = inject('utils')
function removeItem(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('items.confirm_delete'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'danger',
hideNoButton: false,
size: 'lg',
})
.then((res) => {
if (res) {
itemStore.deleteItem({ ids: [id] }).then((response) => {
if (response.data.success) {
props.loadData && props.loadData()
return true
}
return true
})
}
})
}
</script>

View File

@ -0,0 +1,109 @@
<template>
<BaseDropdown>
<template #activator>
<BaseButton v-if="route.name === 'notes.view'" variant="primary">
<BaseIcon name="DotsHorizontalIcon" class="h-5 text-white" />
</BaseButton>
<BaseIcon v-else name="DotsHorizontalIcon" class="h-5 text-gray-500" />
</template>
<!-- edit note -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.MANAGE_NOTE)"
@click="editNote(row.id)"
>
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
<!-- delete note -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.MANAGE_NOTE)"
@click="removeNote(row.id)"
>
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useDialogStore } from '@/scripts/stores/dialog'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useI18n } from 'vue-i18n'
import { useNotesStore } from '@/scripts/admin/stores/note'
import { useRoute } from 'vue-router'
import { inject } from 'vue'
import { useUserStore } from '@/scripts/admin/stores/user'
import { useModalStore } from '@/scripts/stores/modal'
import abilities from '@/scripts/admin/stub/abilities'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
loadData: {
type: Function,
default: null,
},
})
const dialogStore = useDialogStore()
const notificationStore = useNotificationStore()
const { t } = useI18n()
const noteStore = useNotesStore()
const route = useRoute()
const userStore = useUserStore()
const modalStore = useModalStore()
const $utils = inject('utils')
function editNote(data) {
noteStore.fetchNote(data)
modalStore.openModal({
title: t('settings.customization.notes.edit_note'),
componentName: 'NoteModal',
size: 'md',
refreshData: props.loadData,
})
}
function removeNote(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('settings.customization.notes.note_confirm_delete'),
yesLabel: t('general.yes'),
noLabel: t('general.no'),
variant: 'danger',
hideNoButton: false,
size: 'lg',
})
.then(async () => {
let response = await noteStore.deleteNote(id)
if (response.data.success) {
notificationStore.showNotification({
type: 'success',
message: t('settings.customization.notes.deleted_message'),
})
} else {
notificationStore.showNotification({
type: 'error',
message: t('settings.customization.notes.already_in_use'),
})
}
props.loadData && props.loadData()
})
}
</script>

View File

@ -0,0 +1,166 @@
<template>
<BaseDropdown :content-loading="contentLoading">
<template #activator>
<BaseButton v-if="route.name === 'payments.view'" variant="primary">
<BaseIcon name="DotsHorizontalIcon" class="h-5 text-white" />
</BaseButton>
<BaseIcon v-else name="DotsHorizontalIcon" class="h-5 text-gray-500" />
</template>
<!-- Copy pdf url -->
<BaseDropdown-item
v-if="
route.name === 'payments.view' &&
userStore.hasAbilities(abilities.VIEW_PAYMENT)
"
class="rounded-md"
@click="copyPdfUrl"
>
<BaseIcon
name="LinkIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.copy_pdf_url') }}
</BaseDropdown-item>
<!-- edit payment -->
<router-link
v-if="userStore.hasAbilities(abilities.EDIT_PAYMENT)"
:to="`/admin/payments/${row.id}/edit`"
>
<BaseDropdownItem>
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
</router-link>
<!-- view payment -->
<router-link
v-if="
route.name !== 'payments.view' &&
userStore.hasAbilities(abilities.VIEW_PAYMENT)
"
:to="`/admin/payments/${row.id}/view`"
>
<BaseDropdownItem>
<BaseIcon
name="EyeIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.view') }}
</BaseDropdownItem>
</router-link>
<!-- Send Estimate -->
<BaseDropdownItem
v-if="
row.status !== 'SENT' &&
route.name !== 'payments.view' &&
userStore.hasAbilities(abilities.SEND_PAYMENT)
"
@click="sendPayment(row)"
>
<BaseIcon
name="PaperAirplaneIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('payments.send_payment') }}
</BaseDropdownItem>
<!-- delete payment -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.DELETE_PAYMENT)"
@click="removePayment(row.id)"
>
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useDialogStore } from '@/scripts/stores/dialog'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useModalStore } from '@/scripts/stores/modal'
import { useI18n } from 'vue-i18n'
import { usePaymentStore } from '@/scripts/admin/stores/payment'
import { useRoute, useRouter } from 'vue-router'
import { inject } from 'vue'
import { useUserStore } from '@/scripts/admin/stores/user'
import abilities from '@/scripts/admin/stub/abilities'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
contentLoading: {
type: Boolean,
default: false,
},
})
const dialogStore = useDialogStore()
const notificationStore = useNotificationStore()
const { t } = useI18n()
const paymentStore = usePaymentStore()
const route = useRoute()
const router = useRouter()
const userStore = useUserStore()
const modalStore = useModalStore()
const $utils = inject('utils')
function removePayment(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('payments.confirm_delete', 1),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'danger',
size: 'lg',
hideNoButton: false,
})
.then(async (res) => {
if (res) {
await paymentStore.deletePayment({ ids: [id] })
router.push(`/admin/payments`)
props.table && props.table.refresh()
return true
}
})
}
function copyPdfUrl() {
let pdfUrl = `${window.location.origin}/payments/pdf/${props.row?.unique_hash}`
$utils.copyTextToClipboard(pdfUrl)
notificationStore.showNotification({
type: 'success',
message: t('general.copied_pdf_url_clipboard'),
})
}
async function sendPayment(payment) {
modalStore.openModal({
title: t('payments.send_payment'),
componentName: 'SendPaymentModal',
id: payment.id,
data: payment,
variant: 'lg',
})
}
</script>

View File

@ -0,0 +1,93 @@
<template>
<BaseDropdown>
<template #activator>
<BaseButton v-if="route.name === 'paymentModes.view'" variant="primary">
<BaseIcon name="DotsHorizontalIcon" class="h-5 text-white" />
</BaseButton>
<BaseIcon v-else name="DotsHorizontalIcon" class="h-5 text-gray-500" />
</template>
<!-- edit paymentMode -->
<BaseDropdownItem @click="editPaymentMode(row.id)">
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
<!-- delete paymentMode -->
<BaseDropdownItem @click="removePaymentMode(row.id)">
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useDialogStore } from '@/scripts/stores/dialog'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useI18n } from 'vue-i18n'
import { usePaymentStore } from '@/scripts/admin/stores/payment'
import { useRoute, useRouter } from 'vue-router'
import { inject } from 'vue'
import { useUserStore } from '@/scripts/admin/stores/user'
import { useModalStore } from '@/scripts/stores/modal'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
loadData: {
type: Function,
default: null,
},
})
const dialogStore = useDialogStore()
const notificationStore = useNotificationStore()
const { t } = useI18n()
const paymentStore = usePaymentStore()
const route = useRoute()
const userStore = useUserStore()
const modalStore = useModalStore()
const $utils = inject('utils')
function editPaymentMode(id) {
paymentStore.fetchPaymentMode(id)
modalStore.openModal({
title: t('settings.payment_modes.edit_payment_mode'),
componentName: 'PaymentModeModal',
refreshData: props.loadData && props.loadData,
size: 'sm',
})
}
function removePaymentMode(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('settings.payment_modes.payment_mode_confirm_delete'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'danger',
hideNoButton: false,
size: 'lg',
})
.then(async (res) => {
if (res) {
await paymentStore.deletePaymentMode(id)
props.loadData && props.loadData()
}
})
}
</script>

View File

@ -0,0 +1,131 @@
<template>
<BaseDropdown :content-loading="recurringInvoiceStore.isFetchingViewData">
<template #activator>
<BaseButton
v-if="route.name === 'recurring-invoices.view'"
variant="primary"
>
<BaseIcon name="DotsHorizontalIcon" class="h-5 text-white" />
</BaseButton>
<BaseIcon v-else name="DotsHorizontalIcon" class="h-5 text-gray-500" />
</template>
<!-- Edit Recurring Invoice -->
<router-link
v-if="userStore.hasAbilities(abilities.EDIT_RECURRING_INVOICE)"
:to="`/admin/recurring-invoices/${row.id}/edit`"
>
<BaseDropdownItem>
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
</router-link>
<!-- View Recurring Invoice -->
<router-link
v-if="
route.name !== 'recurring-invoices.view' &&
userStore.hasAbilities(abilities.VIEW_RECURRING_INVOICE)
"
:to="`recurring-invoices/${row.id}/view`"
>
<BaseDropdownItem>
<BaseIcon
name="EyeIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.view') }}
</BaseDropdownItem>
</router-link>
<!-- Delete Recurring Invoice -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.DELETE_RECURRING_INVOICE)"
@click="removeMultipleRecurringInvoices(row.id)"
>
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useInvoiceStore } from '@/scripts/admin/stores/invoice'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useDialogStore } from '@/scripts/stores/dialog'
import { useModalStore } from '@/scripts/stores/modal'
import { useI18n } from 'vue-i18n'
import { useRoute, useRouter } from 'vue-router'
import { useUserStore } from '@/scripts/admin/stores/user'
import { inject } from 'vue'
import { useRecurringInvoiceStore } from '@/scripts/admin/stores/recurring-invoice'
import abilities from '@/scripts/admin/stub/abilities'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
loadData: {
type: Function,
default: () => {},
},
})
const recurringInvoiceStore = useRecurringInvoiceStore()
const notificationStore = useNotificationStore()
const dialogStore = useDialogStore()
const userStore = useUserStore()
const { t } = useI18n()
const route = useRoute()
const router = useRouter()
const utils = inject('utils')
async function removeMultipleRecurringInvoices(id = null) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('invoices.confirm_delete'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'danger',
hideNoButton: false,
size: 'lg',
})
.then(async (res) => {
if (res) {
await recurringInvoiceStore
.deleteMultipleRecurringInvoices(id)
.then((res) => {
if (res.data.success) {
props.table && props.table.refresh()
recurringInvoiceStore.$patch((state) => {
state.selectedRecurringInvoices = []
state.selectAllField = false
})
notificationStore.showNotification({
type: 'success',
message: t('recurring_invoices.deleted_message', 2),
})
} else if (res.data.error) {
notificationStore.showNotification({
type: 'error',
message: res.data.message,
})
}
})
}
})
}
</script>

View File

@ -0,0 +1,106 @@
<template>
<BaseDropdown>
<template #activator>
<BaseButton v-if="route.name === 'roles.view'" variant="primary">
<BaseIcon name="DotsHorizontalIcon" class="h-5 text-white" />
</BaseButton>
<BaseIcon v-else name="DotsHorizontalIcon" class="h-5 text-gray-500" />
</template>
<!-- edit role -->
<BaseDropdownItem
v-if="userStore.currentUser.is_owner"
@click="editRole(row.id)"
>
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
<!-- delete role -->
<BaseDropdownItem
v-if="userStore.currentUser.is_owner"
@click="removeRole(row.id)"
>
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useDialogStore } from '@/scripts/stores/dialog'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useI18n } from 'vue-i18n'
import { useRoleStore } from '@/scripts/admin/stores/role'
import { useRoute, useRouter } from 'vue-router'
import { inject } from 'vue'
import { useUserStore } from '@/scripts/admin/stores/user'
import { useModalStore } from '@/scripts/stores/modal'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
loadData: {
type: Function,
default: null,
},
})
const dialogStore = useDialogStore()
const notificationStore = useNotificationStore()
const { t } = useI18n()
const roleStore = useRoleStore()
const route = useRoute()
const userStore = useUserStore()
const modalStore = useModalStore()
const $utils = inject('utils')
async function editRole(id) {
Promise.all([
await roleStore.fetchAbilities(),
await roleStore.fetchRole(id),
]).then(() => {
modalStore.openModal({
title: t('settings.roles.edit_role'),
componentName: 'RolesModal',
size: 'lg',
refreshData: props.loadData,
})
})
}
async function removeRole(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('settings.roles.confirm_delete'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'danger',
hideNoButton: false,
size: 'lg',
})
.then(async (res) => {
if (res) {
await roleStore.deleteRole(id).then((response) => {
if (response.data) {
props.loadData && props.loadData()
}
})
}
})
}
</script>

View File

@ -0,0 +1,104 @@
<template>
<BaseDropdown>
<template #activator>
<BaseButton v-if="route.name === 'tax-types.view'" variant="primary">
<BaseIcon name="DotsHorizontalIcon" class="h-5 text-white" />
</BaseButton>
<BaseIcon v-else name="DotsHorizontalIcon" class="h-5 text-gray-500" />
</template>
<!-- edit tax-type -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.EDIT_TAX_TYPE)"
@click="editTaxType(row.id)"
>
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
<!-- delete tax-type -->
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.DELETE_TAX_TYPE)"
@click="removeTaxType(row.id)"
>
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useDialogStore } from '@/scripts/stores/dialog'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useI18n } from 'vue-i18n'
import { useTaxTypeStore } from '@/scripts/admin/stores/tax-type'
import { useRoute, useRouter } from 'vue-router'
import { inject } from 'vue'
import { useUserStore } from '@/scripts/admin/stores/user'
import { useModalStore } from '@/scripts/stores/modal'
import abilities from '@/scripts/admin/stub/abilities'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
loadData: {
type: Function,
default: null,
},
})
const dialogStore = useDialogStore()
const notificationStore = useNotificationStore()
const { t } = useI18n()
const taxTypeStore = useTaxTypeStore()
const route = useRoute()
const userStore = useUserStore()
const modalStore = useModalStore()
const $utils = inject('utils')
async function editTaxType(id) {
await taxTypeStore.fetchTaxType(id)
modalStore.openModal({
title: t('settings.tax_types.edit_tax'),
componentName: 'TaxTypeModal',
size: 'sm',
refreshData: props.loadData && props.loadData,
})
}
function removeTaxType(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('settings.tax_types.confirm_delete'),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'danger',
hideNoButton: false,
size: 'lg',
})
.then(async (res) => {
if (res) {
let response = await taxTypeStore.deleteTaxType(id)
if (response.data.success) {
props.loadData && props.loadData()
return true
}
props.loadData && props.loadData()
}
})
}
</script>

View File

@ -0,0 +1,87 @@
<template>
<BaseDropdown>
<template #activator>
<BaseButton v-if="route.name === 'users.view'" variant="primary">
<BaseIcon name="DotsHorizontalIcon" class="h-5 text-white" />
</BaseButton>
<BaseIcon v-else name="DotsHorizontalIcon" class="h-5 text-gray-500" />
</template>
<!-- edit user -->
<router-link :to="`/admin/users/${row.id}/edit`">
<BaseDropdownItem>
<BaseIcon
name="PencilIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.edit') }}
</BaseDropdownItem>
</router-link>
<!-- delete user -->
<BaseDropdownItem @click="removeUser(row.id)">
<BaseIcon
name="TrashIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
/>
{{ $t('general.delete') }}
</BaseDropdownItem>
</BaseDropdown>
</template>
<script setup>
import { useDialogStore } from '@/scripts/stores/dialog'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useI18n } from 'vue-i18n'
import { useUserStore } from '@/scripts/admin/stores/user'
import { useRoute, useRouter } from 'vue-router'
import { inject } from 'vue'
import { useUsersStore } from '@/scripts/admin/stores/users'
const props = defineProps({
row: {
type: Object,
default: null,
},
table: {
type: Object,
default: null,
},
loadData: {
type: Function,
default: null,
},
})
const dialogStore = useDialogStore()
const notificationStore = useNotificationStore()
const { t } = useI18n()
const userStore = useUserStore()
const route = useRoute()
const router = useRouter()
const usersStore = useUsersStore()
const $utils = inject('utils')
function removeUser(id) {
dialogStore
.openDialog({
title: t('general.are_you_sure'),
message: t('users.confirm_delete', 1),
yesLabel: t('general.ok'),
noLabel: t('general.cancel'),
variant: 'danger',
size: 'lg',
hideNoButton: false,
})
.then((res) => {
if (res) {
usersStore.deleteUser({ ids: [id] }).then((res) => {
if (res) {
props.loadData && props.loadData()
}
})
}
})
}
</script>