Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

changes for #15 #618

Merged
merged 7 commits into from
Jul 28, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 48 additions & 25 deletions client/src/components/FiltersSideMenu/filters.js
Original file line number Diff line number Diff line change
@@ -21,9 +21,8 @@ import utilityStyles from "../../styles/utility.module.css";
* locations: the values for the location filter options
* achievements: the values for the achievements filter options
*/
export default function SearchTabFilters({ locations, achievements }) {
export default function SearchTabFilters({ achievements }) {
const search = useSearch();
const [locationsData, setLocationsData] = useState(locations);
const [achievementsData, setAchievementsData] = useState(achievements);

/**
@@ -49,9 +48,8 @@ export default function SearchTabFilters({ locations, achievements }) {
};

useEffect(() => {
setLocationsData(locations);
setAchievementsData(achievements);
}, [locations, achievements]);
}, [achievements]);

const filterData = (query, initialValues, property, setState) => {
const q = query.toLowerCase();
@@ -134,6 +132,32 @@ export default function SearchTabFilters({ locations, achievements }) {
}
};

const addLocationToFilter = (location) => {
const locationFilters = JSON.parse(
JSON.stringify(search.selectedLocations)
);

if (locationFilters.findIndex((s) => s.id === location.id) !== -1) {
return;
}
locationFilters.push({ name: location.value, id: location.id });
search["selectLocations"](locationFilters);
};

const removeLocationFromFilter = (location) => {
const locationFilters = JSON.parse(
JSON.stringify(search.selectedLocations)
);
const index = locationFilters.findIndex((s) => s.id === location.id);

if (index === -1) {
return;
}

locationFilters.splice(index, 1);
search["selectLocations"](locationFilters);
};

const addSkillToFilter = (skill) => {
const skillFilters = JSON.parse(JSON.stringify(search.selectedSkills));

@@ -230,27 +254,27 @@ export default function SearchTabFilters({ locations, achievements }) {
/>
{search.isFilterActive(FILTERS.LOCATIONS) && (
<div className={utilityStyles.mt32}>
<Collapsible
onCollapsed={(isCollapsed) =>
filterData("", locations, "name", setLocationsData)
}
title="Location"
collapsed={false}
>
<SearchBox
placeholder="Search for a location"
name={"location search"}
onChange={(q) =>
filterData(q.trim(), locations, "name", setLocationsData)
}
/>
<TagList
key="l"
tags={locationsData}
selected={search.selectedLocations}
selector={"selectLocations"}
noResultsText={"No location found"}
<Collapsible title="Location">
<SuggestionBox
placeholder={"Search for a location"}
onSelect={addLocationToFilter}
purpose="locations"
companyAttrId={search.getAttributeId(FILTERS.LOCATIONS)}
/>
{search.selectedLocations.length > 0 && (
<div className={utilityStyles.mt16}>
{search.selectedLocations.map((location) => {
return (
<Pill
key={location.id}
name={location.name}
removable={true}
onRemove={() => removeLocationFromFilter(location)}
/>
);
})}
</div>
)}
</Collapsible>
</div>
)}
@@ -334,7 +358,6 @@ export default function SearchTabFilters({ locations, achievements }) {
}

SearchTabFilters.propTypes = {
locations: PT.array,
achievements: PT.array,
};

5 changes: 2 additions & 3 deletions client/src/components/FiltersSideMenu/index.jsx
Original file line number Diff line number Diff line change
@@ -4,15 +4,14 @@ import PT from "prop-types";
import style from "./style.module.scss";
import SearchTabFilters from "./filters";

export default function FiltersSideMenu({ locations, achievements }) {
export default function FiltersSideMenu({ achievements }) {
return (
<div className={style.container}>
<SearchTabFilters locations={locations} achievements={achievements} />
<SearchTabFilters achievements={achievements} />
</div>
);
}

FiltersSideMenu.propTypes = {
locations: PT.array.isRequired,
achievements: PT.array.isRequired,
};
9 changes: 9 additions & 0 deletions client/src/components/SuggestionBox/index.jsx
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ import config from "../../config";
import api from "../../services/api";
import style from "./style.module.scss";
import _ from "lodash";
import { useSearch, FILTERS } from "../../lib/search";

const NO_RESULTS_FOUND = "no results found";
const DELAY_SEARCH = 300;
@@ -95,13 +96,19 @@ export default function SuggestionBox({
placeholder,
onSelect,
}) {
const search = useSearch();
const apiClient = api();
const [suggestions, setSuggestions] = React.useState([]);
const [value, setValue] = React.useState("");

const onChange = (event, { newValue }) => setValue(newValue.trim());

const onSuggestionsFetchRequested = async ({ value }) => {
if (purpose === "locations") {
if (!companyAttrId) {
companyAttrId = search.getAttributeId(FILTERS.LOCATIONS);
}
}
if (purpose === "skills") {
let data = await getSkillsSuggestions(apiClient, value);

@@ -128,6 +135,8 @@ export default function SuggestionBox({
const onSuggestionSelected = (event, { suggestion }) => {
if (purpose === "skills") {
if (suggestion.name !== NO_RESULTS_FOUND) onSelect(suggestion);
} else if (purpose === "locations") {
if (suggestion.name !== NO_RESULTS_FOUND) onSelect(suggestion);
} else {
if (suggestion.name !== NO_RESULTS_FOUND)
onSelect(companyAttrId, suggestion);
16 changes: 12 additions & 4 deletions client/src/lib/company-attributes.js
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ let primaryAttributeIds = [
* Get the attributes associated with the company (organization)
* @param {Object} apiClient The api client (you can get this from src/services/api and then call api() to get the apiClient)
*/
export async function getCompanyAttributes(apiClient, cancelToken) {
export async function getAttributes(apiClient, cancelToken) {
let response;
let attributeGroups;
let attributes = [];
@@ -70,14 +70,22 @@ export async function getCompanyAttributes(apiClient, cancelToken) {
}
}

// Finally, we only need the company attributes
attributes = attributes.filter((attribute) => {
// Finally, split 2 attribute types
const companyAttrs = attributes.filter((attribute) => {
if (primaryAttributeIds.includes(attribute.name)) {
return false;
}

return true;
});

return attributes;
const generalAttrs = attributes.filter((attribute) => {
if (primaryAttributeIds.includes(attribute.name)) {
return true;
}

return false;
});

return [companyAttrs, generalAttrs];
}
10 changes: 10 additions & 0 deletions client/src/lib/search.js
Original file line number Diff line number Diff line change
@@ -66,6 +66,14 @@ function useProvideSearch() {
setPopupShown(true);
};

const setFilter = (id, filter) => {
return (filters[id] = filter);
};

const getAttributeId = (filter) => {
return filters[filter].id;
};

const isFilterActive = (filter) => {
return filters[filter].active;
};
@@ -132,7 +140,9 @@ function useProvideSearch() {
popupShown,
showPopup,
filters,
setFilter,
setFilters,
getAttributeId,
isFilterActive,
activateFilter,
deactivateFilter,
32 changes: 21 additions & 11 deletions client/src/pages/Search/Global.jsx
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ import Pagination from "../../components/Pagination";

import * as helper from "./helper";
import { useAuth0 } from "../../react-auth0-spa";
import { getCompanyAttributes } from "../../lib/company-attributes";
import { getAttributes } from "../../lib/company-attributes";
import { useSearch, FILTERS } from "../../lib/search";
import { makeColorIterator, avatarColors } from "../../lib/colors";
import config from "../../config";
@@ -50,7 +50,6 @@ export default function SearchGlobal({ keyword }) {
const apiClient = api();
const searchContext = useSearch();
const [isSearching, setIsSearching] = React.useState(false);
const [locations, setLocations] = React.useState([]);
const [achievements, setAchievements] = React.useState([]);
const [users, setUsers] = React.useState([]);
const [page, setPage] = React.useState(1);
@@ -85,11 +84,9 @@ export default function SearchGlobal({ keyword }) {
let isSubscribed = true;

(async () => {
const locations = await staticData.getLocations();
const achievements = await staticData.getAchievements();

if (isSubscribed) {
setLocations(locations);
setAchievements(achievements);
}
})();
@@ -107,7 +104,7 @@ export default function SearchGlobal({ keyword }) {
let isSubscribed = true;

(async () => {
const companyAttrs = await getCompanyAttributes(
const [companyAttrs, generalAttrs] = await getAttributes(
apiClient,
cancelTokenSource.token
);
@@ -125,6 +122,17 @@ export default function SearchGlobal({ keyword }) {
searchContext.setFilters(filtersWithCompanyAttrs);
}
}
if (generalAttrs) {
generalAttrs.forEach((generalAttr) => {
if (generalAttr.name === config.STANDARD_USER_ATTRIBUTES.location) {
filtersWithCompanyAttrs[FILTERS.LOCATIONS].id = generalAttr.id;
searchContext.setFilter(
FILTERS.LOCATIONS,
filtersWithCompanyAttrs[FILTERS.LOCATIONS]
);
}
});
}
})();

return () => {
@@ -145,7 +153,7 @@ export default function SearchGlobal({ keyword }) {
searchContext.filters[FILTERS.LOCATIONS].active &&
searchContext.selectedLocations.length > 0
) {
criteria.locations = searchContext.selectedLocations;
criteria.locations = searchContext.selectedLocations.map((l) => l.name);
}
if (
searchContext.filters[FILTERS.SKILLS].active &&
@@ -209,10 +217,12 @@ export default function SearchGlobal({ keyword }) {
pageChanged = true;
}

if (_.isEqual(prevCriteria, criteria)
&& prevKeyword === keyword
&& prevOrderBy === orderBy
&& pageChanged === false) {
if (
_.isEqual(prevCriteria, criteria) &&
prevKeyword === keyword &&
prevOrderBy === orderBy &&
pageChanged === false
) {
return;
} else {
setPrevCriteria(criteria);
@@ -302,7 +312,7 @@ export default function SearchGlobal({ keyword }) {
return (
<>
<div className={style.sideMenu}>
<FiltersSideMenu locations={locations} achievements={achievements} />
<FiltersSideMenu achievements={achievements} />
</div>
{!isSearching && users.length > 0 && (
<div className={style.rightSide}>
34 changes: 0 additions & 34 deletions client/src/services/static-data.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,3 @@
async function getLocations() {
const mockLocationTags = [
{ name: "London" },
{ name: "New York" },
{ name: "East Carmen" },
{ name: "Savanahville" },
{ name: "Lake Audra" },
{ name: "Elainaville" },
{ name: "Howellstad" },
{ name: "West Reneefort" },
{ name: "Vanside" },
{ name: "East Jonatan" },
{ name: "Gottliebton" },
{ name: "Ervinchester" },
{ name: "Matteoburgh" },
{ name: "Curtmouth" },
{ name: "North Raphaelleton" },
{ name: "Laishaside" },
{ name: "West Trystanmouth" },
{ name: "West Torrey" },
{ name: "Abernathystad" },
{ name: "Danland" },
{ name: "Lednertown" },
{ name: "Athenamouth" },
{ name: "North Abagailport" },
{ name: "North Andres" },
{ name: "New Herbert" },
{ name: "Bergstrombury" },
{ name: "West Santinoside" },
];
return mockLocationTags;
}

async function getAchievements() {
const mockAchievementsTags = [
{ name: "Informatika" },
@@ -42,6 +9,5 @@ async function getAchievements() {
}

export default {
getLocations,
getAchievements,
};