Skip to content

Commit

Permalink
CV2-4980: Filter improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
amoedoamorim committed Jan 24, 2025
1 parent c0fa1bb commit 800a645
Show file tree
Hide file tree
Showing 21 changed files with 158 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@
"description": "Menu option to enable searching items by channel",
"defaultMessage": "Channel"
},
{
"id": "addFilterMenu.claim",
"description": "Menu option to enable searching items by claim",
"defaultMessage": "Claim"
},
{
"id": "addFilterMenu.createdBy",
"description": "Menu option to enable searching items by author",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"defaultMessage": "Media language"
},
{
"id": "search.reportLanguage",
"description": "Label for report language filter",
"defaultMessage": "Report language"
"id": "search.articleLanguage",
"description": "Label for article language filter",
"defaultMessage": "Article language"
},
{
"id": "search.requestLanguage",
Expand Down
7 changes: 7 additions & 0 deletions src/app/components/article/ArticleFilters.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ const ArticleFilters = ({
teamSlug,
type,
}) => {
console.log('currentFilters', currentFilters); // eslint-disable-line

const [filters, setFilters] = React.useState({ ...currentFilters });

const [typeFilter, setTypeFilter] = React.useState([type]);
Expand Down Expand Up @@ -118,6 +120,11 @@ const ArticleFilters = ({
const value = filters[filter];
const connector = ((i === 0) ? null : filterConnector);

console.log('connector', connector); // eslint-disable-line
console.log('filter', filter); // eslint-disable-line
console.log('i', i); // eslint-disable-line


if (filter === 'imported') {
return (
<React.Fragment key={filter}>
Expand Down
5 changes: 2 additions & 3 deletions src/app/components/article/Explainers.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react/sort-prop-types */
import React from 'react';
import { graphql } from 'react-relay/compat';
import PropTypes from 'prop-types';
Expand Down Expand Up @@ -44,7 +43,7 @@ const Explainers = ({ intl, routeParams }) => {

return (
<Articles
filterOptions={['users', 'tags', 'range']}
filterOptions={['users', 'tags', 'range', 'language_filter']}
icon={<BookIcon />}
sortOptions={sortOptions}
teamSlug={routeParams.team}
Expand All @@ -58,10 +57,10 @@ const Explainers = ({ intl, routeParams }) => {
Explainers.defaultProps = {};

Explainers.propTypes = {
intl: intlShape.isRequired,
routeParams: PropTypes.shape({
team: PropTypes.string.isRequired, // slug
}).isRequired,
intl: intlShape.isRequired,
};

export default injectIntl(Explainers);
3 changes: 1 addition & 2 deletions src/app/components/article/FactChecks.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react/sort-prop-types */
import React from 'react';
import { graphql } from 'react-relay/compat';
import PropTypes from 'prop-types';
Expand Down Expand Up @@ -58,10 +57,10 @@ const FactChecks = ({ intl, routeParams }) => {
FactChecks.defaultProps = {};

FactChecks.propTypes = {
intl: intlShape.isRequired,
routeParams: PropTypes.shape({
team: PropTypes.string.isRequired, // slug
}).isRequired,
intl: intlShape.isRequired,
};

export default injectIntl(FactChecks);
5 changes: 2 additions & 3 deletions src/app/components/article/ImportedArticles.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react/sort-prop-types */
import React from 'react';
import { graphql } from 'react-relay/compat';
import PropTypes from 'prop-types';
Expand Down Expand Up @@ -45,7 +44,7 @@ const ImportedArticles = ({ intl, routeParams }) => {
return (
<Articles
defaultFilters={{ imported: true }}
filterOptions={['users', 'tags', 'range']}
filterOptions={['tags', 'range', 'imported', 'language_filter']}
icon={<FileDownloadIcon />}
sortOptions={sortOptions}
teamSlug={routeParams.team}
Expand All @@ -59,10 +58,10 @@ const ImportedArticles = ({ intl, routeParams }) => {
ImportedArticles.defaultProps = {};

ImportedArticles.propTypes = {
intl: intlShape.isRequired,
routeParams: PropTypes.shape({
team: PropTypes.string.isRequired, // slug
}).isRequired,
intl: intlShape.isRequired,
};

export default injectIntl(ImportedArticles);
5 changes: 2 additions & 3 deletions src/app/components/article/PublishedArticles.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react/sort-prop-types */
import React from 'react';
import { graphql } from 'react-relay/compat';
import PropTypes from 'prop-types';
Expand Down Expand Up @@ -45,7 +44,7 @@ const PublishedArticles = ({ intl, routeParams }) => {
return (
<Articles
defaultFilters={{ report_status: 'published' }}
filterOptions={['users', 'tags', 'range']}
filterOptions={['users', 'tags', 'range', 'verification_status', 'language_filter', 'published_by']}
icon={<PublishedIcon />}
sortOptions={sortOptions}
teamSlug={routeParams.team}
Expand All @@ -59,10 +58,10 @@ const PublishedArticles = ({ intl, routeParams }) => {
PublishedArticles.defaultProps = {};

PublishedArticles.propTypes = {
intl: intlShape.isRequired,
routeParams: PropTypes.shape({
team: PropTypes.string.isRequired, // slug
}).isRequired,
intl: intlShape.isRequired,
};

export default injectIntl(PublishedArticles);
5 changes: 4 additions & 1 deletion src/app/components/search/AllItems.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ export default function AllItems({ routeParams }) {
<Search
defaultQuery={defaultQuery}
hideFields={[
'cluster_teams', 'cluster_published_reports', 'feed_fact_checked_by',
'cluster_teams',
'cluster_published_reports',
'feed_fact_checked_by',
'published_by',
]}
icon={<PermMediaIcon />}
listSubtitle={<FormattedMessage defaultMessage="Media Clusters List" description="Displayed on top of the tipline lists title on the search results page." id="search.tiplineSubHeader" />}
Expand Down
11 changes: 5 additions & 6 deletions src/app/components/search/LanguageFilter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react/sort-prop-types */
import React from 'react';
import { QueryRenderer, graphql } from 'react-relay/compat';
import Relay from 'react-relay/classic';
Expand All @@ -20,9 +19,9 @@ const messages = defineMessages({
defaultMessage: 'Media language',
},
report_language: {
id: 'search.reportLanguage',
description: 'Label for report language filter',
defaultMessage: 'Report language',
id: 'search.articleLanguage',
description: 'Label for article language filter',
defaultMessage: 'Article language',
},
request_language: {
id: 'search.requestLanguage',
Expand Down Expand Up @@ -121,12 +120,13 @@ const LanguageFilter = ({

LanguageFilter.defaultProps = {
hide: false,
value: null,
optionsToHide: [],
value: null,
};

LanguageFilter.propTypes = {
hide: PropTypes.bool,
intl: intlShape.isRequired,
optionsToHide: PropTypes.arrayOf(PropTypes.string),
value: PropTypes.oneOfType([
PropTypes.shape({
Expand All @@ -141,7 +141,6 @@ LanguageFilter.propTypes = {
]),
onChange: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired,
intl: intlShape.isRequired,
};

export default injectIntl(LanguageFilter);
46 changes: 28 additions & 18 deletions src/app/components/search/MultiSelectFilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const Tag = ({
label,
onDelete,
readOnly,
...props
}) => (
<>
{label ?
Expand All @@ -43,7 +42,6 @@ const Tag = ({
[styles['filter-value-removable']]: !readOnly,
})
}
{...props}
>
<span>{label}</span>
{ readOnly ? null : (
Expand All @@ -67,7 +65,7 @@ const Tag = ({
)}
</div>
:
<div className={cx('multi-select-filter__tag', styles['filter-value'], styles['filter-value-missing'])} {...props}>
<div className={cx('multi-select-filter__tag', styles['filter-value'], styles['filter-value-missing'])}>
<span>
<FormattedMessage defaultMessage="Property deleted" description="Message shown a placeholder when someone tries to filter a search by a property that the user has deleted" id="filter.tag.deleted" />
</span>
Expand Down Expand Up @@ -111,6 +109,8 @@ const MultiSelectFilter = ({
return option ? option.label : '';
};

const getOptionForValue = value => options.find(o => String(o.value) === String(value));

const handleTagDelete = (value) => {
const newValue = [...selectedArray.filter(o => o !== value)];
onChange(newValue);
Expand All @@ -137,21 +137,31 @@ const MultiSelectFilter = ({
{label}
</div>
}
{ !oneOption && selectedArray.map((value, index) => (
<React.Fragment key={getLabelForValue(value)}>
{ index > 0 ? (
<OperatorToggle
operator={operator}
onClick={onToggleOperator}
/>
) : null }
<Tag
label={getLabelForValue(value)}
readOnly={readOnly}
onDelete={() => handleTagDelete(value)}
/>
</React.Fragment>
)) }
{ !oneOption && selectedArray.map((value, index) => {
const option = getOptionForValue(value);

return option.hasChildren ? null : (
<React.Fragment key={getLabelForValue(value)}>
{ index > 0 ? (
<OperatorToggle
operator={operator}
onClick={onToggleOperator}
/>
) : null }
{/*
If option has children it's a category. Don't render a Tag for it.
E.g.: "Social Media" in Media type filter
*/}
{ !getOptionForValue(value).hasChildren &&
<Tag
label={getLabelForValue(value)}
readOnly={readOnly}
onDelete={() => handleTagDelete(value)}
/>
}
</React.Fragment>
);
}) }
{ !oneOption && selectedArray.length > 0 && showSelect ? (
<OperatorToggle
operator={operator}
Expand Down
7 changes: 3 additions & 4 deletions src/app/components/search/RemoveableWrapper.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react/sort-prop-types */
import React from 'react';
import { FormattedMessage } from 'react-intl';
import PropTypes from 'prop-types';
Expand Down Expand Up @@ -61,16 +60,16 @@ const RemoveableWrapper = ({
};

RemoveableWrapper.defaultProps = {
readOnly: false,
children: null,
readOnly: false,
onRemove: null,
};

RemoveableWrapper.propTypes = {
icon: PropTypes.object.isRequired,
onRemove: PropTypes.func,
children: PropTypes.node,
icon: PropTypes.object.isRequired,
readOnly: PropTypes.bool,
onRemove: PropTypes.func,
};

export default RemoveableWrapper;
7 changes: 6 additions & 1 deletion src/app/components/search/SavedSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ const SavedSearch = ({ routeParams }) => (
<div className="saved-search search-results-wrapper">
<Search
defaultQuery={defaultQuery}
hideFields={['feed_fact_checked_by', 'cluster_teams', 'cluster_published_reports']}
hideFields={[
'feed_fact_checked_by',
'cluster_teams',
'cluster_published_reports',
'published_by',
]}
icon={<ListIcon />}
listActions={
<ProjectActions
Expand Down
41 changes: 20 additions & 21 deletions src/app/components/search/Search.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react/sort-prop-types */
import React from 'react';
import PropTypes from 'prop-types';
import SearchResults from './SearchResults';
Expand Down Expand Up @@ -104,36 +103,36 @@ export default function Search({
}

Search.defaultProps = {
feedTeam: null,
extra: null,
feed: null,
savedSearch: null,
feedTeam: null,
hideFields: [],
readOnlyFields: [],
listActions: undefined,
showExpand: true,
resultType: 'default',
icon: null,
extra: null,
listActions: undefined,
listSubtitle: null,
readOnlyFields: [],
resultType: 'default',
savedSearch: null,
showExpand: true,
};

Search.propTypes = {
searchUrlPrefix: PropTypes.string.isRequired,
mediaUrlPrefix: PropTypes.string.isRequired,
listActions: PropTypes.node, // or undefined
feedTeam: PropTypes.object, // or null
defaultQuery: PropTypes.object.isRequired, // may be empty
extra: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), // or null
feed: PropTypes.object, // or null
savedSearch: PropTypes.object, // or null
listSubtitle: PropTypes.object,
teamSlug: PropTypes.string.isRequired,
title: PropTypes.node.isRequired,
icon: PropTypes.node,
feedTeam: PropTypes.object, // or null
hideFields: PropTypes.arrayOf(PropTypes.string.isRequired), // or undefined
readOnlyFields: PropTypes.arrayOf(PropTypes.string.isRequired), // or undefined
icon: PropTypes.node,
listActions: PropTypes.node, // or undefined
listSubtitle: PropTypes.object,
mediaUrlPrefix: PropTypes.string.isRequired,
page: PropTypes.oneOf(['all-items', 'tipline-inbox', 'imported-fact-checks', 'suggested-matches', 'unmatched-media', 'published', 'list', 'feed', 'spam', 'trash', 'assigned-to-me']).isRequired, // FIXME Define listing types as a global constant
query: PropTypes.object.isRequired, // may be empty
defaultQuery: PropTypes.object.isRequired, // may be empty
showExpand: PropTypes.bool,
readOnlyFields: PropTypes.arrayOf(PropTypes.string.isRequired), // or undefined
resultType: PropTypes.string, // 'default' or 'feed', for now
extra: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), // or null
savedSearch: PropTypes.object, // or null
searchUrlPrefix: PropTypes.string.isRequired,
showExpand: PropTypes.bool,
teamSlug: PropTypes.string.isRequired,
title: PropTypes.node.isRequired,
};
6 changes: 6 additions & 0 deletions src/app/components/search/SearchFields/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,14 @@ const SearchFields = ({
[...stateQuery.team_tasks, {}] : [{}];
} else if (field === 'range') {
newQuery.range = { created_at: {} };
} else if (field === 'linked_items_count') {
newQuery.linked_items_count = { min: 1, max: '' };
} else {
newQuery[field] = [];
}

console.log('newQuery', newQuery); // eslint-disable-line

setStateQuery(newQuery);
};

Expand All @@ -207,6 +211,8 @@ const SearchFields = ({
const handleNumericRange = (filterKey, value) => {
const newQuery = { ...stateQuery };
newQuery[filterKey] = value;
console.log('filterKey', filterKey); // eslint-disable-line
console.log('value', value); // eslint-disable-line
setStateQuery(newQuery);
};

Expand Down
Loading

0 comments on commit 800a645

Please sign in to comment.