/* eslint jsx-a11y/tabindex-no-positive: 0 */ import React, {Component, PropTypes} from 'react' import { Menu, RetinaImg, LabelColorizer, BoldedSearchResult, } from 'nylas-component-kit' import { Utils, Actions, TaskQueue, Label, SyncbackCategoryTask, ChangeLabelsTask, } from 'nylas-exports' import {Categories} from 'nylas-observables' export default class LabelPickerPopover extends Component { static propTypes = { threads: PropTypes.array.isRequired, account: PropTypes.object.isRequired, }; constructor(props) { super(props) this._labels = [] this.state = this._recalculateState(this.props, {searchValue: ''}) } componentDidMount() { this._registerObservables() } componentWillReceiveProps(nextProps) { this._registerObservables(nextProps) this.setState(this._recalculateState(nextProps)) } componentWillUnmount() { this._unregisterObservables() } _registerObservables = (props = this.props) => { this._unregisterObservables() this.disposables = [ Categories.forAccount(props.account).sort().subscribe(this._onLabelsChanged), ] }; _unregisterObservables = () => { if (this.disposables) { this.disposables.forEach(disp => disp.dispose()) } }; _recalculateState = (props = this.props, {searchValue = (this.state.searchValue || "")} = {}) => { const {threads} = props if (threads.length === 0) { return {categoryData: [], searchValue} } const categoryData = this._labels.filter(label => Utils.wordSearchRegExp(searchValue).test(label.displayName) ).map((label) => { return { id: label.id, category: label, displayName: label.displayName, backgroundColor: LabelColorizer.backgroundColorDark(label), usage: threads.filter(t => t.categories.find(c => c.id === label.id)).length, numThreads: threads.length, }; }); if (searchValue.length > 0) { categoryData.push({ searchValue: searchValue, newCategoryItem: true, id: "category-create-new", }); } return {categoryData, searchValue} }; _onLabelsChanged = (categories) => { this._labels = categories.filter(c => { return (c instanceof Label) && (!c.role) && (c.path !== "N1-Snoozed"); }); this.setState(this._recalculateState()) }; _onEscape = () => { Actions.closePopover() }; _onSelectLabel = (item) => { const {account, threads} = this.props if (threads.length === 0) return; if (item.newCategoryItem) { const syncbackTask = new SyncbackCategoryTask({ path: this.state.searchValue, accountId: account.id, }) TaskQueue.waitForPerformRemote(syncbackTask).then((finishedTask) => { if (!finishedTask.created) { NylasEnv.showErrorDialog({title: "Error", message: `Could not create label.`}) return; } Actions.queueTask(new ChangeLabelsTask({ source: "Category Picker: New Category", threads: threads, labelsToRemove: [], labelsToAdd: [finishedTask.created], })); }) Actions.queueTask(syncbackTask); } else if (item.usage === threads.length) { Actions.queueTask(new ChangeLabelsTask({ source: "Category Picker: Existing Category", threads: threads, labelsToRemove: [item.category], labelsToAdd: [], })); } else { Actions.queueTask(new ChangeLabelsTask({ source: "Category Picker: Existing Category", threads: threads, labelsToRemove: [], labelsToAdd: [item.category], })); } Actions.closePopover() }; _onSearchValueChange = (event) => { this.setState( this._recalculateState(this.props, {searchValue: event.target.value}) ) }; _renderCheckbox = (item) => { const styles = {} let checkStatus; styles.backgroundColor = item.backgroundColor if (item.usage === 0) { checkStatus = } else if (item.usage < item.numThreads) { checkStatus = ( this._onSelectLabel(item)} /> ) } else { checkStatus = ( this._onSelectLabel(item)} /> ) } return (
this._onSelectLabel(item)} /> {checkStatus}
) }; _renderCreateNewItem = ({searchValue}) => { return (
“{searchValue}” (create new)
) }; _renderItem = (item) => { if (item.divider) { return } else if (item.newCategoryItem) { return this._renderCreateNewItem(item) } return (
{this._renderCheckbox(item)}
) }; render() { const headerComponents = [ , ] return (
item.id} itemContent={this._renderItem} onSelect={this._onSelectLabel} onEscape={this._onEscape} defaultSelectedIndex={this.state.searchValue === "" ? -1 : 0} />
) } }