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)
This commit is contained in:
parent
b2dda2fc35
commit
914a92cae8
3 changed files with 42 additions and 16 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<boolean>(true);
|
||||
const [activeOption, setActiveOption] = useState<TabOptions>(isCreateMode ? TabOptions.Teams : TabOptions.Users);
|
||||
const [teamSearchResults, setTeamSearchResults] = useState<GrafanaTeam[]>([]);
|
||||
const [userSearchResults, setUserSearchResults] = useState<UserCurrentlyOnCall[]>([]);
|
||||
const [onCallUserSearchResults, setOnCallUserSearchResults] = useState<UserCurrentlyOnCall[]>([]);
|
||||
const [notOnCallUserSearchResults, setNotOnCallUserSearchResults] = useState<UserCurrentlyOnCall[]>([]);
|
||||
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<UserCurrentlyOnCall[]>({ searchTerm, is_currently_oncall: 'all' });
|
||||
setUserSearchResults(userResults);
|
||||
const _search = async (is_currently_oncall: boolean) => {
|
||||
const response = await userStore.search<PaginatedUsersResponse<UserCurrentlyOnCall>>({
|
||||
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(
|
|||
) : (
|
||||
<>
|
||||
<Alert
|
||||
className={cx('team-direct-paging-info-alert')}
|
||||
className={cx('info-alert')}
|
||||
severity="info"
|
||||
title={
|
||||
(
|
||||
|
|
@ -330,8 +340,22 @@ const AddRespondersPopup = observer(
|
|||
)}
|
||||
{!searchLoading && activeOption === TabOptions.Users && (
|
||||
<>
|
||||
<UserResultsSection header="On-call now" users={usersCurrentlyOnCall} />
|
||||
<UserResultsSection header="Not on-call" users={usersNotCurrentlyOnCall} />
|
||||
<Alert
|
||||
className={cx('info-alert')}
|
||||
severity="info"
|
||||
title={
|
||||
(
|
||||
<Text type="primary">
|
||||
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.
|
||||
</Text>
|
||||
) as any
|
||||
}
|
||||
/>
|
||||
<UserResultsSection header="On-call now" users={onCallUserSearchResults} />
|
||||
<div style={{ marginTop: '10px' }}>
|
||||
<UserResultsSection header="Not on-call" users={notOnCallUserSearchResults} />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import { isUserActionAllowed, UserActions } from 'utils/authorization';
|
|||
import { getTimezone, prepareForUpdate } from './user.helpers';
|
||||
import { User } from './user.types';
|
||||
|
||||
type PaginatedUsersResponse<UT = User> = {
|
||||
export type PaginatedUsersResponse<UT = User> = {
|
||||
count: number;
|
||||
page_size: number;
|
||||
results: UT[];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue