mattermost-mobile/app/components/team_list/index.tsx
Julien Tant fb9760151c
[MM-60405] Crossteam search (#8411)
* Add new team picker for search

* try fix result header

* fix style

* add test for team picker

* add some tests

* add tests on team list and team list item

* hide All Teams search behind FF

* use style variable for separator

* ALL TEAMS does not have a search history

* Update app/components/team_list/index.test.tsx

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>

* move ALL_TEAMS_ID to a constant file

* memoize the construction of team list to prevent useless allocation

* combine pushes

* move style to stylesheet

* revert changes to Package.resolved

* improve team list index tests

* add test to ensure team picker does not show for just one team

* add test to ensure the file icon filter only shows when i'm on the file tab

* improve jsx readability by making the if test positive

* add test to make sure team picket does not show if there's only one team

* test: remove snapshot and add expect that separator exists in index 0 but index 1 (#8474)

* Trigger Build

---------

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Rahim Rahman <rahim.rahman@mattermost.com>
2025-02-05 13:46:38 -07:00

110 lines
3.3 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {BottomSheetFlatList} from '@gorhom/bottom-sheet';
import React, {useCallback, useMemo} from 'react';
import {type ListRenderItemInfo, View} from 'react-native';
import {FlatList} from 'react-native-gesture-handler'; // Keep the FlatList from gesture handler so it works well with bottom sheet
import Loading from '@components/loading';
import {useTheme} from '@context/theme';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import TeamListItem from './team_list_item';
import type TeamModel from '@typings/database/models/servers/team';
type Props = {
iconBackgroundColor?: string;
iconTextColor?: string;
loading?: boolean;
onEndReached?: () => void;
onPress: (id: string) => void;
selectedTeamId?: string;
teams: Array<Team|TeamModel>;
testID?: string;
textColor?: string;
type?: BottomSheetList;
hideIcon?: boolean;
separatorAfterFirstItem?: boolean;
}
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
return {
container: {
flexGrow: 1,
},
contentContainer: {
marginBottom: 4,
},
separator: {
height: 1,
backgroundColor: changeOpacity(theme.centerChannelColor, 0.08),
},
};
});
const keyExtractor = (item: TeamModel) => item.id;
export default function TeamList({
iconBackgroundColor,
iconTextColor,
loading = false,
onEndReached,
onPress,
selectedTeamId,
teams,
testID,
textColor,
type = 'FlatList',
hideIcon = false,
separatorAfterFirstItem = false,
}: Props) {
const List = useMemo(() => (type === 'FlatList' ? FlatList : BottomSheetFlatList), [type]);
const theme = useTheme();
const styles = getStyleSheet(theme);
const renderTeam = useCallback(({item: t, index: i}: ListRenderItemInfo<Team|TeamModel>) => {
let teamListItem = (
<TeamListItem
onPress={onPress}
team={t}
textColor={textColor}
iconBackgroundColor={iconBackgroundColor}
iconTextColor={iconTextColor}
selectedTeamId={selectedTeamId}
hideIcon={hideIcon}
/>
);
if (separatorAfterFirstItem && i === 0) {
teamListItem = (<>
{teamListItem}
<View
style={styles.separator}
testID={`team_list.separator-${i}`}
/>
</>);
}
return teamListItem;
}, [textColor, iconTextColor, iconBackgroundColor, onPress, selectedTeamId, hideIcon, separatorAfterFirstItem, styles.separator]);
let footer;
if (loading) {
footer = (<Loading testID='team_list.loading'/>);
}
return (
<View style={styles.container}>
<List
data={teams}
renderItem={renderTeam}
keyExtractor={keyExtractor}
contentContainerStyle={styles.contentContainer}
testID={`${testID}.flat_list`}
onEndReached={onEndReached}
ListFooterComponent={footer}
scrollEnabled={teams.length > 3}
/>
</View>
);
}