Changeset View
Changeset View
Standalone View
Standalone View
web/calendar/filter-panel.react.js
Show All 30 Lines | |||||
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 { | ||||
useFilterThreadInfos, | useFilterThreadInfos, | ||||
useFilterThreadSearchIndex, | useFilterThreadSearchIndex, | ||||
} from '../selectors/calendar-selectors'; | } from '../selectors/calendar-selectors'; | ||||
import { filteredCommunityThreadIDsSelector } from '../selectors/thread-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); | |||||
tomek: This can be simplified, but you don't have to do that if you think that the simplified version… | |||||
inkaAuthorUnsubmitted Done Inline ActionsI'd prefer to keep it as it is. It's also consistent with the function right above. inka: I'd prefer to keep it as it is. It's also consistent with the function right above. | |||||
} | |||||
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), | |||||
); | |||||
tomekUnsubmitted Not Done Inline ActionsMutating a variable is usually reducing the maintainability. Can we avoid this by introducing a new name instead of reassigning? tomek: Mutating a variable is usually reducing the maintainability. Can we avoid this by introducing a… | |||||
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} | ||||
onCollapse={this.onCollapse} | onCollapse={this.onCollapse} | ||||
selected={!this.props.filteredThreadIDs} | selected={ | ||||
!this.props.filteredThreadIDs || | |||||
this.props.filteredThreadIDs.size === | |||||
this.props.filteredCommunityThreadIDs?.size | |||||
} | |||||
inkaAuthorUnsubmitted Done Inline ActionsWe want the square next to the "Your chats" button to be filled when all chats from the picked community are selected. Not only when all chats the user is a member of are selected. inka: We want the square next to the "Your chats" button to be filled when all chats from the picked… | |||||
kamilUnsubmitted Not Done Inline ActionsCould you amend this to the test plan? kamil: Could you amend this to the test plan? | |||||
key="all" | key="all" | ||||
/>, | />, | ||||
); | ); | ||||
} else { | } else { | ||||
filters.push( | filters.push( | ||||
<div className={css.noResults} key="noResults"> | <div className={css.noResults} key="noResults"> | ||||
No results | No results | ||||
</div>, | </div>, | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | onToggle = (threadID: string, value: boolean) => { | ||||
} else { | } else { | ||||
// Thread filter exists and thread is being added | // Thread filter exists and thread is being added | ||||
newThreadIDs = [...selectedThreadIDs, threadID]; | newThreadIDs = [...selectedThreadIDs, threadID]; | ||||
} | } | ||||
this.setFilterThreads(newThreadIDs); | this.setFilterThreads(newThreadIDs); | ||||
}; | }; | ||||
onToggleAll = (value: boolean) => { | onToggleAll = (value: boolean) => { | ||||
this.setFilterThreads(value ? null : []); | const allChats = this.props.filteredCommunityThreadIDs | ||||
? Array.from(this.props.filteredCommunityThreadIDs) | |||||
: null; | |||||
inkaAuthorUnsubmitted Done Inline ActionsWhen a community is picked, we want pressing the "Your chats" button to pick / unpick only chats from this community inka: When a community is picked, we want pressing the "Your chats" button to pick / unpick only… | |||||
this.setFilterThreads(value ? allChats : []); | |||||
tomekUnsubmitted Not Done Inline ActionsWe can optimize this a bit by avoiding the conversion to an array when the value is not being used (when !value) tomek: We can optimize this a bit by avoiding the conversion to an array when the value is not being… | |||||
}; | }; | ||||
onClickOnly = (threadID: string) => { | onClickOnly = (threadID: string) => { | ||||
this.setFilterThreads([threadID]); | this.setFilterThreads([threadID]); | ||||
}; | }; | ||||
setFilterThreads(threadIDs: ?$ReadOnlyArray<string>) { | setFilterThreads(threadIDs: ?$ReadOnlyArray<string>) { | ||||
if (!threadIDs) { | if (!threadIDs) { | ||||
▲ Show 20 Lines • Show All 165 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 = 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} | |||||
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; |
This can be simplified, but you don't have to do that if you think that the simplified version is less readable