feat(ui) - assist filters with pagination
This commit is contained in:
parent
1a5c50cefa
commit
133714a4cb
22 changed files with 100 additions and 100 deletions
|
|
@ -17,7 +17,7 @@ const DropdownChips = ({
|
|||
}
|
||||
|
||||
const onSelect = ({ value }) => {
|
||||
const newSlected = selected.concat(value);
|
||||
const newSlected = selected.concat(value.value);
|
||||
onChange(newSlected)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ function DashboardView(props: RouteComponentProps<Props>) {
|
|||
plain
|
||||
period={period}
|
||||
onChange={(period: any) => dashboardStore.setPeriod(period)}
|
||||
right={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="mx-4" />
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import FunnelIssuesSort from '../FunnelIssuesSort';
|
|||
import FunnelIssuesList from '../FunnelIssuesList';
|
||||
import { DateTime } from 'luxon';
|
||||
import { debounce } from 'App/utils';
|
||||
import useIsMounted from 'App/hooks/useIsMounted'
|
||||
import useIsMounted from 'App/hooks/useIsMounted';
|
||||
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
||||
|
||||
function FunnelIssues() {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ function WidgetPreview(props: Props) {
|
|||
<SelectDateRange
|
||||
period={period}
|
||||
onChange={(period: any) => dashboardStore.setPeriod(period)}
|
||||
right={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const toMs = value => value !== '' ? value * 1000 * 60 : null
|
|||
|
||||
export default class FilterDuration extends React.PureComponent {
|
||||
state = { focused: false }
|
||||
onChange = (e, { name, value }) => {
|
||||
onChange = ({ target: { name, value }}) => {
|
||||
const { onChange } = this.props;
|
||||
if (typeof onChange === 'function') {
|
||||
onChange({
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ function FilterItem(props: Props) {
|
|||
onChange={onSourceOperatorChange}
|
||||
className="mx-2 flex-shrink-0"
|
||||
value={filter.sourceOperator}
|
||||
isDisabled={filter.operatorDisabled}
|
||||
/>
|
||||
<FilterSource filter={filter} onUpdate={props.onUpdate} />
|
||||
</>
|
||||
|
|
@ -78,6 +79,7 @@ function FilterItem(props: Props) {
|
|||
onChange={onOperatorChange}
|
||||
className="mx-2 flex-shrink-0"
|
||||
value={filter.operator}
|
||||
isDisabled={filter.operatorDisabled}
|
||||
/>
|
||||
{ canShowValues && (<FilterValue filter={filter} onUpdate={props.onUpdate} />) }
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -51,9 +51,8 @@ function FilterModal(props: Props) {
|
|||
} = props;
|
||||
const hasSearchQuery = searchQuery && searchQuery.length > 0;
|
||||
const showSearchList = isMainSearch && searchQuery.length > 0;
|
||||
console.log('filters', props.filters)
|
||||
|
||||
const onFilterSearchClick = (filter) => {
|
||||
const onFilterSearchClick = (filter: any) => {
|
||||
const _filter = filtersMap[filter.type];
|
||||
_filter.value = [filter.value];
|
||||
onFilterClick(_filter);
|
||||
|
|
|
|||
|
|
@ -57,9 +57,10 @@ interface Props {
|
|||
className?: string;
|
||||
options?: any;
|
||||
value?: string;
|
||||
isDisabled?: boolean;
|
||||
}
|
||||
function FilterOperator(props: Props) {
|
||||
const { options, value, onChange, className = '' } = props;
|
||||
const { options, value, onChange, isDisabled = false, className = '' } = props;
|
||||
|
||||
return (
|
||||
<div className="mx-2">
|
||||
|
|
@ -68,6 +69,7 @@ function FilterOperator(props: Props) {
|
|||
options={options}
|
||||
styles={dropdownStyles}
|
||||
placeholder="Select"
|
||||
isDisabled={isDisabled}
|
||||
defaultValue={ value }
|
||||
onChange={({ value }: any) => onChange(null, { name: 'operator', value })}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,10 @@ function FilterSelection(props: Props) {
|
|||
</OutsideClickDetectingDiv>
|
||||
{showModal && (
|
||||
<div className="absolute left-0 border shadow rounded bg-white z-50">
|
||||
<FilterModal onFilterClick={onFilterClick} filters={isRoute(ASSIST_ROUTE, window.location.pathname) ? props.filterListLive : props.filterList } />
|
||||
<FilterModal
|
||||
onFilterClick={onFilterClick}
|
||||
filters={isRoute(ASSIST_ROUTE, window.location.pathname) ? props.filterListLive : props.filterList }
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -52,7 +55,7 @@ function FilterSelection(props: Props) {
|
|||
}
|
||||
|
||||
export default connect((state: any) => ({
|
||||
filters: state.getIn([ 'search', 'filterList' ]),
|
||||
liveFilters: state.getIn([ 'search', 'filterListLive' ]),
|
||||
filterList: state.getIn([ 'search', 'filterList' ]),
|
||||
filterListLive: state.getIn([ 'search', 'filterListLive' ]),
|
||||
isLive: state.getIn([ 'sessions', 'activeTab' ]).type === 'live',
|
||||
}), { })(FilterSelection);
|
||||
|
|
@ -57,17 +57,16 @@ function FilterValue(props: Props) {
|
|||
}
|
||||
|
||||
const getParms = (key: any) => {
|
||||
let params = {};
|
||||
let params: any = { type: filter.key };
|
||||
switch (filter.category) {
|
||||
case FilterCategory.METADATA:
|
||||
params = { type: FilterKey.METADATA, key: key };
|
||||
default:
|
||||
params = { type: filter.key };
|
||||
}
|
||||
|
||||
if (isRoute(ASSIST_ROUTE, window.location.pathname)) {
|
||||
params = { ...params, live: true };
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ const dropdownStyles = {
|
|||
...provided, opacity, transition,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
height: '26px',
|
||||
height: '20px',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -70,7 +70,7 @@ interface Props {
|
|||
filter: any; // event/filter
|
||||
// options: any[];
|
||||
value: string;
|
||||
onChange: (e, { name, value }) => void;
|
||||
onChange: (value: any) => void;
|
||||
className?: string;
|
||||
options: any[];
|
||||
search?: boolean;
|
||||
|
|
@ -94,7 +94,7 @@ function FilterValueDropdown(props: Props) {
|
|||
options={ options }
|
||||
name="issue_type"
|
||||
defaultValue={ value }
|
||||
onChange={ onChange }
|
||||
onChange={ (value: any) => onChange(value.value) }
|
||||
placeholder="Select"
|
||||
styles={dropdownStyles}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { fetchLiveList } from 'Duck/sessions';
|
||||
import { connect } from 'react-redux';
|
||||
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';
|
||||
import { applyFilter, addAttribute } from 'Duck/filters';
|
||||
import { applyFilter } from 'Duck/liveSearch';
|
||||
import { FilterKey } from 'App/types/filter/filterType';
|
||||
import { addFilterByKeyAndValue, updateCurrentPage, updateSort } from 'Duck/liveSearch';
|
||||
import { addFilterByKeyAndValue, updateCurrentPage } from 'Duck/liveSearch';
|
||||
import Select from 'Shared/Select';
|
||||
import SortOrderButton from 'Shared/SortOrderButton';
|
||||
import { capitalize } from 'App/utils';
|
||||
|
|
@ -18,42 +17,38 @@ const AUTOREFRESH_INTERVAL = .5 * 60 * 1000
|
|||
const PER_PAGE = 10;
|
||||
|
||||
interface Props {
|
||||
loading: Boolean,
|
||||
loading: boolean,
|
||||
metaListLoading: boolean
|
||||
list: List<any>,
|
||||
fetchLiveList: () => Promise<void>,
|
||||
applyFilter: () => void,
|
||||
filters: any,
|
||||
addAttribute: (obj: any) => void,
|
||||
// fetchLiveList: () => Promise<void>,
|
||||
applyFilter: (filter: any) => void,
|
||||
filter: any,
|
||||
// addAttribute: (obj: any) => void,
|
||||
addFilterByKeyAndValue: (key: FilterKey, value: string) => void,
|
||||
updateCurrentPage: (page: number) => void,
|
||||
currentPage: number,
|
||||
totla: number,
|
||||
metaList: any,
|
||||
updateSort: (sort: any) => void,
|
||||
sort: any,
|
||||
total: number,
|
||||
}
|
||||
|
||||
function LiveSessionList(props: Props) {
|
||||
const { loading, filters, list, currentPage, metaList = [], sort } = props;
|
||||
const { loading, metaListLoading, filter, list, currentPage, total, metaList = [], sort } = props;
|
||||
var timeoutId: any;
|
||||
const { filters } = filter;
|
||||
const hasUserFilter = filters.map((i: any) => i.key).includes(KEYS.USERID);
|
||||
const [sessions, setSessions] = React.useState(list);
|
||||
const sortOptions = metaList.map((i: any) => ({
|
||||
text: capitalize(i), label: i
|
||||
label: capitalize(i), value: i
|
||||
})).toJS();
|
||||
|
||||
// useEffect(() => {
|
||||
// if (filters.size === 0) {
|
||||
// props.addFilterByKeyAndValue(FilterKey.USERID, '');
|
||||
// }
|
||||
// }, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (metaList.size === 0 || !!sort.field) return;
|
||||
if (metaListLoading || metaList.size === 0 || !!filter.sort) return;
|
||||
|
||||
if (sortOptions[0]) {
|
||||
props.updateSort({ field: sortOptions[0].value });
|
||||
props.applyFilter({ sort: sortOptions[0].value });
|
||||
}
|
||||
}, [metaList]);
|
||||
}, [metaListLoading]);
|
||||
|
||||
// useEffect(() => {
|
||||
// const filteredSessions = filters.size > 0 ? props.list.filter(session => {
|
||||
|
|
@ -77,7 +72,7 @@ function LiveSessionList(props: Props) {
|
|||
// }, [filters, list]);
|
||||
|
||||
useEffect(() => {
|
||||
props.fetchLiveList();
|
||||
props.applyFilter({ ...filter});
|
||||
timeout();
|
||||
return () => {
|
||||
clearTimeout(timeoutId)
|
||||
|
|
@ -93,13 +88,12 @@ function LiveSessionList(props: Props) {
|
|||
}
|
||||
|
||||
const onSortChange = ({ value }: any) => {
|
||||
value = value.value
|
||||
props.updateSort({ field: value });
|
||||
props.applyFilter({ sort: value.value });
|
||||
}
|
||||
|
||||
const timeout = () => {
|
||||
timeoutId = setTimeout(() => {
|
||||
props.fetchLiveList();
|
||||
props.applyFilter({ ...filter});
|
||||
timeout();
|
||||
}, AUTOREFRESH_INTERVAL);
|
||||
}
|
||||
|
|
@ -110,10 +104,10 @@ function LiveSessionList(props: Props) {
|
|||
<div className="flex items-baseline">
|
||||
<h3 className="text-2xl capitalize">
|
||||
<span>Live Sessions</span>
|
||||
<span className="ml-2 font-normal color-gray-medium">{sessions.size}</span>
|
||||
<span className="ml-2 font-normal color-gray-medium">{total}</span>
|
||||
</h3>
|
||||
|
||||
<LiveSessionReloadButton />
|
||||
<LiveSessionReloadButton onClick={() => props.applyFilter({ ...filter }) } />
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<div className="flex items-center ml-6 mr-4">
|
||||
|
|
@ -122,12 +116,12 @@ function LiveSessionList(props: Props) {
|
|||
plain
|
||||
right
|
||||
options={sortOptions}
|
||||
defaultValue={sort.field}
|
||||
// defaultValue={sort.field}
|
||||
onChange={onSortChange}
|
||||
value={sort.field}
|
||||
value={sortOptions.find((i: any) => i.value === filter.sort) || sortOptions[0]}
|
||||
/>
|
||||
</div>
|
||||
<SortOrderButton onChange={(state: any) => props.updateSort({ order: state })} sortOrder={sort.order} />
|
||||
<SortOrderButton onChange={(state: any) => props.applyFilter({ order: state })} sortOrder={filter.order} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -140,10 +134,10 @@ function LiveSessionList(props: Props) {
|
|||
}
|
||||
image={<img src="/assets/img/live-sessions.png"
|
||||
style={{ width: '70%', marginBottom: '30px' }}/>}
|
||||
show={ !loading && sessions && sessions.size === 0}
|
||||
show={ !loading && list.size === 0}
|
||||
>
|
||||
<Loader loading={ loading }>
|
||||
{sessions.map(session => (
|
||||
{list.map(session => (
|
||||
<SessionItem
|
||||
key={ session.sessionId }
|
||||
session={ session }
|
||||
|
|
@ -157,7 +151,7 @@ function LiveSessionList(props: Props) {
|
|||
<div className="w-full flex items-center justify-center py-6">
|
||||
<Pagination
|
||||
page={currentPage}
|
||||
totalPages={Math.ceil(sessions.size / PER_PAGE)}
|
||||
totalPages={Math.ceil(total / PER_PAGE)}
|
||||
onPageChange={(page: any) => props.updateCurrentPage(page)}
|
||||
limit={PER_PAGE}
|
||||
/>
|
||||
|
|
@ -172,17 +166,16 @@ export default withPermissions(['ASSIST_LIVE'])(connect(
|
|||
(state: any) => ({
|
||||
list: state.getIn(['liveSearch', 'list']),
|
||||
loading: state.getIn([ 'liveSearch', 'fetchList', 'loading' ]),
|
||||
filters: state.getIn([ 'liveSearch', 'instance', 'filters' ]),
|
||||
metaListLoading: state.getIn([ 'customFields', 'fetchRequest', 'loading' ]),
|
||||
filter: state.getIn([ 'liveSearch', 'instance' ]),
|
||||
total: state.getIn([ 'liveSearch', 'total' ]),
|
||||
currentPage: state.getIn(["liveSearch", "currentPage"]),
|
||||
metaList: state.getIn(['customFields', 'list']).map((i: any) => i.key),
|
||||
sort: state.getIn(['liveSearch', 'sort']),
|
||||
}),
|
||||
{
|
||||
fetchLiveList,
|
||||
applyFilter,
|
||||
addAttribute,
|
||||
addFilterByKeyAndValue,
|
||||
updateCurrentPage,
|
||||
updateSort,
|
||||
}
|
||||
)(LiveSessionList));
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
import React from 'react'
|
||||
import ReloadButton from '../ReloadButton'
|
||||
import { connect } from 'react-redux'
|
||||
import { fetchSessions } from 'Duck/liveSearch'
|
||||
// import { fetchSessions } from 'Duck/liveSearch'
|
||||
|
||||
interface Props {
|
||||
loading: boolean
|
||||
fetchSessions: typeof fetchSessions
|
||||
onClick: () => void
|
||||
}
|
||||
function LiveSessionReloadButton(props: Props) {
|
||||
const { loading } = props
|
||||
const { loading, onClick } = props
|
||||
return (
|
||||
<ReloadButton loading={loading} onClick={() => props.fetchSessions()} className="cursor-pointer" />
|
||||
<ReloadButton loading={loading} onClick={onClick} className="cursor-pointer" />
|
||||
)
|
||||
}
|
||||
|
||||
export default connect(state => ({
|
||||
export default connect((state: any) => ({
|
||||
loading: state.getIn([ 'sessions', 'fetchLiveListRequest', 'loading' ]),
|
||||
}), { fetchSessions })(LiveSessionReloadButton)
|
||||
}))(LiveSessionReloadButton)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
import React from 'react';
|
||||
import FilterList from 'Shared/Filters/FilterList';
|
||||
import FilterSelection from 'Shared/Filters/FilterSelection';
|
||||
import SaveFilterButton from 'Shared/SaveFilterButton';
|
||||
import { connect } from 'react-redux';
|
||||
import { Button } from 'UI';
|
||||
import { edit, addFilter } from 'Duck/liveSearch';
|
||||
import SaveFunnelButton from '../SaveFunnelButton';
|
||||
|
||||
interface Props {
|
||||
appliedFilter: any;
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ interface Props {
|
|||
[x:string]: any;
|
||||
}
|
||||
export default function({ name = '', onChange, right = false, plain = false, options, isSearchable = false, components = {}, styles = {}, defaultValue = '', ...rest }: Props) {
|
||||
const defaultSelected = options.find(o => o.value === defaultValue) || options[0];
|
||||
const defaultSelected = defaultValue ? (options.find(o => o.value === defaultValue) || options[0]): null;
|
||||
const customStyles = {
|
||||
option: (provided, state) => ({
|
||||
option: (provided: any, state: any) => ({
|
||||
...provided,
|
||||
whiteSpace: 'nowrap',
|
||||
transition: 'all 0.3s',
|
||||
|
|
|
|||
|
|
@ -10,11 +10,12 @@ interface Props {
|
|||
period: any,
|
||||
onChange: (data: any) => void;
|
||||
disableCustom?: boolean;
|
||||
right?: boolean;
|
||||
[x: string]: any;
|
||||
}
|
||||
function SelectDateRange(props: Props) {
|
||||
const [isCustom, setIsCustom] = React.useState(false);
|
||||
const { period, disableCustom = false, ...rest } = props;
|
||||
const { right = false, period, disableCustom = false, ...rest } = props;
|
||||
let selectedValue = DATE_RANGE_OPTIONS.find((obj: any) => obj.value === period.rangeName)
|
||||
const options = DATE_RANGE_OPTIONS.filter((obj: any) => disableCustom ? obj.value !== CUSTOM_RANGE : true);
|
||||
|
||||
|
|
@ -54,7 +55,7 @@ function SelectDateRange(props: Props) {
|
|||
<OutsideClickDetectingDiv
|
||||
onClickOutside={() => setIsCustom(false)}
|
||||
>
|
||||
<div className="absolute top-0 mt-10 z-40 right-0" style={{
|
||||
<div className={ cn("absolute top-0 mt-10 z-40", { 'right-0' : right })} style={{
|
||||
width: '770px',
|
||||
// margin: 'auto 50vh 0',
|
||||
// transform: 'translateX(-50%)'
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ function ListingVisibility(props) {
|
|||
type="number"
|
||||
name="count"
|
||||
placeholder="E.g 10"
|
||||
style={{ height: '38px', width: '100%'}}
|
||||
// style={{ height: '38px', width: '100%'}}
|
||||
onChange={(e, { value }) => {
|
||||
changeSettings({ count: value })
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ function Input(props: Props) {
|
|||
return (
|
||||
<div className={cn({ "relative" : icon || leadingButton }, wrapperClassName)}>
|
||||
{icon && <Icon name={icon} className="absolute top-0 bottom-0 my-auto ml-4" size="14" />}
|
||||
<input className={ cn("p-2 border border-gray-light bg-white h-10 w-full rounded", className, { 'pl-10' : icon }) } {...rest} />
|
||||
<input style={{ height: '36px'}} className={ cn("p-2 border border-gray-light bg-white w-full rounded", className, { 'pl-10' : icon }) } {...rest} />
|
||||
{ leadingButton && <div className="absolute top-0 bottom-0 right-0">{ leadingButton }</div> }
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ export const fetchList = (siteId) => (dispatch, getState) => {
|
|||
dispatch(refreshFilterOptions());
|
||||
});
|
||||
}
|
||||
|
||||
export const fetchSources = () => {
|
||||
return {
|
||||
types: array(FETCH_SOURCES),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { fetchListType, fetchType, editType } from './funcTools/crud';
|
|||
import { createRequestReducer } from './funcTools/request';
|
||||
import { mergeReducers, success } from './funcTools/tools';
|
||||
import Filter from 'Types/filter';
|
||||
// import { fetchList as fetchSessionList } from './sessions';
|
||||
import { liveFiltersMap, filtersMap } from 'Types/filter/newFilter';
|
||||
import { filterMap, checkFilterValue, hasFilterApplied } from './search';
|
||||
import Session from 'Types/session';
|
||||
|
|
@ -17,29 +16,24 @@ const EDIT = editType(name);
|
|||
const CLEAR_SEARCH = `${name}/CLEAR_SEARCH`;
|
||||
const APPLY = `${name}/APPLY`;
|
||||
const UPDATE_CURRENT_PAGE = `${name}/UPDATE_CURRENT_PAGE`;
|
||||
const UPDATE_SORT = `${name}/UPDATE_SORT`;
|
||||
const FETCH_SESSION_LIST = fetchListType(`${name}/FETCH_SESSION_LIST`);
|
||||
|
||||
const initialState = Map({
|
||||
list: List(),
|
||||
instance: new Filter({ filters: [] }),
|
||||
instance: new Filter({ filters: [], sort: '' }),
|
||||
filterSearchList: {},
|
||||
currentPage: 1,
|
||||
sort: {
|
||||
order: 'asc',
|
||||
field: ''
|
||||
}
|
||||
});
|
||||
|
||||
function reducer(state = initialState, action = {}) {
|
||||
switch (action.type) {
|
||||
case APPLY:
|
||||
return state.mergeIn(['instance'], action.filter).set('currentPage', 1);
|
||||
case EDIT:
|
||||
return state.mergeIn(['instance'], action.instance);
|
||||
return state.mergeIn(['instance'], action.instance).set('currentPage', 1);
|
||||
case UPDATE_CURRENT_PAGE:
|
||||
return state.set('currentPage', action.page);
|
||||
case UPDATE_SORT:
|
||||
return state.mergeIn(['sort'], action.sort);
|
||||
case FETCH_SESSION_LIST:
|
||||
case success(FETCH_SESSION_LIST):
|
||||
const { sessions, total } = action.data;
|
||||
const list = List(sessions).map(Session);
|
||||
return state
|
||||
|
|
@ -72,7 +66,6 @@ const reduceThenFetchResource = actionCreator => (...args) => (dispatch, getStat
|
|||
dispatch(actionCreator(...args));
|
||||
const filter = getState().getIn([ 'liveSearch', 'instance']).toData();
|
||||
filter.filters = filter.filters.map(filterMap);
|
||||
|
||||
filter.limit = 10;
|
||||
filter.page = getState().getIn([ 'liveSearch', 'currentPage']);
|
||||
|
||||
|
|
@ -91,10 +84,9 @@ export const edit = reduceThenFetchResource((instance) => ({
|
|||
instance,
|
||||
}));
|
||||
|
||||
export const applyFilter = reduceThenFetchResource((filter, fromUrl=false) => ({
|
||||
export const applyFilter = reduceThenFetchResource((filter) => ({
|
||||
type: APPLY,
|
||||
filter,
|
||||
fromUrl,
|
||||
}));
|
||||
|
||||
export const fetchSessions = (filter) => (dispatch, getState) => {
|
||||
|
|
@ -125,7 +117,7 @@ export const addFilter = (filter) => (dispatch, getState) => {
|
|||
}
|
||||
|
||||
export const addFilterByKeyAndValue = (key, value, operator = undefined) => (dispatch, getState) => {
|
||||
let defaultFilter = filtersMap[key];
|
||||
let defaultFilter = liveFiltersMap[key];
|
||||
defaultFilter.value = value;
|
||||
if (operator) {
|
||||
defaultFilter.operator = operator;
|
||||
|
|
@ -133,19 +125,10 @@ export const addFilterByKeyAndValue = (key, value, operator = undefined) => (dis
|
|||
dispatch(addFilter(defaultFilter));
|
||||
}
|
||||
|
||||
export function updateCurrentPage(page) {
|
||||
return {
|
||||
type: UPDATE_CURRENT_PAGE,
|
||||
page,
|
||||
};
|
||||
}
|
||||
|
||||
export function updateSort(sort) {
|
||||
return {
|
||||
type: UPDATE_SORT,
|
||||
sort,
|
||||
};
|
||||
}
|
||||
export const updateCurrentPage = reduceThenFetchResource((page, fromUrl=false) => ({
|
||||
type: UPDATE_CURRENT_PAGE,
|
||||
page,
|
||||
}));
|
||||
|
||||
export function fetchFilterSearch(params) {
|
||||
params.live = true
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ export const checkFilterValue = (value) => {
|
|||
return Array.isArray(value) ? (value.length === 0 ? [""] : value) : [value];
|
||||
}
|
||||
|
||||
export const filterMap = ({category, value, key, operator, sourceOperator, source, custom, isEvent, filters }) => ({
|
||||
export const filterMap = ({category, value, key, operator, sourceOperator, source, custom, isEvent, filters, sort, order }) => ({
|
||||
value: checkValues(key, value),
|
||||
custom,
|
||||
type: category === FilterCategory.METADATA ? FilterKey.METADATA : key,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { capitalize } from 'App/utils';
|
|||
const countryOptions = Object.keys(countries).map(i => ({ label: countries[i], value: i }));
|
||||
const containsFilters = [{ key: 'contains', label: 'contains', text: 'contains', value: 'contains' }]
|
||||
|
||||
export const metaFilter = { key: FilterKey.METADATA, type: FilterType.MULTIPLE, category: FilterCategory.METADATA, label: 'Metadata', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/metadata' };
|
||||
// export const metaFilter = { key: FilterKey.METADATA, type: FilterType.MULTIPLE, category: FilterCategory.METADATA, label: 'Metadata', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/metadata' };
|
||||
export const filters = [
|
||||
{ key: FilterKey.CLICK, type: FilterType.MULTIPLE, category: FilterCategory.INTERACTIONS, label: 'Click', operator: 'on', operatorOptions: filterOptions.targetOperators, icon: 'filters/click', isEvent: true },
|
||||
{ key: FilterKey.INPUT, type: FilterType.MULTIPLE, category: FilterCategory.INTERACTIONS, label: 'Input', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/input', isEvent: true },
|
||||
|
|
@ -29,7 +29,7 @@ export const filters = [
|
|||
]},
|
||||
{ key: FilterKey.STATEACTION, type: FilterType.MULTIPLE, category: FilterCategory.JAVASCRIPT, label: 'StateAction', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/state-action', isEvent: true },
|
||||
{ key: FilterKey.ERROR, type: FilterType.MULTIPLE, category: FilterCategory.JAVASCRIPT, label: 'Error', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/error', isEvent: true },
|
||||
{ key: FilterKey.METADATA, type: FilterType.MULTIPLE, category: FilterCategory.METADATA, label: 'Metadata', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/metadata', isEvent: true },
|
||||
// { key: FilterKey.METADATA, type: FilterType.MULTIPLE, category: FilterCategory.METADATA, label: 'Metadata', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/metadata', isEvent: true },
|
||||
|
||||
// FILTERS
|
||||
{ key: FilterKey.USER_OS, type: FilterType.MULTIPLE, category: FilterCategory.GEAR, label: 'User OS', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/os' },
|
||||
|
|
@ -63,9 +63,16 @@ export const liveFiltersMap = filters.reduce((acc, filter) => {
|
|||
if (
|
||||
filter.category !== FilterCategory.INTERACTIONS &&
|
||||
filter.category !== FilterCategory.JAVASCRIPT &&
|
||||
filter.category !== FilterCategory.PERFORMANCE
|
||||
filter.category !== FilterCategory.PERFORMANCE &&
|
||||
filter.key !== FilterKey.DURATION &&
|
||||
filter.key !== FilterKey.REFERRER
|
||||
) {
|
||||
acc[filter.key] = filter;
|
||||
acc[filter.key].operator = 'contains';
|
||||
acc[filter.key].operatorDisabled = true;
|
||||
if (filter.key === FilterKey.PLATFORM) {
|
||||
acc[filter.key].operator = 'is';
|
||||
}
|
||||
}
|
||||
return acc
|
||||
}, {});
|
||||
|
|
@ -98,12 +105,19 @@ export const addElementToFiltersMap = (
|
|||
export const addElementToLiveFiltersMap = (
|
||||
category = FilterCategory.METADATA,
|
||||
key,
|
||||
type = FilterType.STRING,
|
||||
type = FilterType.MULTIPLE,
|
||||
operator = 'contains',
|
||||
operatorOptions = containsFilters,
|
||||
icon = 'filters/metadata'
|
||||
) => {
|
||||
liveFiltersMap[key] = { key, type, category, label: capitalize(key), operator: operator, operatorOptions, icon, isLive: true }
|
||||
liveFiltersMap[key] = {
|
||||
key, type, category, label: capitalize(key),
|
||||
operator: operator,
|
||||
operatorOptions,
|
||||
icon,
|
||||
operatorDisabled: true,
|
||||
isLive: true
|
||||
}
|
||||
}
|
||||
|
||||
export default Record({
|
||||
|
|
@ -132,11 +146,13 @@ export default Record({
|
|||
|
||||
operator: '',
|
||||
operatorOptions: [],
|
||||
operatorDisabled: false,
|
||||
isEvent: false,
|
||||
index: 0,
|
||||
options: [],
|
||||
|
||||
filters: [],
|
||||
|
||||
}, {
|
||||
keyKey: "_key",
|
||||
fromJS: ({ value, type, subFilter = false, ...filter }) => {
|
||||
|
|
@ -189,6 +205,7 @@ export const generateLiveFilterOptions = (map) => {
|
|||
Object.keys(map).filter(i => map[i].isLive).forEach(key => {
|
||||
const filter = map[key];
|
||||
filter.operator = 'contains';
|
||||
filter.operatorDisabled = true;
|
||||
if (filterSection.hasOwnProperty(filter.category)) {
|
||||
filterSection[filter.category].push(filter);
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue