diff --git a/__tests__/shared/components/challenge-listing/Filters/FiltersSwitch.jsx b/__tests__/shared/components/challenge-listing/Filters/FiltersSwitch.jsx deleted file mode 100644 index 8e27a3f8ac..0000000000 --- a/__tests__/shared/components/challenge-listing/Filters/FiltersSwitch.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import FiltersSwitch from 'components/challenge-listing/Filters/FiltersSwitch'; - -import { JU } from 'topcoder-react-utils'; - -const onSwitch = jest.fn(); - -const mockDatas = [{ - active: false, - filtersCount: 0, - onSwitch, - className: 'name', -}, { - active: true, - filtersCount: 5, - onSwitch, - className: 'name', -}]; - -test('Matches shallow shapshot', () => { - mockDatas.forEach(data => JU.shallowSnapshot()); -}); - -test('handle events', () => { - const dom = JU.renderDom(); - const matches = JU.findInDomByClass(dom, 'tc-outline-btn'); - JU.simulate.click(matches); - expect(onSwitch).toHaveBeenCalledTimes(1); -}); diff --git a/__tests__/shared/components/challenge-listing/Filters/__snapshots__/ChallengeSearchBar.jsx.snap b/__tests__/shared/components/challenge-listing/Filters/__snapshots__/ChallengeSearchBar.jsx.snap index aacf12eafc..bec9762b66 100644 --- a/__tests__/shared/components/challenge-listing/Filters/__snapshots__/ChallengeSearchBar.jsx.snap +++ b/__tests__/shared/components/challenge-listing/Filters/__snapshots__/ChallengeSearchBar.jsx.snap @@ -2,86 +2,72 @@ exports[`Matches shallow shapshot 1`] = `
- + + + +
+ `; exports[`Matches shallow shapshot 2`] = `
- + + + +
+ `; diff --git a/__tests__/shared/components/challenge-listing/Filters/__snapshots__/FiltersPanel.jsx.snap b/__tests__/shared/components/challenge-listing/Filters/__snapshots__/FiltersPanel.jsx.snap index 7b3c253c41..5297459e04 100644 --- a/__tests__/shared/components/challenge-listing/Filters/__snapshots__/FiltersPanel.jsx.snap +++ b/__tests__/shared/components/challenge-listing/Filters/__snapshots__/FiltersPanel.jsx.snap @@ -2,7 +2,25 @@ exports[`Matches shallow shapshot 1`] = `
+ + More Filters +
+`; + +exports[`Matches shallow shapshot 2`] = ` +
- - - - - - - - - - setQuery(event.target.value)} - onKeyPress={event => (event.key === 'Enter' ? onSearch(query.trim()) : null)} - placeholder={placeholder} - type="text" - value={query} - /> - onClearSearch()} - onKeyPress={() => onClearSearch()} - > - ⨯ - - onSearch(query.trim())} - onKeyPress={() => onSearch(query.trim())} - tabIndex="0" - role="button" - > - - - +
+
+
+ { + const s = e.target.value; + onSearch(s.trim()); + }} + placeholder={placeholder} + type="text" + value={query} + onChange={() => {}} + /> + + + +
+
); } ChallengeSearchBar.defaultProps = { placeholder: '', - label: 'Search: ', }; ChallengeSearchBar.propTypes = { onSearch: PT.func.isRequired, - onClearSearch: PT.func.isRequired, - label: PT.string, placeholder: PT.string, query: PT.string.isRequired, - setQuery: PT.func.isRequired, }; diff --git a/src/shared/components/challenge-listing/Filters/ChallengeSearchBar/style.scss b/src/shared/components/challenge-listing/Filters/ChallengeSearchBar/style.scss index bcf05d0753..da95906071 100644 --- a/src/shared/components/challenge-listing/Filters/ChallengeSearchBar/style.scss +++ b/src/shared/components/challenge-listing/Filters/ChallengeSearchBar/style.scss @@ -8,43 +8,39 @@ $challenge-space-60: $base-unit * 12; $challenge-radius-1: $corner-radius / 2; $challenge-radius-4: $corner-radius * 2; -/* -100px is necessary to compensate for the temporarly added `Alpha preview` - * banner. Should be modified / removed together with banner. */ -$search-bar-width: '100% - 536px'; -$search-input-width: '100% - 56px'; +.container { + background: $tc-gray-neutral-light; + border-bottom: 1px solid $tc-gray-30; + padding: 0 $base-unit * 3; + + @media (max-width: #{$screen-lg - 1px}) { + display: none; + } +} .ChallengeSearchBar { - display: inline-block; - vertical-align: middle; - margin-right: 40px; + display: block; position: relative; top: 10px; height: 60px; - label { + .input-container { font-size: 12px; - display: inline-flex; + display: flex; width: 100%; justify-content: center; align-items: center; } - @include xs-to-md { - display: none; - } - - @include calc(width, $search-bar-width); - input:not([type="checkbox"]) { - display: inline-block; flex: 1; background: $tc-white; border: 1px solid $tc-gray-20; - border-radius: $challenge-radius-4 0 0 $challenge-radius-4; + border-left: 0; + border-radius: 0 $challenge-radius-4 $challenge-radius-4 0; margin-bottom: 0; - margin-left: 10px; - vertical-align: middle; - padding-right: 28px; + padding-left: 0; + order: 2; @include placeholder { @include roboto-light; @@ -56,47 +52,27 @@ $search-input-width: '100% - 56px'; } &:hover { - border: 1px solid $tc-gray-40; + border-color: 1px solid $tc-gray-40; } } .SearchButton { - display: inline-block; - background: $tc-gray-20; + background: $tc-white; cursor: pointer; padding: $challenge-space-10 + 1 $challenge-space-20 $challenge-space-10 - 2; - border-radius: 0 $challenge-radius-4 $challenge-radius-4 0; - vertical-align: middle; + border-radius: $challenge-radius-4 0 0 $challenge-radius-4; height: 40px; - - &.active, - &:hover { - background: $tc-dark-blue; - } + order: 1; + border: 1px solid $tc-gray-20; + border-right: 0; .zoomIcon { height: 16px; width: 16px; } - } - - .ClearButton { - display: none; - cursor: pointer; - position: absolute; - right: $challenge-space-60 - 3; - padding: $base-unit; - border-radius: 0 $challenge-radius-4 $challenge-radius-4 0; - vertical-align: middle; - height: 38px; - font-size: 25px; - - &.active { - display: inline-block; - } &:hover { - color: $tc-red-110; + border-color: $tc-gray-40; } } } diff --git a/src/shared/components/challenge-listing/Filters/ChallengeSearchBar/ui-zoom.svg b/src/shared/components/challenge-listing/Filters/ChallengeSearchBar/ui-zoom.svg index 764232cb67..dca2ed444b 100644 --- a/src/shared/components/challenge-listing/Filters/ChallengeSearchBar/ui-zoom.svg +++ b/src/shared/components/challenge-listing/Filters/ChallengeSearchBar/ui-zoom.svg @@ -1,5 +1,5 @@ - - \ No newline at end of file + diff --git a/src/shared/components/challenge-listing/Filters/FiltersPanel/index.jsx b/src/shared/components/challenge-listing/Filters/FiltersPanel/index.jsx index 187ac39121..6c86e2b5c8 100644 --- a/src/shared/components/challenge-listing/Filters/FiltersPanel/index.jsx +++ b/src/shared/components/challenge-listing/Filters/FiltersPanel/index.jsx @@ -32,11 +32,16 @@ import Tooltip from 'components/Tooltip'; import { config, Link } from 'topcoder-react-utils'; import { COMPOSE, PRIORITY } from 'react-css-super-themr'; import { REVIEW_OPPORTUNITY_TYPES } from 'utils/tc'; -import { BUCKETS, isFilterEmpty } from 'utils/challenge-listing/buckets'; +import { isFilterEmpty } from 'utils/challenge-listing/buckets'; +import SwitchWithLabel from 'components/SwitchWithLabel'; +import { challenge as challengeUtils } from 'topcoder-react-lib'; +import { createStaticRanges } from 'utils/challenge-listing/date-range'; +import UiSimpleRemove from '../../Icons/ui-simple-remove.svg'; +import FiltersIcon from '../../Icons/filters-icon.svg'; import CheckmarkIcon from './CheckmarkIcon'; import style from './style.scss'; -import UiSimpleRemove from '../../Icons/ui-simple-remove.svg'; +const Filter = challengeUtils.filter; export default function FiltersPanel({ communityFilters, @@ -53,19 +58,39 @@ export default function FiltersPanel({ selectCommunity, // selectedCommunityId, setFilterState, - setSearchText, - validKeywords, + // validKeywords, validTypes, // isSavingFilter, + expanded, + setExpanded, + past, }) { - let className = 'FiltersPanel'; - if (hidden) className += ' hidden'; + if (hidden && !expanded) { + return ( +
{ + setExpanded(!expanded); + }} + onKeyDown={(e) => { + if (e.key !== 'Enter') { + return; + } + setExpanded(!expanded); + }} + tabIndex={0} + role="button" + > + More Filters +
+ ); + } const isVisitorRegisteredToCommunity = (visitorGroupIds, communityGroupIds) => Boolean( _.intersection(visitorGroupIds, communityGroupIds).length, ); - const isAllBucket = activeBucket === BUCKETS.ALL; + // const isAllBucket = activeBucket === BUCKETS.ALL; const getLabel = (community) => { const { communityName } = community; @@ -173,7 +198,7 @@ export default function FiltersPanel({ challenges in this sub community

-)} + )} > {selectItem} @@ -200,14 +225,9 @@ export default function FiltersPanel({ data: getLabel(community), })); - // const disableClearSaveFilterButtons = false; - // const disableClearSaveFilterButtons = isSavingFilter || ( - // selectedCommunityId === defaultCommunityId - // && _.isEmpty(filterState) - // ); - const disableClearSaveFilterButtons = isFilterEmpty(filterState); + const disableClearFilterButtons = isFilterEmpty(filterState, past ? 'past' : '', activeBucket); - const mapOps = item => ({ label: item, value: item }); + // const mapOps = item => ({ label: item, value: item }); const mapTypes = item => ({ label: item.name, value: item.abbreviation }); const getCommunityOption = () => { if (filterState.events && filterState.events.length) { @@ -219,8 +239,18 @@ export default function FiltersPanel({ return ''; }; + const isTrackOn = track => filterState.tracks && filterState.tracks[track]; + + const switchTrack = (track, on) => { + const act = on ? Filter.addTrack : Filter.removeTrack; + const filterObj = act(filterState, track); + setFilterState({ ...filterObj }); + }; + + const staticRanges = createStaticRanges(); + return ( -
+
Filters @@ -233,8 +263,9 @@ export default function FiltersPanel({
-
-
+ +
+ {/*
-
-
*/} + +
+
+ + Track + +
+ + switchTrack('Des', on)} + /> + + + switchTrack('Dev', on)} + /> + + + switchTrack('DS', on)} + /> + + + switchTrack('QA', on)} + /> + +
+
+
+ + { past + && ( +
+
+ + Past Period + +
+ { + staticRanges.map(range => ( + + !r.isSelected({ + startDate: filterState.endDateStart, + endDate: filterState.startDateEnd, + })) + && (!!filterState.endDateStart || !!filterState.startDateEnd) + ) : ( + range.isSelected({ + startDate: filterState.endDateStart, + endDate: filterState.startDateEnd, + }) + ) + } + onChange={() => { + if (range.isCustom) { + setFilterState({ + ..._.clone(filterState), + customDate: true, + }); + } else { + setFilterState({ + ..._.clone(filterState), + endDateStart: moment(range.startDate).toISOString(), + startDateEnd: moment(range.endDate).toISOString(), + customDate: false, + }); + } + }} + /> + {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */} + + + )) + } +
+
+
+ ) + } + + { past && filterState.customDate + && ( +
+
+ {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */} + + { + const d = range.endDate ? moment(range.endDate).toISOString() : null; + const s = range.startDate ? moment(range.startDate).toISOString() : null; + setFilterState({ + ..._.clone(filterState), + endDateStart: s, + startDateEnd: d, + }); + }} + range={{ + startDate: filterState.endDateStart + ? moment(filterState.endDateStart).toDate() + : null, + endDate: filterState.startDateEnd + ? moment(filterState.startDateEnd).toDate() + : null, + }} + /> +
+
+ ) + } + + { !isReviewOpportunitiesBucket + && ( +
+
+ + Challenge Type + +
+ { + validTypes + .map(mapTypes) + .map(option => ( + + { + let { types } = filterState; + + if (e.target.checked) { + types = types.concat(option.value); + } else { + types = types.filter(type => type !== option.value); + } + + setFilterState({ ..._.clone(filterState), types }); + }} + /> + + + )) + } +
+
+
+ ) + } + + {/* Only shown when the Review Opportunity bucket is selected */} + { isReviewOpportunitiesBucket + ? ( +
+
+ +
+ { + Object.entries(REVIEW_OPPORTUNITY_TYPES) + .map(([value, label]) => ({ value, label })) + .map(option => ( + + { + let { reviewOpportunityTypes = [] } = filterState; + + if (e.target.checked) { + reviewOpportunityTypes = reviewOpportunityTypes + .concat(option.value); + } else { + reviewOpportunityTypes = reviewOpportunityTypes.filter( + reviewType => reviewType !== option.value, + ); + } + + setFilterState({ ..._.clone(filterState), reviewOpportunityTypes }); + }} + /> + + + )) + } +
+
+
+ ) : null + } + +
+
+ @@ -292,108 +540,11 @@ export default function FiltersPanel({ />
-
-
- - - - - -