Changeset View
Changeset View
Standalone View
Standalone View
web/calendar/filter-panel.react.js
Show All 13 Lines | |||||
import { | import { | ||||
useModalContext, | useModalContext, | ||||
type PushModal, | type PushModal, | ||||
} from 'lib/components/modal-provider.react'; | } from 'lib/components/modal-provider.react'; | ||||
import { | import { | ||||
filteredThreadIDsSelector, | filteredThreadIDsSelector, | ||||
includeDeletedSelector, | includeDeletedSelector, | ||||
filteredCommunityThreadIDsSelector, | |||||
} from 'lib/selectors/calendar-filter-selectors'; | } from 'lib/selectors/calendar-filter-selectors'; | ||||
import SearchIndex from 'lib/shared/search-index'; | import SearchIndex from 'lib/shared/search-index'; | ||||
import { | import { | ||||
calendarThreadFilterTypes, | calendarThreadFilterTypes, | ||||
type FilterThreadInfo, | type FilterThreadInfo, | ||||
updateCalendarThreadFilter, | updateCalendarThreadFilter, | ||||
clearCalendarThreadFilter, | clearCalendarThreadFilter, | ||||
setCalendarDeletedFilter, | setCalendarDeletedFilter, | ||||
updateCalendarCommunityFilter, | |||||
clearCalendarCommunityFilter, | |||||
} from 'lib/types/filter-types'; | } from 'lib/types/filter-types'; | ||||
import type { Dispatch } from 'lib/types/redux-types'; | import type { Dispatch } from 'lib/types/redux-types'; | ||||
import ThreadSettingsModal from '../modals/threads/settings/thread-settings-modal.react'; | import ThreadSettingsModal from '../modals/threads/settings/thread-settings-modal.react'; | ||||
import { useSelector } from '../redux/redux-utils'; | import { useSelector } from '../redux/redux-utils'; | ||||
import { | import { | ||||
webFilterThreadInfos, | webFilterThreadInfos, | ||||
webFilterThreadSearchIndex, | webFilterThreadSearchIndex, | ||||
} from '../selectors/calendar-selectors'; | } from '../selectors/calendar-selectors'; | ||||
import { MagnifyingGlass } from '../vectors.react'; | import { MagnifyingGlass } from '../vectors.react'; | ||||
import css from './filter-panel.css'; | import css from './filter-panel.css'; | ||||
type Props = { | type Props = { | ||||
+filterThreadInfos: () => $ReadOnlyArray<FilterThreadInfo>, | +filterThreadInfos: () => $ReadOnlyArray<FilterThreadInfo>, | ||||
+filterThreadSearchIndex: () => SearchIndex, | +filterThreadSearchIndex: () => SearchIndex, | ||||
+filteredThreadIDs: ?$ReadOnlySet<string>, | +filteredThreadIDs: ?$ReadOnlySet<string>, | ||||
+filteredCommunityThreadIDs: ?$ReadOnlySet<string>, | |||||
+includeDeleted: boolean, | +includeDeleted: boolean, | ||||
+dispatch: Dispatch, | +dispatch: Dispatch, | ||||
+pushModal: PushModal, | +pushModal: PushModal, | ||||
}; | }; | ||||
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 = { | ||||
query: '', | query: '', | ||||
searchResults: [], | searchResults: [], | ||||
collapsed: false, | collapsed: false, | ||||
}; | }; | ||||
currentlySelected(threadID: string): boolean { | currentlySelected(threadID: string): boolean { | ||||
if (!this.props.filteredThreadIDs) { | if (!this.props.filteredThreadIDs) { | ||||
return true; | return true; | ||||
} | } | ||||
return this.props.filteredThreadIDs.has(threadID); | return this.props.filteredThreadIDs.has(threadID); | ||||
} | } | ||||
inCurrentCommunity(threadID: string): boolean { | |||||
if (!this.props.filteredCommunityThreadIDs) { | |||||
return true; | |||||
} | |||||
return this.props.filteredCommunityThreadIDs.has(threadID); | |||||
} | |||||
render() { | render() { | ||||
const filterThreadInfos = this.state.query | let filterThreadInfos = this.state.query | ||||
? this.state.searchResults | ? this.state.searchResults | ||||
: this.props.filterThreadInfos(); | : this.props.filterThreadInfos(); | ||||
filterThreadInfos = filterThreadInfos.filter(item => | |||||
this.inCurrentCommunity(item.threadInfo.id), | |||||
); | |||||
let filters = []; | let filters = []; | ||||
if (!this.state.query || filterThreadInfos.length > 0) { | if (!this.state.query || filterThreadInfos.length > 0) { | ||||
filters.push( | filters.push( | ||||
<Category | <Category | ||||
numThreads={filterThreadInfos.length} | numThreads={filterThreadInfos.length} | ||||
onToggle={this.onToggleAll} | onToggle={this.onToggleAll} | ||||
collapsed={this.state.collapsed} | collapsed={this.state.collapsed} | ||||
▲ Show 20 Lines • Show All 134 Lines • ▼ Show 20 Lines | onChangeQuery = (event: SyntheticEvent<HTMLInputElement>) => { | ||||
const results = this.props | const results = this.props | ||||
.filterThreadInfos() | .filterThreadInfos() | ||||
.filter(filterThreadInfo => | .filter(filterThreadInfo => | ||||
resultIDs.has(filterThreadInfo.threadInfo.id), | resultIDs.has(filterThreadInfo.threadInfo.id), | ||||
); | ); | ||||
this.setState({ query, searchResults: results, collapsed: false }); | this.setState({ query, searchResults: results, collapsed: false }); | ||||
}; | }; | ||||
onSetCommunity = (communityID: string) => { | |||||
const threadIDs = this.props | |||||
.filterThreadInfos() | |||||
.filter( | |||||
thread => | |||||
thread.threadInfo.community === communityID || | |||||
thread.threadInfo.id === communityID, | |||||
) | |||||
.map(item => item.threadInfo.id); | |||||
this.props.dispatch({ | |||||
type: updateCalendarCommunityFilter, | |||||
payload: { | |||||
type: calendarThreadFilterTypes.COMMUNITY, | |||||
threadIDs, | |||||
}, | |||||
}); | |||||
}; | |||||
onResetCommunity = () => { | |||||
this.props.dispatch({ | |||||
type: clearCalendarCommunityFilter, | |||||
}); | |||||
}; | |||||
clearQuery = (event: SyntheticEvent<HTMLAnchorElement>) => { | clearQuery = (event: SyntheticEvent<HTMLAnchorElement>) => { | ||||
event.preventDefault(); | event.preventDefault(); | ||||
this.setState({ query: '', searchResults: [], collapsed: false }); | this.setState({ query: '', searchResults: [], collapsed: false }); | ||||
}; | }; | ||||
onCollapse = (value: boolean) => { | onCollapse = (value: boolean) => { | ||||
this.setState({ collapsed: value }); | this.setState({ collapsed: value }); | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | 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<{}>( | const ConnectedFilterPanel: React.ComponentType<{}> = React.memo<{}>( | ||||
function ConnectedFilterPanel(): React.Node { | function ConnectedFilterPanel(): React.Node { | ||||
const filteredThreadIDs = useSelector(filteredThreadIDsSelector); | const filteredThreadIDs = useSelector(filteredThreadIDsSelector); | ||||
const filteredCommunityThreadIDs = useSelector( | |||||
filteredCommunityThreadIDsSelector, | |||||
); | |||||
const filterThreadInfos = useSelector(webFilterThreadInfos); | const filterThreadInfos = useSelector(webFilterThreadInfos); | ||||
const filterThreadSearchIndex = useSelector(webFilterThreadSearchIndex); | const filterThreadSearchIndex = useSelector(webFilterThreadSearchIndex); | ||||
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} | |||||
filterThreadInfos={filterThreadInfos} | filterThreadInfos={filterThreadInfos} | ||||
filterThreadSearchIndex={filterThreadSearchIndex} | filterThreadSearchIndex={filterThreadSearchIndex} | ||||
includeDeleted={includeDeleted} | includeDeleted={includeDeleted} | ||||
dispatch={dispatch} | dispatch={dispatch} | ||||
pushModal={modalContext.pushModal} | pushModal={modalContext.pushModal} | ||||
/> | /> | ||||
); | ); | ||||
}, | }, | ||||
); | ); | ||||
export default ConnectedFilterPanel; | export default ConnectedFilterPanel; |