Changeset View
Changeset View
Standalone View
Standalone View
web/calendar/filter-panel.react.js
// @flow | // @flow | ||||
import { | import { | ||||
faCog, | faCog, | ||||
faTimesCircle, | faTimesCircle, | ||||
faChevronUp, | faChevronUp, | ||||
faChevronDown, | faChevronDown, | ||||
} from '@fortawesome/free-solid-svg-icons'; | } from '@fortawesome/free-solid-svg-icons'; | ||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; | ||||
import classNames from 'classnames'; | import classNames from 'classnames'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { ChevronsLeft } from 'react-feather'; | |||||
import { useDispatch } from 'react-redux'; | import { useDispatch } from 'react-redux'; | ||||
import Switch from 'react-switch'; | import Switch from 'react-switch'; | ||||
import { | import { | ||||
useModalContext, | useModalContext, | ||||
type PushModal, | type PushModal, | ||||
} from 'lib/components/modal-provider.react.js'; | } from 'lib/components/modal-provider.react.js'; | ||||
import { | import { | ||||
Show All 23 Lines | |||||
type Props = { | type Props = { | ||||
+filterThreadInfos: $ReadOnlyArray<FilterThreadInfo>, | +filterThreadInfos: $ReadOnlyArray<FilterThreadInfo>, | ||||
+filterThreadSearchIndex: SearchIndex, | +filterThreadSearchIndex: SearchIndex, | ||||
+filteredThreadIDs: ?$ReadOnlySet<string>, | +filteredThreadIDs: ?$ReadOnlySet<string>, | ||||
+filteredCommunityThreadIDs: ?$ReadOnlySet<string>, | +filteredCommunityThreadIDs: ?$ReadOnlySet<string>, | ||||
+includeDeleted: boolean, | +includeDeleted: boolean, | ||||
+dispatch: Dispatch, | +dispatch: Dispatch, | ||||
+pushModal: PushModal, | +pushModal: PushModal, | ||||
+toggleFilters: (event: SyntheticEvent<HTMLAnchorElement>) => void, | |||||
}; | }; | ||||
type State = { | type State = { | ||||
+query: string, | +query: string, | ||||
+searchResults: $ReadOnlyArray<FilterThreadInfo>, | +searchResults: $ReadOnlyArray<FilterThreadInfo>, | ||||
+collapsed: boolean, | +collapsed: boolean, | ||||
}; | }; | ||||
class FilterPanel extends React.PureComponent<Props, State> { | class FilterPanel extends React.PureComponent<Props, State> { | ||||
state: State = { | state: State = { | ||||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | return ( | ||||
<input | <input | ||||
type="text" | type="text" | ||||
placeholder="Search" | placeholder="Search" | ||||
value={this.state.query} | value={this.state.query} | ||||
onChange={this.onChangeQuery} | onChange={this.onChangeQuery} | ||||
/> | /> | ||||
{clearQueryButton} | {clearQueryButton} | ||||
</div> | </div> | ||||
<a onClick={this.props.toggleFilters} className={css.collapseButton}> | |||||
<ChevronsLeft size={30} /> | |||||
</a> | |||||
</div> | </div> | ||||
<div className={css.filters}>{filters}</div> | <div className={css.filters}>{filters}</div> | ||||
<div className={css.extras}> | <div className={css.extras}> | ||||
<label htmlFor="include-deleted-switch"> | <label htmlFor="include-deleted-switch"> | ||||
<Switch | <Switch | ||||
checked={this.props.includeDeleted} | checked={this.props.includeDeleted} | ||||
onChange={this.onChangeIncludeDeleted} | onChange={this.onChangeIncludeDeleted} | ||||
checkedIcon={false} | checkedIcon={false} | ||||
▲ Show 20 Lines • Show All 224 Lines • ▼ Show 20 Lines | class Category extends React.PureComponent<CategoryProps> { | ||||
}; | }; | ||||
onCollapse = (event: SyntheticEvent<HTMLAnchorElement>) => { | onCollapse = (event: SyntheticEvent<HTMLAnchorElement>) => { | ||||
event.preventDefault(); | event.preventDefault(); | ||||
this.props.onCollapse(!this.props.collapsed); | this.props.onCollapse(!this.props.collapsed); | ||||
}; | }; | ||||
} | } | ||||
const ConnectedFilterPanel: React.ComponentType<{}> = React.memo<{}>( | type ConnectedFilterPanelProps = { | ||||
function ConnectedFilterPanel(): React.Node { | +toggleFilters: (event: SyntheticEvent<HTMLAnchorElement>) => void, | ||||
}; | |||||
const ConnectedFilterPanel: React.ComponentType<ConnectedFilterPanelProps> = | |||||
React.memo<ConnectedFilterPanelProps>(function ConnectedFilterPanel( | |||||
props: ConnectedFilterPanelProps, | |||||
): React.Node { | |||||
const filteredThreadIDs = useSelector(filteredThreadIDsSelector); | const filteredThreadIDs = useSelector(filteredThreadIDsSelector); | ||||
const filteredCommunityThreadIDs = useSelector( | const filteredCommunityThreadIDs = useSelector( | ||||
filterThreadIDsBelongingToCommunitySelector, | filterThreadIDsBelongingToCommunitySelector, | ||||
); | ); | ||||
const filterThreadInfos = useFilterThreadInfos(); | const filterThreadInfos = useFilterThreadInfos(); | ||||
const filterThreadSearchIndex = useFilterThreadSearchIndex(); | const filterThreadSearchIndex = useFilterThreadSearchIndex(); | ||||
const includeDeleted = useSelector(includeDeletedSelector); | const includeDeleted = useSelector(includeDeletedSelector); | ||||
const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
const modalContext = useModalContext(); | const modalContext = useModalContext(); | ||||
return ( | return ( | ||||
<FilterPanel | <FilterPanel | ||||
filteredThreadIDs={filteredThreadIDs} | filteredThreadIDs={filteredThreadIDs} | ||||
filteredCommunityThreadIDs={filteredCommunityThreadIDs} | filteredCommunityThreadIDs={filteredCommunityThreadIDs} | ||||
filterThreadInfos={filterThreadInfos} | filterThreadInfos={filterThreadInfos} | ||||
filterThreadSearchIndex={filterThreadSearchIndex} | filterThreadSearchIndex={filterThreadSearchIndex} | ||||
includeDeleted={includeDeleted} | includeDeleted={includeDeleted} | ||||
dispatch={dispatch} | dispatch={dispatch} | ||||
pushModal={modalContext.pushModal} | pushModal={modalContext.pushModal} | ||||
toggleFilters={props.toggleFilters} | |||||
/> | /> | ||||
); | ); | ||||
}, | }); | ||||
); | |||||
export default ConnectedFilterPanel; | export default ConnectedFilterPanel; |