change(ui): default filters and events order

This commit is contained in:
Shekar Siri 2024-06-27 11:37:26 +02:00
parent 03486d2f4f
commit 3fb41b63d3
6 changed files with 116 additions and 138 deletions

View file

@ -4,6 +4,7 @@ import {CARD_LIST, CARD_CATEGORIES, CardType} from './ExampleCards';
import {useStore} from 'App/mstore';
import Option from './Option';
import CardsLibrary from "Components/Dashboard/components/DashboardList/NewDashModal/CardsLibrary";
import {FUNNEL} from "App/constants/card";
interface SelectCardProps {
onClose: (refresh?: boolean) => void;
@ -20,22 +21,33 @@ const SelectCard: React.FC<SelectCardProps> = (props: SelectCardProps) => {
const dashboardId = window.location.pathname.split('/')[3];
const [libraryQuery, setLibraryQuery] = React.useState<string>('');
const handleCardSelection = (card: string) => {
console.log('card', card);
const selectedCard = CARD_LIST.find((c) => c.key === card) as CardType;
metricStore.merge({
const cardData: any = {
metricType: selectedCard.cardType,
name: selectedCard.title,
metricOf: selectedCard.metricOf,
});
};
if (selectedCard.cardType === FUNNEL) {
cardData.series = []
cardData.series.filter = []
}
metricStore.merge(cardData);
metricStore.instance.resetDefaults();
onCard();
};
const cardItems = useMemo(() => {
return CARD_LIST.filter((card) => card.category === selected).map((card) => (
<div key={card.key} className={card.width ? `col-span-${card.width}` : 'col-span-2'}>
<card.example onCard={handleCardSelection} type={card.key} title={card.title} data={card.data} height={card.height}/>
<card.example onCard={handleCardSelection}
type={card.key}
title={card.title}
data={card.data}
height={card.height}/>
</div>
));
}, [selected]);
@ -58,11 +70,6 @@ const SelectCard: React.FC<SelectCardProps> = (props: SelectCardProps) => {
return (
<>
{/*<Header selectedCount={selectedCards.length}*/}
{/* onAdd={onAddSelected}*/}
{/* title={dashboardId ? (isLibrary ? "Add Card" : "Create Card") : "Select a template to create a card"}*/}
{/*/>*/}
<Space className="items-center justify-between">
<div className="text-xl leading-4 font-medium">
{dashboardId ? (isLibrary ? "Add Card" : "Create Card") : "Select a template to create a card"}
@ -77,7 +84,6 @@ const SelectCard: React.FC<SelectCardProps> = (props: SelectCardProps) => {
<Input.Search
placeholder="Search"
// onSearch={(value) => setLibraryQuery(value)}
onChange={(value) => setLibraryQuery(value.target.value)}
style={{width: 200}}
/>
@ -86,32 +92,17 @@ const SelectCard: React.FC<SelectCardProps> = (props: SelectCardProps) => {
</Space>
{!isLibrary && <CategorySelector setSelected={setSelectedCategory} selected={selected}/>}
{isLibrary ? <CardsLibrary query={libraryQuery} selectedList={selectedCards} category={selected}
onCard={onCardClick}/> :
{isLibrary ?
<CardsLibrary query={libraryQuery}
selectedList={selectedCards}
category={selected}
onCard={onCardClick}/> :
<ExampleCardsGrid items={cardItems}/>}
</>
);
};
// interface HeaderProps {
// selectedCount?: number,
// onAdd?: () => void;
// title?: string;
// }
//
// const Header: React.FC<HeaderProps> = ({title = '', selectedCount = 0, onAdd = () => null}) => (
// <div className="flex items-center justify-between">
// <div className="text-lg leading-4 font-semibold">{title}</div>
// <div className="text-sm text-gray-500">
// {selectedCount > 0 ? (
// <Button type="link" onClick={onAdd}>
// Add {selectedCount} Selected
// </Button>
// ) : ''}
// </div>
// </div>
// );
interface CategorySelectorProps {
setSelected?: React.Dispatch<React.SetStateAction<string>>;
selected?: string;

View file

@ -105,6 +105,7 @@ function FilterSeries(props: Props) {
}
const onChangeEventsOrder = (_: any, {name, value}: any) => {
console.log(name, value)
series.filter.updateKey(name, value);
observeChanges();
};
@ -129,7 +130,7 @@ function FilterSeries(props: Props) {
)}
{expandable && !expanded && (
<Space className="justify-between w-full px-6 py-2">
<Space className="justify-between w-full px-5 py-2">
<FilterCountLabels filters={series.filter.filters} toggleExpand={() => setExpanded(!expanded)}/>
<Button onClick={() => setExpanded(!expanded)}
size="small"
@ -162,7 +163,7 @@ function FilterSeries(props: Props) {
)}
</div>
<div className="border-t h-12 flex items-center">
<div className="-mx-4 px-6">
<div className="-mx-4 px-5">
<AddStepButton excludeFilterKeys={excludeFilterKeys} series={series}/>
</div>
</div>

View file

@ -0,0 +1,55 @@
import {observer} from "mobx-react-lite";
import {Tooltip} from "UI";
import {Segmented} from "antd";
import React from "react";
const EventsOrder = observer((props: {
onChange: (e: any, v: any) => void,
filter: any,
}) => {
const {filter, onChange} = props;
const eventsOrderSupport = filter.eventsOrderSupport;
const options = [
{
name: 'eventsOrder',
label: 'THEN',
value: 'then',
disabled: eventsOrderSupport && !eventsOrderSupport.includes('then'),
},
{
name: 'eventsOrder',
label: 'AND',
value: 'and',
disabled: eventsOrderSupport && !eventsOrderSupport.includes('and'),
},
{
name: 'eventsOrder',
label: 'OR',
value: 'or',
disabled: eventsOrderSupport && !eventsOrderSupport.includes('or'),
},
];
return <div className="flex items-center gap-2">
<div
className="color-gray-medium text-sm"
style={{textDecoration: "underline dotted"}}
>
<Tooltip
title={`Select the operator to be applied between events in your search.`}
>
<div>Events Order</div>
</Tooltip>
</div>
<Segmented
size={"small"}
className="text-sm"
onChange={(v) => onChange(null, options.find((i) => i.value === v))}
value={filter.eventsOrder}
options={options}
/>
</div>;
});
export default EventsOrder;

View file

@ -1,12 +1,11 @@
import {Segmented} from 'antd';
import {Space} from 'antd';
import {List} from 'immutable';
import {GripHorizontal} from 'lucide-react';
import {observer} from 'mobx-react-lite';
import React, {useEffect} from 'react';
import {Tooltip} from 'UI';
import FilterItem from '../FilterItem';
import EventsOrder from "Shared/Filters/FilterList/EventsOrder";
interface Props {
filter?: any; // event/filter
@ -38,7 +37,6 @@ function FilterList(props: Props) {
} = props;
const filters = List(filter.filters);
const eventsOrderSupport = filter.eventsOrderSupport;
const hasEvents = filters.filter((i: any) => i.isEvent).size > 0;
const hasFilters = filters.filter((i: any) => !i.isEvent).size > 0;
@ -111,25 +109,6 @@ function FilterList(props: Props) {
[draggedInd, hoveredItem, filters, props.onFilterMove]
);
const eventOrderItems = [
{
label: 'THEN',
value: 'then',
disabled: eventsOrderSupport && !eventsOrderSupport.includes('then'),
},
{
label: 'AND',
value: 'and',
disabled: eventsOrderSupport && !eventsOrderSupport.includes('and'),
},
{
label: 'OR',
value: 'or',
disabled: eventsOrderSupport && !eventsOrderSupport.includes('or'),
},
];
const eventsNum = filters.filter((i: any) => i.isEvent).size
return (
<div className="flex flex-col">
@ -137,37 +116,16 @@ function FilterList(props: Props) {
<>
<div className="flex items-center mb-2">
<div className="text-sm color-gray-medium mr-auto">
{filter.eventsHeader}
{filter.eventsHeader || 'EVENTS'}
</div>
{!hideEventsOrder && (
<div className="flex items-center gap-2">
<div
className="color-gray-medium text-sm"
style={{textDecoration: 'underline dotted'}}
>
<Tooltip
title={`Select the operator to be applied between events in your search.`}
>
<div>Events Order</div>
</Tooltip>
</div>
<Segmented
size={'small'}
onChange={(v) =>
props.onChangeEventsOrder(
null,
eventOrderItems.find((i) => i.value === v)
)
}
value={filter.eventsOrder}
options={eventOrderItems}
/>
{actions && actions.map((action, index) => (
<div key={index}>{action}</div>
))}
</div>
)}
<Space>
{!hideEventsOrder && <EventsOrder filter={filter}
onChange={props.onChangeEventsOrder}/>}
{actions && actions.map((action, index) => (
<div key={index}>{action}</div>
))}
</Space>
</div>
<div className={'flex flex-col'}>
{filters.map((filter: any, filterIndex: number) =>
@ -263,50 +221,3 @@ function FilterList(props: Props) {
}
export default observer(FilterList);
function EventsOrder(props: {
onChange: (e: any, v: any) => void,
filter: any,
eventsOrderSupport: any
}) {
const {filter, eventsOrderSupport, onChange} = props;
const options = [
{
label: 'THEN',
value: 'then',
disabled: eventsOrderSupport && !eventsOrderSupport.includes('then'),
},
{
label: 'AND',
value: 'and',
disabled: eventsOrderSupport && !eventsOrderSupport.includes('and'),
},
{
label: 'OR',
value: 'or',
disabled: eventsOrderSupport && !eventsOrderSupport.includes('or'),
},
];
return <div className="flex items-center gap-2">
<div
className="color-gray-medium text-sm"
style={{textDecoration: "underline dotted"}}
>
<Tooltip
title={`Select the operator to be applied between events in your search.`}
>
<div>Events Order</div>
</Tooltip>
</div>
<Segmented
size={"small"}
// onChange={props.onChange}
onChange={(v) => onChange(null, options.find((i) => i.value === v))}
value={filter.eventsOrder}
options={options}
/>
</div>;
}

View file

@ -1,9 +1,13 @@
import { makeAutoObservable, runInAction, observable, action } from "mobx"
import {makeAutoObservable, runInAction, observable, action} from "mobx"
import FilterItem from "./filterItem"
import { filtersMap, conditionalFiltersMap } from 'Types/filter/newFilter';
import {filtersMap, conditionalFiltersMap} from 'Types/filter/newFilter';
import {FilterKey} from "Types/filter/filterType";
export default class Filter {
public static get ID_KEY():string { return "filterId" }
public static get ID_KEY(): string {
return "filterId"
}
filterId: string = ''
name: string = ''
filters: FilterItem[] = []
@ -70,7 +74,7 @@ export default class Filter {
fromJson(json: any) {
this.name = json.name
this.filters = json.filters.map((i: Record<string, any>) =>
new FilterItem(undefined, this.isConditional, this.isMobile).fromJson(i)
new FilterItem(undefined, this.isConditional, this.isMobile).fromJson(i)
);
this.eventsOrder = json.eventsOrder
return this
@ -79,7 +83,7 @@ export default class Filter {
fromData(data) {
this.name = data.name
this.filters = data.filters.map((i: Record<string, any>) =>
new FilterItem(undefined, this.isConditional, this.isMobile).fromData(i)
new FilterItem(undefined, this.isConditional, this.isMobile).fromData(i)
)
this.eventsOrder = data.eventsOrder
return this
@ -121,4 +125,10 @@ export default class Filter {
removeExcludeFilter(index: number) {
this.excludes.splice(index, 1)
}
addFunnelDefaultFilters() {
this.filters = []
this.addFilter({...filtersMap[FilterKey.CLICK], value: [''], operator: 'onAny'})
this.addFilter({...filtersMap[FilterKey.CLICK], value: [''], operator: 'onAny'})
}
}

View file

@ -265,6 +265,16 @@ export default class Widget {
});
}
resetDefaults() {
if (this.metricType === FUNNEL) {
this.series = [];
this.series.push(new FilterSeries());
this.series[0].filter.addFunnelDefaultFilters();
this.series[0].filter.eventsOrder = 'then';
this.series[0].filter.eventsOrderSupport = ['then'];
}
}
exists() {
return this.metricId !== undefined;
}