composables: cherry-pick
This commit is contained in:
No files matched your search
@@ -2,7 +2,6 @@ import type { DataTableLoader } from '~/components/pub/my-ui/data-table/type'
|
|||||||
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
|
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
|
||||||
import { refDebounced, useUrlSearchParams } from '@vueuse/core'
|
import { refDebounced, useUrlSearchParams } from '@vueuse/core'
|
||||||
import * as z from 'zod'
|
import * as z from 'zod'
|
||||||
import { is } from "date-fns/locale"
|
|
||||||
|
|
||||||
// Default query schema yang bisa digunakan semua list
|
// Default query schema yang bisa digunakan semua list
|
||||||
export const defaultQuerySchema = z.object({
|
export const defaultQuerySchema = z.object({
|
||||||
@@ -38,10 +37,23 @@ interface UsePaginatedListOptions<T = any> {
|
|||||||
}>
|
}>
|
||||||
// Nama endpoint untuk logging error
|
// Nama endpoint untuk logging error
|
||||||
entityName: string
|
entityName: string
|
||||||
|
/**
|
||||||
|
* Apakah state harus disinkronkan ke URL Browser?
|
||||||
|
* Set `false` jika digunakan di dalam Modal, Drawer, atau Nested Component
|
||||||
|
* agar tidak menimpa URL halaman induk.
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
syncToUrl?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export function usePaginatedList<T = any>(options: UsePaginatedListOptions<T>) {
|
export function usePaginatedList<T = any>(options: UsePaginatedListOptions<T>) {
|
||||||
const { querySchema = defaultQuerySchema, defaultQuery = defaultQueryParams, fetchFn, entityName } = options
|
const {
|
||||||
|
querySchema = defaultQuerySchema,
|
||||||
|
defaultQuery = defaultQueryParams,
|
||||||
|
fetchFn,
|
||||||
|
entityName,
|
||||||
|
syncToUrl = true, // Default true agar behavior lama tetap jalan
|
||||||
|
} = options
|
||||||
|
|
||||||
// State management
|
// State management
|
||||||
const data = ref<T[]>([])
|
const data = ref<T[]>([])
|
||||||
@@ -49,11 +61,19 @@ export function usePaginatedList<T = any>(options: UsePaginatedListOptions<T>) {
|
|||||||
isTableLoading: false,
|
isTableLoading: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
// URL state management
|
let queryParams: any
|
||||||
const queryParams = useUrlSearchParams('history', {
|
|
||||||
initialValue: defaultQuery,
|
if (syncToUrl) {
|
||||||
removeFalsyValues: true,
|
// Mode Halaman Utama: Sync ke URL
|
||||||
})
|
queryParams = useUrlSearchParams('history', {
|
||||||
|
initialValue: defaultQuery,
|
||||||
|
removeFalsyValues: true,
|
||||||
|
write: false,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Mode Nested/Modal: Local Reactive State
|
||||||
|
queryParams = reactive({ ...defaultQuery })
|
||||||
|
}
|
||||||
|
|
||||||
const params = computed(() => {
|
const params = computed(() => {
|
||||||
const result = querySchema.safeParse(queryParams)
|
const result = querySchema.safeParse(queryParams)
|
||||||
@@ -168,7 +188,7 @@ export function usePaginatedList<T = any>(options: UsePaginatedListOptions<T>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transform(endpoint: string ,params: any): string {
|
export function transform(endpoint: string, params: any): string {
|
||||||
const urlParams = new URLSearchParams()
|
const urlParams = new URLSearchParams()
|
||||||
|
|
||||||
Object.entries(params).forEach(([key, value]) => {
|
Object.entries(params).forEach(([key, value]) => {
|
||||||
|
|||||||
@@ -3,18 +3,18 @@ import { useRoute, useRouter } from 'vue-router'
|
|||||||
|
|
||||||
export function useQueryCRUD(modeKey: string = 'mode', recordIdKey: string = 'record-id') {
|
export function useQueryCRUD(modeKey: string = 'mode', recordIdKey: string = 'record-id') {
|
||||||
type params = {
|
type params = {
|
||||||
mode: string,
|
mode: string
|
||||||
recordId: any
|
recordId: any
|
||||||
}
|
}
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const crudQueryParams = computed<params> ({
|
const crudQueryParams = computed<params>({
|
||||||
get: () => {
|
get: () => {
|
||||||
return {
|
return {
|
||||||
mode: route.query[modeKey] && route.query[modeKey] === 'entry' ? 'entry' : 'list',
|
mode: route.query[modeKey] && route.query[modeKey] === 'entry' ? 'entry' : 'list',
|
||||||
recordId: route.query[recordIdKey]
|
recordId: route.query[recordIdKey],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
set: (val) => {
|
set: (val) => {
|
||||||
@@ -30,17 +30,15 @@ export function useQueryCRUD(modeKey: string = 'mode', recordIdKey: string = 're
|
|||||||
})
|
})
|
||||||
|
|
||||||
const goToEntry = (myRecord_id?: any) => {
|
const goToEntry = (myRecord_id?: any) => {
|
||||||
if(myRecord_id) {
|
if (myRecord_id) {
|
||||||
crudQueryParams.value = { mode: 'entry', recordId: myRecord_id }
|
crudQueryParams.value.mode = 'entry'
|
||||||
|
crudQueryParams.value.recordId = myRecord_id
|
||||||
} else {
|
} else {
|
||||||
crudQueryParams.value = { mode: 'entry', recordId: undefined }
|
crudQueryParams.value.mode = 'entry'
|
||||||
|
crudQueryParams.value.recordId = undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const goToDetail = (myRecord_id: string|number) => {
|
|
||||||
crudQueryParams.value = { mode: 'list', recordId: String(myRecord_id) }
|
|
||||||
}
|
|
||||||
|
|
||||||
const backToList = () => {
|
const backToList = () => {
|
||||||
delete route.query[recordIdKey]
|
delete route.query[recordIdKey]
|
||||||
router.push({
|
router.push({
|
||||||
@@ -52,15 +50,22 @@ export function useQueryCRUD(modeKey: string = 'mode', recordIdKey: string = 're
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return { crudQueryParams, goToEntry, goToDetail, backToList }
|
return { crudQueryParams, goToEntry, backToList }
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useQueryCRUDMode(key: string = 'mode') {
|
export function useQueryCRUDMode(key: string = 'mode') {
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const mode = computed<'list' | 'entry'>({
|
const mode = computed<'list' | 'entry' | 'view'>({
|
||||||
get: () => (route.query[key] && route.query[key] === 'entry' ? 'entry' : 'list'),
|
get: () => {
|
||||||
|
const q = route.query[key]
|
||||||
|
|
||||||
|
if (q === 'entry') return 'entry'
|
||||||
|
if (q === 'view') return 'view'
|
||||||
|
|
||||||
|
return 'list'
|
||||||
|
},
|
||||||
set: (val) => {
|
set: (val) => {
|
||||||
router.push({
|
router.push({
|
||||||
path: route.path,
|
path: route.path,
|
||||||
@@ -72,9 +77,22 @@ export function useQueryCRUDMode(key: string = 'mode') {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const goToEntry = (myRecord_id?: any) => {
|
const fromView = computed(() => route.query['from'] === 'view')
|
||||||
mode.value = 'entry'
|
|
||||||
if(myRecord_id) {
|
const goToEntry = (options?: { fromView?: boolean }) => {
|
||||||
|
router.push({
|
||||||
|
path: route.path,
|
||||||
|
query: {
|
||||||
|
...route.query,
|
||||||
|
[key]: 'entry',
|
||||||
|
from: options?.fromView ? 'view' : undefined,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const goToView = (myRecord_id?: any) => {
|
||||||
|
mode.value = 'view'
|
||||||
|
if (myRecord_id) {
|
||||||
myRecord_id.value = myRecord_id
|
myRecord_id.value = myRecord_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,13 +103,32 @@ export function useQueryCRUDMode(key: string = 'mode') {
|
|||||||
query: {
|
query: {
|
||||||
...route.query,
|
...route.query,
|
||||||
mode: 'list',
|
mode: 'list',
|
||||||
// HAPUS record-id
|
|
||||||
recordIdKey: undefined,
|
recordIdKey: undefined,
|
||||||
|
from: undefined,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return { mode, goToEntry, backToList }
|
const backToView = () => {
|
||||||
|
router.push({
|
||||||
|
path: route.path,
|
||||||
|
query: {
|
||||||
|
...route.query,
|
||||||
|
mode: 'view',
|
||||||
|
from: undefined,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const goBack = () => {
|
||||||
|
if (fromView.value) {
|
||||||
|
backToView()
|
||||||
|
} else {
|
||||||
|
backToList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { mode, fromView, goToEntry, goToView, backToList, backToView, goBack }
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useQueryCRUDRecordId(key: string = 'record-id') {
|
export function useQueryCRUDRecordId(key: string = 'record-id') {
|
||||||
@@ -114,4 +151,3 @@ export function useQueryCRUDRecordId(key: string = 'record-id') {
|
|||||||
|
|
||||||
return { recordId }
|
return { recordId }
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user