ui: further changes for search/cards

This commit is contained in:
nick-delirium 2025-01-14 11:58:51 +01:00
parent 908b0ac88b
commit 5fcc974382
No known key found for this signature in database
GPG key ID: 93ABD695DF5FDBA0
15 changed files with 251 additions and 125 deletions

View file

@ -60,6 +60,13 @@ function AlertForm(props) {
const triggerOptions = metricStore.instance.series.length > 0 ? allTriggerSeries.filter(s => {
return metricStore.instance.series.findIndex(ms => ms.seriesId === s.value) !== -1
}).map(v => {
const labelArr = v.label.split('.')
labelArr.shift()
return {
...v,
label: labelArr.join('.')
}
}) : allTriggerSeries
const instance = alertsStore.instance
const deleting = loading

View file

@ -18,19 +18,21 @@ function BigNumChart(props: Props) {
onSeriesFocus,
} = props;
return (
<div className={'flex flex-row flex-wrap gap-2'} style={{ height: 240 }}>
{values.map((val, i) => (
<BigNum
key={i}
color={colors[i]}
series={val.series}
value={val.value}
label={label}
compData={val.compData}
valueLabel={val.valueLabel}
onSeriesFocus={onSeriesFocus}
/>
))}
<div className={'pb-3'}>
<div className={'flex flex-row flex-wrap gap-2'} style={{ height: 240 }}>
{values.map((val, i) => (
<BigNum
key={i}
color={colors[i]}
series={val.series}
value={val.value}
label={label}
compData={val.compData}
valueLabel={val.valueLabel}
onSeriesFocus={onSeriesFocus}
/>
))}
</div>
</div>
)
}

View file

@ -9,24 +9,13 @@ import {
HEATMAP,
ERRORS,
FUNNEL,
INSIGHTS,
TABLE,
TIMESERIES,
USER_PATH,
PERFORMANCE, RETENTION
} from "App/constants/card";
import { FilterKey } from 'Types/filter/filterType';
import { BarChart, TrendingUp, SearchSlash } from 'lucide-react';
import ByIssues from 'Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByIssues';
import InsightsExample from 'Components/Dashboard/components/DashboardList/NewDashModal/Examples/InsightsExample';
import ByUser from 'Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByUser';
import BarChartCard from 'Components/Dashboard/components/DashboardList/NewDashModal/Examples/BarChart';
import SpeedIndexByLocationExample
from 'Components/Dashboard/components/DashboardList/NewDashModal/Examples/SpeedIndexByLocationExample';
import CallsWithErrorsExample
from 'Components/Dashboard/components/DashboardList/NewDashModal/Examples/CallsWithErrorsExample';
import SlowestDomains
from 'Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/SlowestDomains';
import HeatmapsExample from 'Components/Dashboard/components/DashboardList/NewDashModal/Examples/HeatmapsExample';
import ByReferrer from 'Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByRferrer';
import ByFetch from 'Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByFecth';
@ -60,7 +49,7 @@ export interface CardType {
export const CARD_LIST: CardType[] = [
{
title: 'Funnel',
title: 'Untitled Funnel',
key: FUNNEL,
cardType: FUNNEL,
category: CARD_CATEGORIES[0].key,
@ -92,7 +81,7 @@ export const CARD_LIST: CardType[] = [
}
},
{
title: 'Heatmaps',
title: 'Untitled Heatmaps',
key: HEATMAP,
cardType: HEATMAP,
metricOf: 'heatMapUrl',
@ -100,14 +89,14 @@ export const CARD_LIST: CardType[] = [
example: HeatmapsExample
},
{
title: 'Journey',
title: 'Untitled Journey',
key: USER_PATH,
cardType: USER_PATH,
category: CARD_CATEGORIES[0].key,
example: ExamplePath
},
{
title: 'Trend',
title: 'Untitled Trend',
key: TIMESERIES,
cardType: TIMESERIES,
metricOf: 'sessionCount',
@ -122,7 +111,7 @@ export const CARD_LIST: CardType[] = [
example: ExampleTrend
},
{
title: 'Users Trend',
title: 'Untitled Users Trend',
key: TIMESERIES + '_userCount',
cardType: TIMESERIES,
metricOf: 'userCount',
@ -140,7 +129,7 @@ export const CARD_LIST: CardType[] = [
// Web analytics
{
title: 'Top Users',
title: 'Untitled Top Users',
key: FilterKey.USERID,
cardType: TABLE,
metricOf: FilterKey.USERID,
@ -149,7 +138,7 @@ export const CARD_LIST: CardType[] = [
},
{
title: 'Top Browsers',
title: 'Untitled Top Browsers',
key: FilterKey.USER_BROWSER,
cardType: TABLE,
metricOf: FilterKey.USER_BROWSER,
@ -165,7 +154,7 @@ export const CARD_LIST: CardType[] = [
// example: BySystem,
// },
{
title: 'Top Countries',
title: 'Untitled Top Countries',
key: FilterKey.USER_COUNTRY,
cardType: TABLE,
metricOf: FilterKey.USER_COUNTRY,
@ -174,7 +163,7 @@ export const CARD_LIST: CardType[] = [
},
{
title: 'Top Devices',
title: 'Untitled Top Devices',
key: FilterKey.USER_DEVICE,
cardType: TABLE,
metricOf: FilterKey.USER_DEVICE,
@ -182,7 +171,7 @@ export const CARD_LIST: CardType[] = [
example: BySystem
},
{
title: 'Top Pages',
title: 'Untitled Top Pages',
key: FilterKey.LOCATION,
cardType: TABLE,
metricOf: FilterKey.LOCATION,
@ -191,7 +180,7 @@ export const CARD_LIST: CardType[] = [
},
{
title: 'Top Referrer',
title: 'Untitled Top Referrer',
key: FilterKey.REFERRER,
cardType: TABLE,
metricOf: FilterKey.REFERRER,
@ -201,7 +190,7 @@ export const CARD_LIST: CardType[] = [
// Monitors
{
title: 'Table of Errors',
title: 'Untitled Table of Errors',
key: FilterKey.ERRORS,
cardType: TABLE,
metricOf: FilterKey.ERRORS,
@ -216,7 +205,7 @@ export const CARD_LIST: CardType[] = [
example: TableOfErrors
},
{
title: 'Top Network Requests',
title: 'Untitled Top Network Requests',
key: FilterKey.FETCH,
cardType: TABLE,
metricOf: FilterKey.FETCH,
@ -224,7 +213,7 @@ export const CARD_LIST: CardType[] = [
example: ByFetch
},
{
title: 'Sessions with 4xx/5xx Requests',
title: 'Untitled Sessions with 4xx/5xx Requests',
key: TIMESERIES + '_4xx_requests',
cardType: TIMESERIES,
metricOf: 'sessionCount',
@ -258,7 +247,7 @@ export const CARD_LIST: CardType[] = [
example: ExampleTrend
},
{
title: 'Sessions with Slow Network Requests',
title: 'Untitled Sessions with Slow Network Requests',
key: TIMESERIES + '_slow_network_requests',
cardType: TIMESERIES,
metricOf: 'sessionCount',

View file

@ -118,11 +118,13 @@ interface Props {
emptyMessage?: any;
observeChanges?: () => void;
excludeFilterKeys?: Array<string>;
excludeCategory?: string[]
canExclude?: boolean;
expandable?: boolean;
isHeatmap?: boolean;
removeEvents?: boolean;
defaultClosed?: boolean;
collapseState: boolean;
onToggleCollapse: () => void;
}
function FilterSeries(props: Props) {
@ -137,23 +139,13 @@ function FilterSeries(props: Props) {
expandable = false,
isHeatmap,
removeEvents,
defaultClosed,
collapseState,
onToggleCollapse,
excludeCategory
} = props;
const [expanded, setExpanded] = useState(!defaultClosed || hideHeader);
const expanded = !collapseState
const setExpanded = onToggleCollapse
const { series, seriesIndex } = props;
const [prevLength, setPrevLength] = useState(0);
useEffect(() => {
if (
series.filter.filters.length === 1 &&
prevLength === 0 &&
seriesIndex === 0 &&
!defaultClosed
) {
setExpanded(true);
}
setPrevLength(series.filter.filters.length);
}, [series.filter.filters.length, defaultClosed]);
const onUpdateFilter = (filterIndex: any, filter: any) => {
series.filter.updateFilter(filterIndex, filter);
@ -234,6 +226,7 @@ function FilterSeries(props: Props) {
mergeUp={!hideHeader}
mergeDown
cannotAdd={isHeatmap}
excludeCategory={excludeCategory}
/>
}
<FilterList
@ -246,6 +239,7 @@ function FilterSeries(props: Props) {
excludeFilterKeys={excludeFilterKeys}
onAddFilter={onAddFilter}
mergeUp={!removeEvents}
excludeCategory={excludeCategory}
/>
</>
) : null}

View file

@ -1,5 +1,5 @@
import React from 'react';
import { Card, Space, Button, Alert, Form, Select } from 'antd';
import { Card, Space, Button, Alert, Form, Select, Tooltip } from 'antd';
import { useStore } from 'App/mstore';
import { eventKeys } from 'Types/filter/newFilter';
import {
@ -13,18 +13,37 @@ import {
} from 'App/constants/card';
import FilterSeries from 'Components/Dashboard/components/FilterSeries/FilterSeries';
import { issueCategories } from 'App/constants/filterOptions';
import { PlusIcon } from 'lucide-react';
import { PlusIcon, ChevronUp } from 'lucide-react';
import { observer } from 'mobx-react-lite';
import FilterItem from 'Shared/Filters/FilterItem';
import { FilterKey } from 'Types/filter/filterType';
import { FilterKey, FilterCategory } from 'Types/filter/filterType';
function WidgetFormNew() {
const getExcludedKeys = (metricType: string) => {
switch (metricType) {
case USER_PATH:
case HEATMAP:
return eventKeys;
default:
return [];
}
}
const getExcludedCategories = (metricType: string) => {
switch (metricType) {
case USER_PATH:
case FUNNEL:
return [FilterCategory.DEVTOOLS]
default:
return [];
}
}
function WidgetFormNew({ layout }: { layout: string }) {
const { metricStore } = useStore();
const metric: any = metricStore.instance;
const excludeFilterKeys = getExcludedKeys(metric.metricType);
const excludeCategory = getExcludedCategories(metric.metricType);
const isHeatMap = metric.metricType === HEATMAP;
const isPathAnalysis = metric.metricType === USER_PATH;
const excludeFilterKeys = isHeatMap || isPathAnalysis ? eventKeys : [];
const isPredefined = metric.metricType === ERRORS;
return isPredefined ? (
@ -32,16 +51,36 @@ function WidgetFormNew() {
) : (
<Space direction="vertical" className="w-full">
<AdditionalFilters />
<FilterSection metric={metric} excludeFilterKeys={excludeFilterKeys} />
<FilterSection
layout={layout}
metric={metric}
excludeCategory={excludeCategory}
excludeFilterKeys={excludeFilterKeys}
/>
</Space>
);
}
export default observer(WidgetFormNew);
const FilterSection = observer(({ metric, excludeFilterKeys }: any) => {
const defaultClosed = React.useRef(metric.exists());
const defaultSeries = React.useRef(metric.series.map((s) => s.name));
const FilterSection = observer(({ layout, metric, excludeFilterKeys, excludeCategory }: any) => {
const allOpen = layout.startsWith('flex-row');
const defaultClosed = React.useRef(!allOpen && metric.exists());
const [seriesCollapseState, setSeriesCollapseState] = React.useState<Record<number, boolean>>({});
React.useEffect(() => {
const defaultSeriesCollapseState: Record<number, boolean> = {};
metric.series.forEach((s: any) => {
defaultSeriesCollapseState[s.seriesId] = defaultSeriesCollapseState[
s.seriesId
]
? defaultSeriesCollapseState[s.seriesId]
: allOpen
? false
: defaultClosed.current;
});
setSeriesCollapseState(defaultSeriesCollapseState);
}, [metric.series]);
const isTable = metric.metricType === TABLE;
const isHeatMap = metric.metricType === HEATMAP;
const isFunnel = metric.metricType === FUNNEL;
@ -57,6 +96,27 @@ const FilterSection = observer(({ metric, excludeFilterKeys }: any) => {
isInsights ||
isRetention ||
isPathAnalysis;
const collapseAll = () => {
setSeriesCollapseState((seriesCollapseState) => {
const newState = { ...seriesCollapseState };
Object.keys(newState).forEach((key) => {
newState[key] = true;
});
return newState;
});
}
const expandAll = () => {
setSeriesCollapseState((seriesCollapseState) => {
const newState = { ...seriesCollapseState };
Object.keys(newState).forEach((key) => {
newState[key] = false;
});
return newState;
});
}
const allCollapsed = Object.values(seriesCollapseState).every((v) => v);
return (
<>
{metric.series.length > 0 &&
@ -70,6 +130,7 @@ const FilterSection = observer(({ metric, excludeFilterKeys }: any) => {
removeEvents={isPathAnalysis}
supportsEmpty={!isHeatMap && !isPathAnalysis}
excludeFilterKeys={excludeFilterKeys}
excludeCategory={excludeCategory}
observeChanges={() => metric.updateKey('hasChanged', true)}
hideHeader={
isTable ||
@ -82,11 +143,13 @@ const FilterSection = observer(({ metric, excludeFilterKeys }: any) => {
series={series}
onRemoveSeries={() => metric.removeSeries(index)}
canDelete={metric.series.length > 1}
defaultClosed={
metric.hasChanged
? defaultSeries.current.includes(series.name)
: defaultClosed.current
}
collapseState={seriesCollapseState[series.seriesId]}
onToggleCollapse={() => {
setSeriesCollapseState((seriesCollapseState) => ({
...seriesCollapseState,
[series.seriesId]: !seriesCollapseState[series.seriesId],
}));
}}
emptyMessage={
isTable
? 'Filter data using any event or attribute. Use Add Step button below to do so.'
@ -96,21 +159,30 @@ const FilterSection = observer(({ metric, excludeFilterKeys }: any) => {
/>
</div>
))}
{!isSingleSeries && canAddSeries && (
<div className={'mx-auto flex items-center gap-2 w-fit'}>
<Tooltip title={canAddSeries ? '' : 'Maximum of 3 series reached.'}>
<Button
onClick={() => {
if (!canAddSeries) return;
metric.addSeries();
}}
disabled={!canAddSeries || isSingleSeries}
size="small"
type="primary"
icon={<PlusIcon size={16} />}
>
Add Series
</Button>
</Tooltip>
<Button
onClick={() => {
if (!canAddSeries) return;
metric.addSeries();
}}
size="small"
type="text"
className="w-full cursor-pointer flex items-center py-2 justify-center gap-2 font-medium hover:text-teal btn-add-series"
size={'small'}
type={'text'}
icon={<ChevronUp size={16} className={allCollapsed ? 'rotate-180' : ''} />}
onClick={allCollapsed ? expandAll : collapseAll}
>
<PlusIcon size={16} />
Add Series
{allCollapsed ? 'Expand' : 'Collapse'} All
</Button>
)}
</div>
</>
);
});

View file

@ -198,7 +198,7 @@ function WidgetView(props: Props) {
/>
<div className={cn('flex gap-4', layout)}>
<div className={layout.startsWith('flex-row') ? 'w-1/3 ' : 'w-full'}>
<WidgetFormNew />
<WidgetFormNew layout={layout} />
</div>
<div className={layout.startsWith('flex-row') ? 'w-2/3' : 'w-full'}>
<WidgetPreview name={widget.name} isEditing={expanded} />

View file

@ -18,6 +18,7 @@ interface Props {
saveRequestPayloads?: boolean;
disableDelete?: boolean;
excludeFilterKeys?: Array<string>;
excludeCategory?: Array<string>;
allowedFilterKeys?: Array<string>;
readonly?: boolean;
hideIndex?: boolean;
@ -35,6 +36,7 @@ function FilterItem(props: Props) {
hideDelete = false,
allowedFilterKeys = [],
excludeFilterKeys = [],
excludeCategory = [],
isConditional,
hideIndex = false,
} = props;
@ -84,6 +86,7 @@ function FilterItem(props: Props) {
onFilterClick={replaceFilter}
allowedFilterKeys={allowedFilterKeys}
excludeFilterKeys={excludeFilterKeys}
excludeCategory={excludeCategory}
disabled={disableDelete || props.readonly}
/>

View file

@ -8,7 +8,7 @@ import EventsOrder from 'Shared/Filters/FilterList/EventsOrder';
import FilterSelection from '../FilterSelection/FilterSelection';
interface Props {
filter?: any; // event/filter
filter?: any;
onUpdateFilter: (filterIndex: any, filter: any) => void;
onFilterMove?: (filters: any) => void;
onRemoveFilter: (filterIndex: any) => void;
@ -19,6 +19,7 @@ interface Props {
supportsEmpty?: boolean;
readonly?: boolean;
excludeFilterKeys?: Array<string>;
excludeCategory?: string[];
isConditional?: boolean;
actions?: React.ReactNode[];
onAddFilter: (filter: any) => void;
@ -37,6 +38,7 @@ export const FilterList = observer((props: Props) => {
onAddFilter,
readonly,
borderless,
excludeCategory,
} = props;
const filters = filter.filters;
@ -65,6 +67,8 @@ export const FilterList = observer((props: Props) => {
filter={undefined}
onFilterClick={onAddFilter}
disabled={readonly}
excludeFilterKeys={excludeFilterKeys}
excludeCategory={excludeCategory}
>
<Button
icon={<Filter size={16} strokeWidth={1} />}
@ -116,6 +120,7 @@ export const EventsList = observer((props: Props) => {
actions = [],
onAddFilter,
cannotAdd,
excludeCategory,
} = props;
const filters = filter.filters;
@ -210,6 +215,7 @@ export const EventsList = observer((props: Props) => {
mode={'events'}
filter={undefined}
onFilterClick={onAddFilter}
excludeCategory={excludeCategory}
>
<Button
icon={<Plus size={16} strokeWidth={1} />}
@ -298,6 +304,7 @@ export const EventsList = observer((props: Props) => {
excludeFilterKeys={excludeFilterKeys}
readonly={props.readonly}
isConditional={isConditional}
excludeCategory={excludeCategory}
/>
</div>
) : null

View file

@ -36,7 +36,7 @@ import { Icon, Loader } from 'UI';
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
import { Input } from 'antd';
import { FilterKey } from 'Types/filter/filterType';
import { FilterCategory, FilterKey } from "Types/filter/filterType";
import stl from './FilterModal.module.css';
import { observer } from 'mobx-react-lite';
import { useStore } from 'App/mstore';
@ -80,13 +80,15 @@ export const IconMap = {
function filterJson(
jsonObj: Record<string, any>,
excludeKeys: string[] = [],
excludeCategory: string[] = [],
allowedFilterKeys: string[] = [],
mode: 'filters' | 'events'
): Record<string, any> {
return Object.fromEntries(
Object.entries(jsonObj)
.map(([key, value]) => {
const arr = value.filter((i: { key: string, isEvent: boolean }) => {
const arr = value.filter((i: { key: string, isEvent: boolean, category: string }) => {
if (excludeCategory.includes(i.category)) return false;
if (excludeKeys.includes(i.key)) return false;
if (mode === 'events' && !i.isEvent) return false;
if (mode === 'filters' && i.isEvent) return false;
@ -139,6 +141,7 @@ interface Props {
isMainSearch?: boolean;
searchQuery?: string;
excludeFilterKeys?: Array<string>;
excludeCategory?: Array<string>;
allowedFilterKeys?: Array<string>;
isConditional?: boolean;
isMobile?: boolean;
@ -162,6 +165,7 @@ function FilterModal(props: Props) {
onFilterClick = () => null,
isMainSearch = false,
excludeFilterKeys = [],
excludeCategory = [],
allowedFilterKeys = [],
isConditional,
mode,
@ -185,10 +189,18 @@ function FilterModal(props: Props) {
? searchStoreLive.loadingFilterSearch
: searchStore.loadingFilterSearch;
const parseAndAdd = (filter) => {
if (filter.category === FilterCategory.EVENTS && filter.key.startsWith('_')) {
filter.value = [filter.key.substring(1)];
filter.key = FilterKey.CUSTOM;
filter.label = 'Custom Events'
}
onFilterClick(filter)
}
const onFilterSearchClick = (filter: any) => {
const _filter = { ...filtersMap[filter.type] };
_filter.value = [filter.value];
onFilterClick(_filter);
parseAndAdd(_filter);
};
const filterJsonObj = isConditional
@ -198,7 +210,7 @@ function FilterModal(props: Props) {
: filters;
const { matchingCategories, matchingFilters } = getMatchingEntries(
searchQuery,
filterJson(filterJsonObj, excludeFilterKeys, allowedFilterKeys, mode)
filterJson(filterJsonObj, excludeFilterKeys, excludeCategory, allowedFilterKeys, mode)
);
const isResultEmpty =
@ -247,7 +259,7 @@ function FilterModal(props: Props) {
className={cn(
'flex items-center p-2 cursor-pointer gap-1 rounded-lg hover:bg-active-blue'
)}
onClick={() => onFilterClick({ ...filter })}
onClick={() => parseAndAdd({ ...filter })}
>
{filter.category ? <div style={{ width: 100 }} className={'text-neutral-500/90 w-full flex justify-between items-center'}>
<span>{filter.category}</span>

View file

@ -13,6 +13,7 @@ interface Props {
onFilterClick: (filter: any) => void;
children?: any;
excludeFilterKeys?: Array<string>;
excludeCategory?: Array<string>;
allowedFilterKeys?: Array<string>;
disabled?: boolean;
isConditional?: boolean;
@ -26,6 +27,7 @@ function FilterSelection(props: Props) {
onFilterClick,
children,
excludeFilterKeys = [],
excludeCategory = [],
allowedFilterKeys = [],
disabled = false,
isConditional,
@ -86,6 +88,7 @@ function FilterSelection(props: Props) {
onFilterClick={onAddFilter}
excludeFilterKeys={excludeFilterKeys}
allowedFilterKeys={allowedFilterKeys}
excludeCategory={excludeCategory}
isConditional={isConditional}
isMobile={isMobile}
mode={mode}

View file

@ -18,9 +18,8 @@ interface Props {
}
function FilterValue(props: Props) {
const { filter } = props;
const isEvent = filter.isEvent;
const [durationValues, setDurationValues] = useState({
minDuration: filter.value[0],
minDuration: filter.value?.[0],
maxDuration: filter.value.length > 1 ? filter.value[1] : filter.value[0],
});
const showCloseButton = filter.value.length > 1;

View file

@ -1,17 +1,16 @@
import { makeAutoObservable } from 'mobx';
import { customFieldService } from 'App/services';
import { customFieldService, filterService } from 'App/services';
import {
addElementToConditionalFiltersMap,
addElementToMobileConditionalFiltersMap,
addElementToFiltersMap,
addElementToFlagConditionsMap,
addElementToLiveFiltersMap,
clearMetaFilters
clearMetaFilters,
} from 'Types/filter/newFilter';
import { FilterCategory } from 'Types/filter/filterType';
import { FilterCategory, FilterType } from "Types/filter/filterType";
import CustomField from 'App/mstore/types/customField';
import customFields from 'Components/Client/CustomFields';
import filterOptions from 'App/constants';
class CustomFieldStore {
isLoading: boolean = false;
@ -48,14 +47,40 @@ class CustomFieldStore {
const response = await customFieldService.fetchList(siteId);
clearMetaFilters();
response.forEach((item: any) => {
addElementToFiltersMap(FilterCategory.METADATA, '_' + item.key);
addElementToLiveFiltersMap(FilterCategory.METADATA, '_' + item.key);
addElementToFlagConditionsMap(FilterCategory.METADATA, '_' + item.key);
addElementToConditionalFiltersMap(FilterCategory.METADATA, '_' + item.key);
addElementToMobileConditionalFiltersMap(FilterCategory.METADATA, '_' + item.key);
const calls = [
addElementToFiltersMap,
addElementToLiveFiltersMap,
addElementToFlagConditionsMap,
addElementToConditionalFiltersMap,
addElementToMobileConditionalFiltersMap,
];
calls.forEach((call) => {
call(FilterCategory.METADATA, '_' + item.key);
});
});
this.list = response.map((item_1: any) => new CustomField(item_1));
this.fetchedMetadata = true;
filterService.fetchTopValues('custom', undefined).then((response: []) => {
response.forEach((item: any) => {
const calls = [
addElementToFiltersMap,
addElementToFlagConditionsMap,
addElementToConditionalFiltersMap,
addElementToMobileConditionalFiltersMap,
];
calls.forEach((call) => {
call(
FilterCategory.EVENTS,
'_' + item.value,
FilterType.MULTIPLE,
'is',
filterOptions.stringOperators,
'filters/custom',
true
);
});
});
});
} finally {
this.isLoading = false;
}
@ -65,11 +90,14 @@ class CustomFieldStore {
this.isLoading = true;
try {
const response = await customFieldService.get('/integration/sources');
this.sources = response.map(({ value, ...item }: any) => new CustomField({
label: value,
key: value,
...item
}));
this.sources = response.map(
({ value, ...item }: any) =>
new CustomField({
label: value,
key: value,
...item,
})
);
} finally {
this.isLoading = false;
}
@ -79,16 +107,18 @@ class CustomFieldStore {
this.isSaving = true;
try {
const wasCreating = !instance.exists();
const response = wasCreating ? await customFieldService.create(siteId, instance.toData()) :
await customFieldService.update(siteId, instance.toData());
const response = wasCreating
? await customFieldService.create(siteId, instance.toData())
: await customFieldService.update(siteId, instance.toData());
const updatedInstance = new CustomField(response);
if (wasCreating) {
this.list.push(updatedInstance);
} else {
const index = this.list.findIndex(item => item.index === instance.index);
if (index >= 0)
this.list[index] = updatedInstance;
const index = this.list.findIndex(
(item) => item.index === instance.index
);
if (index >= 0) this.list[index] = updatedInstance;
}
} finally {
this.isSaving = false;
@ -99,7 +129,7 @@ class CustomFieldStore {
this.isSaving = true;
try {
await customFieldService.delete(siteId, index);
this.list = this.list.filter(item => item.index !== index);
this.list = this.list.filter((item) => item.index !== index);
} finally {
this.isSaving = false;
}
@ -115,5 +145,4 @@ class CustomFieldStore {
}
}
export default CustomFieldStore;

View file

@ -1,5 +1,4 @@
import { makeAutoObservable } from 'mobx';
import { filters } from 'Types/filter/newFilter';
import { filterService } from 'App/services';
interface TopValue {

View file

@ -1,10 +1,11 @@
export enum FilterCategory {
AUTOCAPTURE = 'Autocapture',
DEVTOOLS = 'Devtools',
DEVTOOLS = 'DevTools',
USER = 'User',
METADATA = 'Metadata',
SESSION = 'Session',
ISSUE = 'Issue',
EVENTS = 'Events',
}
export const setQueryParamKeyFromFilterkey = (filterKey: string) => {

View file

@ -135,7 +135,7 @@ export const filters = [
{
key: FilterKey.CUSTOM,
type: FilterType.MULTIPLE,
category: FilterCategory.DEVTOOLS,
category: FilterCategory.EVENTS,
label: 'Custom Events',
placeholder: 'Enter event key',
operator: 'is',
@ -951,6 +951,7 @@ export const clearMetaFilters = () => {
* @param {*} operator
* @param {*} operatorOptions
* @param {*} icon
* @param {*} isEvent
*/
export const addElementToFiltersMap = (
category = FilterCategory.METADATA,
@ -958,7 +959,8 @@ export const addElementToFiltersMap = (
type = FilterType.MULTIPLE,
operator = 'is',
operatorOptions = filterOptions.stringOperators,
icon = 'filters/metadata'
icon = 'filters/metadata',
isEvent = false
) => {
filtersMap[key] = {
key,
@ -969,7 +971,8 @@ export const addElementToFiltersMap = (
operator: operator,
operatorOptions,
icon,
isLive: true
isLive: true,
isEvent,
};
};
@ -992,7 +995,8 @@ export const addElementToFlagConditionsMap = (
type = FilterType.MULTIPLE,
operator = 'is',
operatorOptions = filterOptions.stringOperators,
icon = 'filters/metadata'
icon = 'filters/metadata',
isEvent = false
) => {
fflagsConditionsMap[key] = {
key,
@ -1002,7 +1006,8 @@ export const addElementToFlagConditionsMap = (
operator: operator,
operatorOptions,
icon,
isLive: true
isLive: true,
isEvent,
};
};
@ -1012,7 +1017,8 @@ export const addElementToConditionalFiltersMap = (
type = FilterType.MULTIPLE,
operator = 'is',
operatorOptions = filterOptions.stringOperators,
icon = 'filters/metadata'
icon = 'filters/metadata',
isEvent = false
) => {
conditionalFiltersMap[key] = {
key,
@ -1022,7 +1028,8 @@ export const addElementToConditionalFiltersMap = (
operator: operator,
operatorOptions,
icon,
isLive: true
isLive: true,
isEvent,
};
};
@ -1032,7 +1039,8 @@ export const addElementToMobileConditionalFiltersMap = (
type = FilterType.MULTIPLE,
operator = 'is',
operatorOptions = filterOptions.stringOperators,
icon = 'filters/metadata'
icon = 'filters/metadata',
isEvent = false
) => {
mobileConditionalFiltersMap[key] = {
key,
@ -1042,7 +1050,8 @@ export const addElementToMobileConditionalFiltersMap = (
operator: operator,
operatorOptions,
icon,
isLive: true
isLive: true,
isEvent,
};
};