@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quazardous/qdadm",
3
- "version": "2.3.1",
3
+ "version": "2.4.1",
4
4
  "description": "Vue 3 framework for admin dashboards with PrimeVue",
5
5
  "author": "quazardous",
6
6
  "license": "MIT",
@@ -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
- const sortField = ref<string | null>(defaultSort)
247
- const sortOrder = ref(defaultSortOrder)
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
- // Handle nulls
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 sort_order === 'asc' ? 1 : -1
180
- if (bVal == null) return sort_order === 'asc' ? -1 : 1
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
- })