-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feat] technology filter functionality #85
Changes from all commits
93f6f67
9c1dca3
6468f17
5f7bd30
0116ffa
eb902a1
37eee59
70a37f9
2da013d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,29 +56,70 @@ export default function MapViewScreen({ | |
projectSize: { min: 0, max: 0 }, | ||
location: [], | ||
}); | ||
const [filteredProjectsFromDropdowns, setFilteredProjectsFromDropdowns] = | ||
useState<Project[]>(projects); | ||
|
||
const handleFilterChange = (filter: FilterType) => { | ||
console.log(filter); | ||
const [filteredProjectsFromSearch, setFilteredProjectsFromSearch] = | ||
useState<Project[]>(projects); | ||
|
||
// clear filters | ||
const clearFilters = () => { | ||
setSelectedFilters({ | ||
status: [], | ||
technology: [], | ||
projectSize: { min: 0, max: 0 }, | ||
location: [], | ||
}); | ||
setFilteredProjects(projects); | ||
setFilteredProjectsFromDropdowns(projects); | ||
}; | ||
|
||
// show projects based on selected filters | ||
const handleFilterButtonClick = () => { | ||
/* eslint-disable @typescript-eslint/no-unused-vars */ | ||
const { status, technology, projectSize, location } = selectedFilters; | ||
// add all filtering logic here | ||
const technologyProjects = projects?.filter(project => | ||
technology.includes(project.renewable_energy_technology), | ||
); | ||
setFilteredProjectsFromDropdowns(technologyProjects); | ||
}; | ||
|
||
// search within all projects or filtered projects from dropdowns | ||
useEffect(() => { | ||
let filtered: Project[] = []; | ||
filtered = | ||
projects?.filter(project => | ||
let projectsToSearch: Project[] = []; | ||
|
||
if (filteredProjectsFromDropdowns.length > 0) { | ||
projectsToSearch = filteredProjectsFromDropdowns; | ||
} else { | ||
projectsToSearch = projects; | ||
} | ||
|
||
const searchedProjects: Project[] = | ||
projectsToSearch?.filter(project => | ||
Comment on lines
+90
to
+99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can filters be applied after a search is made? In that case, would it make sense to search then filter? I wonder if there's a way to treat "search" similar to a filter criteria. Each filter would then be applied sequentially in the order they're selected. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The way that I've implemented it allows for filtering after a search is made! I think it does make sense to search then filter? For example, if someone wanted to checkout a project that has a common word "north", "south", etc. and then wanted to filter by dropdowns. This is probably a niche, rare use case but the way that the filtering is implemented allows for search then filter and filter then search to produce the same outputs in the project modal. Do you mind explaining your idea of sequentially applying filters? I'm not quite sure I understand how the projects would be rendered differently. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok it seems that the implementation already works as intended then. I was just curious about the ordering that filters are applied, because it could affect performance. For example, if you wish to search for "north" and filter by "hydroelectric," it might make sense to filter first then search, because depending on the search implementation, I imagine search would be an asymptotically slower operation (??), and thus better to perform on a smaller subset of projects. The more I think about it, this is entirely dependent on search logic and how project data is stored, which I don't have much context on. Just something to consider! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with Ronnie. We should filter --> search. Every time the user types a letter to search we are searching based on what the user has typed so far, so I think it would be better to search on a smaller subset. @ethan-tam33 can you adjust your sprint to filter then search? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm are you both suggesting that we prevent any searching until the user clicks on at least one filter? Regarding the time complexity of searching, I believe the way that we have set it up has filtering for search and dropdown filters to have the same complexity. We're iterating over each project and checking if it includes the search term or is included in the dropdown filters. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see that search isn't very complex in this case. Although I think the reason I bring this up is based off the main There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ohh ok I see what you are saying! I agree that we should do this for filters part of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For now, just squash and merge your sprint so that I can check everything works smoothly for this week's sprints. We can sort this out another time. |
||
project.project_name.toLowerCase().includes(searchTerm.toLowerCase()), | ||
) ?? null; | ||
) ?? []; | ||
|
||
setFilteredProjects(filtered); | ||
}, [projects, searchTerm, setFilteredProjects]); | ||
setFilteredProjectsFromSearch(searchedProjects); | ||
}, [projects, searchTerm, filteredProjectsFromDropdowns]); | ||
|
||
useEffect(() => { | ||
setFilteredProjects(filteredProjectsFromDropdowns); | ||
}, [filteredProjectsFromDropdowns, setFilteredProjects]); | ||
|
||
useEffect(() => { | ||
setFilteredProjects(filteredProjectsFromSearch); | ||
}, [filteredProjectsFromSearch, setFilteredProjects]); | ||
|
||
return ( | ||
<> | ||
<SearchBar searchTerm={searchTerm} setSearchTerm={setSearchTerm} /> | ||
<FilterBar | ||
filters={filters} | ||
onFilterChange={handleFilterChange} | ||
selectedFilters={selectedFilters} | ||
setSelectedFilters={setSelectedFilters} | ||
handleFilterButtonClick={handleFilterButtonClick} | ||
clearFilters={clearFilters} | ||
/> | ||
<Map | ||
projects={projects} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,6 +72,12 @@ export const ButtonWithIconStyles = styled.div` | |
cursor: pointer; | ||
`; | ||
|
||
export const FilterIconStyles = styled.div` | ||
display: flex; | ||
align-items: center; | ||
flex-direction: row; | ||
`; | ||
Comment on lines
+75
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Any chance the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm previously only |
||
|
||
export const IconStyles = styled.div` | ||
width: '3rem', | ||
height: '3rem', | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unsure how these are used to filter projects. Perhaps we could setup the logic for filtering by all criteria (built in a way that would allow us to add/remove filters). For each project, we'd need to check that each selected feature is satisfied.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh I see, that's a good idea! I made the filters under the impression that they wouldn't need to be changed, but I agree that making the logic more flexible would be better in the long run.
The way filtering works currently is that I have a pre-defined object of possible filters (
selectedFilters
) that the projects can filter through within thehandleFilterButtonClick
method.selectedFilters
gets updated every time a new filter is applied or un-applied. Is there anything specifically you would want me clarify?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just wanted to make sure all filters were being used. It seems that the current implementation hardcodes filtering according to the
technology
criteria. For flexibility purposes, we could iterate over all attributes of theselectedFilters
object in a way that is agnostic to what the filters actually are.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh I see, I think I'm doing that? The
technology
variable in line 80 is just a list that holds a bunch of strings (or is empty). Then line 82 filters all the projects by checking if itsrenewable_energy_technology
attribute is within thistechnology
list, without caring about specific values. Is this what you mean about not hardcoding the attributes?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess, given that this PR is only for the technology filter, your implementation suffices. I was just curious if there was a way to iterate over the
selectedFilters
object so we could easily implementstatus
,projectSize
, andlocation
filters as well. However doing so in a way where each filter is it's own function/reducer that, when applied to a given row, can immediately determine whether it belongs in the output. Does that make sense? It might not be necessary for this implementation, but it's one possible approach.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh I see now, you're referring to the general filters. I think we can definitely do that and it makes sense to do so- this probably will involve some mapping of the filters to the project attributes in question. And then the method can just do an agnostic loop over that mapping to filter the projects. Thanks Ronnie! I'll adjust my PR for this.