Refactor filter handling and improve type safety
Remove unused excludeFilterKeys parameter, replace any types with proper Filter interfaces, and update API response handling to use events property instead of values.
This commit is contained in:
parent
2c390ab605
commit
7c40851dcb
14 changed files with 151 additions and 97 deletions
|
|
@ -9,17 +9,16 @@ import { observer } from 'mobx-react-lite';
|
|||
|
||||
interface Props {
|
||||
series: any;
|
||||
excludeFilterKeys: Array<string>;
|
||||
}
|
||||
|
||||
function AddStepButton({ series, excludeFilterKeys }: Props) {
|
||||
function AddStepButton({ series }: Props) {
|
||||
const { t } = useTranslation();
|
||||
const { metricStore, filterStore } = useStore();
|
||||
const metric: any = metricStore.instance;
|
||||
const filters: Filter[] = filterStore.getCurrentProjectFilters();
|
||||
// console.log('filters', filters)
|
||||
|
||||
const onAddFilter = (filter: any) => {
|
||||
const onAddFilter = (filter: Filter) => {
|
||||
console.log('Add Step Button', filter);
|
||||
series.filter.addFilter(filter);
|
||||
metric.updateKey('hasChanged', true);
|
||||
};
|
||||
|
|
@ -27,7 +26,7 @@ function AddStepButton({ series, excludeFilterKeys }: Props) {
|
|||
<FilterSelection
|
||||
filters={filters}
|
||||
onFilterClick={onAddFilter}
|
||||
mode={'filters'} // excludeFilterKeys={excludeFilterKeys}
|
||||
// mode={'filters'} // excludeFilterKeys={excludeFilterKeys}
|
||||
>
|
||||
<Button
|
||||
type="text"
|
||||
|
|
|
|||
|
|
@ -40,12 +40,12 @@ function ExcludeFilters(props: Props) {
|
|||
<FilterItem
|
||||
hideIndex
|
||||
filterIndex={index}
|
||||
allowedFilterKeys={[
|
||||
FilterKey.LOCATION,
|
||||
FilterKey.CLICK,
|
||||
FilterKey.INPUT,
|
||||
FilterKey.CUSTOM,
|
||||
]}
|
||||
// allowedFilterKeys={[
|
||||
// FilterKey.LOCATION,
|
||||
// FilterKey.CLICK,
|
||||
// FilterKey.INPUT,
|
||||
// FilterKey.CUSTOM,
|
||||
// ]}
|
||||
filter={f}
|
||||
onUpdate={(f) => onUpdateFilter(index, f)}
|
||||
onRemoveFilter={() => onRemoveFilter(index)}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ const FilterCountLabels = observer(
|
|||
</Space>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const FilterSeriesHeader = observer(
|
||||
|
|
@ -67,8 +67,8 @@ const FilterSeriesHeader = observer(
|
|||
'px-4 ps-2 h-12 flex items-center relative bg-white border-gray-lighter border-t border-l border-r rounded-t-xl',
|
||||
{
|
||||
hidden: props.hidden,
|
||||
'rounded-b-xl': !props.expanded
|
||||
}
|
||||
'rounded-b-xl': !props.expanded,
|
||||
},
|
||||
)}
|
||||
>
|
||||
<Space className="mr-auto" size={30}>
|
||||
|
|
@ -111,7 +111,7 @@ const FilterSeriesHeader = observer(
|
|||
</Space>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
interface Props {
|
||||
|
|
@ -135,20 +135,19 @@ interface Props {
|
|||
|
||||
function FilterSeries(props: Props) {
|
||||
const {
|
||||
observeChanges = () => {
|
||||
},
|
||||
observeChanges = () => {},
|
||||
canDelete,
|
||||
hideHeader = false,
|
||||
emptyMessage = 'Add an event or filter step to define the series.',
|
||||
supportsEmpty = true,
|
||||
excludeFilterKeys = [],
|
||||
// emptyMessage = 'Add an event or filter step to define the series.',
|
||||
// supportsEmpty = true,
|
||||
// excludeFilterKeys = [],
|
||||
canExclude = false,
|
||||
expandable = false,
|
||||
isHeatmap,
|
||||
removeEvents,
|
||||
collapseState,
|
||||
onToggleCollapse,
|
||||
excludeCategory
|
||||
// excludeCategory,
|
||||
} = props;
|
||||
const { filterStore } = useStore();
|
||||
const expanded = isHeatmap || !collapseState;
|
||||
|
|
@ -159,13 +158,18 @@ function FilterSeries(props: Props) {
|
|||
const eventOptions: Filter[] = allFilterOptions.filter((i) => i.isEvent);
|
||||
const propertyOptions: Filter[] = allFilterOptions.filter((i) => !i.isEvent);
|
||||
|
||||
const onUpdateFilter = (filterIndex: any, filter: any) => {
|
||||
const onUpdateFilter = (filterIndex: number, filter: Filter) => {
|
||||
series.filter.updateFilter(filterIndex, filter);
|
||||
observeChanges();
|
||||
};
|
||||
|
||||
const onFilterMove = (newFilters: any) => {
|
||||
series.filter.replaceFilters(newFilters);
|
||||
// const onFilterMove = (newFilters: Filter[]) => {
|
||||
// series.filter.replaceFilters(newFilters);
|
||||
// observeChanges();
|
||||
// };
|
||||
//
|
||||
const onFilterMove = (draggedIndex: number, newPosition: number) => {
|
||||
series.filter.moveFilter(draggedIndex, newPosition);
|
||||
observeChanges();
|
||||
};
|
||||
|
||||
|
|
@ -174,18 +178,18 @@ function FilterSeries(props: Props) {
|
|||
observeChanges();
|
||||
};
|
||||
|
||||
const onRemoveFilter = (filterIndex: any) => {
|
||||
const onRemoveFilter = (filterIndex: number) => {
|
||||
series.filter.removeFilter(filterIndex);
|
||||
observeChanges();
|
||||
};
|
||||
|
||||
const onAddFilter = (filter: any) => {
|
||||
const onAddFilter = (filter: Filter) => {
|
||||
filter.autoOpen = true;
|
||||
series.filter.addFilter(filter);
|
||||
observeChanges();
|
||||
};
|
||||
|
||||
console.log('series.filter.filters', series.filter.filters);
|
||||
console.log('series', series);
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
|
@ -232,10 +236,12 @@ function FilterSeries(props: Props) {
|
|||
<div className="bg-white rounded-b-xl border p-4">
|
||||
<FilterListHeader
|
||||
title={'Events'}
|
||||
showEventsOrder={series.filter.filters.filter((f: any) => f.isEvent).length > 0}
|
||||
showEventsOrder={
|
||||
series.filter.filters.filter((f: any) => f.isEvent).length > 0
|
||||
}
|
||||
orderProps={{
|
||||
eventsOrder: series.filter.eventsOrder,
|
||||
eventsOrderSupport: ['then', 'and', 'or']
|
||||
eventsOrderSupport: ['then', 'and', 'or'],
|
||||
}}
|
||||
onChangeOrder={onChangeEventsOrder}
|
||||
filterSelection={
|
||||
|
|
@ -271,7 +277,9 @@ function FilterSeries(props: Props) {
|
|||
|
||||
<FilterListHeader
|
||||
title={'Filters'}
|
||||
showEventsOrder={series.filter.filters.map((f: any) => !f.isEvent).length > 0}
|
||||
showEventsOrder={
|
||||
series.filter.filters.map((f: any) => !f.isEvent).length > 0
|
||||
}
|
||||
filterSelection={
|
||||
<FilterSelection
|
||||
filters={propertyOptions}
|
||||
|
|
@ -290,7 +298,7 @@ function FilterSeries(props: Props) {
|
|||
/>
|
||||
|
||||
<UnifiedFilterList
|
||||
title="Events"
|
||||
title="Filters"
|
||||
filters={series.filter.filters.filter((f: any) => !f.isEvent)}
|
||||
isDraggable={false}
|
||||
showIndices={false}
|
||||
|
|
|
|||
|
|
@ -10,10 +10,11 @@ import FilterSource from '../FilterSource';
|
|||
import { useStore } from '@/mstore';
|
||||
import { getIconForFilter } from 'Shared/Filters/FilterModal/FilterModal';
|
||||
import { Filter, getOperatorsByType } from '@/mstore/types/filterConstants';
|
||||
import { FilterItemData } from '@/mstore/types/filterItem';
|
||||
|
||||
interface Props {
|
||||
filterIndex?: number;
|
||||
filter: any;
|
||||
filter: FilterItemData;
|
||||
onUpdate: (filter: any) => void;
|
||||
onRemoveFilter: () => void;
|
||||
isFilter?: boolean;
|
||||
|
|
@ -358,7 +359,7 @@ function FilterItem(props: Props) {
|
|||
</>
|
||||
)}
|
||||
|
||||
{operatorOptions.length > 0 && filter.dataType && !isUserEvent && (
|
||||
{operatorOptions.length > 0 && filter.dataType && !filter.isEvent && (
|
||||
<>
|
||||
<FilterOperator
|
||||
options={operatorOptions}
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ interface UnifiedFilterListProps {
|
|||
filters: Filter[];
|
||||
header?: React.ReactNode;
|
||||
filterSelection?: React.ReactNode;
|
||||
handleRemove: (key: string) => void;
|
||||
handleUpdate: (key: string, updatedFilter: any) => void;
|
||||
handleRemove: (index: string) => void;
|
||||
handleUpdate: (index: string, updatedFilter: Filter) => void;
|
||||
handleAdd: (newFilter: Filter) => void;
|
||||
handleMove: (draggedIndex: number, newPosition: number) => void;
|
||||
handleMove?: (draggedIndex: number, newPosition: number) => void;
|
||||
isDraggable?: boolean;
|
||||
showIndices?: boolean;
|
||||
readonly?: boolean;
|
||||
|
|
@ -141,7 +141,7 @@ const UnifiedFilterList = (props: UnifiedFilterListProps) => {
|
|||
!(dragInd === hoverIndex && hoverPosition === 'top') &&
|
||||
!(dragInd === hoverIndex - 1 && hoverPosition === 'bottom')
|
||||
) {
|
||||
handleMove(dragInd, newPosition);
|
||||
handleMove?.(dragInd, newPosition);
|
||||
}
|
||||
|
||||
setHoveredItem({ i: null, position: null });
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ const ValueAutoComplete = observer(
|
|||
}, [initialValues]);
|
||||
|
||||
useEffect(() => {
|
||||
if (filterKey && !filterStore.topValues[filterKey]) {
|
||||
if (!params.isEvent && filterKey && !filterStore.topValues[filterKey]) {
|
||||
setLoadingTopValues(true);
|
||||
filterStore
|
||||
.fetchTopValues({
|
||||
|
|
@ -155,10 +155,10 @@ const ValueAutoComplete = observer(
|
|||
autoCompleteParams.eventName = params.eventName;
|
||||
}
|
||||
|
||||
const data: { values: any[] }[] =
|
||||
const data: { events: any[] }[] =
|
||||
await searchService.fetchAutoCompleteValues(autoCompleteParams);
|
||||
const _options =
|
||||
data.values?.map((i: any) => ({
|
||||
data.events?.map((i: any) => ({
|
||||
value: i.value,
|
||||
label: i.value,
|
||||
})) || [];
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import { Plus } from 'lucide-react';
|
|||
import { Filter } from '@/mstore/types/filterConstants';
|
||||
import FilterListHeader from 'Shared/Filters/FilterList/FilterListHeader';
|
||||
|
||||
|
||||
function SessionFilters() {
|
||||
const { searchStore, filterStore } = useStore();
|
||||
const searchInstance = searchStore.instance;
|
||||
|
|
@ -23,13 +22,20 @@ function SessionFilters() {
|
|||
|
||||
const onChangeEventsOrder = (
|
||||
_e: React.MouseEvent<HTMLButtonElement>,
|
||||
{ value }: { value: string }
|
||||
{ value }: { value: string },
|
||||
) => {
|
||||
searchStore.edit({
|
||||
eventsOrder: value
|
||||
eventsOrder: value,
|
||||
});
|
||||
};
|
||||
|
||||
const moveFilter = (index: number, newIndex: number) => {
|
||||
const updatedFilters = [...searchInstance.filters];
|
||||
const filterToMove = updatedFilters.splice(index, 1)[0];
|
||||
updatedFilters.splice(newIndex, 0, filterToMove);
|
||||
searchStore.edit({ filters: updatedFilters });
|
||||
};
|
||||
|
||||
const eventFilters = searchInstance.filters.filter((i) => i.isEvent);
|
||||
const attributeFilters = searchInstance.filters.filter((i) => !i.isEvent);
|
||||
|
||||
|
|
@ -66,7 +72,7 @@ function SessionFilters() {
|
|||
handleRemove={searchStore.removeFilter}
|
||||
handleUpdate={searchStore.updateFilter}
|
||||
handleAdd={searchStore.addFilter}
|
||||
handleMove={searchStore.moveFilter}
|
||||
handleMove={moveFilter}
|
||||
/>
|
||||
|
||||
<Divider className="my-3" />
|
||||
|
|
@ -99,7 +105,7 @@ function SessionFilters() {
|
|||
handleRemove={searchStore.removeFilter}
|
||||
handleUpdate={searchStore.updateFilter}
|
||||
handleAdd={searchStore.addFilter}
|
||||
handleMove={searchStore.moveFilter}
|
||||
// handleMove={moveFilter}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -95,8 +95,10 @@ export default class FilterStore {
|
|||
[params.isEvent ? 'eventName' : 'propertyName']: filter.name,
|
||||
});
|
||||
|
||||
console.log('response', response.events);
|
||||
|
||||
runInAction(() => {
|
||||
this.setTopValues(valKey, response);
|
||||
this.setTopValues(valKey, response.events);
|
||||
});
|
||||
|
||||
return this.topValues[valKey] || [];
|
||||
|
|
@ -221,7 +223,10 @@ export default class FilterStore {
|
|||
return this.getAllFilters(String(projectStore.activeSiteId));
|
||||
};
|
||||
|
||||
getEventFilters = async (eventName: string): Promise<Filter[]> => {
|
||||
getEventFilters = async (
|
||||
eventName: string,
|
||||
isAutoCapture: boolean,
|
||||
): Promise<Filter[]> => {
|
||||
const cacheKey = `${projectStore.activeSiteId}_${eventName}`;
|
||||
|
||||
// Check cache with TTL
|
||||
|
|
@ -236,8 +241,10 @@ export default class FilterStore {
|
|||
}
|
||||
|
||||
try {
|
||||
this.pendingFetches[cacheKey] =
|
||||
this.fetchAndProcessPropertyFilters(eventName);
|
||||
this.pendingFetches[cacheKey] = this.fetchAndProcessPropertyFilters(
|
||||
eventName,
|
||||
isAutoCapture,
|
||||
);
|
||||
const filters = await this.pendingFetches[cacheKey];
|
||||
|
||||
runInAction(() => {
|
||||
|
|
|
|||
|
|
@ -405,7 +405,7 @@ class SearchStore {
|
|||
this.instance = Object.assign(this.instance, search);
|
||||
};
|
||||
|
||||
updateFilter = (id: string, search: Partial<FilterItem>) => {
|
||||
updateFilter = (id: string, search: Partial<Filter>) => {
|
||||
const newFilters = this.instance.filters.map((f: any) => {
|
||||
if (f.id === id) {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ type FilterData = Partial<FilterItem> & {
|
|||
sourceOperator?: string;
|
||||
source?: any;
|
||||
filters?: FilterData[];
|
||||
isEvent?: boolean;
|
||||
};
|
||||
|
||||
export const checkFilterValue = (value: unknown): string[] => {
|
||||
|
|
@ -172,6 +173,18 @@ export default class FilterStore implements IFilterStore {
|
|||
this[key] = value;
|
||||
}
|
||||
|
||||
moveFilter(index: number, newIndex: number) {
|
||||
if (
|
||||
index >= 0 &&
|
||||
index < this.filters.length &&
|
||||
newIndex >= 0 &&
|
||||
newIndex < this.filters.length
|
||||
) {
|
||||
const [removed] = this.filters.splice(index, 1);
|
||||
this.filters.splice(newIndex, 0, removed);
|
||||
}
|
||||
}
|
||||
|
||||
private createFilterItemFromData(filterData: FilterData): FilterItem {
|
||||
const dataWithValue = {
|
||||
...filterData,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ export interface Filter {
|
|||
value?: string[];
|
||||
propertyOrder?: string;
|
||||
filters?: Filter[];
|
||||
autoOpen?: boolean;
|
||||
}
|
||||
|
||||
export const OPERATORS = {
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ import { FilterProperty, Operator } from '@/mstore/types/filterConstants';
|
|||
|
||||
type JsonData = Record<string, any>;
|
||||
|
||||
// Define a proper interface for initialization data
|
||||
interface FilterItemData {
|
||||
export interface IFilter {
|
||||
id?: string;
|
||||
name?: string;
|
||||
displayName?: string;
|
||||
description?: string;
|
||||
possibleTypes?: string[];
|
||||
dataType?: string;
|
||||
autoCaptured?: boolean;
|
||||
metadataName?: string;
|
||||
category?: string;
|
||||
|
|
@ -23,57 +23,55 @@ interface FilterItemData {
|
|||
isEvent?: boolean;
|
||||
value?: string[];
|
||||
propertyOrder?: string;
|
||||
filters?: FilterItemData[];
|
||||
filters?: IFilter[];
|
||||
autoOpen?: boolean;
|
||||
}
|
||||
|
||||
// Define valid keys that can be updated
|
||||
type FilterItemKeys = keyof FilterItemData;
|
||||
type FilterItemKeys = keyof IFilter;
|
||||
|
||||
export default class FilterItem {
|
||||
id: string = '';
|
||||
name: string = '';
|
||||
displayName?: string;
|
||||
description?: string;
|
||||
possibleTypes?: string[];
|
||||
autoCaptured?: boolean;
|
||||
metadataName?: string;
|
||||
displayName?: string = '';
|
||||
description?: string = '';
|
||||
possibleTypes?: string[] = [];
|
||||
dataType?: string = '';
|
||||
autoCaptured?: boolean = false;
|
||||
// metadataName?: string = '';
|
||||
category: string = '';
|
||||
subCategory?: string;
|
||||
type?: string;
|
||||
icon?: string;
|
||||
properties?: FilterProperty[];
|
||||
operator?: string;
|
||||
operators?: Operator[];
|
||||
isEvent?: boolean;
|
||||
value?: string[];
|
||||
propertyOrder?: string;
|
||||
filters?: FilterItem[];
|
||||
autoOpen?: boolean;
|
||||
subCategory?: string = '';
|
||||
type?: string = '';
|
||||
icon?: string = '';
|
||||
properties?: FilterProperty[] = [];
|
||||
operator?: string = '';
|
||||
operators?: Operator[] = [];
|
||||
isEvent?: boolean = false;
|
||||
value?: string[] = [''];
|
||||
propertyOrder?: string = '';
|
||||
filters?: FilterItem[] = [];
|
||||
autoOpen?: boolean = false;
|
||||
|
||||
constructor(data: FilterItemData = {}) {
|
||||
constructor(data: IFilter = {}) {
|
||||
makeAutoObservable(this);
|
||||
this.initializeFromData(data);
|
||||
}
|
||||
|
||||
private initializeFromData(data: FilterItemData): void {
|
||||
// Set default operator if not provided
|
||||
private initializeFromData(data: IFilter): void {
|
||||
const processedData = {
|
||||
...data,
|
||||
operator: data.operator || 'is',
|
||||
};
|
||||
|
||||
// Handle filters array transformation
|
||||
if (Array.isArray(data.filters)) {
|
||||
processedData.filters = data.filters.map(
|
||||
(filterData: FilterItemData) => new FilterItem(filterData),
|
||||
(filterData: IFilter) => new FilterItem(filterData),
|
||||
);
|
||||
}
|
||||
|
||||
this.merge(processedData);
|
||||
}
|
||||
|
||||
updateKey<K extends FilterItemKeys>(key: K, value: FilterItemData[K]): void {
|
||||
updateKey<K extends FilterItemKeys>(key: K, value: IFilter[K]): void {
|
||||
if (key in this) {
|
||||
(this as any)[key] = value;
|
||||
} else {
|
||||
|
|
@ -81,7 +79,8 @@ export default class FilterItem {
|
|||
}
|
||||
}
|
||||
|
||||
merge(data: FilterItemData): void {
|
||||
merge(data: IFilter): void {
|
||||
console.log('Object.entries(data)', Object.entries(data));
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
if (key in this && value !== undefined) {
|
||||
(this as any)[key] = value;
|
||||
|
|
@ -89,7 +88,7 @@ export default class FilterItem {
|
|||
});
|
||||
}
|
||||
|
||||
fromData(data: FilterItemData): FilterItem {
|
||||
fromData(data: IFilter): FilterItem {
|
||||
if (!data) {
|
||||
console.warn('fromData called with null/undefined data');
|
||||
return this;
|
||||
|
|
@ -98,14 +97,15 @@ export default class FilterItem {
|
|||
Object.assign(this, data);
|
||||
this.type = 'string';
|
||||
this.name = data.name || '';
|
||||
this.dataType = data.dataType || '';
|
||||
this.category = data.category || '';
|
||||
this.subCategory = data.subCategory;
|
||||
this.operator = data.operator;
|
||||
this.isEvent = Boolean(data.isEvent);
|
||||
|
||||
// Safely handle filters array
|
||||
if (Array.isArray(data.filters)) {
|
||||
this.filters = data.filters.map(
|
||||
(filterData: FilterItemData) => new FilterItem(filterData),
|
||||
(filterData: IFilter) => new FilterItem(filterData),
|
||||
);
|
||||
} else {
|
||||
this.filters = [];
|
||||
|
|
@ -121,13 +121,16 @@ export default class FilterItem {
|
|||
}
|
||||
|
||||
this.type = 'string';
|
||||
this.name = data.type || '';
|
||||
this.category = data.category || '';
|
||||
this.subCategory = data.subCategory;
|
||||
this.operator = data.operator;
|
||||
this.value = Array.isArray(data.value) ? data.value : [''];
|
||||
|
||||
// Safely handle filters array
|
||||
this.name = data.name || '';
|
||||
this.isEvent = Boolean(data.isEvent);
|
||||
this.autoCaptured = Boolean(data.autoCaptured);
|
||||
this.dataType = data.dataType || '';
|
||||
|
||||
if (Array.isArray(data.filters)) {
|
||||
this.filters = data.filters.map(
|
||||
(filterData: JsonData) => new FilterItem(filterData),
|
||||
|
|
@ -142,7 +145,6 @@ export default class FilterItem {
|
|||
toJson(): JsonData {
|
||||
const json: JsonData = {
|
||||
type: this.name,
|
||||
isEvent: Boolean(this.isEvent),
|
||||
value:
|
||||
this.value?.map((item: any) => (item ? item.toString() : '')) || [],
|
||||
operator: this.operator,
|
||||
|
|
@ -150,9 +152,14 @@ export default class FilterItem {
|
|||
filters: Array.isArray(this.filters)
|
||||
? this.filters.map((filter) => filter.toJson())
|
||||
: [],
|
||||
|
||||
// these props are required to get the source filter later
|
||||
isEvent: Boolean(this.isEvent),
|
||||
name: this.name,
|
||||
autoCaptured: this.autoCaptured,
|
||||
dataType: this.dataType,
|
||||
};
|
||||
|
||||
// Handle metadata category
|
||||
const isMetadata = this.category === FilterCategory.METADATA;
|
||||
if (isMetadata) {
|
||||
json.type = FilterKey.METADATA;
|
||||
|
|
@ -160,7 +167,6 @@ export default class FilterItem {
|
|||
json.sourceOperator = this.operator;
|
||||
}
|
||||
|
||||
// Handle duration type
|
||||
if (this.type === FilterKey.DURATION) {
|
||||
json.value = this.value?.map((item: any) => (item ? Number(item) : 0));
|
||||
}
|
||||
|
|
@ -168,7 +174,6 @@ export default class FilterItem {
|
|||
return json;
|
||||
}
|
||||
|
||||
// Additional utility methods
|
||||
isValid(): boolean {
|
||||
return Boolean(this.name && this.category);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,21 @@ import { makeAutoObservable, observable, action } from 'mobx';
|
|||
import FilterStore from './filter';
|
||||
import { JsonData } from '@/mstore/types/filterConstants';
|
||||
|
||||
export default class FilterSeries {
|
||||
export interface IFilterSeries {
|
||||
seriesId?: any;
|
||||
name: string;
|
||||
filter: FilterStore;
|
||||
update(key: any, value: any): void;
|
||||
fromJson(json: JsonData, isHeatmap?: boolean): this;
|
||||
fromData(data: any): this;
|
||||
toJson(): {
|
||||
seriesId?: any;
|
||||
name: string;
|
||||
filter: ReturnType<FilterStore['toJson']>;
|
||||
};
|
||||
}
|
||||
|
||||
export default class FilterSeries implements IFilterSeries {
|
||||
public static get ID_KEY(): string {
|
||||
return 'seriesId';
|
||||
}
|
||||
|
|
@ -16,7 +30,7 @@ export default class FilterSeries {
|
|||
name: observable,
|
||||
filter: observable.shallow,
|
||||
|
||||
update: action
|
||||
update: action,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -30,7 +44,7 @@ export default class FilterSeries {
|
|||
this.name = json.name;
|
||||
this.filter = new FilterStore().fromJson(
|
||||
json.filter || { filters: [] },
|
||||
isHeatmap
|
||||
isHeatmap,
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -46,7 +60,7 @@ export default class FilterSeries {
|
|||
return {
|
||||
seriesId: this.seriesId,
|
||||
name: this.name,
|
||||
filter: this.filter.toJson()
|
||||
filter: this.filter.toJson(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import {
|
||||
CUSTOM_RANGE,
|
||||
DATE_RANGE_VALUES,
|
||||
getDateRangeFromValue
|
||||
getDateRangeFromValue,
|
||||
} from 'App/dateRange';
|
||||
import FilterItem from 'App/mstore/types/filterItem';
|
||||
import { makeAutoObservable, observable } from 'mobx';
|
||||
import { LAST_24_HOURS, LAST_30_DAYS, LAST_7_DAYS } from 'Types/app/period';
|
||||
import { roundToNextMinutes } from '@/utils';
|
||||
// import { Filter } from '@/mstore/types/filterConstants';
|
||||
import { Filter } from '@/mstore/types/filterConstants';
|
||||
|
||||
// @ts-ignore
|
||||
const rangeValue = DATE_RANGE_VALUES.LAST_24_HOURS;
|
||||
|
|
@ -75,7 +75,7 @@ export default class Search {
|
|||
|
||||
constructor(initialData?: Partial<ISearch>) {
|
||||
makeAutoObservable(this, {
|
||||
filters: observable
|
||||
filters: observable,
|
||||
});
|
||||
Object.assign(this, {
|
||||
name: '',
|
||||
|
|
@ -105,7 +105,7 @@ export default class Search {
|
|||
strict: false,
|
||||
eventsOrder: 'then',
|
||||
limit: 10,
|
||||
...initialData
|
||||
...initialData,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ export default class Search {
|
|||
toSearch() {
|
||||
const js: any = { ...this };
|
||||
js.filters = this.filters.map((filter: any) =>
|
||||
new FilterItem(filter).toJson()
|
||||
new FilterItem(filter).toJson(),
|
||||
);
|
||||
|
||||
const { startDate, endDate } = this.getDateRange(
|
||||
|
|
@ -182,7 +182,7 @@ export default class Search {
|
|||
case CUSTOM_RANGE:
|
||||
if (!customStartDate || !customEndDate) {
|
||||
throw new Error(
|
||||
'Start date and end date must be provided for CUSTOM_RANGE.'
|
||||
'Start date and end date must be provided for CUSTOM_RANGE.',
|
||||
);
|
||||
}
|
||||
startDate = customStartDate;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue