feat(ui) - assist filters wip
This commit is contained in:
parent
2fe2406d0c
commit
aa669d6a86
5 changed files with 70 additions and 64 deletions
|
|
@ -4,8 +4,8 @@ import LiveSessionSearch from 'Shared/LiveSessionSearch';
|
|||
import cn from 'classnames'
|
||||
import withPageTitle from 'HOCs/withPageTitle';
|
||||
import withPermissions from 'HOCs/withPermissions'
|
||||
import SessionSearch from '../shared/SessionSearch';
|
||||
import MainSearchBar from '../shared/MainSearchBar';
|
||||
// import SessionSearch from '../shared/SessionSearch';
|
||||
// import MainSearchBar from '../shared/MainSearchBar';
|
||||
import AssistSearchField from './AssistSearchField';
|
||||
|
||||
function Assist() {
|
||||
|
|
@ -13,11 +13,8 @@ function Assist() {
|
|||
<div className="page-margin container-90 flex relative">
|
||||
<div className="flex-1 flex">
|
||||
<div className={cn("w-full mx-auto")} style={{ maxWidth: '1300px'}}>
|
||||
|
||||
{/* <MainSearchBar /> */}
|
||||
<AssistSearchField />
|
||||
<LiveSessionSearch />
|
||||
{/* <SessionSearch /> */}
|
||||
<div className="my-4" />
|
||||
<LiveSessionList />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ interface Props {
|
|||
params?: any;
|
||||
headerText?: string;
|
||||
placeholder?: string;
|
||||
onSelect: (e, item) => void;
|
||||
onSelect: (e: any, item: any) => void;
|
||||
value: any;
|
||||
icon?: string;
|
||||
}
|
||||
|
|
@ -44,17 +44,17 @@ function FilterAutoComplete(props: Props) {
|
|||
const [options, setOptions] = useState<any>([]);
|
||||
const [query, setQuery] = useState(value);
|
||||
|
||||
const requestValues = (q) => {
|
||||
const requestValues = (q: any) => {
|
||||
setLoading(true);
|
||||
|
||||
return new APIClient()[method?.toLocaleLowerCase()](endpoint, { ...params, q })
|
||||
.then(response => {
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
return response.json();
|
||||
}
|
||||
throw new Error(response.statusText);
|
||||
})
|
||||
.then(({ data }) => {
|
||||
.then(({ data }: any) => {
|
||||
setOptions(data);
|
||||
})
|
||||
.finally(() => setLoading(false));
|
||||
|
|
@ -62,7 +62,7 @@ function FilterAutoComplete(props: Props) {
|
|||
|
||||
const debouncedRequestValues = React.useCallback(debounce(requestValues, 1000), [params]);
|
||||
|
||||
const onInputChange = ({ target: { value } }) => {
|
||||
const onInputChange = ({ target: { value } }: any) => {
|
||||
setQuery(value);
|
||||
if (!showModal) {
|
||||
setShowModal(true);
|
||||
|
|
@ -85,7 +85,7 @@ function FilterAutoComplete(props: Props) {
|
|||
}
|
||||
}
|
||||
|
||||
const onItemClick = (e, item) => {
|
||||
const onItemClick = (e: any, item: any) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ function FilterAutoComplete(props: Props) {
|
|||
) : (
|
||||
<div>
|
||||
{
|
||||
options.map((item, i) => (
|
||||
options.map((item: any, i: any) => (
|
||||
<div
|
||||
key={item.value + '_' + i}
|
||||
className={ cn(stl.filterItem) }
|
||||
|
|
|
|||
|
|
@ -5,10 +5,13 @@ import { FilterKey, FilterCategory, FilterType } from 'Types/filter/filterType';
|
|||
import FilterValueDropdown from '../FilterValueDropdown';
|
||||
import FilterDuration from '../FilterDuration';
|
||||
import { debounce } from 'App/utils';
|
||||
import { assist as assistRoute, isRoute } from "App/routes";
|
||||
|
||||
const ASSIST_ROUTE = assistRoute();
|
||||
|
||||
interface Props {
|
||||
filter: any;
|
||||
onUpdate: (filter) => void;
|
||||
onUpdate: (filter: any) => void;
|
||||
}
|
||||
function FilterValue(props: Props) {
|
||||
const { filter } = props;
|
||||
|
|
@ -21,13 +24,13 @@ function FilterValue(props: Props) {
|
|||
props.onUpdate({ ...filter, value: newValue });
|
||||
}
|
||||
|
||||
const onRemoveValue = (valueIndex) => {
|
||||
const newValue = filter.value.filter((_, index) => index !== valueIndex);
|
||||
const onRemoveValue = (valueIndex: any) => {
|
||||
const newValue = filter.value.filter((_: any, index: any) => index !== valueIndex);
|
||||
props.onUpdate({ ...filter, value: newValue });
|
||||
}
|
||||
|
||||
const onChange = (e, item, valueIndex) => {
|
||||
const newValues = filter.value.map((_, _index) => {
|
||||
const onChange = (e: any, item: any, valueIndex: any) => {
|
||||
const newValues = filter.value.map((_: any, _index: any) => {
|
||||
if (_index === valueIndex) {
|
||||
return item.value;
|
||||
}
|
||||
|
|
@ -38,11 +41,11 @@ function FilterValue(props: Props) {
|
|||
|
||||
const debounceOnSelect = React.useCallback(debounce(onChange, 500), [onChange]);
|
||||
|
||||
const onDurationChange = (newValues) => {
|
||||
const onDurationChange = (newValues: any) => {
|
||||
setDurationValues({ ...durationValues, ...newValues });
|
||||
}
|
||||
|
||||
const handleBlur = (e) => {
|
||||
const handleBlur = (e: any) => {
|
||||
if (filter.type === FilterType.DURATION) {
|
||||
const { maxDuration, minDuration, key } = filter;
|
||||
if (maxDuration || minDuration) return;
|
||||
|
|
@ -53,16 +56,22 @@ function FilterValue(props: Props) {
|
|||
}
|
||||
}
|
||||
|
||||
const getParms = (key) => {
|
||||
const getParms = (key: any) => {
|
||||
let params = {};
|
||||
switch (filter.category) {
|
||||
case FilterCategory.METADATA:
|
||||
return { type: FilterKey.METADATA, key: key };
|
||||
params = { type: FilterKey.METADATA, key: key };
|
||||
default:
|
||||
return { type: filter.key };
|
||||
params = { type: filter.key };
|
||||
}
|
||||
|
||||
if (isRoute(ASSIST_ROUTE, window.location.pathname)) {
|
||||
params = { ...params, live: true };
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
const renderValueFiled = (value, valueIndex) => {
|
||||
const renderValueFiled = (value: any, valueIndex: any) => {
|
||||
const showOrButton = valueIndex === lastIndex && filter.type !== FilterType.NUMBER;
|
||||
switch(filter.type) {
|
||||
case FilterType.STRING:
|
||||
|
|
@ -85,7 +94,7 @@ function FilterValue(props: Props) {
|
|||
filter={filter}
|
||||
options={filter.options}
|
||||
onChange={({ value }) => onChange(null, { value }, valueIndex)}
|
||||
/>
|
||||
/>
|
||||
)
|
||||
case FilterType.ISSUE:
|
||||
case FilterType.MULTIPLE_DROPDOWN:
|
||||
|
|
@ -174,7 +183,7 @@ function FilterValue(props: Props) {
|
|||
{ filter.type === FilterType.DURATION ? (
|
||||
renderValueFiled(filter.value, 0)
|
||||
) : (
|
||||
filter.value && filter.value.map((value, valueIndex) => (
|
||||
filter.value && filter.value.map((value: any, valueIndex: any) => (
|
||||
<div key={valueIndex}>
|
||||
{renderValueFiled(value, valueIndex)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { fetchLiveList } from 'Duck/sessions';
|
||||
import { connect } from 'react-redux';
|
||||
import { NoContent, Loader, LoadMoreButton, Pagination } from 'UI';
|
||||
import { List, Map } from 'immutable';
|
||||
import { NoContent, Loader, Pagination } from 'UI';
|
||||
import { List } from 'immutable';
|
||||
import SessionItem from 'Shared/SessionItem';
|
||||
import withPermissions from 'HOCs/withPermissions'
|
||||
import { KEYS } from 'Types/filter/customFilter';
|
||||
|
|
@ -23,7 +23,7 @@ interface Props {
|
|||
fetchLiveList: () => Promise<void>,
|
||||
applyFilter: () => void,
|
||||
filters: any,
|
||||
addAttribute: (obj) => void,
|
||||
addAttribute: (obj: any) => void,
|
||||
addFilterByKeyAndValue: (key: FilterKey, value: string) => void,
|
||||
updateCurrentPage: (page: number) => void,
|
||||
currentPage: number,
|
||||
|
|
@ -34,16 +34,13 @@ interface Props {
|
|||
|
||||
function LiveSessionList(props: Props) {
|
||||
const { loading, filters, list, currentPage, metaList = [], sort } = props;
|
||||
var timeoutId;
|
||||
const hasUserFilter = filters.map(i => i.key).includes(KEYS.USERID);
|
||||
var timeoutId: any;
|
||||
const hasUserFilter = filters.map((i: any) => i.key).includes(KEYS.USERID);
|
||||
const [sessions, setSessions] = React.useState(list);
|
||||
const sortOptions = metaList.map(i => ({
|
||||
const sortOptions = metaList.map((i: any) => ({
|
||||
text: capitalize(i), label: i
|
||||
})).toJS();
|
||||
|
||||
// const displayedCount = Math.min(currentPage * PER_PAGE, sessions.size);
|
||||
// const addPage = () => props.updateCurrentPage(props.currentPage + 1)
|
||||
|
||||
// useEffect(() => {
|
||||
// if (filters.size === 0) {
|
||||
// props.addFilterByKeyAndValue(FilterKey.USERID, '');
|
||||
|
|
@ -53,31 +50,31 @@ function LiveSessionList(props: Props) {
|
|||
useEffect(() => {
|
||||
if (metaList.size === 0 || !!sort.field) return;
|
||||
|
||||
if ( sortOptions[0]) {
|
||||
if (sortOptions[0]) {
|
||||
props.updateSort({ field: sortOptions[0].value });
|
||||
}
|
||||
}, [metaList]);
|
||||
|
||||
useEffect(() => {
|
||||
const filteredSessions = filters.size > 0 ? props.list.filter(session => {
|
||||
let hasValidFilter = true;
|
||||
filters.forEach(filter => {
|
||||
if (!hasValidFilter) return;
|
||||
// useEffect(() => {
|
||||
// const filteredSessions = filters.size > 0 ? props.list.filter(session => {
|
||||
// let hasValidFilter = true;
|
||||
// filters.forEach(filter => {
|
||||
// if (!hasValidFilter) return;
|
||||
|
||||
const _values = filter.value.filter(i => i !== '' && i !== null && i !== undefined).map(i => i.toLowerCase());
|
||||
if (filter.key === FilterKey.USERID) {
|
||||
const _userId = session.userId ? session.userId.toLowerCase() : '';
|
||||
hasValidFilter = _values.length > 0 ? (_values.includes(_userId) && hasValidFilter) || _values.some(i => _userId.includes(i)) : hasValidFilter;
|
||||
}
|
||||
if (filter.category === FilterCategory.METADATA) {
|
||||
const _source = session.metadata[filter.key] ? session.metadata[filter.key].toLowerCase() : '';
|
||||
hasValidFilter = _values.length > 0 ? (_values.includes(_source) && hasValidFilter) || _values.some(i => _source.includes(i)) : hasValidFilter;
|
||||
}
|
||||
})
|
||||
return hasValidFilter;
|
||||
}) : props.list;
|
||||
setSessions(filteredSessions);
|
||||
}, [filters, list]);
|
||||
// const _values = filter.value.filter(i => i !== '' && i !== null && i !== undefined).map(i => i.toLowerCase());
|
||||
// if (filter.key === FilterKey.USERID) {
|
||||
// const _userId = session.userId ? session.userId.toLowerCase() : '';
|
||||
// hasValidFilter = _values.length > 0 ? (_values.includes(_userId) && hasValidFilter) || _values.some(i => _userId.includes(i)) : hasValidFilter;
|
||||
// }
|
||||
// if (filter.category === FilterCategory.METADATA) {
|
||||
// const _source = session.metadata[filter.key] ? session.metadata[filter.key].toLowerCase() : '';
|
||||
// hasValidFilter = _values.length > 0 ? (_values.includes(_source) && hasValidFilter) || _values.some(i => _source.includes(i)) : hasValidFilter;
|
||||
// }
|
||||
// })
|
||||
// return hasValidFilter;
|
||||
// }) : props.list;
|
||||
// setSessions(filteredSessions);
|
||||
// }, [filters, list]);
|
||||
|
||||
useEffect(() => {
|
||||
props.fetchLiveList();
|
||||
|
|
@ -95,7 +92,8 @@ function LiveSessionList(props: Props) {
|
|||
}
|
||||
}
|
||||
|
||||
const onSortChange = (e, { value }) => {
|
||||
const onSortChange = ({ value }: any) => {
|
||||
value = value.value
|
||||
props.updateSort({ field: value });
|
||||
}
|
||||
|
||||
|
|
@ -145,9 +143,7 @@ function LiveSessionList(props: Props) {
|
|||
show={ !loading && sessions && sessions.size === 0}
|
||||
>
|
||||
<Loader loading={ loading }>
|
||||
{sessions && sliceListPerPage(sessions.sortBy(i => i.metadata[sort.field]).update(list => {
|
||||
return sort.order === 'desc' ? list.reverse() : list;
|
||||
}), currentPage - 1).map(session => (
|
||||
{sessions.map(session => (
|
||||
<SessionItem
|
||||
key={ session.sessionId }
|
||||
session={ session }
|
||||
|
|
@ -162,7 +158,7 @@ function LiveSessionList(props: Props) {
|
|||
<Pagination
|
||||
page={currentPage}
|
||||
totalPages={Math.ceil(sessions.size / PER_PAGE)}
|
||||
onPageChange={(page) => props.updateCurrentPage(page)}
|
||||
onPageChange={(page: any) => props.updateCurrentPage(page)}
|
||||
limit={PER_PAGE}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -173,12 +169,12 @@ function LiveSessionList(props: Props) {
|
|||
}
|
||||
|
||||
export default withPermissions(['ASSIST_LIVE'])(connect(
|
||||
(state) => ({
|
||||
(state: any) => ({
|
||||
list: state.getIn(['liveSearch', 'list']),
|
||||
loading: state.getIn([ 'liveSearch', 'fetchList', 'loading' ]),
|
||||
filters: state.getIn([ 'liveSearch', 'instance', 'filters' ]),
|
||||
currentPage: state.getIn(["liveSearch", "currentPage"]),
|
||||
metaList: state.getIn(['customFields', 'list']).map(i => i.key),
|
||||
metaList: state.getIn(['customFields', 'list']).map((i: any) => i.key),
|
||||
sort: state.getIn(['liveSearch', 'sort']),
|
||||
}),
|
||||
{
|
||||
|
|
|
|||
|
|
@ -53,14 +53,18 @@ export const filters = [
|
|||
{ key: FilterKey.FETCH_FAILED, type: FilterType.MULTIPLE, category: FilterCategory.PERFORMANCE, label: 'Failed Request', operator: 'isAny', operatorOptions: filterOptions.stringOperatorsPerformance, icon: 'filters/fetch-failed', isEvent: true },
|
||||
{ key: FilterKey.ISSUE, type: FilterType.ISSUE, category: FilterCategory.JAVASCRIPT, label: 'Issue', operator: 'is', operatorOptions: filterOptions.getOperatorsByKeys(['is', 'isAny', 'isNot']), icon: 'filters/click', options: filterOptions.issueOptions },
|
||||
];
|
||||
|
||||
|
||||
export const filtersMap = filters.reduce((acc, filter) => {
|
||||
acc[filter.key] = filter;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
|
||||
export const liveFiltersMap = filters.reduce((acc, filter) => {
|
||||
if (filter.category !== FilterCategory.INTERACTIONS && filter.category !== FilterCategory.JAVASCRIPT) {
|
||||
if (
|
||||
filter.category !== FilterCategory.INTERACTIONS &&
|
||||
filter.category !== FilterCategory.JAVASCRIPT &&
|
||||
filter.category !== FilterCategory.PERFORMANCE
|
||||
) {
|
||||
acc[filter.key] = filter;
|
||||
}
|
||||
return acc
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue