feat: remove 'code' field from Business Type; update filters and form validation
This commit is contained in:
parent
a71be47b58
commit
8c7002a326
@ -13,7 +13,6 @@ import {
|
|||||||
|
|
||||||
export interface BusinessType {
|
export interface BusinessType {
|
||||||
id: string
|
id: string
|
||||||
code: string
|
|
||||||
name: string
|
name: string
|
||||||
description: string | null
|
description: string | null
|
||||||
is_active: boolean | number
|
is_active: boolean | number
|
||||||
@ -23,11 +22,10 @@ export function copy(id: string) {
|
|||||||
navigator.clipboard.writeText(id)
|
navigator.clipboard.writeText(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const nameAndCodeFilter: FilterFn<BusinessType> = (row, _columnId, filterValue) => {
|
const nameFilter: FilterFn<BusinessType> = (row, _columnId, filterValue) => {
|
||||||
const search = (filterValue as string).toLowerCase()
|
const search = (filterValue as string).toLowerCase()
|
||||||
const name = (row.original.name as string).toLowerCase()
|
const name = (row.original.name as string).toLowerCase()
|
||||||
const code = (row.original.code as string).toLowerCase()
|
return name.includes(search)
|
||||||
return name.includes(search) || code.includes(search)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const booleanFilter: FilterFn<BusinessType> = (row, columnId, filterValue) => {
|
const booleanFilter: FilterFn<BusinessType> = (row, columnId, filterValue) => {
|
||||||
@ -44,27 +42,17 @@ export function getColumns(callbacks: {
|
|||||||
onToggleStatus: (businessType: BusinessType, value: boolean) => void
|
onToggleStatus: (businessType: BusinessType, value: boolean) => void
|
||||||
}): ColumnDef<BusinessType>[] {
|
}): ColumnDef<BusinessType>[] {
|
||||||
return [
|
return [
|
||||||
{
|
|
||||||
accessorKey: 'code',
|
|
||||||
header: ({ column }) => {
|
|
||||||
return h(Button, {
|
|
||||||
variant: 'ghost',
|
|
||||||
onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'),
|
|
||||||
}, () => ['Kode', h(ArrowUpDown, { class: 'ml-2 h-4 w-4' })])
|
|
||||||
},
|
|
||||||
cell: ({ row }) => h('div', { class: 'font-medium' }, row.getValue('code')),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'name_search',
|
id: 'name_search',
|
||||||
accessorFn: row => `${row.name} ${row.code}`,
|
accessorFn: row => row.name,
|
||||||
header: ({ column }) => {
|
header: ({ column }) => {
|
||||||
return h(Button, {
|
return h(Button, {
|
||||||
variant: 'ghost',
|
variant: 'ghost',
|
||||||
onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'),
|
onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'),
|
||||||
}, () => ['Nama', h(ArrowUpDown, { class: 'ml-2 h-4 w-4' })])
|
}, () => ['Nama', h(ArrowUpDown, { class: 'ml-2 h-4 w-4' })])
|
||||||
},
|
},
|
||||||
cell: ({ row }) => h('div', {}, row.original.name),
|
cell: ({ row }) => h('div', { class: 'font-medium' }, row.original.name),
|
||||||
filterFn: nameAndCodeFilter,
|
filterFn: nameFilter,
|
||||||
enableHiding: false,
|
enableHiding: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -57,12 +57,11 @@ const formMode = ref<FormMode>('create')
|
|||||||
const selectedBusinessType = ref<BusinessType | null>(null)
|
const selectedBusinessType = ref<BusinessType | null>(null)
|
||||||
|
|
||||||
interface FormData {
|
interface FormData {
|
||||||
code: string
|
|
||||||
name: string
|
name: string
|
||||||
description: string
|
description: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const form = ref<FormData>({ code: '', name: '', description: '' })
|
const form = ref<FormData>({ name: '', description: '' })
|
||||||
|
|
||||||
// --- Loading states ---
|
// --- Loading states ---
|
||||||
const formLoading = ref(false)
|
const formLoading = ref(false)
|
||||||
@ -75,7 +74,7 @@ const formTitle = computed(() => formMode.value === 'create' ? 'Tambah Jenis Bis
|
|||||||
function openCreateForm() {
|
function openCreateForm() {
|
||||||
formMode.value = 'create'
|
formMode.value = 'create'
|
||||||
selectedBusinessType.value = null
|
selectedBusinessType.value = null
|
||||||
form.value = { code: '', name: '', description: '' }
|
form.value = { name: '', description: '' }
|
||||||
formOpen.value = true
|
formOpen.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +82,6 @@ function handleEdit(bt: BusinessType) {
|
|||||||
formMode.value = 'edit'
|
formMode.value = 'edit'
|
||||||
selectedBusinessType.value = bt
|
selectedBusinessType.value = bt
|
||||||
form.value = {
|
form.value = {
|
||||||
code: bt.code,
|
|
||||||
name: bt.name,
|
name: bt.name,
|
||||||
description: bt.description ?? '',
|
description: bt.description ?? '',
|
||||||
}
|
}
|
||||||
@ -116,8 +114,8 @@ const columns = computed(() => getColumns({ onEdit: handleEdit, onDelete: handle
|
|||||||
|
|
||||||
// --- CRUD operations ---
|
// --- CRUD operations ---
|
||||||
async function handleFormSubmit() {
|
async function handleFormSubmit() {
|
||||||
if (!form.value.code.trim() || !form.value.name.trim()) {
|
if (!form.value.name.trim()) {
|
||||||
toast.error('Kode dan nama wajib diisi')
|
toast.error('Nama wajib diisi')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +125,6 @@ async function handleFormSubmit() {
|
|||||||
await $fetch(`${config.public.apiBase}/business-types`, {
|
await $fetch(`${config.public.apiBase}/business-types`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
code: form.value.code.trim(),
|
|
||||||
name: form.value.name.trim(),
|
name: form.value.name.trim(),
|
||||||
description: form.value.description.trim() || null,
|
description: form.value.description.trim() || null,
|
||||||
},
|
},
|
||||||
@ -137,7 +134,6 @@ async function handleFormSubmit() {
|
|||||||
await $fetch(`${config.public.apiBase}/business-types/${selectedBusinessType.value!.id}`, {
|
await $fetch(`${config.public.apiBase}/business-types/${selectedBusinessType.value!.id}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
body: {
|
body: {
|
||||||
code: form.value.code.trim(),
|
|
||||||
name: form.value.name.trim(),
|
name: form.value.name.trim(),
|
||||||
description: form.value.description.trim() || null,
|
description: form.value.description.trim() || null,
|
||||||
},
|
},
|
||||||
@ -195,7 +191,7 @@ function resetFilters(table: any) {
|
|||||||
// --- Reset on dialog close ---
|
// --- Reset on dialog close ---
|
||||||
watch(formOpen, (val) => {
|
watch(formOpen, (val) => {
|
||||||
if (!val) {
|
if (!val) {
|
||||||
form.value = { code: '', name: '', description: '' }
|
form.value = { name: '', description: '' }
|
||||||
selectedBusinessType.value = null
|
selectedBusinessType.value = null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -232,7 +228,7 @@ watch(deleteOpen, (val) => {
|
|||||||
<DataTable v-else ref="tableRef" :columns="columns" :data="businessTypes ?? []">
|
<DataTable v-else ref="tableRef" :columns="columns" :data="businessTypes ?? []">
|
||||||
<template #filters="{ table }">
|
<template #filters="{ table }">
|
||||||
<div class="flex items-center gap-2 py-4">
|
<div class="flex items-center gap-2 py-4">
|
||||||
<Input class="max-w-sm" placeholder="Cari nama atau kode..."
|
<Input class="max-w-sm" placeholder="Cari nama..."
|
||||||
:model-value="(table.getColumn('name_search')?.getFilterValue() as string) ?? ''"
|
:model-value="(table.getColumn('name_search')?.getFilterValue() as string) ?? ''"
|
||||||
@update:model-value="table.getColumn('name_search')?.setFilterValue($event)" />
|
@update:model-value="table.getColumn('name_search')?.setFilterValue($event)" />
|
||||||
<Select :model-value="getStatusFilter(table)"
|
<Select :model-value="getStatusFilter(table)"
|
||||||
@ -296,10 +292,6 @@ watch(deleteOpen, (val) => {
|
|||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<form id="businessTypeForm" @submit.prevent="handleFormSubmit">
|
<form id="businessTypeForm" @submit.prevent="handleFormSubmit">
|
||||||
<FieldGroup class="gap-4">
|
<FieldGroup class="gap-4">
|
||||||
<Field>
|
|
||||||
<FieldLabel for="form-code">Kode <span class="text-red-500">*</span></FieldLabel>
|
|
||||||
<Input id="form-code" v-model="form.code" placeholder="Masukkan kode" :disabled="formLoading" />
|
|
||||||
</Field>
|
|
||||||
<Field>
|
<Field>
|
||||||
<FieldLabel for="form-name">Nama <span class="text-red-500">*</span></FieldLabel>
|
<FieldLabel for="form-name">Nama <span class="text-red-500">*</span></FieldLabel>
|
||||||
<Input id="form-name" v-model="form.name" placeholder="Masukkan nama" :disabled="formLoading" />
|
<Input id="form-name" v-model="form.name" placeholder="Masukkan nama" :disabled="formLoading" />
|
||||||
|
|||||||
39
docs/history/2026-07-24-hapus-kode-business-type.md
Normal file
39
docs/history/2026-07-24-hapus-kode-business-type.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Hapus Kolom Code dari Business Type (Frontend)
|
||||||
|
|
||||||
|
**Tanggal:** 2026-07-24
|
||||||
|
**Status:** Selesai
|
||||||
|
|
||||||
|
## Tujuan
|
||||||
|
Menghapus kolom `code` dari tampilan dan form data Jenis Bisnis di admin panel.
|
||||||
|
|
||||||
|
## Yang Dikerjakan
|
||||||
|
|
||||||
|
### 1. DataTable Columns
|
||||||
|
- Hapus kolom `code` dari tabel
|
||||||
|
- `nameAndCodeFilter` → `nameFilter` (hanya filter berdasarkan nama)
|
||||||
|
- `accessorFn` diubah dari `` row => `${row.name} ${row.code}` `` → `row => row.name`
|
||||||
|
- Placeholder search diubah dari "Cari nama atau kode..." → "Cari nama..."
|
||||||
|
|
||||||
|
### 2. Form Dialog
|
||||||
|
- Hapus field `code` dari form create/edit
|
||||||
|
- Hapus `code` dari interface `FormData`
|
||||||
|
- Sebelum: form fields = Kode (wajib), Nama (wajib), Deskripsi
|
||||||
|
- Sesudah: form fields = Nama (wajib), Deskripsi
|
||||||
|
|
||||||
|
### 3. CRUD Operations
|
||||||
|
- Hapus `code` dari body POST (create) dan PUT (update)
|
||||||
|
- Validasi diubah dari "Kode dan nama wajib diisi" → "Nama wajib diisi"
|
||||||
|
|
||||||
|
### 4. TypeScript Interface
|
||||||
|
- Hapus `code` dari `BusinessType` interface
|
||||||
|
|
||||||
|
## File yang Diubah
|
||||||
|
|
||||||
|
| File | Aksi | Detail |
|
||||||
|
|------|------|--------|
|
||||||
|
| `web2/app/pages/admin/business-types/columns.ts` | Diubah | Hapus kolom code, filter, accessorFn |
|
||||||
|
| `web2/app/pages/admin/business-types/index.vue` | Diubah | Hapus code dari form, body, validasi |
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- Search hanya berdasarkan nama setelah perubahan ini
|
||||||
|
- Tidak ada perubahan pada toggle status atau delete dialog
|
||||||
Loading…
Reference in New Issue
Block a user