From 914a92cae84b3a941572fe9ebd7ba8ddfc8d13bb Mon Sep 17 00:00:00 2001 From: Joey Orlando Date: Mon, 13 Nov 2023 08:43:33 -0500 Subject: [PATCH] Improve performance on user search results in add responders dropdown (#3325) ## Which issue(s) this PR fixes Closes https://github.com/grafana/oncall/issues/3321 ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated - [ ] Documentation added (or `pr:no public docs` PR label added if not required) - [ ] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --- .../AddRespondersPopup.module.scss | 4 +- .../AddRespondersPopup/AddRespondersPopup.tsx | 52 ++++++++++++++----- grafana-plugin/src/models/user/user.ts | 2 +- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/grafana-plugin/src/containers/AddResponders/parts/AddRespondersPopup/AddRespondersPopup.module.scss b/grafana-plugin/src/containers/AddResponders/parts/AddRespondersPopup/AddRespondersPopup.module.scss index 7b5f57ac..cfbe02c8 100644 --- a/grafana-plugin/src/containers/AddResponders/parts/AddRespondersPopup/AddRespondersPopup.module.scss +++ b/grafana-plugin/src/containers/AddResponders/parts/AddRespondersPopup/AddRespondersPopup.module.scss @@ -1,4 +1,6 @@ .add-responders-dropdown { + max-height: 500px; + overflow: hidden; border: var(--border-medium); position: absolute; right: 16px; @@ -8,7 +10,7 @@ z-index: 10; } -.team-direct-paging-info-alert { +.info-alert { margin: 8px; } diff --git a/grafana-plugin/src/containers/AddResponders/parts/AddRespondersPopup/AddRespondersPopup.tsx b/grafana-plugin/src/containers/AddResponders/parts/AddRespondersPopup/AddRespondersPopup.tsx index 6e256c39..e1aea823 100644 --- a/grafana-plugin/src/containers/AddResponders/parts/AddRespondersPopup/AddRespondersPopup.tsx +++ b/grafana-plugin/src/containers/AddResponders/parts/AddRespondersPopup/AddRespondersPopup.tsx @@ -10,6 +10,7 @@ import GTable from 'components/GTable/GTable'; import Text from 'components/Text/Text'; import { Alert as AlertType } from 'models/alertgroup/alertgroup.types'; import { GrafanaTeam } from 'models/grafana_team/grafana_team.types'; +import { PaginatedUsersResponse } from 'models/user/user'; import { UserCurrentlyOnCall } from 'models/user/user.types'; import { useStore } from 'state/useStore'; import { useDebouncedCallback, useOnClickOutside } from 'utils/hooks'; @@ -51,12 +52,11 @@ const AddRespondersPopup = observer( const [searchLoading, setSearchLoading] = useState(true); const [activeOption, setActiveOption] = useState(isCreateMode ? TabOptions.Teams : TabOptions.Users); const [teamSearchResults, setTeamSearchResults] = useState([]); - const [userSearchResults, setUserSearchResults] = useState([]); + const [onCallUserSearchResults, setOnCallUserSearchResults] = useState([]); + const [notOnCallUserSearchResults, setNotOnCallUserSearchResults] = useState([]); const [searchTerm, setSearchTerm] = useState(''); const ref = useRef(); - const usersCurrentlyOnCall = userSearchResults.filter(({ is_currently_oncall }) => is_currently_oncall); - const usersNotCurrentlyOnCall = userSearchResults.filter(({ is_currently_oncall }) => !is_currently_oncall); useOnClickOutside(ref, () => { setVisible(false); @@ -97,11 +97,18 @@ const AddRespondersPopup = observer( ); const searchForUsers = useCallback(async () => { - /** - * specifying is_currently_oncall=all will tell the backend not to paginate the results - */ - const userResults = await userStore.search({ searchTerm, is_currently_oncall: 'all' }); - setUserSearchResults(userResults); + const _search = async (is_currently_oncall: boolean) => { + const response = await userStore.search>({ + searchTerm, + is_currently_oncall, + }); + return response.results; + }; + + const [onCallUserSearchResults, notOnCallUserSearchResults] = await Promise.all([_search(true), _search(false)]); + + setOnCallUserSearchResults(onCallUserSearchResults); + setNotOnCallUserSearchResults(notOnCallUserSearchResults); }, [searchTerm]); const searchForTeams = useCallback(async () => { @@ -153,9 +160,12 @@ const AddRespondersPopup = observer( useEffect(() => { if (existingPagedUsers.length > 0) { const existingPagedUserIds = existingPagedUsers.map(({ pk }) => pk); - setUserSearchResults((userSearchResults) => - userSearchResults.filter(({ pk }) => !existingPagedUserIds.includes(pk)) - ); + + const _filterUsers = (users: UserCurrentlyOnCall[]) => + users.filter(({ pk }) => !existingPagedUserIds.includes(pk)); + + setOnCallUserSearchResults(_filterUsers); + setNotOnCallUserSearchResults(_filterUsers); } }, [existingPagedUsers]); @@ -293,7 +303,7 @@ const AddRespondersPopup = observer( ) : ( <> - - + + We display a maximum of 100 users per category. Use the search bar above to refine results. You + can search by username, email, or team name. + + ) as any + } + /> + +
+ +
)} diff --git a/grafana-plugin/src/models/user/user.ts b/grafana-plugin/src/models/user/user.ts index 1c658077..a3d10505 100644 --- a/grafana-plugin/src/models/user/user.ts +++ b/grafana-plugin/src/models/user/user.ts @@ -15,7 +15,7 @@ import { isUserActionAllowed, UserActions } from 'utils/authorization'; import { getTimezone, prepareForUpdate } from './user.helpers'; import { User } from './user.types'; -type PaginatedUsersResponse = { +export type PaginatedUsersResponse = { count: number; page_size: number; results: UT[];