diff --git a/frontend/app/src/people/interfaces.ts b/frontend/app/src/people/interfaces.ts index 523fe1cb5..5b9bdbc0c 100644 --- a/frontend/app/src/people/interfaces.ts +++ b/frontend/app/src/people/interfaces.ts @@ -407,6 +407,11 @@ export interface BountyHeaderProps { checkboxIdToSelectedMapLanguage: any; } +export interface PeopleHeaderProps { + onChangeLanguage: (number) => void; + checkboxIdToSelectedMapLanguage: any; +} + export interface DeleteTicketModalProps { closeModal: () => void; confirmDelete: () => void; diff --git a/frontend/app/src/people/main/Body.tsx b/frontend/app/src/people/main/Body.tsx index 195053218..2acbb32e5 100644 --- a/frontend/app/src/people/main/Body.tsx +++ b/frontend/app/src/people/main/Body.tsx @@ -3,6 +3,8 @@ import React, { useEffect, useState } from 'react'; import { useHistory } from 'react-router'; import styled from 'styled-components'; import { EuiLoadingSpinner, EuiGlobalToastList } from '@elastic/eui'; +import PeopleHeader from 'people/widgetViews/PeopleHeader'; +import { Person as PersonType } from 'store/main'; import { SearchTextInput } from '../../components/common'; import { colors } from '../../config/colors'; import { useFuse, useIsMobile, usePageScroll, useScreenWidth } from '../../hooks'; @@ -24,6 +26,7 @@ const Body = styled.div<{ isMobile: boolean }>` & > .header { display: flex; justify-content: flex-end; + gap: 8px; padding: 10px 0; } & > .content { @@ -50,6 +53,8 @@ function BodyComponent() { const [loading, setLoading] = useState(true); const screenWidth = useScreenWidth(); const [openStartUpModel, setOpenStartUpModel] = useState(false); + const [checkboxIdToSelectedMapLanguage, setCheckboxIdToSelectedMapLanguage] = useState({}); + const [filterResult, setFilterResult] = useState(main.people); const closeModal = () => setOpenStartUpModel(false); const { peoplePageNumber } = ui; const history = useHistory(); @@ -71,6 +76,16 @@ function BodyComponent() { const loadBackwardFunc = () => loadMore(-1); const { loadingBottom, handleScroll } = usePageScroll(loadForwardFunc, loadBackwardFunc); + const onChangeLanguage = (optionId: any) => { + const newCheckboxIdToSelectedMapLanguage = { + ...checkboxIdToSelectedMapLanguage, + ...{ + [optionId]: !checkboxIdToSelectedMapLanguage[optionId], + }, + }; + setCheckboxIdToSelectedMapLanguage(newCheckboxIdToSelectedMapLanguage); + }; + const toastsEl = ( { + const requiredLanguages = Object.keys(codingLanguages).filter( + (key: string) => codingLanguages[key], + ); + + return users.filter((user: PersonType) => { + const userCodingLanguages = (user.extras.coding_languages ?? []).map( + (t: { [key: string]: string }) => t.value, + ); + return requiredLanguages?.every((requiredLanguage: string) => + userCodingLanguages.includes(requiredLanguage), + ); + }); + }; + + useEffect(() => { + setFilterResult(filterByCodingLanguage(main.people, checkboxIdToSelectedMapLanguage)); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [checkboxIdToSelectedMapLanguage]); + // update search useEffect(() => { (async () => { @@ -116,6 +155,11 @@ function BodyComponent() { }} >
+ + { ui.setSearchText(e); @@ -134,7 +178,7 @@ function BodyComponent() { />
- {(people ?? []).map((t: any) => ( + {(ui.searchText ? people : filterResult).map((t: any) => ( ))} - {!people.length && } + {!(ui.searchText ? people : filterResult)?.length && }
diff --git a/frontend/app/src/people/widgetViews/PeopleHeader.tsx b/frontend/app/src/people/widgetViews/PeopleHeader.tsx new file mode 100644 index 000000000..bbd7a0506 --- /dev/null +++ b/frontend/app/src/people/widgetViews/PeopleHeader.tsx @@ -0,0 +1,247 @@ +import styled from 'styled-components'; +import { PeopleHeaderProps } from 'people/interfaces'; +import { observer } from 'mobx-react-lite'; +import React, { useState, useEffect } from 'react'; +import { EuiCheckboxGroup, EuiPopover, EuiText } from '@elastic/eui'; +import MaterialIcon from '@material/react-material-icon'; +import { colors } from 'config'; +import { filterCount } from 'people/utils/ExtraFunctions'; +import { GetValue, coding_languages } from '../utils/languageLabelStyle'; + +interface styledProps { + color?: any; +} + +const FilterWrapper = styled.div` + display: flex; + align-items: center; + gap: 4px; +`; + +const FilterTrigger = styled.div` + width: 78px; + height: 48px; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + margin-left: 19px; + cursor: pointer; + user-select: none; + .filterImageContainer { + display: flex; + justify-content: center; + align-items: center; + height: 48px; + width: 36px; + .materialIconImage { + color: ${(p: any) => p.color && p.color.grayish.G200}; + cursor: pointer; + font-size: 18px; + margin-top: 4px; + } + } + .filterText { + font-family: 'Barlow'; + font-style: normal; + font-weight: 500; + font-size: 16px; + line-height: 19px; + display: flex; + align-items: center; + color: ${(p: any) => p.color && p.color.grayish.G200}; + } + &:hover { + .filterImageContainer { + .materialIconImage { + color: ${(p: any) => p.color && p.color.grayish.G50} !important; + cursor: pointer; + font-size: 18px; + margin-top: 4px; + } + } + .filterText { + color: ${(p: any) => p.color && p.color.grayish.G50}; + } + } + &:active { + .filterImageContainer { + .materialIconImage { + color: ${(p: any) => p.color && p.color.grayish.G10} !important; + cursor: pointer; + font-size: 18px; + margin-top: 4px; + } + } + .filterText { + color: ${(p: any) => p.color && p.color.grayish.G10}; + } + } +`; + +const FilterCount = styled.div` + height: 20px; + width: 20px; + border-radius: 50%; + margin-left: 4px; + display: flex; + justify-content: center; + align-items: center; + margin-top: -5px; + background: ${(p: any) => p?.color && p.color.blue1}; + .filterCountText { + font-family: 'Barlow'; + font-style: normal; + font-weight: 500; + font-size: 13px; + display: flex; + align-items: center; + text-align: center; + color: ${(p: any) => p.color && p.color.pureWhite}; + } +`; + +const PopOverBox = styled.div` + display: flex; + flex-direction: column; + max-height: 304px; + padding: 15px 0px 20px 21px; + .rightBoxHeading { + font-family: 'Barlow'; + font-style: normal; + font-weight: 700; + font-size: 12px; + line-height: 32px; + text-transform: uppercase; + color: ${(p: any) => p.color && p.color.grayish.G100}; + } +`; + +const EuiPopOverCheckboxWrapper = styled.div` + min-width: 285px; + max-width: 285px; + height: 240px; + user-select: none; + + &.CheckboxOuter > div { + height: 100%; + display: grid; + grid-template-columns: 1fr 1fr; + justify-content: center; + .euiCheckboxGroup__item { + .euiCheckbox__square { + top: 5px; + border: 1px solid ${(p: any) => p?.color && p?.color?.grayish.G500}; + border-radius: 2px; + } + .euiCheckbox__input + .euiCheckbox__square { + background: ${(p: any) => p?.color && p?.color?.pureWhite} no-repeat center; + } + .euiCheckbox__input:checked + .euiCheckbox__square { + border: 1px solid ${(p: any) => p?.color && p?.color?.blue1}; + background: ${(p: any) => p?.color && p?.color?.blue1} no-repeat center; + background-image: url('static/checkboxImage.svg'); + } + .euiCheckbox__label { + font-family: 'Barlow'; + font-style: normal; + font-weight: 500; + font-size: 13px; + line-height: 16px; + color: ${(p: any) => p?.color && p?.color?.grayish.G50}; + &:hover { + color: ${(p: any) => p?.color && p?.color?.grayish.G05}; + } + } + input.euiCheckbox__input:checked ~ label { + color: ${(p: any) => p?.color && p?.color?.blue1}; + } + } + } +`; + +const Coding_Languages = GetValue(coding_languages); + +const PeopleHeader = ({ onChangeLanguage, checkboxIdToSelectedMapLanguage }: PeopleHeaderProps) => { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const [filterCountNumber, setFilterCountNumber] = useState(0); + const onToggleButton = () => setIsPopoverOpen((prev: boolean) => !prev); + const closePopover = () => setIsPopoverOpen(false); + const color = colors['light']; + + useEffect(() => { + setFilterCountNumber(filterCount(checkboxIdToSelectedMapLanguage)); + }, [checkboxIdToSelectedMapLanguage]); + + const panelStyles = { + border: 'none', + boxShadow: `0px 1px 20px ${color.black90}`, + background: `${color.pureWhite}`, + borderRadius: '6px', + minWidth: '300px', + minHeight: '304px', + marginTop: '0px', + marginLeft: '20px', + }; + + return ( + + +
+ +
+ + Filter + + + } + panelStyle={panelStyles} + isOpen={isPopoverOpen} + closePopover={closePopover} + panelClassName="yourClassNameHere" + panelPaddingSize="none" + anchorPosition="downLeft" + > +
+ + Skills + + { + onChangeLanguage(id); + }} + /> + + +
+
+ {filterCountNumber > 0 && ( + + {filterCountNumber} + + )} +
+ ); +}; + +export default observer(PeopleHeader);