Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<q-page class="q-pa-md">
|
||||
<div class="row items-center justify-between q-mb-md">
|
||||
<div>
|
||||
<div class="text-h6">Urun Seri Tanimlamalari</div>
|
||||
<div class="text-caption text-grey-7">Seri kodu ve beden seri basliklari burada yonetilir.</div>
|
||||
</div>
|
||||
<div class="row q-gutter-sm">
|
||||
<q-btn color="secondary" outline icon="refresh" label="Yenile" :loading="loading" @click="reload" />
|
||||
<q-btn color="primary" icon="add" label="Yeni Seri" :disable="!canUpdate" @click="newRow" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<q-table
|
||||
flat
|
||||
bordered
|
||||
row-key="id"
|
||||
:rows="rows"
|
||||
:columns="columns"
|
||||
:loading="loading"
|
||||
:pagination="{ rowsPerPage: 0 }"
|
||||
hide-bottom
|
||||
class="bg-white"
|
||||
>
|
||||
<template #body-cell-is_active="props">
|
||||
<q-td :props="props">
|
||||
<q-toggle v-model="props.row.is_active" dense :disable="!canUpdate || saving" @update:model-value="() => markDirty(props.row)" />
|
||||
</q-td>
|
||||
</template>
|
||||
|
||||
<template #body-cell-actions="props">
|
||||
<q-td :props="props" class="text-right">
|
||||
<q-btn dense flat round icon="edit" color="primary" :disable="!canUpdate" @click="editRow(props.row)" />
|
||||
<q-btn dense flat round icon="delete" color="negative" :disable="!canUpdate" @click="removeRow(props.row)" />
|
||||
</q-td>
|
||||
</template>
|
||||
</q-table>
|
||||
|
||||
<q-dialog v-model="dialogOpen" persistent>
|
||||
<q-card style="min-width: 520px">
|
||||
<q-card-section class="row items-center justify-between">
|
||||
<div class="text-subtitle1">{{ editing.id ? 'Seri Duzenle' : 'Yeni Seri' }}</div>
|
||||
<q-btn flat round dense icon="close" v-close-popup />
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-section class="q-gutter-md">
|
||||
<q-input v-model="editing.code" dense outlined label="Seri Kodu" autofocus />
|
||||
<q-input v-model="editing.title" dense outlined label="Seri Basligi" />
|
||||
<q-input v-model="editing.parent_filter" dense outlined label="Parent Filter" />
|
||||
<q-input v-model.number="editing.sort_order" dense outlined type="number" label="Sira" />
|
||||
<q-input v-model="editing.notes" dense outlined type="textarea" label="Not" />
|
||||
<q-toggle v-model="editing.is_active" label="Aktif" />
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn flat label="Vazgec" v-close-popup />
|
||||
<q-btn color="primary" icon="save" label="Kaydet" :loading="saving" @click="saveDialog" />
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</q-page>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { Dialog, Notify } from 'quasar'
|
||||
import api from 'src/services/api'
|
||||
import { usePermissionStore } from 'stores/permissionStore'
|
||||
|
||||
const perm = usePermissionStore()
|
||||
const canUpdate = computed(() => perm.hasApiPermission('pricing:update'))
|
||||
|
||||
const loading = ref(false)
|
||||
const saving = ref(false)
|
||||
const rows = ref([])
|
||||
const dialogOpen = ref(false)
|
||||
const editing = ref(emptyRow())
|
||||
|
||||
const columns = [
|
||||
{ name: 'code', label: 'Seri Kodu', field: 'code', align: 'left', sortable: true },
|
||||
{ name: 'title', label: 'Seri Basligi', field: 'title', align: 'left', sortable: true },
|
||||
{ name: 'parent_filter', label: 'Parent Filter', field: 'parent_filter', align: 'left', sortable: true },
|
||||
{ name: 'sort_order', label: 'Sira', field: 'sort_order', align: 'right', sortable: true },
|
||||
{ name: 'is_active', label: 'Aktif', field: 'is_active', align: 'center', sortable: true },
|
||||
{ name: 'actions', label: '', field: 'actions', align: 'right' }
|
||||
]
|
||||
|
||||
function emptyRow () {
|
||||
return {
|
||||
id: 0,
|
||||
code: '',
|
||||
title: '',
|
||||
is_active: true,
|
||||
parent_filter: '',
|
||||
sort_order: 0,
|
||||
notes: ''
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeRow (row) {
|
||||
return {
|
||||
id: Number(row.id || 0),
|
||||
code: String(row.code || '').trim(),
|
||||
title: String(row.title || '').trim(),
|
||||
is_active: row.is_active !== false,
|
||||
parent_filter: String(row.parent_filter || '').trim(),
|
||||
sort_order: Number(row.sort_order || 0),
|
||||
notes: String(row.notes || '').trim()
|
||||
}
|
||||
}
|
||||
|
||||
async function reload () {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await api.get('/pricing/product-series/definitions')
|
||||
rows.value = (Array.isArray(res.data) ? res.data : []).map(normalizeRow)
|
||||
} catch (err) {
|
||||
Notify.create({ type: 'negative', message: err?.response?.data || err?.message || 'Seri tanimlari alinamadi' })
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function newRow () {
|
||||
editing.value = emptyRow()
|
||||
dialogOpen.value = true
|
||||
}
|
||||
|
||||
function editRow (row) {
|
||||
editing.value = { ...normalizeRow(row) }
|
||||
dialogOpen.value = true
|
||||
}
|
||||
|
||||
function markDirty (row) {
|
||||
saveInline(row)
|
||||
}
|
||||
|
||||
async function saveInline (row) {
|
||||
if (!canUpdate.value || !row.id) return
|
||||
saving.value = true
|
||||
try {
|
||||
await api.put(`/pricing/product-series/definitions/${row.id}`, normalizeRow(row))
|
||||
Notify.create({ type: 'positive', message: 'Kaydedildi' })
|
||||
} catch (err) {
|
||||
Notify.create({ type: 'negative', message: err?.response?.data || err?.message || 'Seri tanimi kaydedilemedi' })
|
||||
await reload()
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function saveDialog () {
|
||||
const payload = normalizeRow(editing.value)
|
||||
if (!payload.code) {
|
||||
Notify.create({ type: 'warning', message: 'Seri kodu zorunludur' })
|
||||
return
|
||||
}
|
||||
saving.value = true
|
||||
try {
|
||||
if (payload.id) {
|
||||
await api.put(`/pricing/product-series/definitions/${payload.id}`, payload)
|
||||
} else {
|
||||
await api.post('/pricing/product-series/definitions', payload)
|
||||
}
|
||||
dialogOpen.value = false
|
||||
await reload()
|
||||
Notify.create({ type: 'positive', message: 'Kaydedildi' })
|
||||
} catch (err) {
|
||||
Notify.create({ type: 'negative', message: err?.response?.data || err?.message || 'Seri tanimi kaydedilemedi' })
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function removeRow (row) {
|
||||
Dialog.create({
|
||||
title: 'Seri pasife alinsin mi?',
|
||||
message: `${row.code} - ${row.title}`,
|
||||
cancel: true,
|
||||
persistent: true
|
||||
}).onOk(async () => {
|
||||
saving.value = true
|
||||
try {
|
||||
await api.delete(`/pricing/product-series/definitions/${row.id}`)
|
||||
await reload()
|
||||
Notify.create({ type: 'positive', message: 'Pasife alindi' })
|
||||
} catch (err) {
|
||||
Notify.create({ type: 'negative', message: err?.response?.data || err?.message || 'Seri tanimi silinemedi' })
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(reload)
|
||||
</script>
|
||||
Reference in New Issue
Block a user