WIP - search with AI
This commit is contained in:
@@ -145,6 +145,11 @@ const editConfig = computed(() => {
|
||||
|
||||
const listPageSize = computed(() => listConfig.value?.pageSize ?? 25)
|
||||
const maxFrontendRecords = computed(() => listConfig.value?.maxFrontendRecords ?? 500)
|
||||
const searchQuery = ref('')
|
||||
const searchSummary = ref('')
|
||||
const searchLoading = ref(false)
|
||||
|
||||
const isSearchActive = computed(() => searchQuery.value.trim().length > 0)
|
||||
|
||||
// Fetch object definition
|
||||
const fetchObjectDefinition = async () => {
|
||||
@@ -235,6 +240,36 @@ const loadListRecords = async (
|
||||
return result
|
||||
}
|
||||
|
||||
const searchListRecords = async (
|
||||
page = 1,
|
||||
options?: { append?: boolean; pageSize?: number }
|
||||
) => {
|
||||
if (!isSearchActive.value) {
|
||||
return initializeListRecords()
|
||||
}
|
||||
searchLoading.value = true
|
||||
try {
|
||||
const pageSize = options?.pageSize ?? listPageSize.value
|
||||
const response = await api.post('/ai/search', {
|
||||
objectApiName: objectApiName.value,
|
||||
query: searchQuery.value.trim(),
|
||||
page,
|
||||
pageSize,
|
||||
})
|
||||
const data = response?.data ?? []
|
||||
const total = response?.totalCount ?? data.length
|
||||
records.value = options?.append ? [...records.value, ...data] : data
|
||||
totalCount.value = total
|
||||
searchSummary.value = response?.explanation || ''
|
||||
return response
|
||||
} catch (e: any) {
|
||||
error.value = e.message || 'Failed to search records'
|
||||
return null
|
||||
} finally {
|
||||
searchLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const initializeListRecords = async () => {
|
||||
const firstResult = await loadListRecords(1)
|
||||
const resolvedTotal = firstResult?.totalCount ?? totalCount.value ?? records.value.length
|
||||
@@ -247,6 +282,10 @@ const initializeListRecords = async () => {
|
||||
}
|
||||
|
||||
const handlePageChange = async (page: number, pageSize: number) => {
|
||||
if (isSearchActive.value) {
|
||||
await searchListRecords(page, { append: page > 1, pageSize })
|
||||
return
|
||||
}
|
||||
const loadedPages = Math.ceil(records.value.length / pageSize)
|
||||
if (page > loadedPages && totalCount.value > records.value.length) {
|
||||
await loadListRecords(page, { append: true, pageSize })
|
||||
@@ -254,9 +293,24 @@ const handlePageChange = async (page: number, pageSize: number) => {
|
||||
}
|
||||
|
||||
const handleLoadMore = async (page: number, pageSize: number) => {
|
||||
if (isSearchActive.value) {
|
||||
await searchListRecords(page, { append: true, pageSize })
|
||||
return
|
||||
}
|
||||
await loadListRecords(page, { append: true, pageSize })
|
||||
}
|
||||
|
||||
const handleSearch = async (query: string) => {
|
||||
const trimmed = query.trim()
|
||||
searchQuery.value = trimmed
|
||||
if (!trimmed) {
|
||||
searchSummary.value = ''
|
||||
await initializeListRecords()
|
||||
return
|
||||
}
|
||||
await searchListRecords(1, { append: false, pageSize: listPageSize.value })
|
||||
}
|
||||
|
||||
// Watch for route changes
|
||||
watch(() => route.params, async (newParams, oldParams) => {
|
||||
// Reset current record when navigating to 'new'
|
||||
@@ -325,14 +379,16 @@ onMounted(async () => {
|
||||
v-else-if="view === 'list' && listConfig"
|
||||
:config="listConfig"
|
||||
:data="records"
|
||||
:loading="dataLoading"
|
||||
:loading="dataLoading || searchLoading"
|
||||
:total-count="totalCount"
|
||||
:search-summary="searchSummary"
|
||||
:base-url="`/runtime/objects`"
|
||||
selectable
|
||||
@row-click="handleRowClick"
|
||||
@create="handleCreate"
|
||||
@edit="handleEdit"
|
||||
@delete="handleDelete"
|
||||
@search="handleSearch"
|
||||
@page-change="handlePageChange"
|
||||
@load-more="handleLoadMore"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user