change(ui): add clickmap card type, add query effect for metric type dd

This commit is contained in:
sylenien 2022-12-12 16:48:57 +01:00
parent 4a611a6d4a
commit 013db32b60
8 changed files with 66 additions and 34 deletions

View file

@ -4,7 +4,7 @@ import CustomMetricPercentage from 'App/components/Dashboard/Widgets/CustomMetri
import CustomMetricTable from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricTable';
import CustomMetricPieChart from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricPieChart';
import { Styles } from 'App/components/Dashboard/Widgets/common';
import { observer, useObserver } from 'mobx-react-lite';
import { observer } from 'mobx-react-lite';
import { Loader } from 'UI';
import { useStore } from 'App/mstore';
import WidgetPredefinedChart from '../WidgetPredefinedChart';
@ -13,23 +13,25 @@ import { getStartAndEndTimestampsByDensity } from 'Types/dashboard/helper';
import { debounce } from 'App/utils';
import useIsMounted from 'App/hooks/useIsMounted'
import { FilterKey } from 'Types/filter/filterType';
import { CLICKMAP } from 'App/constants/card';
import FunnelWidget from 'App/components/Funnels/FunnelWidget';
import ErrorsWidget from '../Errors/ErrorsWidget';
import SessionWidget from '../Sessions/SessionWidget';
import CustomMetricTableSessions from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricTableSessions';
import CustomMetricTableErrors from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricTableErrors';
interface Props {
metric: any;
isWidget?: boolean;
isTemplate?: boolean;
}
function WidgetChart(props: Props) {
const { isWidget = false, metric, isTemplate } = props;
const { dashboardStore, metricStore } = useStore();
const _metric: any = metricStore.instance;
const period = useObserver(() => dashboardStore.period);
const drillDownPeriod = useObserver(() => dashboardStore.drillDownPeriod);
const period = dashboardStore.period;
const drillDownPeriod = dashboardStore.drillDownPeriod;
const drillDownFilter = dashboardStore.drillDownFilter;
const colors = Styles.customMetricColors;
const [loading, setLoading] = useState(true)
@ -175,6 +177,11 @@ function WidgetChart(props: Props) {
)
}
}
if (metricType === CLICKMAP) {
return (
<div>rendering clickmap</div>
)
}
return <div>Unknown</div>;
}

View file

@ -2,7 +2,7 @@ import React from 'react';
import { metricTypes, metricOf, issueOptions } from 'App/constants/filterOptions';
import { FilterKey } from 'Types/filter/filterType';
import { useStore } from 'App/mstore';
import { useObserver } from 'mobx-react-lite';
import { observer } from 'mobx-react-lite';
import { Button, Icon, SegmentSelection } from 'UI'
import FilterSeries from '../FilterSeries';
import { confirm, Tooltip } from 'UI';
@ -28,8 +28,8 @@ function WidgetForm(props: Props) {
const { history, match: { params: { siteId, dashboardId } } } = props;
const { metricStore, dashboardStore } = useStore();
const dashboards = dashboardStore.dashboards;
const isSaving = useObserver(() => metricStore.isSaving);
const metric: any = useObserver(() => metricStore.instance)
const isSaving = metricStore.isSaving;
const metric: any = metricStore.instance
const timeseriesOptions = metricOf.filter(i => i.type === 'timeseries');
const tableOptions = metricOf.filter(i => i.type === 'table');
@ -37,7 +37,7 @@ function WidgetForm(props: Props) {
const isFunnel = metric.metricType === 'funnel';
const canAddToDashboard = metric.exists() && dashboards.length > 0;
const canAddSeries = metric.series.length < 3;
const eventsLength = useObserver(() => metric.series[0].filter.filters.filter((i: any) => i.isEvent).length)
const eventsLength = metric.series[0].filter.filters.filter((i: any) => i.isEvent).length
const cannotSaveFunnel = isFunnel && (!metric.series[0] || eventsLength <= 1);
const writeOption = ({ value, name }: any) => {
@ -100,12 +100,12 @@ function WidgetForm(props: Props) {
}
}
return useObserver(() => (
return (
<div className="p-6">
<div className="form-group">
<label className="font-medium">Metric Type</label>
<div className="flex items-center">
<MetricTypeDropdown onSelect={writeOption} />
<MetricTypeDropdown />
<MetricSubtypeDropdown onSelect={writeOption} />
{/* {metric.metricType === 'timeseries' && (
@ -216,7 +216,7 @@ function WidgetForm(props: Props) {
</div>
</div>
</div>
));
);
}
export default WidgetForm;
export default observer(WidgetForm);

View file

@ -1,5 +1,5 @@
import { useStore } from 'App/mstore';
import { useObserver } from 'mobx-react-lite';
import { observer } from 'mobx-react-lite';
import { TYPES } from 'App/constants/card';
import { MetricType } from 'App/components/Dashboard/components/MetricTypeItem/MetricTypeItem';
import React from 'react';
@ -12,8 +12,8 @@ interface Props {
}
function MetricSubtypeDropdown(props: Props) {
const { metricStore } = useStore();
const metric: any = useObserver(() => metricStore.instance);
const metric: any = metricStore.instance;
const options = React.useMemo(() => {
const type = TYPES.find((i: MetricType) => i.slug === metric.metricType);
if (type && type.subTypes) {
@ -56,4 +56,4 @@ function MetricSubtypeDropdown(props: Props) {
) : null;
}
export default MetricSubtypeDropdown;
export default observer(MetricSubtypeDropdown);

View file

@ -4,15 +4,16 @@ import Select from 'Shared/Select';
import { MetricType } from 'App/components/Dashboard/components/MetricTypeItem/MetricTypeItem';
import { components } from 'react-select';
import CustomDropdownOption from 'Shared/CustomDropdownOption';
import { useObserver } from 'mobx-react-lite';
import { observer } from 'mobx-react-lite';
import { useStore } from 'App/mstore';
import withLocationHandlers from 'HOCs/withLocationHandlers';
interface Props {
onSelect: any;
query: Record<string, (key: string) => any>;
}
function MetricTypeDropdown(props: Props) {
const { metricStore } = useStore();
const metric: any = useObserver(() => metricStore.instance);
const metric: any = metricStore.instance;
const options: any = useMemo(() => {
// TYPES.shift(); // remove "Add from library" item
return TYPES.filter((i: MetricType) => i.slug !== LIBRARY).map((i: MetricType) => ({
@ -23,16 +24,25 @@ function MetricTypeDropdown(props: Props) {
}));
}, []);
const onSelect = (_: any, option: Record<string, any>) =>
props.onSelect({ value: { value: option.value }, name: option.name });
React.useEffect(() => {
const queryCardType = props.query.get('type')
if (queryCardType && options.length > 0 && metric.metricType) {
const type = options.find(i => i.value === queryCardType)
setTimeout(() => onChange(type.value), 0)
console.log('trying to change to ', type, metric.metricType)
}
}, [])
const onChange = (type: string) => {
metricStore.changeType(type)
}
return (
<Select
name="metricType"
placeholder="Select Card Type"
options={options}
value={options.find((i: any) => i.value === metric.metricType) || options[0]}
onChange={props.onSelect}
onChange={(selected) => onChange(selected.value.value as string)}
// onSelect={onSelect}
components={{
MenuList: ({ children, ...props }: any) => {
@ -51,4 +61,4 @@ function MetricTypeDropdown(props: Props) {
);
}
export default MetricTypeDropdown;
export default withLocationHandlers()(observer(MetricTypeDropdown));

View file

@ -3,7 +3,7 @@ import cn from 'classnames';
import WidgetWrapper from '../WidgetWrapper';
import { useStore } from 'App/mstore';
import { SegmentSelection, Button, Icon } from 'UI';
import { useObserver } from 'mobx-react-lite';
import { observer } from 'mobx-react-lite';
import { FilterKey } from 'Types/filter/filterType';
import WidgetDateRange from '../WidgetDateRange/WidgetDateRange';
// import Period, { LAST_24_HOURS, LAST_30_DAYS } from 'Types/app/period';
@ -18,12 +18,12 @@ function WidgetPreview(props: Props) {
const { className = '' } = props;
const { metricStore, dashboardStore } = useStore();
const dashboards = dashboardStore.dashboards;
const metric: any = useObserver(() => metricStore.instance);
const metric: any = metricStore.instance;
const isTimeSeries = metric.metricType === 'timeseries';
const isTable = metric.metricType === 'table';
const drillDownFilter = useObserver(() => dashboardStore.drillDownFilter);
const disableVisualization = useObserver(() => metric.metricOf === FilterKey.SESSIONS || metric.metricOf === FilterKey.ERRORS);
// const period = useObserver(() => dashboardStore.drillDownPeriod);
const drillDownFilter = dashboardStore.drillDownFilter;
const disableVisualization = metric.metricOf === FilterKey.SESSIONS || metric.metricOf === FilterKey.ERRORS;
// const period = dashboardStore.drillDownPeriod;
const chagneViewType = (e, { name, value }: any) => {
metric.update({ [ name ]: value });
@ -40,7 +40,7 @@ function WidgetPreview(props: Props) {
const canAddToDashboard = metric.exists() && dashboards.length > 0;
return useObserver(() => (
return (
<>
<div className={cn(className, 'bg-white rounded border')}>
<div className="flex items-center justify-between px-4 pt-2">
@ -93,7 +93,7 @@ function WidgetPreview(props: Props) {
className="ml-2 p-0"
onClick={() => setShowDashboardSelectionModal(true)}
disabled={!canAddToDashboard}
>
>
<Icon name="columns-gap-filled" size="14" className="mr-2" color="teal"/>
Add to Dashboard
</Button>
@ -112,7 +112,7 @@ function WidgetPreview(props: Props) {
/>
)}
</>
));
);
}
export default WidgetPreview;
export default observer(WidgetPreview);

View file

@ -12,6 +12,7 @@ export interface CardType {
export const LIBRARY = 'library';
export const TIMESERIES = 'timeseries';
export const TABLE = 'table';
export const CLICKMAP = 'clickmap'
export const TYPES: CardType[] = [
{
@ -20,6 +21,15 @@ export const TYPES: CardType[] = [
description: 'Select a pre existing card from card library',
slug: LIBRARY,
},
{
title: 'Clickmap',
icon: 'puzzle-piece',
description: 'Track the features that are being used the most.',
slug: CLICKMAP,
subTypes: [
{ title: 'Visited URL', slug: FilterKey.CLICKMAP_URL, description: "" },
]
},
{
title: 'Timeseries',
icon: 'graph-up',

View file

@ -1,4 +1,4 @@
import { makeAutoObservable, computed } from 'mobx';
import { makeAutoObservable } from 'mobx';
import Widget from './types/widget';
import { metricService, errorService } from 'App/services';
import { toast } from 'react-toastify';
@ -24,7 +24,6 @@ export default class MetricStore {
makeAutoObservable(this);
}
@computed
get sortedWidgets() {
return [...this.metrics].sort((a, b) => b.lastModified - a.lastModified);
}
@ -44,6 +43,10 @@ export default class MetricStore {
this.instance.updateKey('hasChanged', true);
}
changeType(value: string) {
this.instance.update({ metricType: value})
}
reset(id: string) {
const metric = this.findById(id);
if (metric) {

View file

@ -274,4 +274,6 @@ export enum FilterKey {
RESOURCE_TYPE_VS_RESPONSE_END = 'resourceTypeVsResponseEnd',
RESOURCE_FETCH_TIME = 'resourceFetchTime',
SLOWEST_RESOURCES = 'slowestResources',
CLICKMAP_URL = 'clickmapUrl'
}