From 0e4206d4aca16978c5682333732babb2dc7f6f95 Mon Sep 17 00:00:00 2001 From: Rares Mardare Date: Mon, 21 Aug 2023 17:22:10 +0300 Subject: [PATCH 1/5] prevent duplicate calls on /users, fixed initial search --- CHANGELOG.md | 1 + .../components/UsersFilters/UsersFilters.tsx | 5 +- grafana-plugin/src/pages/users/Users.tsx | 59 +++++++++++-------- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b50fa49d..529101f8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Changed HTTP Endpoint to Email for inbound email integrations ([#2816](https://github.com/grafana/oncall/issues/2816)) +- Fixed initial search on Users page ([#2842](https://github.com/grafana/oncall/issues/2842)) ## v1.3.25 (2023-08-18) diff --git a/grafana-plugin/src/components/UsersFilters/UsersFilters.tsx b/grafana-plugin/src/components/UsersFilters/UsersFilters.tsx index e7834dcbc..a39c5194c 100644 --- a/grafana-plugin/src/components/UsersFilters/UsersFilters.tsx +++ b/grafana-plugin/src/components/UsersFilters/UsersFilters.tsx @@ -11,10 +11,11 @@ interface UsersFiltersProps { value: any; onChange: (filters: any) => void; className?: string; + isLoading?: boolean; } const UsersFilters = (props: UsersFiltersProps) => { - const { value = { searchTerm: '' }, onChange, className } = props; + const { value = { searchTerm: '' }, onChange, className, isLoading } = props; const onSearchTermChangeCallback = useCallback( (e: ChangeEvent) => { @@ -31,6 +32,8 @@ const UsersFilters = (props: UsersFiltersProps) => { return (
} className={cx('search', 'control')} placeholder="Search users..." diff --git a/grafana-plugin/src/pages/users/Users.tsx b/grafana-plugin/src/pages/users/Users.tsx index 69b417942..2bdf65151 100644 --- a/grafana-plugin/src/pages/users/Users.tsx +++ b/grafana-plugin/src/pages/users/Users.tsx @@ -47,28 +47,34 @@ interface UsersState extends PageBaseState { searchTerm: string; }; initialUsersLoaded: boolean; + queuedUpdateUsers: boolean; } @observer class Users extends React.Component { - state: UsersState = { - page: 1, - isWrongTeam: false, - userPkToEdit: undefined, - usersFilters: { - searchTerm: '', - }, - - errorData: initErrorDataState(), - initialUsersLoaded: false, - }; + constructor(props: UsersProps) { + super(props); - async componentDidMount() { const { query: { p }, - } = this.props; - this.setState({ page: p ? Number(p) : 1 }, this.updateUsers); + } = props; + + this.state = { + page: p ? Number(p) : 1, + isWrongTeam: false, + userPkToEdit: undefined, + usersFilters: { + searchTerm: '', + }, + errorData: initErrorDataState(), + initialUsersLoaded: false, + queuedUpdateUsers: false, + }; + } + + async componentDidMount() { + this.updateUsers(); this.parseParams(); } @@ -84,14 +90,14 @@ class Users extends React.Component { LocationHelper.update({ p: page }, 'partial'); await userStore.updateItems(usersFilters, page); - this.setState({ initialUsersLoaded: true }); + this.setState({ initialUsersLoaded: true }, () => { + if (this.state.queuedUpdateUsers) { + this.updateUsers(); + } + }); }; componentDidUpdate(prevProps: UsersProps) { - if (!this.state.initialUsersLoaded) { - this.updateUsers(); - } - if (prevProps.match.params.id !== this.props.match.params.id) { this.parseParams(); } @@ -181,9 +187,12 @@ class Users extends React.Component { const { count, results } = userStore.getSearchResult(); const columns = this.getTableColumns(); + // disable search until we get all users retrieved so that there's no conflict on update + const isSearchDisabled = !initialUsersLoaded; + const handleClear = () => this.setState({ usersFilters: { searchTerm: '' } }, () => { - this.debouncedUpdateUsers(); + this.updateUsers(); }); return ( @@ -195,6 +204,7 @@ class Users extends React.Component { className={cx('users-filters')} value={usersFilters} onChange={this.handleUsersFiltersChange} + isLoading={isSearchDisabled} />
);