Ios conditions (#2039)
* feat(ui): condition set for mobile * feat(ui): more filters for mobile, auto recognize mobile projects * feat(ui): add memoryUsage filter for ios * fix(ui): fix up filter name * fix(ui): lost files * fix(ui): cast filter value to string? * feat(ui): condition set for mobile * feat(ui): more filters for mobile, auto recognize mobile projects * feat(ui): add memoryUsage filter for ios * fix(ui): fix up filter name * fix(ui): lost files * fix(ui): cast filter value to string?
This commit is contained in:
parent
eaadcf4604
commit
44d934e956
11 changed files with 225 additions and 31 deletions
|
|
@ -173,6 +173,7 @@ const Sites = ({ loading, sites, user, init }: PropsFromRedux) => {
|
||||||
setShowCaptureRate={setShowCaptureRate}
|
setShowCaptureRate={setShowCaptureRate}
|
||||||
showCaptureRate={showCaptureRate}
|
showCaptureRate={showCaptureRate}
|
||||||
projectId={activeProject?.id}
|
projectId={activeProject?.id}
|
||||||
|
isMobile={activeProject?.platform !== 'web'}
|
||||||
open={showCaptureRate && !!activeProject}
|
open={showCaptureRate && !!activeProject}
|
||||||
/>
|
/>
|
||||||
</Loader>
|
</Loader>
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ interface Props {
|
||||||
onChangeEventsOrder: (_: any, { name, value }: any) => void;
|
onChangeEventsOrder: (_: any, { name, value }: any) => void;
|
||||||
isConditional?: boolean;
|
isConditional?: boolean;
|
||||||
changeName: (name: string) => void;
|
changeName: (name: string) => void;
|
||||||
|
isMobile?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ConditionSetComponent({
|
function ConditionSetComponent({
|
||||||
|
|
@ -40,6 +41,7 @@ function ConditionSetComponent({
|
||||||
onRemoveFilter,
|
onRemoveFilter,
|
||||||
onChangeEventsOrder,
|
onChangeEventsOrder,
|
||||||
isConditional,
|
isConditional,
|
||||||
|
isMobile,
|
||||||
changeName,
|
changeName,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
return (
|
return (
|
||||||
|
|
@ -97,6 +99,7 @@ function ConditionSetComponent({
|
||||||
filter={undefined}
|
filter={undefined}
|
||||||
onFilterClick={onAddFilter}
|
onFilterClick={onAddFilter}
|
||||||
excludeFilterKeys={excludeFilterKeys}
|
excludeFilterKeys={excludeFilterKeys}
|
||||||
|
isMobile={isMobile}
|
||||||
>
|
>
|
||||||
<Button variant="text-primary" icon="plus">
|
<Button variant="text-primary" icon="plus">
|
||||||
Add Condition
|
Add Condition
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ interface Props {
|
||||||
setChanged?: (changed: boolean) => void;
|
setChanged?: (changed: boolean) => void;
|
||||||
excludeFilterKeys?: string[];
|
excludeFilterKeys?: string[];
|
||||||
isConditional?: boolean;
|
isConditional?: boolean;
|
||||||
|
isMobile?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ConditionSet({
|
function ConditionSet({
|
||||||
|
|
@ -28,6 +29,7 @@ function ConditionSet({
|
||||||
setChanged,
|
setChanged,
|
||||||
excludeFilterKeys,
|
excludeFilterKeys,
|
||||||
isConditional,
|
isConditional,
|
||||||
|
isMobile,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const [forceRender, forceRerender] = React.useState(false);
|
const [forceRender, forceRerender] = React.useState(false);
|
||||||
|
|
||||||
|
|
@ -87,6 +89,7 @@ function ConditionSet({
|
||||||
onRemoveFilter={onRemoveFilter}
|
onRemoveFilter={onRemoveFilter}
|
||||||
onChangeEventsOrder={onChangeEventsOrder}
|
onChangeEventsOrder={onChangeEventsOrder}
|
||||||
isConditional={isConditional}
|
isConditional={isConditional}
|
||||||
|
isMobile={isMobile}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,7 @@ import {
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { Icon, Loader } from 'UI';
|
import { Icon, Loader } from 'UI';
|
||||||
|
|
||||||
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
||||||
|
|
||||||
import { FilterKey } from '../../../../types/filter/filterType';
|
import { FilterKey } from '../../../../types/filter/filterType';
|
||||||
|
|
@ -122,21 +120,23 @@ export const getMatchingEntries = (
|
||||||
interface Props {
|
interface Props {
|
||||||
filters: any;
|
filters: any;
|
||||||
conditionalFilters: any;
|
conditionalFilters: any;
|
||||||
|
mobileConditionalFilters: any;
|
||||||
onFilterClick?: (filter: any) => void;
|
onFilterClick?: (filter: any) => void;
|
||||||
filterSearchList: any;
|
filterSearchList: any;
|
||||||
// metaOptions: any,
|
|
||||||
isMainSearch?: boolean;
|
isMainSearch?: boolean;
|
||||||
fetchingFilterSearchList: boolean;
|
fetchingFilterSearchList: boolean;
|
||||||
searchQuery?: string;
|
searchQuery?: string;
|
||||||
excludeFilterKeys?: Array<string>;
|
excludeFilterKeys?: Array<string>;
|
||||||
allowedFilterKeys?: Array<string>;
|
allowedFilterKeys?: Array<string>;
|
||||||
isConditional?: boolean;
|
isConditional?: boolean;
|
||||||
|
isMobile?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function FilterModal(props: Props) {
|
function FilterModal(props: Props) {
|
||||||
const {
|
const {
|
||||||
filters,
|
filters,
|
||||||
conditionalFilters,
|
conditionalFilters,
|
||||||
|
mobileConditionalFilters,
|
||||||
onFilterClick = () => null,
|
onFilterClick = () => null,
|
||||||
filterSearchList,
|
filterSearchList,
|
||||||
isMainSearch = false,
|
isMainSearch = false,
|
||||||
|
|
@ -145,6 +145,7 @@ function FilterModal(props: Props) {
|
||||||
excludeFilterKeys = [],
|
excludeFilterKeys = [],
|
||||||
allowedFilterKeys = [],
|
allowedFilterKeys = [],
|
||||||
isConditional,
|
isConditional,
|
||||||
|
isMobile,
|
||||||
} = props;
|
} = props;
|
||||||
const showSearchList = isMainSearch && searchQuery.length > 0;
|
const showSearchList = isMainSearch && searchQuery.length > 0;
|
||||||
|
|
||||||
|
|
@ -154,14 +155,12 @@ function FilterModal(props: Props) {
|
||||||
onFilterClick(_filter);
|
onFilterClick(_filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const filterJsonObj = isConditional
|
||||||
|
? isMobile ? mobileConditionalFilters : conditionalFilters
|
||||||
|
: filters;
|
||||||
const { matchingCategories, matchingFilters } = getMatchingEntries(
|
const { matchingCategories, matchingFilters } = getMatchingEntries(
|
||||||
searchQuery,
|
searchQuery,
|
||||||
filterJson(
|
filterJson(filterJsonObj, excludeFilterKeys, allowedFilterKeys)
|
||||||
isConditional ? conditionalFilters : filters,
|
|
||||||
excludeFilterKeys,
|
|
||||||
allowedFilterKeys
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const isResultEmpty =
|
const isResultEmpty =
|
||||||
(!filterSearchList || Object.keys(filterSearchList).length === 0) &&
|
(!filterSearchList || Object.keys(filterSearchList).length === 0) &&
|
||||||
|
|
@ -275,6 +274,7 @@ export default connect((state: any, props: any) => {
|
||||||
? state.getIn(['search', 'filterListLive'])
|
? state.getIn(['search', 'filterListLive'])
|
||||||
: state.getIn(['search', 'filterList']),
|
: state.getIn(['search', 'filterList']),
|
||||||
conditionalFilters: state.getIn(['search', 'filterListConditional']),
|
conditionalFilters: state.getIn(['search', 'filterListConditional']),
|
||||||
|
mobileConditionalFilters: state.getIn(['search', 'filterListMobileConditional']),
|
||||||
filterSearchList: props.isLive
|
filterSearchList: props.isLive
|
||||||
? state.getIn(['liveSearch', 'filterSearchList'])
|
? state.getIn(['liveSearch', 'filterSearchList'])
|
||||||
: state.getIn(['search', 'filterSearchList']),
|
: state.getIn(['search', 'filterSearchList']),
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,11 @@ interface Props {
|
||||||
allowedFilterKeys?: Array<string>;
|
allowedFilterKeys?: Array<string>;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
isConditional?: boolean;
|
isConditional?: boolean;
|
||||||
|
isMobile?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function FilterSelection(props: Props) {
|
function FilterSelection(props: Props) {
|
||||||
const { filter, onFilterClick, children, excludeFilterKeys = [], allowedFilterKeys = [], disabled = false, isConditional } = props;
|
const { filter, onFilterClick, children, excludeFilterKeys = [], allowedFilterKeys = [], disabled = false, isConditional, isMobile } = props;
|
||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -68,6 +69,7 @@ function FilterSelection(props: Props) {
|
||||||
excludeFilterKeys={excludeFilterKeys}
|
excludeFilterKeys={excludeFilterKeys}
|
||||||
allowedFilterKeys={allowedFilterKeys}
|
allowedFilterKeys={allowedFilterKeys}
|
||||||
isConditional={isConditional}
|
isConditional={isConditional}
|
||||||
|
isMobile={isMobile}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,12 @@ type Props = {
|
||||||
setShowCaptureRate: (show: boolean) => void;
|
setShowCaptureRate: (show: boolean) => void;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
showCaptureRate: boolean;
|
showCaptureRate: boolean;
|
||||||
|
isMobile?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
function CaptureRate(props: Props) {
|
function CaptureRate(props: Props) {
|
||||||
const [conditions, setConditions] = React.useState<Conditions[]>([]);
|
const [conditions, setConditions] = React.useState<Conditions[]>([]);
|
||||||
const { isAdmin, projectId, isEnterprise } = props;
|
const { isAdmin, projectId, isEnterprise, isMobile } = props;
|
||||||
const { settingsStore } = useStore();
|
const { settingsStore } = useStore();
|
||||||
const [changed, setChanged] = useState(false);
|
const [changed, setChanged] = useState(false);
|
||||||
const {
|
const {
|
||||||
|
|
@ -42,7 +43,7 @@ function CaptureRate(props: Props) {
|
||||||
}, [projectId]);
|
}, [projectId]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setConditions(captureConditions.map((condition: any) => new Conditions(condition, true)));
|
setConditions(captureConditions.map((condition: any) => new Conditions(condition, true, isMobile)));
|
||||||
}, [captureConditions]);
|
}, [captureConditions]);
|
||||||
|
|
||||||
const onCaptureRateChange = (input: string) => {
|
const onCaptureRateChange = (input: string) => {
|
||||||
|
|
@ -137,6 +138,7 @@ function CaptureRate(props: Props) {
|
||||||
setChanged={setChanged}
|
setChanged={setChanged}
|
||||||
conditions={conditions}
|
conditions={conditions}
|
||||||
setConditions={setConditions}
|
setConditions={setConditions}
|
||||||
|
isMobile={isMobile}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,12 @@ function ConditionalRecordingSettings({
|
||||||
conditions,
|
conditions,
|
||||||
setConditions,
|
setConditions,
|
||||||
setChanged,
|
setChanged,
|
||||||
|
isMobile,
|
||||||
}: {
|
}: {
|
||||||
setChanged: (changed: boolean) => void;
|
setChanged: (changed: boolean) => void;
|
||||||
conditions: Conditions[];
|
conditions: Conditions[];
|
||||||
setConditions: (conditions: Conditions[]) => void;
|
setConditions: (conditions: Conditions[]) => void;
|
||||||
|
isMobile?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const addConditionSet = () => {
|
const addConditionSet = () => {
|
||||||
setChanged(true);
|
setChanged(true);
|
||||||
|
|
@ -60,6 +62,7 @@ function ConditionalRecordingSettings({
|
||||||
setChanged={setChanged}
|
setChanged={setChanged}
|
||||||
excludeFilterKeys={nonConditionalFlagFilters}
|
excludeFilterKeys={nonConditionalFlagFilters}
|
||||||
isConditional
|
isConditional
|
||||||
|
isMobile={isMobile}
|
||||||
/>
|
/>
|
||||||
{index !== conditions.length - 1 ? (
|
{index !== conditions.length - 1 ? (
|
||||||
<div className={'text-disabled-text flex justify-center w-full'}>
|
<div className={'text-disabled-text flex justify-center w-full'}>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { createEdit, createInit } from './funcTools/crud';
|
||||||
import { createRequestReducer } from './funcTools/request';
|
import { createRequestReducer } from './funcTools/request';
|
||||||
import {
|
import {
|
||||||
addElementToConditionalFiltersMap,
|
addElementToConditionalFiltersMap,
|
||||||
|
addElementToMobileConditionalFiltersMap,
|
||||||
addElementToFiltersMap,
|
addElementToFiltersMap,
|
||||||
addElementToFlagConditionsMap,
|
addElementToFlagConditionsMap,
|
||||||
addElementToLiveFiltersMap,
|
addElementToLiveFiltersMap,
|
||||||
|
|
@ -54,6 +55,7 @@ const reducer = (state = initialState, action = {}) => {
|
||||||
addElementToLiveFiltersMap(FilterCategory.METADATA, '_' + item.key);
|
addElementToLiveFiltersMap(FilterCategory.METADATA, '_' + item.key);
|
||||||
addElementToFlagConditionsMap(FilterCategory.METADATA, '_' + item.key)
|
addElementToFlagConditionsMap(FilterCategory.METADATA, '_' + item.key)
|
||||||
addElementToConditionalFiltersMap(FilterCategory.METADATA, '_' + item.key)
|
addElementToConditionalFiltersMap(FilterCategory.METADATA, '_' + item.key)
|
||||||
|
addElementToMobileConditionalFiltersMap(FilterCategory.METADATA, '_' + item.key)
|
||||||
});
|
});
|
||||||
return state.set('list', List(action.data).map(CustomField)).set('fetchedMetadata', true)
|
return state.set('list', List(action.data).map(CustomField)).set('fetchedMetadata', true)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ import {
|
||||||
filtersMap,
|
filtersMap,
|
||||||
liveFiltersMap,
|
liveFiltersMap,
|
||||||
conditionalFiltersMap,
|
conditionalFiltersMap,
|
||||||
generateFilterOptions
|
generateFilterOptions,
|
||||||
|
mobileConditionalFiltersMap,
|
||||||
} from "Types/filter/newFilter";
|
} from "Types/filter/newFilter";
|
||||||
import { DURATION_FILTER } from 'App/constants/storageKeys';
|
import { DURATION_FILTER } from 'App/constants/storageKeys';
|
||||||
import Period, { CUSTOM_RANGE } from 'Types/app/period';
|
import Period, { CUSTOM_RANGE } from 'Types/app/period';
|
||||||
|
|
@ -20,7 +21,6 @@ import Period, { CUSTOM_RANGE } from 'Types/app/period';
|
||||||
const ERRORS_ROUTE = errorsRoute();
|
const ERRORS_ROUTE = errorsRoute();
|
||||||
|
|
||||||
const name = 'search';
|
const name = 'search';
|
||||||
const idKey = 'searchId';
|
|
||||||
const PER_PAGE = 10;
|
const PER_PAGE = 10;
|
||||||
|
|
||||||
const FETCH_LIST = fetchListType(name);
|
const FETCH_LIST = fetchListType(name);
|
||||||
|
|
@ -43,19 +43,11 @@ const REFRESH_FILTER_OPTIONS = 'filters/REFRESH_FILTER_OPTIONS';
|
||||||
const CHECK_LATEST = fetchListType(`${name}/CHECK_LATEST`);
|
const CHECK_LATEST = fetchListType(`${name}/CHECK_LATEST`);
|
||||||
const UPDATE_LATEST_REQUEST_TIME = 'filters/UPDATE_LATEST_REQUEST_TIME'
|
const UPDATE_LATEST_REQUEST_TIME = 'filters/UPDATE_LATEST_REQUEST_TIME'
|
||||||
|
|
||||||
// function chartWrapper(chart = []) {
|
|
||||||
// return chart.map((point) => ({ ...point, count: Math.max(point.count, 0) }));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const savedSearchIdKey = 'searchId';
|
|
||||||
// const updateItemInList = createListUpdater(savedSearchIdKey);
|
|
||||||
// const updateInstance = (state, instance) =>
|
|
||||||
// state.getIn(['savedSearch', savedSearchIdKey]) === instance[savedSearchIdKey] ? state.mergeIn(['savedSearch'], SavedFilter(instance)) : state;
|
|
||||||
|
|
||||||
const initialState = Map({
|
const initialState = Map({
|
||||||
filterList: generateFilterOptions(filtersMap),
|
filterList: generateFilterOptions(filtersMap),
|
||||||
filterListLive: generateFilterOptions(liveFiltersMap),
|
filterListLive: generateFilterOptions(liveFiltersMap),
|
||||||
filterListConditional: generateFilterOptions(conditionalFiltersMap),
|
filterListConditional: generateFilterOptions(conditionalFiltersMap),
|
||||||
|
filterListMobileConditional: generateFilterOptions(mobileConditionalFiltersMap),
|
||||||
list: List(),
|
list: List(),
|
||||||
latestRequestTime: null,
|
latestRequestTime: null,
|
||||||
latestList: List(),
|
latestList: List(),
|
||||||
|
|
@ -76,7 +68,8 @@ function reducer(state = initialState, action = {}) {
|
||||||
return state
|
return state
|
||||||
.set('filterList', generateFilterOptions(filtersMap))
|
.set('filterList', generateFilterOptions(filtersMap))
|
||||||
.set('filterListLive', generateFilterOptions(liveFiltersMap))
|
.set('filterListLive', generateFilterOptions(liveFiltersMap))
|
||||||
.set('filterListConditional', generateFilterOptions(conditionalFiltersMap));
|
.set('filterListConditional', generateFilterOptions(conditionalFiltersMap))
|
||||||
|
.set('filterListMobileConditional', generateFilterOptions(mobileConditionalFiltersMap))
|
||||||
case EDIT:
|
case EDIT:
|
||||||
return state.mergeIn(['instance'], action.instance).set('currentPage', 1);
|
return state.mergeIn(['instance'], action.instance).set('currentPage', 1);
|
||||||
case APPLY:
|
case APPLY:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { makeAutoObservable, observable, action } from 'mobx';
|
import { makeAutoObservable, observable, action } from 'mobx';
|
||||||
import { FilterKey, FilterType, FilterCategory } from 'Types/filter/filterType';
|
import { FilterKey, FilterType, FilterCategory } from 'Types/filter/filterType';
|
||||||
import { filtersMap, conditionalFiltersMap } from 'Types/filter/newFilter';
|
import { filtersMap, conditionalFiltersMap, mobileConditionalFiltersMap } from 'Types/filter/newFilter';
|
||||||
|
|
||||||
export default class FilterItem {
|
export default class FilterItem {
|
||||||
type: string = '';
|
type: string = '';
|
||||||
|
|
@ -65,7 +65,11 @@ export default class FilterItem {
|
||||||
const isMetadata = json.type === FilterKey.METADATA;
|
const isMetadata = json.type === FilterKey.METADATA;
|
||||||
let _filter: any = (isMetadata ? filtersMap['_' + json.source] : filtersMap[json.type]) || {};
|
let _filter: any = (isMetadata ? filtersMap['_' + json.source] : filtersMap[json.type]) || {};
|
||||||
if (this.isConditional) {
|
if (this.isConditional) {
|
||||||
_filter = conditionalFiltersMap[json.type] || conditionalFiltersMap[json.source];
|
if (this.isMobile) {
|
||||||
|
_filter = mobileConditionalFiltersMap[json.type] || mobileConditionalFiltersMap[json.source];
|
||||||
|
} else {
|
||||||
|
_filter = conditionalFiltersMap[json.type] || conditionalFiltersMap[json.source];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (mainFilterKey) {
|
if (mainFilterKey) {
|
||||||
const mainFilter = filtersMap[mainFilterKey];
|
const mainFilter = filtersMap[mainFilterKey];
|
||||||
|
|
@ -108,7 +112,7 @@ export default class FilterItem {
|
||||||
const json = {
|
const json = {
|
||||||
type: isMetadata ? FilterKey.METADATA : this.key,
|
type: isMetadata ? FilterKey.METADATA : this.key,
|
||||||
isEvent: Boolean(this.isEvent),
|
isEvent: Boolean(this.isEvent),
|
||||||
value: this.value,
|
value: this.value.map((i: any) => i && i.toString()),
|
||||||
operator: this.operator,
|
operator: this.operator,
|
||||||
source: isMetadata ? this.key.replace(/^_/, '') : this.source,
|
source: isMetadata ? this.key.replace(/^_/, '') : this.source,
|
||||||
sourceOperator: this.sourceOperator,
|
sourceOperator: this.sourceOperator,
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ export const filters = [
|
||||||
operator: 'is',
|
operator: 'is',
|
||||||
placeholder: 'Select method type',
|
placeholder: 'Select method type',
|
||||||
operatorOptions: filterOptions.stringOperatorsLimited,
|
operatorOptions: filterOptions.stringOperatorsLimited,
|
||||||
icon: 'filters/fetch',
|
icon: 'filters/fetch',
|
||||||
options: filterOptions.methodOptions
|
options: filterOptions.methodOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -658,12 +658,174 @@ export const conditionalFilters = [
|
||||||
return aOrder - bOrder
|
return aOrder - bOrder
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const mobileConditionalFilters = [
|
||||||
|
{
|
||||||
|
key: FilterKey.DURATION,
|
||||||
|
type: FilterType.DURATION,
|
||||||
|
category: FilterCategory.RECORDING_ATTRIBUTES,
|
||||||
|
label: 'Duration',
|
||||||
|
operator: 'is',
|
||||||
|
operatorOptions: filterOptions.getOperatorsByKeys(['is']),
|
||||||
|
icon: "filters/duration",
|
||||||
|
isEvent: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: FilterKey.FETCH,
|
||||||
|
type: FilterType.SUB_FILTERS,
|
||||||
|
category: FilterCategory.RECORDING_ATTRIBUTES,
|
||||||
|
operator: 'is',
|
||||||
|
label: 'Network Request',
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
key: FilterKey.FETCH_URL,
|
||||||
|
type: FilterType.MULTIPLE,
|
||||||
|
category: FilterCategory.PERFORMANCE,
|
||||||
|
label: 'with URL',
|
||||||
|
placeholder: 'Enter path or URL',
|
||||||
|
operator: 'is',
|
||||||
|
operatorOptions: filterOptions.stringConditional,
|
||||||
|
icon: "filters/fetch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: FilterKey.FETCH_STATUS_CODE,
|
||||||
|
type: FilterType.NUMBER_MULTIPLE,
|
||||||
|
category: FilterCategory.PERFORMANCE,
|
||||||
|
label: 'with status code',
|
||||||
|
placeholder: 'Enter status code',
|
||||||
|
operator: '=',
|
||||||
|
operatorOptions: filterOptions.customOperators,
|
||||||
|
icon: "filters/fetch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: FilterKey.FETCH_METHOD,
|
||||||
|
type: FilterType.MULTIPLE_DROPDOWN,
|
||||||
|
category: FilterCategory.PERFORMANCE,
|
||||||
|
label: 'with method',
|
||||||
|
operator: 'is',
|
||||||
|
placeholder: 'Select method type',
|
||||||
|
operatorOptions: filterOptions.stringOperatorsLimited,
|
||||||
|
icon: 'filters/fetch',
|
||||||
|
options: filterOptions.methodOptions
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: FilterKey.FETCH_DURATION,
|
||||||
|
type: FilterType.NUMBER,
|
||||||
|
category: FilterCategory.PERFORMANCE,
|
||||||
|
label: 'with duration (ms)',
|
||||||
|
placeholder: 'E.g. 12',
|
||||||
|
operator: '=',
|
||||||
|
operatorOptions: filterOptions.customOperators,
|
||||||
|
icon: "filters/fetch"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
icon: 'filters/fetch',
|
||||||
|
isEvent: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: FilterKey.CUSTOM,
|
||||||
|
type: FilterType.MULTIPLE,
|
||||||
|
category: FilterCategory.RECORDING_ATTRIBUTES,
|
||||||
|
label: 'Custom Events',
|
||||||
|
placeholder: 'Enter event key',
|
||||||
|
operator: 'is',
|
||||||
|
operatorOptions: filterOptions.stringConditional,
|
||||||
|
icon: 'filters/custom',
|
||||||
|
isEvent: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'thermalState',
|
||||||
|
type: FilterType.MULTIPLE_DROPDOWN,
|
||||||
|
category: FilterCategory.PERFORMANCE,
|
||||||
|
label: 'Device Thermal State',
|
||||||
|
placeholder: 'Pick an option',
|
||||||
|
operator: 'is',
|
||||||
|
operatorOptions: filterOptions.getOperatorsByKeys(['is']),
|
||||||
|
icon: 'filters/cpu-load',
|
||||||
|
options: [
|
||||||
|
{ label: 'nominal', value: 0 },
|
||||||
|
{ label: 'warm', value: 1 },
|
||||||
|
{ label: 'hot', value: 2 },
|
||||||
|
{ label: 'critical', value: 3 }
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'mainThreadCPU',
|
||||||
|
type: FilterType.STRING,
|
||||||
|
category: FilterCategory.PERFORMANCE,
|
||||||
|
label: 'Main CPU Load %',
|
||||||
|
placeholder: '0 .. 100',
|
||||||
|
operator: '=',
|
||||||
|
operatorOptions: filterOptions.customOperators,
|
||||||
|
icon: 'filters/cpu-load',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'viewComponent',
|
||||||
|
type: FilterType.STRING,
|
||||||
|
category: FilterCategory.RECORDING_ATTRIBUTES,
|
||||||
|
label: 'View on screen',
|
||||||
|
placeholder: 'View Name',
|
||||||
|
operator: 'is',
|
||||||
|
operatorOptions: filterOptions.getOperatorsByKeys(['is']),
|
||||||
|
icon: 'filters/view',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: FilterKey.USERID,
|
||||||
|
type: FilterType.MULTIPLE,
|
||||||
|
category: FilterCategory.USER,
|
||||||
|
label: 'User Id',
|
||||||
|
operator: 'isUndefined',
|
||||||
|
operatorOptions: [
|
||||||
|
{
|
||||||
|
key: 'isUndefined',
|
||||||
|
label: 'is undefined',
|
||||||
|
value: 'isUndefined'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'isAny',
|
||||||
|
label: 'is present',
|
||||||
|
value: 'isAny'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
icon: 'filters/userid'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'logEvent',
|
||||||
|
type: FilterType.STRING,
|
||||||
|
category: FilterCategory.RECORDING_ATTRIBUTES,
|
||||||
|
label: 'Log in console',
|
||||||
|
placeholder: 'logged value',
|
||||||
|
operator: 'is',
|
||||||
|
operatorOptions: filterOptions.stringOperators,
|
||||||
|
icon: 'filters/console',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'clickEvent',
|
||||||
|
type: FilterType.STRING,
|
||||||
|
category: FilterCategory.INTERACTIONS,
|
||||||
|
label: 'Tap on view',
|
||||||
|
placeholder: 'View Name',
|
||||||
|
operator: 'is',
|
||||||
|
operatorOptions: filterOptions.getOperatorsByKeys(['is']),
|
||||||
|
icon: 'filters/click'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'memoryUsage',
|
||||||
|
type: FilterType.STRING,
|
||||||
|
category: FilterCategory.PERFORMANCE,
|
||||||
|
label: 'Memory usage %',
|
||||||
|
placeholder: '0 .. 100',
|
||||||
|
operatorOptions: filterOptions.customOperators,
|
||||||
|
icon: 'filters/memory-load'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
export const eventKeys = filters.filter((i) => i.isEvent).map(i => i.key);
|
export const eventKeys = filters.filter((i) => i.isEvent).map(i => i.key);
|
||||||
export const nonFlagFilters = filters.filter(i => {
|
export const nonFlagFilters = filters.filter(i => {
|
||||||
return flagConditionFilters.findIndex(f => f.key === i.key) === -1;
|
return flagConditionFilters.findIndex(f => f.key === i.key) === -1;
|
||||||
}).map(i => i.key);
|
}).map(i => i.key);
|
||||||
export const nonConditionalFlagFilters = filters.filter(i => {
|
export const nonConditionalFlagFilters = filters.filter(i => {
|
||||||
return conditionalFilters.findIndex(f => f.key === i.key) === -1;
|
return conditionalFilters.findIndex(f => f.key === i.key) === -1
|
||||||
|
&& mobileConditionalFilters.findIndex(f => f.key === i.key) === -1;
|
||||||
}).map(i => i.key);
|
}).map(i => i.key);
|
||||||
|
|
||||||
export const clickmapFilter = {
|
export const clickmapFilter = {
|
||||||
|
|
@ -717,6 +879,7 @@ export let filtersMap = mapFilters(filters);
|
||||||
export let liveFiltersMap = mapLiveFilters(filters);
|
export let liveFiltersMap = mapLiveFilters(filters);
|
||||||
export let fflagsConditionsMap = mapFilters(flagConditionFilters);
|
export let fflagsConditionsMap = mapFilters(flagConditionFilters);
|
||||||
export let conditionalFiltersMap = mapFilters(conditionalFilters);
|
export let conditionalFiltersMap = mapFilters(conditionalFilters);
|
||||||
|
export let mobileConditionalFiltersMap = mapFilters(mobileConditionalFilters);
|
||||||
|
|
||||||
export const clearMetaFilters = () => {
|
export const clearMetaFilters = () => {
|
||||||
filtersMap = mapFilters(filters);
|
filtersMap = mapFilters(filters);
|
||||||
|
|
@ -802,6 +965,26 @@ export const addElementToConditionalFiltersMap = (
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const addElementToMobileConditionalFiltersMap = (
|
||||||
|
category = FilterCategory.METADATA,
|
||||||
|
key,
|
||||||
|
type = FilterType.MULTIPLE,
|
||||||
|
operator = 'is',
|
||||||
|
operatorOptions = filterOptions.stringOperators,
|
||||||
|
icon = 'filters/metadata'
|
||||||
|
) => {
|
||||||
|
mobileConditionalFiltersMap[key] = {
|
||||||
|
key,
|
||||||
|
type,
|
||||||
|
category,
|
||||||
|
label: capitalize(key),
|
||||||
|
operator: operator,
|
||||||
|
operatorOptions,
|
||||||
|
icon,
|
||||||
|
isLive: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const addElementToLiveFiltersMap = (
|
export const addElementToLiveFiltersMap = (
|
||||||
category = FilterCategory.METADATA,
|
category = FilterCategory.METADATA,
|
||||||
key,
|
key,
|
||||||
|
|
@ -829,11 +1012,9 @@ export default Record({
|
||||||
icon: '',
|
icon: '',
|
||||||
type: '',
|
type: '',
|
||||||
value: [''],
|
value: [''],
|
||||||
source: [''],
|
|
||||||
category: '',
|
category: '',
|
||||||
|
|
||||||
custom: '',
|
custom: '',
|
||||||
// target: Target(),
|
|
||||||
level: '',
|
level: '',
|
||||||
|
|
||||||
hasNoValue: false,
|
hasNoValue: false,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue