fix: honor table defaults and preserve dispatch mappings
This commit is contained in:
@@ -122,7 +122,6 @@ import { computed, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import Icon from '@/components/icons/Icon.vue'
|
||||
import Select from './Select.vue'
|
||||
import { setPersistedPageSize } from '@/composables/usePersistedPageSize'
|
||||
import { getConfiguredTablePageSizeOptions, normalizeTablePageSize } from '@/utils/tablePreferences'
|
||||
|
||||
const { t } = useI18n()
|
||||
@@ -225,7 +224,6 @@ const goToPage = (newPage: number) => {
|
||||
const handlePageSizeChange = (value: string | number | boolean | null) => {
|
||||
if (value === null || typeof value === 'boolean') return
|
||||
const newPageSize = normalizeTablePageSize(typeof value === 'string' ? parseInt(value, 10) : value)
|
||||
setPersistedPageSize(newPageSize)
|
||||
emit('update:pageSize', newPageSize)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
|
||||
import { getPersistedPageSize } from '@/composables/usePersistedPageSize'
|
||||
|
||||
describe('usePersistedPageSize', () => {
|
||||
afterEach(() => {
|
||||
localStorage.clear()
|
||||
delete window.__APP_CONFIG__
|
||||
})
|
||||
|
||||
it('uses the system table default instead of stale localStorage state', () => {
|
||||
window.__APP_CONFIG__ = {
|
||||
table_default_page_size: 1000,
|
||||
table_page_size_options: [20, 50, 1000]
|
||||
} as any
|
||||
localStorage.setItem('table-page-size', '50')
|
||||
localStorage.setItem('table-page-size-source', 'user')
|
||||
|
||||
expect(getPersistedPageSize()).toBe(1000)
|
||||
})
|
||||
})
|
||||
@@ -1,49 +1,9 @@
|
||||
import { getConfiguredTableDefaultPageSize, normalizeTablePageSize } from '@/utils/tablePreferences'
|
||||
|
||||
const STORAGE_KEY = 'table-page-size'
|
||||
const SOURCE_KEY = 'table-page-size-source'
|
||||
|
||||
/**
|
||||
* 从 localStorage 读取/写入 pageSize
|
||||
* 全局共享一个 key,所有表格统一偏好
|
||||
* 读取当前系统配置的表格默认每页条数。
|
||||
* 不再使用本地持久化缓存,所有页面统一以通用表格设置为准。
|
||||
*/
|
||||
export function getPersistedPageSize(fallback = getConfiguredTableDefaultPageSize()): number {
|
||||
try {
|
||||
const stored = localStorage.getItem(STORAGE_KEY)
|
||||
if (stored) {
|
||||
return normalizeTablePageSize(stored)
|
||||
}
|
||||
} catch {
|
||||
// localStorage 不可用(隐私模式等)
|
||||
}
|
||||
return normalizeTablePageSize(fallback)
|
||||
}
|
||||
|
||||
export function setPersistedPageSize(size: number): void {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, String(normalizeTablePageSize(size)))
|
||||
localStorage.setItem(SOURCE_KEY, 'user')
|
||||
} catch {
|
||||
// 静默失败
|
||||
}
|
||||
}
|
||||
|
||||
export function syncPersistedPageSizeWithSystemDefault(defaultSize = getConfiguredTableDefaultPageSize()): void {
|
||||
try {
|
||||
const normalizedDefault = normalizeTablePageSize(defaultSize)
|
||||
const stored = localStorage.getItem(STORAGE_KEY)
|
||||
const source = localStorage.getItem(SOURCE_KEY)
|
||||
const normalizedStored = stored ? normalizeTablePageSize(stored) : null
|
||||
|
||||
if ((source === 'user' || (source === null && stored !== null)) && stored) {
|
||||
localStorage.setItem(STORAGE_KEY, String(normalizedStored ?? normalizedDefault))
|
||||
localStorage.setItem(SOURCE_KEY, 'user')
|
||||
return
|
||||
}
|
||||
|
||||
localStorage.setItem(STORAGE_KEY, String(normalizedDefault))
|
||||
localStorage.setItem(SOURCE_KEY, 'system')
|
||||
} catch {
|
||||
// 静默失败
|
||||
}
|
||||
return normalizeTablePageSize(getConfiguredTableDefaultPageSize() || fallback)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ref, reactive, onUnmounted, toRaw } from 'vue'
|
||||
import { useDebounceFn } from '@vueuse/core'
|
||||
import type { BasePaginationResponse, FetchOptions } from '@/types'
|
||||
import { getPersistedPageSize, setPersistedPageSize } from './usePersistedPageSize'
|
||||
import { getPersistedPageSize } from './usePersistedPageSize'
|
||||
|
||||
interface PaginationState {
|
||||
page: number
|
||||
@@ -88,7 +88,6 @@ export function useTableLoader<T, P extends Record<string, any>>(options: TableL
|
||||
const handlePageSizeChange = (size: number) => {
|
||||
pagination.page_size = size
|
||||
pagination.page = 1
|
||||
setPersistedPageSize(size)
|
||||
load()
|
||||
}
|
||||
|
||||
|
||||
@@ -329,85 +329,8 @@ describe('useAppStore', () => {
|
||||
|
||||
expect((window as any).__APP_CONFIG__.table_default_page_size).toBe(1000)
|
||||
expect((window as any).__APP_CONFIG__.table_page_size_options).toEqual([20, 100, 1000])
|
||||
expect(localStorage.getItem('table-page-size')).toBe('1000')
|
||||
expect(localStorage.getItem('table-page-size-source')).toBe('system')
|
||||
})
|
||||
|
||||
it('fetchPublicSettings(force) 保留用户显式选择的分页大小', async () => {
|
||||
localStorage.setItem('table-page-size', '100')
|
||||
localStorage.setItem('table-page-size-source', 'user')
|
||||
|
||||
vi.mocked(getPublicSettings).mockResolvedValue({
|
||||
registration_enabled: false,
|
||||
email_verify_enabled: false,
|
||||
registration_email_suffix_whitelist: [],
|
||||
promo_code_enabled: true,
|
||||
password_reset_enabled: false,
|
||||
invitation_code_enabled: false,
|
||||
turnstile_enabled: false,
|
||||
turnstile_site_key: '',
|
||||
site_name: 'Updated Site',
|
||||
site_logo: '',
|
||||
site_subtitle: '',
|
||||
api_base_url: '',
|
||||
contact_info: '',
|
||||
doc_url: '',
|
||||
home_content: '',
|
||||
hide_ccs_import_button: false,
|
||||
purchase_subscription_enabled: false,
|
||||
purchase_subscription_url: '',
|
||||
table_default_page_size: 1000,
|
||||
table_page_size_options: [20, 50, 1000],
|
||||
custom_menu_items: [],
|
||||
custom_endpoints: [],
|
||||
linuxdo_oauth_enabled: false,
|
||||
backend_mode_enabled: false,
|
||||
version: '1.0.0'
|
||||
})
|
||||
|
||||
const store = useAppStore()
|
||||
await store.fetchPublicSettings(true)
|
||||
|
||||
expect(localStorage.getItem('table-page-size')).toBe('1000')
|
||||
expect(localStorage.getItem('table-page-size-source')).toBe('user')
|
||||
})
|
||||
|
||||
it('fetchPublicSettings(force) 保留旧版本未标记来源的分页偏好', async () => {
|
||||
localStorage.setItem('table-page-size', '50')
|
||||
|
||||
vi.mocked(getPublicSettings).mockResolvedValue({
|
||||
registration_enabled: false,
|
||||
email_verify_enabled: false,
|
||||
registration_email_suffix_whitelist: [],
|
||||
promo_code_enabled: true,
|
||||
password_reset_enabled: false,
|
||||
invitation_code_enabled: false,
|
||||
turnstile_enabled: false,
|
||||
turnstile_site_key: '',
|
||||
site_name: 'Updated Site',
|
||||
site_logo: '',
|
||||
site_subtitle: '',
|
||||
api_base_url: '',
|
||||
contact_info: '',
|
||||
doc_url: '',
|
||||
home_content: '',
|
||||
hide_ccs_import_button: false,
|
||||
purchase_subscription_enabled: false,
|
||||
purchase_subscription_url: '',
|
||||
table_default_page_size: 1000,
|
||||
table_page_size_options: [20, 50, 1000],
|
||||
custom_menu_items: [],
|
||||
custom_endpoints: [],
|
||||
linuxdo_oauth_enabled: false,
|
||||
backend_mode_enabled: false,
|
||||
version: '1.0.0'
|
||||
})
|
||||
|
||||
const store = useAppStore()
|
||||
await store.fetchPublicSettings(true)
|
||||
|
||||
expect(localStorage.getItem('table-page-size')).toBe('50')
|
||||
expect(localStorage.getItem('table-page-size-source')).toBe('user')
|
||||
expect(localStorage.getItem('table-page-size')).toBeNull()
|
||||
expect(localStorage.getItem('table-page-size-source')).toBeNull()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
type ReleaseInfo
|
||||
} from '@/api/admin/system'
|
||||
import { getPublicSettings as fetchPublicSettingsAPI } from '@/api/auth'
|
||||
import { syncPersistedPageSizeWithSystemDefault } from '@/composables/usePersistedPageSize'
|
||||
|
||||
export const useAppStore = defineStore('app', () => {
|
||||
// ==================== State ====================
|
||||
@@ -288,7 +287,6 @@ export const useAppStore = defineStore('app', () => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.__APP_CONFIG__ = { ...config }
|
||||
}
|
||||
syncPersistedPageSizeWithSystemDefault(config.table_default_page_size)
|
||||
cachedPublicSettings.value = config
|
||||
siteName.value = config.site_name || 'Sub2API'
|
||||
siteLogo.value = config.site_logo || ''
|
||||
|
||||
Reference in New Issue
Block a user