import React, { PureComponent } from 'react'; import { QuickInsertItem } from '@atlaskit/editor-common/provider-factory'; import StatelessElementBrowser from './components/StatelessElementBrowser'; import { Category, Modes } from './types'; export interface Props { categories?: Category[]; mode: keyof typeof Modes; getItems: (query?: string, category?: string) => QuickInsertItem[]; onSelectItem?: (item: QuickInsertItem) => void; onInsertItem: (item: QuickInsertItem) => void; showSearch: boolean; showCategories: boolean; defaultCategory?: string; } export interface State { items: QuickInsertItem[]; categories: Category[]; selectedCategory?: string; searchTerm?: string; } export default class ElementBrowser extends PureComponent { static defaultProps = { defaultCategory: 'all', onInsertItem: () => {}, }; state: State = { categories: [], items: [], searchTerm: '', selectedCategory: this.props.defaultCategory, }; componentDidMount() { const items = this.fetchItems(); this.setState({ items, categories: this.getCategories(items), }); } getCategories = (items: QuickInsertItem[] = this.fetchItems()) => // NOTE: we fetch all items to determine available categories. this.filterCategories(items, this.props.categories); filterCategories = ( items: QuickInsertItem[], categories: Category[] = [], ): Category[] => { const { showCategories } = this.props; if (!showCategories) { return []; } return categories.filter( (category) => category.name === 'all' || items.some((item) => (item.categories || []).includes(category.name)), ); }; fetchItems = (query?: string, category?: string) => { return this.props.getItems(query, category); }; componentDidUpdate(prevProps: Props, prevState: State) { const { searchTerm, selectedCategory } = this.state; // Update both items and categories when there's a new getItems if (this.props.getItems !== prevProps.getItems) { this.setState({ categories: this.getCategories(), items: this.fetchItems(searchTerm, selectedCategory), }); } else if ( searchTerm !== prevState.searchTerm || selectedCategory !== prevState.selectedCategory ) { this.setState({ items: this.fetchItems(searchTerm, selectedCategory), }); } } handleSearch = (searchTerm: string) => { const { defaultCategory } = this.props; this.setState({ searchTerm, selectedCategory: defaultCategory }); }; handleCategorySelection = (clickedCategory: Category) => { const { selectedCategory: stateCategoryValue } = this.state; /** * Reset selection if clicked on the same category twice. */ if (stateCategoryValue === clickedCategory.name) { return this.setState({ selectedCategory: this.props.defaultCategory }); } this.setState({ selectedCategory: clickedCategory.name, searchTerm: '', }); }; render() { const { onInsertItem, onSelectItem, showSearch, showCategories, mode, } = this.props; const { categories, searchTerm, selectedCategory, items } = this.state; return ( ); } }