Skip to content

Commit 6ad5d4f

Browse files
committed
chore: wip
1 parent 1b9d9c5 commit 6ad5d4f

File tree

2 files changed

+20
-132
lines changed

2 files changed

+20
-132
lines changed

Diff for: src/composables/table.ts

+7-130
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,23 @@
1+
import { calculatePagination, currentPage, filterName, filters, goToNextPage, goToPage, goToPrevPage, hits, index, lastPageNumber, perPage, query, results, search, searchFilters, searchParams, setTotalHits, sort, sorts, totalPages } from '@stacksjs/search-engine'
12
import { isObject, isString, useStorage } from '@vueuse/core'
2-
import type { SearchParams, SearchResponse } from 'meilisearch'
3-
import MeiliSearch from 'meilisearch'
43
import type { Ref } from 'vue'
54
import { computed } from 'vue-demi'
65
import type { TableStore } from '~/types'
76

87
const table = (useStorage('table', determineState()).value as TableStore)
98

10-
const results = computed(() => table.results)
11-
const hits = computed(() => results.value?.hits || [])
9+
// table related
1210
const columns = computed(() => table.columns)
13-
const filters = computed(() => table.filters)
14-
const sort = computed(() => table.sort)
15-
const sorts = computed(() => table.sorts)
16-
const type = computed(() => table.type)
17-
const currentPage = computed(() => table.currentPage)
18-
const perPage = computed(() => table.perPage)
19-
const query = computed(() => table.query)
2011
const actions = computed(() => table.actions)
2112
const actionable = computed(() => table.actionable)
2213
const selectedRows = computed(() => table.selectedRows)
2314
const selectedAll = computed(() => table.selectedAll)
24-
const searchParams = computed(() => {
25-
return {
26-
offset: (table.currentPage - 1) * table.perPage,
27-
limit: table.perPage,
28-
sort: isString(table.sort) ? [table.sort] : undefined,
29-
filter: table.filterValue,
30-
}
31-
})
32-
33-
let totalHits = table.results ? table.results.nbHits : 1
34-
const totalPages: Ref<number> = ref(0)
3515
const pages: Ref<number[]> = ref([])
36-
37-
function calculatePagination() {
38-
totalPages.value = Math.ceil(totalHits / table.perPage)
39-
40-
const hitPages = [...Array(totalPages.value).keys()].map(i => i + 1)
41-
const offset = 2
42-
const currentPage = table.currentPage
43-
const lastPage = hitPages[hitPages.length - 1]
44-
45-
let from = currentPage - offset
46-
if (from < 1)
47-
from = 1
48-
49-
let to = from + offset * 2
50-
if (to >= lastPage)
51-
to = lastPage
52-
53-
const allPages = []
54-
for (let page = from; page <= to; page++)
55-
allPages.push(page)
56-
57-
pages.value = allPages
58-
}
59-
6016
const indeterminate = computed(() => (table?.selectedRows?.length ?? 0) > 0 && (table?.selectedRows?.length ?? 0) < hits.value.length)
6117
const lastColumn = computed(() => {
6218
return table.columns[table.columns.length - 1]
6319
})
6420
const readableLastColumn = computed(() => lastColumn[0]?.includes(':') ? lastColumn[0].split(':')[1].trim() : lastColumn[0])
65-
const lastPageNumber = computed(() => Math.ceil((table.results?.nbHits ?? 1) / table.perPage))
6621

6722
// this watchEffect picks up any reactivity changes from `query` and `searchParams` and it will then trigger a search
6823
watchEffect(async () => {
@@ -75,8 +30,7 @@ watchEffect(async () => {
7530
table.hits = results.hits
7631
}
7732

78-
totalHits = table.results?.nbHits ?? 1
79-
33+
setTotalHits(table.results?.nbHits ?? 1)
8034
calculatePagination()
8135
})
8236

@@ -105,7 +59,7 @@ function determineState(): TableStore {
10559
const table: TableStore = {
10660
source: '',
10761
password: '',
108-
type: '',
62+
index: '',
10963
columns: [],
11064
filters: [],
11165
perPage: 20,
@@ -132,84 +86,11 @@ function isColumnSortable(col: string): Boolean {
13286
return false
13387
}
13488

135-
// search methods
136-
function client(): MeiliSearch {
137-
if (!table.source)
138-
table.source = ''
139-
140-
return new MeiliSearch({
141-
host: table.source,
142-
apiKey: import.meta.env.VITE_MEILISEARCH_KEY,
143-
})
144-
}
145-
14689
function hasTableLoaded(state?: any): Boolean {
147-
if (state?.type !== '')
90+
if (state?.index !== '')
14891
return true
14992

150-
return isString(table?.type) && table.type !== '' // a lazy way to check if the table is loaded
151-
}
152-
153-
// we have to accept `query` and `searchParams` because those params are watched from within a watchEffect
154-
async function search(q?: string, options?: SearchParams): Promise<void | SearchResponse<Record<string, any>>> {
155-
if (!hasTableLoaded(table))
156-
return
157-
158-
try {
159-
// if the query is provided as a param, it will trump what there would be otherwise in local storage
160-
const query = isString(q) ? q : (isString(table.query) ? table.query : '')
161-
162-
if (!table.type) {
163-
console.error('no type provided')
164-
return
165-
}
166-
167-
// we w
168-
if (options === undefined)
169-
return await client().index(table.type).search(query, searchParams.value)
170-
171-
return await client().index(table.type).search(query, options)
172-
}
173-
catch (error) {
174-
console.error('error when performing search', error)
175-
}
176-
}
177-
178-
async function searchFilters(index: string): Promise<any> {
179-
return await client().index(index).getFilterableAttributes()
180-
}
181-
182-
function goToPrevPage() {
183-
if (table.currentPage === 1 || currentPage === undefined || table === undefined)
184-
return
185-
186-
table.currentPage--
187-
188-
if (currentPage.value < 1)
189-
table.currentPage = 1
190-
}
191-
192-
function goToNextPage() {
193-
// eslint-disable-next-line no-console
194-
console.log('currentPage before going to next page', currentPage)
195-
196-
if (table.currentPage === totalPages.value || currentPage === undefined || table === undefined)
197-
return
198-
199-
if (table.currentPage < 1)
200-
table.currentPage = 1
201-
else
202-
table.currentPage++
203-
}
204-
205-
function goToPage(page: number) {
206-
if (table.currentPage === page || currentPage === undefined || table === undefined)
207-
return
208-
209-
if (table.currentPage <= 1)
210-
table.currentPage = 1
211-
212-
table.currentPage = page
93+
return isString(table?.index) && table.index !== '' // a lazy way to check if the table is loaded
21394
}
21495

21596
function isColumnUsedAsSort(col: string | object) {
@@ -261,15 +142,11 @@ function columnName(col: string) {
261142
return col.split(':')[0].trim()
262143
}
263144

264-
function filterName(filter: string) {
265-
return filter.split(':')[0].trim()
266-
}
267-
268145
export async function useTable(store?: TableStore) {
269146
return {
270147
store,
271148
table,
272-
type,
149+
index,
273150
columns,
274151
isColumnSortable,
275152
filters,

Diff for: src/types.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import type { Hits, SearchResponse } from 'meilisearch'
66

77
// the TableStore interface is primarily used with regards to how to persist the data to localStorage
88
export interface TableStore {
9-
type: string // the Meilisearch index you would like to use for this table
9+
/**
10+
* The type of table, e.g. 'users', 'posts', 'products', etc.
11+
* i.e. the Meilisearch index name
12+
*/
13+
index: string
1014
columns: string[] // used as table heads/column titles
1115
source?: string // optional: the Meilisearch host name/address (defaults: http://127.0.0.1:7700)
1216
password?: string // optional: the Meilisearch password (defaults: '')
@@ -21,7 +25,14 @@ export interface TableStore {
2125
actionable?: string | boolean // optional: determines whether the table displays any "action items" (defaults: true)
2226
actions?: string | string[] // optional: the specific type of actions to be displayed/utilized in the table (defaults: 'Edit, Delete')
2327
perPage: number // optional: the number of rows (items) to be displayed per page (defaults: 10)
24-
currentPage: number // optional: the current page number (defaults: 1)
28+
/**
29+
* The current page number
30+
* @default 1
31+
* @type {number}
32+
* @memberof TableStore
33+
* @example 1
34+
*/
35+
currentPage: number
2536
results?: SearchResponse<Record<string, any>> // optional: the Meilisearch search response (defaults: {})
2637
hits?: Hits // optional: the Meilisearch hits (we could also name this "rows" as that would be more applicable to the "table domain" but choosing to stay in sync with Meilisearch right now until we implement for a second search engine driver)
2738
selectable?: string | boolean // optional: determines whether the table displays the checkboxes (defaults: true)

0 commit comments

Comments
 (0)