feat(dict): таблица справочника — hide tail columns по умолчанию (без H-scroll)
This commit is contained in:
@@ -28,11 +28,20 @@ const DEFAULT_STATE: DictTableState = { sort: null, hidden: [] }
|
||||
|
||||
const storageKey = (dictName: string): string => `ord-dict-table:${dictName}`
|
||||
|
||||
const readState = (dictName: string): DictTableState => {
|
||||
if (typeof window === 'undefined') return DEFAULT_STATE
|
||||
/**
|
||||
* Прочитать persisted state. Если в storage пусто (юзер ни разу не
|
||||
* взаимодействовал с этим dict) → используем `fallbackHidden` как initial
|
||||
* visibility (для info-dense schemas: hide tail columns по умолчанию,
|
||||
* чтобы таблица помещалась в viewport без H-scroll). Любой toggle/setHidden
|
||||
* запишет state в storage → дальнейшие посещения respect юзерский выбор
|
||||
* вне зависимости от fallback.
|
||||
*/
|
||||
const readState = (dictName: string, fallbackHidden: string[]): DictTableState => {
|
||||
const fallback: DictTableState = { sort: null, hidden: fallbackHidden }
|
||||
if (typeof window === 'undefined') return fallback
|
||||
try {
|
||||
const raw = window.localStorage.getItem(storageKey(dictName))
|
||||
if (!raw) return DEFAULT_STATE
|
||||
if (!raw) return fallback
|
||||
const parsed = JSON.parse(raw) as Partial<DictTableState>
|
||||
return {
|
||||
sort:
|
||||
@@ -46,7 +55,7 @@ const readState = (dictName: string): DictTableState => {
|
||||
: [],
|
||||
}
|
||||
} catch {
|
||||
return DEFAULT_STATE
|
||||
return fallback
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,13 +69,19 @@ const writeState = (dictName: string, state: DictTableState): void => {
|
||||
}
|
||||
}
|
||||
|
||||
export function useDictTableState(dictName: string) {
|
||||
const [state, setState] = useState<DictTableState>(() => readState(dictName))
|
||||
export function useDictTableState(dictName: string, defaultHidden: string[] = []) {
|
||||
// Stable key для defaultHidden чтобы useEffect не зацикливался на каждый
|
||||
// render (массив literal каждый раз new reference). Caller обычно строит
|
||||
// defaultHidden из useMemo, но guard всё равно нужен.
|
||||
const defaultKey = defaultHidden.join(',')
|
||||
const [state, setState] = useState<DictTableState>(() => readState(dictName, defaultHidden))
|
||||
|
||||
// Перечитать когда смена dictName (navigation между справочниками).
|
||||
// Перечитать когда смена dictName (navigation между справочниками) или
|
||||
// когда меняется набор defaultHidden (schema reload → новые extra columns).
|
||||
useEffect(() => {
|
||||
setState(readState(dictName))
|
||||
}, [dictName])
|
||||
setState(readState(dictName, defaultHidden))
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps -- defaultKey stable
|
||||
}, [dictName, defaultKey])
|
||||
|
||||
useEffect(() => {
|
||||
writeState(dictName, state)
|
||||
|
||||
Reference in New Issue
Block a user