-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Searchable teams filter #61
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ | |
|
||
import React, {useCallback, useEffect, useMemo, useState} from 'react'; | ||
|
||
import type {Team} from '@mattermost/types/teams'; | ||
import type {Team, TeamsWithCount} from '@mattermost/types/teams'; | ||
|
||
import {Client4} from 'mattermost-redux/client'; | ||
|
||
|
@@ -32,48 +32,77 @@ const TEAM_FILTER_FILTER_TYPE_OPTIONS: RadioSetting[] = [ | |
|
||
function TeamFilter({id, setSaveNeeded, onChange, config, setInitialSetting}: CustomSettingChildComponentProp) { | ||
const [selectedTeams, setSelectedTeams] = useState<DropdownOption[]>([]); | ||
const [allTeamsOptions, setAllTeamsOptions] = useState<DropdownOption[]>([]); | ||
const [initialOptions, setInitialOptions] = useState<DropdownOption[]>([]); | ||
const [teamFilterType, setTeamFilterType] = useState<TeamFilterType>('everyone'); | ||
|
||
// For fetching initial few teams for displaying in the multiselect dropdown | ||
useEffect(() => { | ||
const task = async () => { | ||
// fetch all teams to populate options | ||
const teams: Team[] = await Client4.getTeams(0, 10000, false) as Team[]; | ||
// getTeams always returns Team[] when includeTotalCount param is set to false | ||
const teams = await Client4.getTeams(0, 20, false) as Team[]; | ||
const options = teams.map((team): DropdownOption => ({ | ||
value: team.id, | ||
label: team.display_name, | ||
raw: team, | ||
})); | ||
setInitialOptions(options); | ||
}; | ||
|
||
task(); | ||
}, []); | ||
|
||
// For fetching the teams which are selected so their names can be displayed | ||
useEffect(() => { | ||
const savedSetting = config.PluginSettings.Plugins['com.mattermost.user-survey']?.systemconsolesetting?.TeamFilter; | ||
const initialFilterTypeValue = savedSetting?.filterType || 'everyone'; | ||
setTeamFilterType(initialFilterTypeValue); | ||
|
||
const task = async () => { | ||
if (!savedSetting?.filteredTeamIDs) { | ||
return; | ||
} | ||
|
||
const teamsByID: {[key: string]: Team} = {}; | ||
const options = teams. | ||
filter((team) => team.delete_at === 0). | ||
map((team): DropdownOption => { | ||
teamsByID[team.id] = team; | ||
|
||
return { | ||
value: team.id, | ||
label: team.display_name, | ||
raw: team, | ||
}; | ||
}); | ||
setAllTeamsOptions(options); | ||
|
||
const savedSetting = config.PluginSettings.Plugins['com.mattermost.user-survey']?.systemconsolesetting?.TeamFilter; | ||
let initialOptions: DropdownOption[] = []; | ||
if (savedSetting?.filteredTeamIDs) { | ||
initialOptions = savedSetting.filteredTeamIDs.map((teamId) => { | ||
const team = teamsByID[teamId]; | ||
return { | ||
label: team?.display_name || `Archived Team: ${teamId}`, | ||
value: teamId, | ||
raw: team, | ||
}; | ||
|
||
const getTeamsByIds = async (teamIds: string[]): Promise<Team[]> => { | ||
const teams: Team[] = []; | ||
const getTeamPromises: Array<Promise<void>> = []; | ||
|
||
const fetchTeam = async (teamId: string) => { | ||
const team = await Client4.getTeam(teamId); | ||
teams.push(team); | ||
return Promise.resolve(); | ||
}; | ||
|
||
teamIds.forEach((teamId) => { | ||
getTeamPromises.push(fetchTeam(teamId)); | ||
}); | ||
} | ||
|
||
setSelectedTeams(initialOptions); | ||
await Promise.all(getTeamPromises); | ||
|
||
return teams; | ||
}; | ||
|
||
const initialFilterTypeValue = savedSetting?.filterType || 'everyone'; | ||
setTeamFilterType(initialFilterTypeValue); | ||
// fetch selected teams | ||
const teams = await getTeamsByIds(savedSetting.filteredTeamIDs); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know this can make many API calls all together, but this would be once, in a very in-frequently accused part of the app. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
teams.forEach((team) => { | ||
teamsByID[team.id] = team; | ||
}); | ||
|
||
// convert team objects to DropdownOption for displaying | ||
const selectedOptions = savedSetting.filteredTeamIDs.map((teamId) => { | ||
const team = teamsByID[teamId]; | ||
return { | ||
label: team?.display_name || `Archived Team: ${teamId}`, | ||
value: teamId, | ||
raw: team, | ||
}; | ||
}); | ||
|
||
setSelectedTeams(selectedOptions); | ||
|
||
const initialConfig: TeamFilterConfig = { | ||
filteredTeamIDs: optionsToTeamIDs(initialOptions), | ||
filteredTeamIDs: optionsToTeamIDs(selectedOptions), | ||
filterType: initialFilterTypeValue, | ||
}; | ||
setInitialSetting(id, initialConfig); | ||
|
@@ -106,6 +135,17 @@ function TeamFilter({id, setSaveNeeded, onChange, config, setInitialSetting}: Cu | |
saveSettings(selectedTeams, value as TeamFilterType); | ||
}, [saveSettings, selectedTeams]); | ||
|
||
const searchTeams = useCallback(async (inputValue: string) => { | ||
// response is always TeamsWithCount when paginating | ||
const {teams} = await Client4.searchTeams(inputValue, {page: 0, per_page: 100}) as TeamsWithCount; | ||
|
||
return teams.map((team): DropdownOption => ({ | ||
value: team.id, | ||
label: team.display_name, | ||
raw: team, | ||
})); | ||
}, []); | ||
|
||
return ( | ||
<div className='TeamFilter'> | ||
<RadioSettingsGroup | ||
|
@@ -118,10 +158,11 @@ function TeamFilter({id, setSaveNeeded, onChange, config, setInitialSetting}: Cu | |
{ | ||
teamFilterType !== 'everyone' && | ||
<Multiselect | ||
options={allTeamsOptions} | ||
options={initialOptions} | ||
customComponents={customComponents} | ||
values={selectedTeams} | ||
onChange={teamFilterOnChangeHandler} | ||
searchOptions={searchTeams} | ||
/> | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this standard way of doing this in this repo. In web we usually have an action.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is how we do it in simple plugins, like this one.