diff --git a/packages/web_ui/src/components/IconReferencePage.tsx b/packages/web_ui/src/components/IconReferencePage.tsx index 2a8f58dc..16ee6dbc 100644 --- a/packages/web_ui/src/components/IconReferencePage.tsx +++ b/packages/web_ui/src/components/IconReferencePage.tsx @@ -9,6 +9,7 @@ import { useParams } from "react-router-dom"; import { useModPack } from "../model/mod_pack"; import { PrototypeMetadataEntry } from "../store/export_prototype_metadata_store"; import useResourceState from "../util/useResourceState"; +import useTableQueryState from "../util/useTableQueryState"; import ResourceState from "./ResourceState"; const { Text } = Typography; @@ -39,7 +40,9 @@ export default function IconReferencePage() { let params = useParams(); let modPackId = Number(params.id); - const [filter, setFilter] = useState(""); + // Filters live as you type, written to the URL on blur, enter or clear + const queryState = useTableQueryState({ namespace: "icon" }); + const filter = queryState.filteredValue("search")?.[0] ?? ""; const [expandedGroups, setExpandedGroups] = useState>(new Set()); const [modPack, synced, error] = useModPack(modPackId); const state = useResourceState(modPack, synced, error, modPackId); @@ -137,7 +140,15 @@ export default function IconReferencePage() { setFilter(e.target.value)} + onChange={e => { + const values = e.target.value ? [e.target.value] : null; + queryState.setFilter("search", values); + if (!values) { + queryState.commitFilter("search", null); + } + }} + onBlur={() => queryState.commitFilter("search")} + onPressEnter={() => queryState.commitFilter("search")} allowClear style={{ width: 320 }} /> diff --git a/packages/web_ui/src/components/UsersPage.tsx b/packages/web_ui/src/components/UsersPage.tsx index e8910729..800097ee 100644 --- a/packages/web_ui/src/components/UsersPage.tsx +++ b/packages/web_ui/src/components/UsersPage.tsx @@ -20,6 +20,7 @@ import PageLayout from "./PageLayout"; import PluginExtra from "./PluginExtra"; import UsersTable from "./UsersTable"; import { InputInstanceWithAll } from "./InputInstance"; +import useTableQueryState from "../util/useTableQueryState"; function CreateUserButton() { let control = useContext(ControlContext); @@ -368,7 +369,10 @@ function BulkUserActionButton() { export default function UsersPage() { const account = useAccount(); - const [instanceId, setInstanceId] = useState(null); + // Kept in the URL with the users table state so back/forward restores it + const tableState = useTableQueryState({ namespace: "user" }); + const instanceParam = Number(tableState.filteredValue("instance")?.[0]); + const instanceId = Number.isInteger(instanceParam) ? instanceParam : null; return setInstanceId(value as number)} + onChange={value => tableState.commitFilter( + "instance", value === null ? null : [String(value)] + )} fieldDefinition={{ optional: true } as any} disabled={false} />}