From ba31f03602695908d6ae4ce86991ca9971c50453 Mon Sep 17 00:00:00 2001 From: Emily <15078396+EmilyBonar@users.noreply.github.com> Date: Thu, 23 May 2024 15:43:56 -0500 Subject: [PATCH] fix: reset InteractiveTable pagination when filters applied [ET-183] [ET-121] (#9413) --- webui/react/src/components/ModelRegistry.tsx | 10 +++---- webui/react/src/components/TaskList.tsx | 27 ++++++++++++++----- .../react/src/pages/Admin/UserManagement.tsx | 4 +-- .../ExperimentCheckpoints.tsx | 11 ++++---- .../ExperimentDetails/ExperimentTrials.tsx | 10 +++---- webui/react/src/pages/ExperimentList.tsx | 14 ++++++---- .../src/pages/Templates/TemplatesList.tsx | 4 +-- 7 files changed, 47 insertions(+), 33 deletions(-) diff --git a/webui/react/src/components/ModelRegistry.tsx b/webui/react/src/components/ModelRegistry.tsx index 5561b7dc981..f4d5c018b1e 100644 --- a/webui/react/src/components/ModelRegistry.tsx +++ b/webui/react/src/components/ModelRegistry.tsx @@ -228,7 +228,7 @@ const ModelRegistry: React.FC = ({ workspace }: Props) => { ); const handleUserFilterReset = useCallback(() => { - updateSettings({ users: undefined }); + updateSettings({ tableOffset: 0, users: undefined }); }, [updateSettings]); const userFilterDropdown = useCallback( @@ -255,7 +255,7 @@ const ModelRegistry: React.FC = ({ workspace }: Props) => { ); const handleNameSearchReset = useCallback(() => { - updateSettings({ name: undefined }); + updateSettings({ name: undefined, tableOffset: 0 }); }, [updateSettings]); const nameFilterSearch = useCallback( @@ -278,7 +278,7 @@ const ModelRegistry: React.FC = ({ workspace }: Props) => { ); const handleDescriptionSearchReset = useCallback(() => { - updateSettings({ description: undefined }); + updateSettings({ description: undefined, tableOffset: 0 }); }, [updateSettings]); const descriptionFilterSearch = useCallback( @@ -301,7 +301,7 @@ const ModelRegistry: React.FC = ({ workspace }: Props) => { ); const handleLabelFilterReset = useCallback(() => { - updateSettings({ tags: undefined }); + updateSettings({ tableOffset: 0, tags: undefined }); }, [updateSettings]); const handleWorkspaceFilterApply = useCallback( @@ -317,7 +317,7 @@ const ModelRegistry: React.FC = ({ workspace }: Props) => { ); const handleWorkspaceFilterReset = useCallback(() => { - updateSettings({ row: undefined, workspace: undefined }); + updateSettings({ row: undefined, tableOffset: 0, workspace: undefined }); }, [updateSettings]); const workspaceFilterDropdown = useCallback( diff --git a/webui/react/src/components/TaskList.tsx b/webui/react/src/components/TaskList.tsx index d202057dc86..c47a64e6cb2 100644 --- a/webui/react/src/components/TaskList.tsx +++ b/webui/react/src/components/TaskList.tsx @@ -124,7 +124,16 @@ const TaskList: React.FC = ({ workspace }: Props) => { users, settings.search, ); - }, [loadedTasks, settings, users]); + }, [ + loadedTasks, + settings.search, + settings.state, + settings.tableLimit, + settings.type, + settings.user, + settings.workspace, + users, + ]); const taskMap = useMemo(() => { return (loadedTasks || []).reduce( @@ -190,13 +199,13 @@ const TaskList: React.FC = ({ workspace }: Props) => { const handleNameSearchApply = useCallback( (newSearch: string) => { - updateSettings({ row: undefined, search: newSearch || undefined }); + updateSettings({ row: undefined, search: newSearch || undefined, tableOffset: 0 }); }, [updateSettings], ); const handleNameSearchReset = useCallback(() => { - updateSettings({ row: undefined, search: undefined }); + updateSettings({ row: undefined, search: undefined, tableOffset: 0 }); }, [updateSettings]); const nameFilterSearch = useCallback( @@ -215,6 +224,7 @@ const TaskList: React.FC = ({ workspace }: Props) => { (types: string[]) => { updateSettings({ row: undefined, + tableOffset: 0, type: types.length !== 0 ? (types as CommandType[]) : undefined, }); }, @@ -225,6 +235,7 @@ const TaskList: React.FC = ({ workspace }: Props) => { (workspaces: string[]) => { updateSettings({ row: undefined, + tableOffset: 0, workspace: workspaces.length !== 0 ? workspaces : undefined, }); }, @@ -232,11 +243,11 @@ const TaskList: React.FC = ({ workspace }: Props) => { ); const handleWorkspaceFilterReset = useCallback(() => { - updateSettings({ row: undefined, workspace: undefined }); + updateSettings({ row: undefined, tableOffset: 0, workspace: undefined }); }, [updateSettings]); const handleTypeFilterReset = useCallback(() => { - updateSettings({ row: undefined, type: undefined }); + updateSettings({ row: undefined, tableOffset: 0, type: undefined }); }, [updateSettings]); const typeFilterDropdown = useCallback( @@ -271,13 +282,14 @@ const TaskList: React.FC = ({ workspace }: Props) => { updateSettings({ row: undefined, state: states.length !== 0 ? (states as CommandState[]) : undefined, + tableOffset: 0, }); }, [updateSettings], ); const handleStateFilterReset = useCallback(() => { - updateSettings({ row: undefined, state: undefined }); + updateSettings({ row: undefined, state: undefined, tableOffset: 0 }); }, [updateSettings]); const stateFilterDropdown = useCallback( @@ -297,6 +309,7 @@ const TaskList: React.FC = ({ workspace }: Props) => { (users: string[]) => { updateSettings({ row: undefined, + tableOffset: 0, user: users.length !== 0 ? users : undefined, }); }, @@ -304,7 +317,7 @@ const TaskList: React.FC = ({ workspace }: Props) => { ); const handleUserFilterReset = useCallback(() => { - updateSettings({ row: undefined, user: undefined }); + updateSettings({ row: undefined, tableOffset: 0, user: undefined }); }, [updateSettings]); const userFilterDropdown = useCallback( diff --git a/webui/react/src/pages/Admin/UserManagement.tsx b/webui/react/src/pages/Admin/UserManagement.tsx index e6bcdc5e1ec..2eacb6b35db 100644 --- a/webui/react/src/pages/Admin/UserManagement.tsx +++ b/webui/react/src/pages/Admin/UserManagement.tsx @@ -211,8 +211,8 @@ const UserManagement: React.FC = () => { const [selectedUserIds, setSelectedUserIds] = useState([]); const [refresh, setRefresh] = useState>({}); const [nameFilter, setNameFilter] = useState(''); - const [roleFilter, setRoleFilter] = useState(''); - const [statusFilter, setStatusFilter] = useState(''); + const [roleFilter, setRoleFilter] = useState(); + const [statusFilter, setStatusFilter] = useState(); const pageRef = useRef(null); const currentUser = Loadable.getOrElse(undefined, useObservable(userStore.currentUser)); const loadableSettings = useObservable(userManagementSettings); diff --git a/webui/react/src/pages/ExperimentDetails/ExperimentCheckpoints.tsx b/webui/react/src/pages/ExperimentDetails/ExperimentCheckpoints.tsx index 59a3c6b36ae..92eb530e31c 100644 --- a/webui/react/src/pages/ExperimentDetails/ExperimentCheckpoints.tsx +++ b/webui/react/src/pages/ExperimentDetails/ExperimentCheckpoints.tsx @@ -94,13 +94,14 @@ const ExperimentCheckpoints: React.FC = ({ experiment, pageRef }: Props) updateSettings({ row: undefined, state: states.length !== 0 ? (states as CheckpointState[]) : undefined, + tableOffset: 0, }); }, [updateSettings], ); const handleStateFilterReset = useCallback(() => { - updateSettings({ row: undefined, state: undefined }); + updateSettings({ row: undefined, state: undefined, tableOffset: 0 }); }, [updateSettings]); const stateFilterDropdown = useCallback( @@ -263,13 +264,11 @@ const ExperimentCheckpoints: React.FC = ({ experiment, pageRef }: Props) stateFilterDropdown, ]); - const stateString = settings.state?.join('.'); const fetchExperimentCheckpoints = useCallback(async () => { if (!settings) return; + + const states = settings.state?.map((state) => encodeCheckpointState(state as CheckpointState)); try { - const states = stateString - ?.split('.') - .map((state) => encodeCheckpointState(state as CheckpointState)); const response = await getExperimentCheckpoints( { id: experiment.id, @@ -294,7 +293,7 @@ const ExperimentCheckpoints: React.FC = ({ experiment, pageRef }: Props) } finally { setIsLoading(false); } - }, [experiment.id, canceler, settings, stateString, checkpoints]); + }, [settings, experiment.id, canceler.signal, checkpoints]); const submitBatchAction = useCallback( async (action: CheckpointAction) => { diff --git a/webui/react/src/pages/ExperimentDetails/ExperimentTrials.tsx b/webui/react/src/pages/ExperimentDetails/ExperimentTrials.tsx index ba7fd389b73..2bbb5b03b76 100644 --- a/webui/react/src/pages/ExperimentDetails/ExperimentTrials.tsx +++ b/webui/react/src/pages/ExperimentDetails/ExperimentTrials.tsx @@ -97,13 +97,14 @@ const ExperimentTrials: React.FC = ({ experiment, pageRef }: Props) => { updateSettings({ row: undefined, state: states.length !== 0 ? (states as RunState[]) : undefined, + tableOffset: 0, }); }, [updateSettings], ); const handleStateFilterReset = useCallback(() => { - updateSettings({ row: undefined, state: undefined }); + updateSettings({ row: undefined, state: undefined, tableOffset: 0 }); }, [updateSettings]); const stateFilterDropdown = useCallback( @@ -312,14 +313,11 @@ const ExperimentTrials: React.FC = ({ experiment, pageRef }: Props) => { [columns, settings, updateSettings], ); - const stateString = useMemo(() => settings.state?.join('.'), [settings.state]); const fetchExperimentTrials = useCallback(async () => { if (!settings) return; + const states = settings.state?.map((state) => encodeExperimentState(state as RunState)); try { - const states = stateString - ?.split('.') - .map((state) => encodeExperimentState(state as RunState)); const { trials: experimentTrials, pagination: responsePagination } = await getExpTrials( { id: experiment.id, @@ -348,7 +346,7 @@ const ExperimentTrials: React.FC = ({ experiment, pageRef }: Props) => { } finally { setIsLoading(false); } - }, [experiment.id, canceler, settings, stateString]); + }, [settings, experiment.id, canceler.signal]); const sendBatchActions = useCallback( async (action: Action) => { diff --git a/webui/react/src/pages/ExperimentList.tsx b/webui/react/src/pages/ExperimentList.tsx index 2266592f6f1..50938f37b44 100644 --- a/webui/react/src/pages/ExperimentList.tsx +++ b/webui/react/src/pages/ExperimentList.tsx @@ -286,13 +286,13 @@ const ExperimentList: React.FC = ({ project }) => { const handleNameSearchApply = useCallback( (newSearch: string) => { - updateSettings({ row: undefined, search: newSearch || undefined }); + updateSettings({ row: undefined, search: newSearch || undefined, tableOffset: 0 }); }, [updateSettings], ); const handleNameSearchReset = useCallback(() => { - updateSettings({ row: undefined, search: undefined }); + updateSettings({ row: undefined, search: undefined, tableOffset: 0 }); }, [updateSettings]); const nameFilterSearch = useCallback( @@ -312,13 +312,14 @@ const ExperimentList: React.FC = ({ project }) => { updateSettings({ label: labels.length !== 0 ? labels : undefined, row: undefined, + tableOffset: 0, }); }, [updateSettings], ); const handleLabelFilterReset = useCallback(() => { - updateSettings({ label: undefined, row: undefined }); + updateSettings({ label: undefined, row: undefined, tableOffset: 0 }); }, [updateSettings]); const labelFilterDropdown = useCallback( @@ -340,13 +341,14 @@ const ExperimentList: React.FC = ({ project }) => { updateSettings({ row: undefined, state: states.length !== 0 ? (states as RunState[]) : undefined, + tableOffset: 0, }); }, [updateSettings], ); const handleStateFilterReset = useCallback(() => { - updateSettings({ row: undefined, state: undefined }); + updateSettings({ row: undefined, state: undefined, tableOffset: 0 }); }, [updateSettings]); const stateFilterDropdown = useCallback( @@ -366,6 +368,7 @@ const ExperimentList: React.FC = ({ project }) => { (users: string[]) => { updateSettings({ row: undefined, + tableOffset: 0, user: users.length !== 0 ? users : undefined, }); }, @@ -373,7 +376,7 @@ const ExperimentList: React.FC = ({ project }) => { ); const handleUserFilterReset = useCallback(() => { - updateSettings({ row: undefined, user: undefined }); + updateSettings({ row: undefined, tableOffset: 0, user: undefined }); }, [updateSettings]); const userFilterDropdown = useCallback( @@ -922,6 +925,7 @@ const ExperimentList: React.FC = ({ project }) => { columns: newColumns, columnWidths: newColumnWidths, row: undefined, + tableOffset: 0, }); }, [settings, updateSettings], diff --git a/webui/react/src/pages/Templates/TemplatesList.tsx b/webui/react/src/pages/Templates/TemplatesList.tsx index 440b1521a50..35a95294269 100644 --- a/webui/react/src/pages/Templates/TemplatesList.tsx +++ b/webui/react/src/pages/Templates/TemplatesList.tsx @@ -118,7 +118,7 @@ const TemplateList: React.FC = ({ workspaceId }) => { ); const handleWorkspaceFilterReset = useCallback(() => { - updateSettings({ workspace: undefined }); + updateSettings({ tableOffset: 0, workspace: undefined }); }, [updateSettings]); const workspaceFilterDropdown = useCallback( @@ -154,7 +154,7 @@ const TemplateList: React.FC = ({ workspaceId }) => { ); const handleNameSearchReset = useCallback(() => { - updateSettings({ name: undefined }); + updateSettings({ name: undefined, tableOffset: 0 }); }, [updateSettings]); const handleNameSearchApply = useCallback(