feat(ui) - filters global search list

This commit is contained in:
Shekar Siri 2022-02-02 17:20:59 +01:00
parent ee02cf8b88
commit af03760075
6 changed files with 76 additions and 143 deletions

View file

@ -2,6 +2,8 @@
border-radius: 3px;
border: solid thin $gray-light;
padding: 20px;
overflow: hidden;
overflow-y: auto;
}
.optionItem {
white-space: nowrap;
@ -14,4 +16,21 @@
fill: $teal !important;
}
}
}
.filterSearchItem {
&:hover {
background-color: $active-blue;
color: $teal;
& svg {
fill: $teal;
}
}
& div {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}

View file

@ -3,15 +3,53 @@ import { Icon } from 'UI';
import { connect } from 'react-redux';
import cn from 'classnames';
import stl from './FilterModal.css';
import { filtersMap } from 'Types/filter/newFilter'
interface Props {
filters: any,
onFilterClick?: (filter) => void
onFilterClick?: (filter) => void,
filterSearchList: any,
}
function FilterModal(props: Props) {
const { filters, onFilterClick = () => null } = props;
const { filters, onFilterClick = () => null, filterSearchList } = props;
const hasFilerSearchList = filterSearchList && Object.keys(filterSearchList).length > 0;
const onFilterSearchClick = (filter) => {
const _filter = filtersMap[filter.type];
_filter.value = [filter.value];
onFilterClick(_filter);
}
return (
<div className={stl.wrapper} style={{ width: '490px', height: '400px', overflowY: 'auto'}}>
{ hasFilerSearchList && (
<div className="border-b -mx-6 px-6 mb-3">
{ filterSearchList && Object.keys(filterSearchList).map((key, index) => {
const filter = filterSearchList[key];
const option = filtersMap[key];
return (
<div
key={index}
className={cn('mb-3')}
>
<div className="font-medium uppercase color-gray-medium text-sm mb-2">{option.label}</div>
<div>
{filter.map((f, i) => (
<div
key={i}
className={cn(stl.filterSearchItem, "cursor-pointer px-3 py-1 text-sm flex items-center")}
onClick={() => onFilterSearchClick({ type: key, value: f.value })}
>
<Icon className="mr-2" name={option.icon} size="16" />
<div className="whitespace-nowrap text-ellipsis overflow-hidden">{f.value}</div>
</div>
))}
</div>
</div>
);
})}
</div>
)}
<div className="" style={{ columns: "100px 2" }}>
{filters && Object.keys(filters).map((key) => (
<div className="mb-6">
@ -32,5 +70,6 @@ function FilterModal(props: Props) {
}
export default connect(state => ({
filters: state.getIn([ 'filters', 'filterList' ])
filters: state.getIn([ 'filters', 'filterList' ]),
filterSearchList: state.getIn([ 'search', 'filterSearchList' ])
}))(FilterModal);

View file

@ -30,7 +30,7 @@ function SessionSearchField(props: Props) {
}
const onAddFilter = (filter) => {
filter.value = [""]
filter.value = filter.value ? filter.value : [""]
const newFilters = appliedFilter.filters.concat(filter);
props.editFilter({
...appliedFilter.filter,

View file

@ -43,7 +43,7 @@ const initialState = Map({
alertMetricId: null,
instance: new Filter({ filters: [] }),
savedSearch: null,
filterSearchList: List(),
filterSearchList: {},
});
// Metric - Series - [] - filters
@ -69,7 +69,17 @@ function reducer(state = initialState, action = {}) {
const { data } = action;
return state.set("list", List(data.map(SavedFilter)));
case success(FETCH_FILTER_SEARCH):
return state.set("filterSearchList", action.data.map(NewFilter));
const groupedList = action.data.reduce((acc, item) => {
const { projectId, type, value } = item;
const key = type;
if (!acc[key]) {
acc[key] = [];
}
acc[key].push({ projectId, value });
return acc;
}, {});
console.log('groupedList', groupedList);
return state.set('filterSearchList', groupedList);
case APPLY_SAVED_SEARCH:
return state.set('savedSearch', action.filter);
}

View file

@ -40,7 +40,7 @@ export enum FilterKey {
REFERRER = "REFERRER",
USER_COUNTRY = "USER_COUNTRY",
JOURNEY = "JOURNEY",
FETCH = "FETCH",
REQUEST = "REQUEST",
GRAPHQL = "GRAPHQL",
STATEACTION = "STATEACTION",
REVID = "REVID",

View file

@ -19,148 +19,13 @@ const ISSUE_OPTIONS = [
{ text: 'JS Exception', value: 'js_exception' },
]
// const filterKeys = ['is', 'isNot'];
// const stringFilterKeys = ['is', 'isNot', 'contains', 'startsWith', 'endsWith', 'notContains'];
// const targetFilterKeys = ['on', 'notOn', 'onAny'];
// const signUpStatusFilterKeys = ['isSignedUp', 'notSignedUp'];
// const rangeFilterKeys = ['before', 'after', 'on', 'inRange', 'notInRange', 'withInLast', 'notWithInLast'];
// const options = [
// {
// key: 'is',
// text: 'is',
// value: 'is'
// }, {
// key: 'isNot',
// text: 'is not',
// value: 'isNot'
// }, {
// key: 'startsWith',
// text: 'starts with',
// value: 'startsWith'
// }, {
// key: 'endsWith',
// text: 'ends with',
// value: 'endsWith'
// }, {
// key: 'contains',
// text: 'contains',
// value: 'contains'
// }, {
// key: 'notContains',
// text: 'not contains',
// value: 'notContains'
// }, {
// key: 'hasAnyValue',
// text: 'has any value',
// value: 'hasAnyValue'
// }, {
// key: 'hasNoValue',
// text: 'has no value',
// value: 'hasNoValue'
// },
// {
// key: 'isSignedUp',
// text: 'is signed up',
// value: 'isSignedUp'
// }, {
// key: 'notSignedUp',
// text: 'not signed up',
// value: 'notSignedUp'
// },
// {
// key: 'before',
// text: 'before',
// value: 'before'
// }, {
// key: 'after',
// text: 'after',
// value: 'after'
// }, {
// key: 'on',
// text: 'on',
// value: 'on'
// }, {
// key: 'notOn',
// text: 'not on',
// value: 'notOn'
// }, {
// key: 'inRage',
// text: 'in rage',
// value: 'inRage'
// }, {
// key: 'notInRage',
// text: 'not in rage',
// value: 'notInRage'
// }, {
// key: 'withinLast',
// text: 'within last',
// value: 'withinLast'
// }, {
// key: 'notWithinLast',
// text: 'not within last',
// value: 'notWithinLast'
// },
// {
// key: 'greaterThan',
// text: 'greater than',
// value: 'greaterThan'
// }, {
// key: 'lessThan',
// text: 'less than',
// value: 'lessThan'
// }, {
// key: 'equal',
// text: 'equal',
// value: 'equal'
// }, {
// key: 'not equal',
// text: 'not equal',
// value: 'not equal'
// },
// {
// key: 'onSelector',
// text: 'on selector',
// value: 'onSelector'
// }, {
// key: 'onText',
// text: 'on text',
// value: 'onText'
// }, {
// key: 'onComponent',
// text: 'on component',
// value: 'onComponent'
// },
// {
// key: 'onAny',
// text: 'on any',
// value: 'onAny'
// }
// ];
// export const filterOptions = options.filter(({key}) => filterKeys.includes(key));
// export const filterOptions.stringOperators = options.filter(({key}) => stringFilterKeys.includes(key));
// export const filterOptions.targetOperators = options.filter(({key}) => targetFilterKeys.includes(key));
// export const booleanOptions = [
// { key: 'true', text: 'true', value: 'true' },
// { key: 'false', text: 'false', value: 'false' },
// ]
// export const filterOptions.customOperators = [
// { key: '=', text: '=', value: '=' },
// { key: '<', text: '<', value: '<' },
// { key: '>', text: '>', value: '>' },
// { key: '<=', text: '<=', value: '<=' },
// { key: '>=', text: '>=', value: '>=' },
// ]
export const filtersMap = {
// EVENTS
[FilterKey.CLICK]: { key: FilterKey.CLICK, type: FilterType.MULTIPLE, category: FilterCategory.INTERACTIONS, label: 'Click', operator: 'on', operatorOptions: filterOptions.targetOperators, icon: 'filters/click', isEvent: true },
[FilterKey.INPUT]: { key: FilterKey.INPUT, type: FilterType.MULTIPLE, category: FilterCategory.INTERACTIONS, label: 'Input', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/input', isEvent: true },
[FilterKey.LOCATION]: { key: FilterKey.LOCATION, type: FilterType.MULTIPLE, category: FilterCategory.INTERACTIONS, label: 'Page', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/location', isEvent: true },
[FilterKey.CUSTOM]: { key: FilterKey.CUSTOM, type: FilterType.MULTIPLE, category: FilterCategory.JAVASCRIPT, label: 'Custom Events', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/custom', isEvent: true },
[FilterKey.FETCH]: { key: FilterKey.FETCH, type: FilterType.MULTIPLE, category: FilterCategory.JAVASCRIPT, label: 'Fetch', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/fetch', isEvent: true },
[FilterKey.REQUEST]: { key: FilterKey.REQUEST, type: FilterType.MULTIPLE, category: FilterCategory.JAVASCRIPT, label: 'Fetch', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/fetch', isEvent: true },
[FilterKey.GRAPHQL]: { key: FilterKey.GRAPHQL, type: FilterType.MULTIPLE, category: FilterCategory.JAVASCRIPT, label: 'GraphQL', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/graphql', isEvent: true },
[FilterKey.STATEACTION]: { key: FilterKey.STATEACTION, type: FilterType.MULTIPLE, category: FilterCategory.JAVASCRIPT, label: 'StateAction', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/state-action', isEvent: true },
[FilterKey.ERROR]: { key: FilterKey.ERROR, type: FilterType.MULTIPLE, category: FilterCategory.JAVASCRIPT, label: 'Error', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/error', isEvent: true },