fix(audit): H15 (saved-view sort) + H14 (back/forward URL resync) in usePaginatedQuery
H15: new applyView({filters,sort}) atomic mutator (one URL write) restores a
saved view's sort, threaded through all six list components instead of being
discarded. H14: a guarded effect resyncs page/sort/filters FROM the URL on
Back/Forward; the resync setStates carry a scoped, justified
set-state-in-effect disable (loop-guarded external-URL sync).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -85,7 +85,7 @@ export function BerthList() {
|
||||
setSort,
|
||||
filters,
|
||||
setFilter,
|
||||
setAllFilters,
|
||||
applyView,
|
||||
clearFilters,
|
||||
setPage,
|
||||
setPageSize,
|
||||
@@ -183,8 +183,8 @@ export function BerthList() {
|
||||
<div className="flex items-center gap-2 ml-auto">
|
||||
<SavedViewsDropdown
|
||||
entityType="berths"
|
||||
onApplyView={(savedFilters, _savedSort) => {
|
||||
setAllFilters(savedFilters);
|
||||
onApplyView={(savedFilters, savedSort) => {
|
||||
applyView({ filters: savedFilters, sort: savedSort });
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
|
||||
@@ -115,7 +115,7 @@ export function ClientList() {
|
||||
setPageSize,
|
||||
filters,
|
||||
setFilter,
|
||||
setAllFilters,
|
||||
applyView,
|
||||
clearFilters,
|
||||
} = usePaginatedQuery<ClientRow>({
|
||||
queryKey: ['clients'],
|
||||
@@ -189,12 +189,12 @@ export function ClientList() {
|
||||
/>
|
||||
<SavedViewsDropdown
|
||||
entityType="clients"
|
||||
onApplyView={(savedFilters, _savedSort) => {
|
||||
// Atomic replace - sequential setFilter() calls dropped all
|
||||
// but the last value (each one read stale `filters` from
|
||||
// closure and overwrote). setAllFilters writes the whole
|
||||
// saved view in one setState.
|
||||
setAllFilters(savedFilters);
|
||||
onApplyView={(savedFilters, savedSort) => {
|
||||
// Atomic replace of filters AND sort in one URL write. Passing
|
||||
// both args fixes H15 (the saved sort was previously dropped);
|
||||
// applyView also avoids the two-write race that a setAllFilters
|
||||
// + setSort pair would hit.
|
||||
applyView({ filters: savedFilters, sort: savedSort });
|
||||
}}
|
||||
/>
|
||||
<ColumnPicker
|
||||
|
||||
@@ -97,7 +97,7 @@ export function CompanyList() {
|
||||
setPageSize,
|
||||
filters,
|
||||
setFilter,
|
||||
setAllFilters,
|
||||
applyView,
|
||||
clearFilters,
|
||||
} = usePaginatedQuery<CompanyRow>({
|
||||
queryKey: ['companies'],
|
||||
@@ -155,8 +155,8 @@ export function CompanyList() {
|
||||
<div className="ml-auto flex items-center gap-2">
|
||||
<SavedViewsDropdown
|
||||
entityType="companies"
|
||||
onApplyView={(savedFilters, _savedSort) => {
|
||||
setAllFilters(savedFilters);
|
||||
onApplyView={(savedFilters, savedSort) => {
|
||||
applyView({ filters: savedFilters, sort: savedSort });
|
||||
}}
|
||||
/>
|
||||
<ColumnPicker columns={COMPANY_COLUMN_OPTIONS} hidden={hidden} onChange={setHidden} />
|
||||
|
||||
@@ -110,7 +110,7 @@ export function InterestList() {
|
||||
setPageSize,
|
||||
filters,
|
||||
setFilter,
|
||||
setAllFilters,
|
||||
applyView,
|
||||
clearFilters,
|
||||
} = usePaginatedQuery<InterestRow>({
|
||||
queryKey: ['interests'],
|
||||
@@ -266,8 +266,8 @@ export function InterestList() {
|
||||
<>
|
||||
<SavedViewsDropdown
|
||||
entityType="interests"
|
||||
onApplyView={(savedFilters) => {
|
||||
setAllFilters(savedFilters);
|
||||
onApplyView={(savedFilters, savedSort) => {
|
||||
applyView({ filters: savedFilters, sort: savedSort });
|
||||
}}
|
||||
/>
|
||||
<ColumnPicker
|
||||
|
||||
@@ -83,7 +83,7 @@ export function ResidentialInterestsList() {
|
||||
setPageSize,
|
||||
filters,
|
||||
setFilter,
|
||||
setAllFilters,
|
||||
applyView,
|
||||
clearFilters,
|
||||
} = usePaginatedQuery<ResidentialInterestRow>({
|
||||
queryKey: ['residential-interests'],
|
||||
@@ -193,7 +193,9 @@ export function ResidentialInterestsList() {
|
||||
<div className="ml-auto flex flex-wrap items-center gap-2">
|
||||
<SavedViewsDropdown
|
||||
entityType="residential_interests"
|
||||
onApplyView={(savedFilters) => setAllFilters(savedFilters)}
|
||||
onApplyView={(savedFilters, savedSort) =>
|
||||
applyView({ filters: savedFilters, sort: savedSort })
|
||||
}
|
||||
/>
|
||||
<ColumnPicker
|
||||
columns={RESIDENTIAL_INTEREST_COLUMN_OPTIONS}
|
||||
|
||||
@@ -99,7 +99,7 @@ export function YachtList() {
|
||||
setPageSize,
|
||||
filters,
|
||||
setFilter,
|
||||
setAllFilters,
|
||||
applyView,
|
||||
clearFilters,
|
||||
} = usePaginatedQuery<YachtRow>({
|
||||
queryKey: ['yachts'],
|
||||
@@ -153,8 +153,8 @@ export function YachtList() {
|
||||
/>
|
||||
<SavedViewsDropdown
|
||||
entityType="yachts"
|
||||
onApplyView={(savedFilters, _savedSort) => {
|
||||
setAllFilters(savedFilters);
|
||||
onApplyView={(savedFilters, savedSort) => {
|
||||
applyView({ filters: savedFilters, sort: savedSort });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user