@quazardous/qdadm 2.3.1 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -89,6 +89,8 @@ import {
|
|
|
89
89
|
clearSessionFilters,
|
|
90
90
|
getSavedPageSize,
|
|
91
91
|
getSessionFilters,
|
|
92
|
+
getSessionSort,
|
|
93
|
+
setSessionSort,
|
|
92
94
|
persistPageSize,
|
|
93
95
|
setSessionFilters,
|
|
94
96
|
snakeToTitle,
|
|
@@ -114,6 +116,7 @@ export function useListPage<T = unknown>(config: UseListPageOptions<T>): UseList
|
|
|
114
116
|
pageSize: defaultPageSize = 10,
|
|
115
117
|
loadOnMount = true,
|
|
116
118
|
persistFilters = true,
|
|
119
|
+
persistSort = true,
|
|
117
120
|
syncUrlParams = true,
|
|
118
121
|
autoLoadFilters = true,
|
|
119
122
|
onBeforeLoad = null,
|
|
@@ -242,9 +245,11 @@ export function useListPage<T = unknown>(config: UseListPageOptions<T>): UseList
|
|
|
242
245
|
const totalRecords = ref(0)
|
|
243
246
|
const rowsPerPageOptions = PAGE_SIZE_OPTIONS
|
|
244
247
|
|
|
245
|
-
// Sorting
|
|
246
|
-
|
|
247
|
-
const
|
|
248
|
+
// Sorting — restored from the per-entity session (#1218), defaultSort as
|
|
249
|
+
// fallback; same persistence discipline as filters/pageSize.
|
|
250
|
+
const savedSort = persistSort ? getSessionSort(filterSessionKey) : null
|
|
251
|
+
const sortField = ref<string | null>(savedSort ? savedSort.field : defaultSort)
|
|
252
|
+
const sortOrder = ref(savedSort ? savedSort.order : defaultSortOrder)
|
|
248
253
|
|
|
249
254
|
// Search
|
|
250
255
|
const searchQuery = ref(savedSearch)
|
|
@@ -1002,6 +1007,12 @@ export function useListPage<T = unknown>(config: UseListPageOptions<T>): UseList
|
|
|
1002
1007
|
function onSort(event: { sortField: string; sortOrder: number }): void {
|
|
1003
1008
|
sortField.value = event.sortField
|
|
1004
1009
|
sortOrder.value = event.sortOrder as 1 | -1
|
|
1010
|
+
if (persistSort) {
|
|
1011
|
+
setSessionSort(filterSessionKey, {
|
|
1012
|
+
field: sortField.value,
|
|
1013
|
+
order: sortOrder.value as 1 | -1,
|
|
1014
|
+
})
|
|
1015
|
+
}
|
|
1005
1016
|
loadItems()
|
|
1006
1017
|
}
|
|
1007
1018
|
|
|
@@ -222,6 +222,8 @@ export interface UseListPageOptions<T = unknown> {
|
|
|
222
222
|
loadOnMount?: boolean
|
|
223
223
|
/** Persist filters to sessionStorage (default: true) */
|
|
224
224
|
persistFilters?: boolean
|
|
225
|
+
/** Persist the active sort per entity (session storage), restored on init (#1218). Default true. */
|
|
226
|
+
persistSort?: boolean
|
|
225
227
|
/** Sync filters to URL query params (default: true) */
|
|
226
228
|
syncUrlParams?: boolean
|
|
227
229
|
/** Filter mode: 'auto' | 'manager' | 'local' */
|
|
@@ -90,6 +90,45 @@ export function clearSessionFilters(key: string): void {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
94
|
+
// Sort session storage (#1218) — same mechanism as filters, keyed by entity
|
|
95
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
96
|
+
|
|
97
|
+
const SORT_SESSION_PREFIX = 'qdadm_sort_'
|
|
98
|
+
|
|
99
|
+
export interface SessionSort {
|
|
100
|
+
field: string | null
|
|
101
|
+
order: 1 | -1
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function getSessionSort(key: string): SessionSort | null {
|
|
105
|
+
try {
|
|
106
|
+
const stored = sessionStorage.getItem(SORT_SESSION_PREFIX + key)
|
|
107
|
+
if (!stored) return null
|
|
108
|
+
const parsed = JSON.parse(stored) as SessionSort
|
|
109
|
+
if (parsed && (parsed.order === 1 || parsed.order === -1)) return parsed
|
|
110
|
+
return null
|
|
111
|
+
} catch {
|
|
112
|
+
return null
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function setSessionSort(key: string, sort: SessionSort): void {
|
|
117
|
+
try {
|
|
118
|
+
sessionStorage.setItem(SORT_SESSION_PREFIX + key, JSON.stringify(sort))
|
|
119
|
+
} catch {
|
|
120
|
+
// Ignore storage errors (quota exceeded, disabled by user, …).
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function clearSessionSort(key: string): void {
|
|
125
|
+
try {
|
|
126
|
+
sessionStorage.removeItem(SORT_SESSION_PREFIX + key)
|
|
127
|
+
} catch {
|
|
128
|
+
// Ignore storage errors.
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
93
132
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
94
133
|
// Smart filter discovery
|
|
95
134
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -174,10 +174,12 @@ export function applyQueryMethods(EntityManagerClass: { prototype: any }): void
|
|
|
174
174
|
const aVal = a[sort_by]
|
|
175
175
|
const bVal = b[sort_by]
|
|
176
176
|
|
|
177
|
-
//
|
|
177
|
+
// Nulls always sort LAST, both directions (#1221) — matches the
|
|
178
|
+
// storage adapters' shared comparator; direction-aware placement
|
|
179
|
+
// put "never seen" rows on top of every desc date sort.
|
|
178
180
|
if (aVal == null && bVal == null) return 0
|
|
179
|
-
if (aVal == null) return
|
|
180
|
-
if (bVal == null) return
|
|
181
|
+
if (aVal == null) return 1
|
|
182
|
+
if (bVal == null) return -1
|
|
181
183
|
|
|
182
184
|
// Compare
|
|
183
185
|
if (typeof aVal === 'string' && typeof bVal === 'string') {
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TestManager - Auto-generated EntityManager
|
|
3
|
-
*
|
|
4
|
-
* Generated by qdadm/gen/generateManagers
|
|
5
|
-
* DO NOT EDIT MANUALLY - Changes will be overwritten
|
|
6
|
-
*
|
|
7
|
-
* Entity: test
|
|
8
|
-
* Endpoint: /test
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { EntityManager } from '@quazardous/qdadm'
|
|
12
|
-
import type { EntityRecord } from '@quazardous/qdadm'
|
|
13
|
-
import { ApiStorage } from '@quazardous/qdadm'
|
|
14
|
-
|
|
15
|
-
export interface TestEntity extends EntityRecord {
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Schema definition for test
|
|
20
|
-
*/
|
|
21
|
-
export const testSchema = {
|
|
22
|
-
name: "test",
|
|
23
|
-
endpoint: "/test",
|
|
24
|
-
fields: {}
|
|
25
|
-
} as const
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Storage options for test
|
|
29
|
-
*/
|
|
30
|
-
const storageOptions = {
|
|
31
|
-
endpoint: "/test"
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* TestManager instance
|
|
36
|
-
*
|
|
37
|
-
* Provides CRUD operations for test entity.
|
|
38
|
-
*/
|
|
39
|
-
export const testManager = new EntityManager<TestEntity>({
|
|
40
|
-
...{
|
|
41
|
-
name: "test",
|
|
42
|
-
idField: "id",
|
|
43
|
-
fields: {}
|
|
44
|
-
},
|
|
45
|
-
storage: new ApiStorage<TestEntity>(storageOptions)
|
|
46
|
-
})
|