145 lines
3.6 KiB
Vue
145 lines
3.6 KiB
Vue
<template>
|
|
<div class="flex h-full w-full">
|
|
<tbl
|
|
ref="tableRef"
|
|
class="h-full w-full"
|
|
@add="openAdd"
|
|
@edit="openEdit"
|
|
@toggle="toggleActive"
|
|
@delete="deleteItem"
|
|
/>
|
|
|
|
<BasicActionSheet
|
|
v-model:visible="editorVisible"
|
|
:title="sheetTitle"
|
|
modal-width="32rem"
|
|
drawer-height="85vh"
|
|
:loading="loading"
|
|
:show-button="true"
|
|
:show-cancel="true"
|
|
:show-ok="true"
|
|
ok-text="ذخیره"
|
|
cancel-text="انصراف"
|
|
@ok="submitForm"
|
|
@close="closeEditor"
|
|
@cancel="closeEditor"
|
|
>
|
|
<div v-if="isMobile" class="mb-3 text-base font-bold">{{ sheetTitle }}</div>
|
|
<AppNotificationEditorFormBody ref="editorRef" :form="form" />
|
|
</BasicActionSheet>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, ref } from 'vue'
|
|
import { message } from 'ant-design-vue'
|
|
import { cloneDeep } from 'lodash'
|
|
import tbl from './components/table.vue'
|
|
import BasicActionSheet from '@/components/BasicActionSheet.vue'
|
|
import AppNotificationEditorFormBody from './components/AppNotificationEditorFormBody.vue'
|
|
import type { AppNotification } from '@/model/appNotifications'
|
|
import {
|
|
createAppNotification,
|
|
deleteAppNotification,
|
|
toggleAppNotificationActive,
|
|
updateAppNotification,
|
|
} from '@/api/appNotifications'
|
|
import { confirmDeleteItem } from '@/utils/confirmModal'
|
|
import { isMobile } from '@core/utils/is'
|
|
|
|
const tableRef = ref<null | { fetch: () => void }>(null)
|
|
const editorRef = ref<{
|
|
validateFields?: () => Promise<unknown>
|
|
resetFields?: () => void
|
|
}>()
|
|
|
|
const loading = ref(false)
|
|
const editorVisible = ref(false)
|
|
const editId = ref<number | undefined>()
|
|
|
|
const defaultForm = (): Partial<AppNotification> => ({
|
|
title: '',
|
|
body: '',
|
|
severity: 'info',
|
|
is_active: true,
|
|
})
|
|
|
|
const form = ref<Partial<AppNotification>>(defaultForm())
|
|
|
|
const sheetTitle = computed(() => (editId.value ? 'ویرایش اعلان' : 'افزودن اعلان'))
|
|
|
|
function refreshTable() {
|
|
tableRef.value?.fetch()
|
|
}
|
|
|
|
function closeEditor() {
|
|
editorVisible.value = false
|
|
}
|
|
|
|
function openAdd() {
|
|
editId.value = undefined
|
|
form.value = defaultForm()
|
|
editorRef.value?.resetFields?.()
|
|
editorVisible.value = true
|
|
}
|
|
|
|
function openEdit(record: AppNotification) {
|
|
editId.value = record.id
|
|
form.value = cloneDeep({
|
|
title: record.title,
|
|
body: record.body,
|
|
severity: record.severity,
|
|
is_active: record.is_active,
|
|
})
|
|
editorVisible.value = true
|
|
}
|
|
|
|
async function submitForm() {
|
|
try {
|
|
await editorRef.value?.validateFields?.()
|
|
loading.value = true
|
|
|
|
const payload = {
|
|
title: String(form.value.title ?? '').trim(),
|
|
body: String(form.value.body ?? '').trim(),
|
|
severity: form.value.severity || 'info',
|
|
is_active: Boolean(form.value.is_active),
|
|
}
|
|
|
|
if (editId.value) {
|
|
await updateAppNotification(editId.value, payload)
|
|
} else {
|
|
await createAppNotification(payload)
|
|
}
|
|
|
|
message.success('اعلان با موفقیت ذخیره شد')
|
|
editorVisible.value = false
|
|
refreshTable()
|
|
} catch (e) {
|
|
console.error(e)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function toggleActive(record: AppNotification) {
|
|
if (!record.id) return
|
|
|
|
try {
|
|
loading.value = true
|
|
await toggleAppNotificationActive(record.id)
|
|
message.success(record.is_active ? 'اعلان غیرفعال شد' : 'اعلان فعال شد')
|
|
refreshTable()
|
|
} catch (e) {
|
|
console.error(e)
|
|
message.error('خطا در تغییر وضعیت')
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function deleteItem(id: number) {
|
|
confirmDeleteItem('اعلان', id, deleteAppNotification, refreshTable)
|
|
}
|
|
</script>
|