fix(ui) - data reload on change

This commit is contained in:
Shekar Siri 2022-04-21 13:28:54 +02:00
parent fabbe92086
commit 3c0d8f81fc
9 changed files with 68 additions and 52 deletions

View file

@ -13,8 +13,7 @@ import { IconButton, Icon } from 'UI';
import FilterSelection from 'Shared/Filters/FilterSelection';
import SeriesName from './SeriesName';
import cn from 'classnames';
import { useDashboardStore } from '../../store/store';
import { observer, useObserver } from 'mobx-react-lite';
import { observer } from 'mobx-react-lite';
interface Props {
seriesIndex: number;
@ -37,7 +36,7 @@ function FilterSeries(props: Props) {
const [expanded, setExpanded] = useState(true)
const { series, seriesIndex } = props;
useEffect(observeChanges, [series])
useEffect(observeChanges, [series.filter]);
const onAddFilter = (filter) => {
series.filter.addFilter(filter)
@ -49,12 +48,10 @@ function FilterSeries(props: Props) {
const onChangeEventsOrder = (e, { name, value }) => {
series.filter.updateKey(name, value)
// props.editSeriesFilter(seriesIndex, { eventsOrder: value });
}
const onRemoveFilter = (filterIndex) => {
series.filter.removeFilter(filterIndex)
// props.removeSeriesFilterFilter(seriesIndex, filterIndex);
}
return (

View file

@ -4,29 +4,32 @@ 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 { useObserver } from 'mobx-react-lite';
import { observer, useObserver } from 'mobx-react-lite';
import { Loader } from 'UI';
import { useStore } from 'App/mstore';
import WidgetPredefinedChart from '../WidgetPredefinedChart';
import CustomMetricOverviewChart from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricOverviewChart';
import { getStartAndEndTimestampsByDensity } from 'Types/dashboard/helper';
import { debounce } from 'App/utils';
interface Props {
metric: any;
isWidget?: boolean
}
function WidgetChart(props: Props) {
const { isWidget = false, metric } = props;
const { dashboardStore } = useStore();
const { dashboardStore, metricStore } = useStore();
const _metric: any = useObserver(() => metricStore.instance);
const period = useObserver(() => dashboardStore.period);
const drillDownFilter = useObserver(() => dashboardStore.drillDownFilter);
const colors = Styles.customMetricColors;
const [loading, setLoading] = useState(false)
const [loading, setLoading] = useState(true)
const isOverviewWidget = metric.metricType === 'predefined' && metric.viewType === 'overview';
const params = { density: isOverviewWidget ? 7 : 70 }
const metricParams = { ...params }
const prevMetricRef = useRef<any>();
const [data, setData] = useState<any>(metric.data);
const isTableWidget = metric.metricType === 'table' && metric.viewType === 'table';
const isPieChart = metric.metricType === 'table' && metric.viewType === 'pieChart';
@ -52,21 +55,28 @@ function WidgetChart(props: Props) {
}
}
const depsString = JSON.stringify(_metric.series);
const fetchMetricChartData = (metric, payload, isWidget) => {
setLoading(true)
dashboardStore.fetchMetricChartData(metric, payload, isWidget).then((res: any) => {
setData(res);
}).finally(() => {
setLoading(false);
});
}
const debounceRequest: any = React.useCallback(debounce(fetchMetricChartData, 500), []);
useEffect(() => {
if (prevMetricRef.current && prevMetricRef.current.name !== metric.name) {
prevMetricRef.current = metric;
return
};
prevMetricRef.current = metric;
setLoading(true);
const payload = isWidget ? { ...params } : { ...metricParams, ...metric.toJson() };
dashboardStore.fetchMetricChartData(metric, payload, isWidget).then((res: any) => {
setData(res);
}).finally(() => {
setLoading(false);
});
}, [period]);
debounceRequest(metric, payload, isWidget);
}, [period, depsString]);
const renderChart = () => {
const { metricType, viewType } = metric;
@ -121,10 +131,10 @@ function WidgetChart(props: Props) {
return <div>Unknown</div>;
}
return useObserver(() => (
<Loader loading={loading}>
<Loader loading={loading} size="small" style={{ height: `${isOverviewWidget ? 100 : 240}px` }}>
{renderChart()}
</Loader>
));
}
export default WidgetChart;
export default observer(WidgetChart);

View file

@ -4,9 +4,8 @@ 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 { HelpText, Button, Icon } from 'UI'
import { Button, Icon } from 'UI'
import FilterSeries from '../FilterSeries';
import { withRouter } from 'react-router-dom';
import { confirm } from 'UI/Confirmation';
import { withSiteId, dashboardMetricDetails, metricDetails } from 'App/routes'
import DashboardSelectionModal from '../DashboardSelectionModal/DashboardSelectionModal';
@ -28,31 +27,34 @@ function WidgetForm(props: Props) {
const timeseriesOptions = metricOf.filter(i => i.type === 'timeseries');
const tableOptions = metricOf.filter(i => i.type === 'table');
const isTable = metric.metricType === 'table';
const isTimeSeries = metric.metricType === 'timeseries';
const _issueOptions = [{ text: 'All', value: 'all' }].concat(issueOptions);
const canAddToDashboard = metric.exists() && dashboards.length > 0;
const write = ({ target: { value, name } }) => metricStore.merge({ [ name ]: value });
const writeOption = (e, { value, name }) => {
metricStore.merge({ [ name ]: value });
const obj = { [ name ]: value };
if (name === 'metricValue') {
metricStore.merge({ metricValue: [value] });
obj['metricValue'] = [value];
}
if (name === 'metricOf') {
if (value === FilterKey.ISSUE) {
metricStore.merge({ metricValue: ['all'] });
obj['metricValue'] = ['all'];
}
}
if (name === 'metricType') {
if (value === 'timeseries') {
metricStore.merge({ metricOf: timeseriesOptions[0].value, viewType: 'lineChart' });
obj['metricOf'] = timeseriesOptions[0].value;
obj['viewType'] = 'lineChart';
} else if (value === 'table') {
metricStore.merge({ metricOf: tableOptions[0].value, viewType: 'table' });
obj['metricOf'] = tableOptions[0].value;
obj['viewType'] = 'table';
}
}
metricStore.merge(obj);
};
const onSave = () => {
@ -172,7 +174,7 @@ function WidgetForm(props: Props) {
'Filter data using any event or attribute. Use Add Step button below to do so.' :
'Add user event or filter to define the series by clicking Add Step.'
}
observeChanges={onObserveChanges}
// observeChanges={onObserveChanges}
/>
</div>
))}

View file

@ -5,12 +5,14 @@ import { useStore } from 'App/mstore';
import SessionItem from 'Shared/SessionItem';
import { observer, useObserver } from 'mobx-react-lite';
import { DateTime } from 'luxon';
import { debounce } from 'App/utils';
interface Props {
className?: string;
}
function WidgetSessions(props: Props) {
const { className = '' } = props;
const [data, setData] = useState<any>([]);
const [loading, setLoading] = useState(false);
const [seriesOptions, setSeriesOptions] = useState([
{ text: 'All', value: 'all' },
]);
@ -30,18 +32,27 @@ function WidgetSessions(props: Props) {
]);
}, [data]);
const fetchSessions = (metricId, filter) => {
setLoading(true)
widget.fetchSessions(metricId, filter).then(res => {
setData(res)
}).finally(() => {
setLoading(false)
});
}
const filteredSessions = getListSessionsBySeries(data, activeSeries);
const { dashboardStore, metricStore } = useStore();
const filter = useObserver(() => dashboardStore.drillDownFilter);
const widget: any = useObserver(() => metricStore.instance);
const startTime = DateTime.fromMillis(filter.startTimestamp).toFormat('LLL dd, yyyy HH:mm a');
const endTime = DateTime.fromMillis(filter.endTimestamp).toFormat('LLL dd, yyyy HH:mm a');
const debounceRequest: any = React.useCallback(debounce(fetchSessions, 1000), []);
const depsString = JSON.stringify(widget.series);
useEffect(() => {
widget.fetchSessions({ ...filter, series: widget.toJsonDrilldown() }).then(res => {
setData(res);
});
}, [filter.startTimestamp, filter.endTimestamp, filter.filters]);
debounceRequest(widget.metricId, { ...filter, series: widget.toJsonDrilldown() });
}, [filter.startTimestamp, filter.endTimestamp, filter.filters, depsString]);
return useObserver(() => (
<div className={cn(className)}>
@ -71,7 +82,7 @@ function WidgetSessions(props: Props) {
</div>
<div className="mt-3">
<Loader loading={widget.sessionsLoading}>
<Loader loading={loading}>
<NoContent
title="No recordings found"
show={filteredSessions.length === 0}

View file

@ -1,5 +1,4 @@
import React, { useEffect, useState } from 'react';
import { withRouter } from 'react-router-dom';
import React, { useState } from 'react';
import { useStore } from 'App/mstore';
import WidgetForm from '../WidgetForm';
import WidgetPreview from '../WidgetPreview';

View file

@ -33,6 +33,7 @@ function WidgetWrapper(props: Props) {
const widget: any = useObserver(() => props.widget);
const isPredefined = widget.metricType === 'predefined';
const dashboard = useObserver(() => dashboardStore.selectedDashboard);
const isOverviewWidget = widget.widgetType === 'predefined' && widget.viewType === 'overview';
const [{ opacity, isDragging }, dragRef] = useDrag({
type: 'item',
@ -117,7 +118,7 @@ function WidgetWrapper(props: Props) {
)}
</div>
<LazyLoad height={100} offset={120} >
<LazyLoad height={!isTemplate ? 300 : 10} offset={!isTemplate ? 100 : 10} >
<div className="px-4" onClick={onChartClick}>
<WidgetChart metric={widget} isWidget={isWidget} />
</div>

View file

@ -73,13 +73,13 @@ export default class MetricStore implements IMetricStore {
paginatedList: computed,
})
reaction(
() => this.metricsSearch,
(metricsSearch) => { // TODO filter the list for View
this.page = 1
this.paginatedList
}
)
// reaction(
// () => this.metricsSearch,
// (metricsSearch) => { // TODO filter the list for View
// this.page = 1
// this.paginatedList
// }
// )
}
// State Actions
@ -92,7 +92,7 @@ export default class MetricStore implements IMetricStore {
}
merge(object: any) {
this.instance = Object.assign(this.instance, object)
Object.assign(this.instance, object)
}
reset(id: string) {

View file

@ -1,6 +1,4 @@
import { makeAutoObservable, runInAction, observable, action, reaction } from "mobx"
import { FilterKey, FilterType } from 'Types/filter/filterType'
import { filtersMap } from 'Types/filter/newFilter'
import { makeAutoObservable, runInAction, observable, action } from "mobx"
import FilterItem from "./filterItem"
export interface IFilter {

View file

@ -4,6 +4,7 @@ import { DateTime } from 'luxon';
import { IFilter } from "./filter";
import { metricService } from "App/services";
import Session, { ISession } from "App/mstore/types/session";
export interface IWidget {
metricId: any
widgetId: any
@ -45,7 +46,7 @@ export interface IWidget {
exists(): boolean
toWidget(): any
setData(data: any): void
fetchSessions(filter: any): Promise<any>
fetchSessions(metricId: any, filter: any): Promise<any>
}
export default class Widget implements IWidget {
public static get ID_KEY():string { return "metricId" }
@ -195,18 +196,15 @@ export default class Widget implements IWidget {
})
}
fetchSessions(filter: any): Promise<any> {
this.sessionsLoading = true
fetchSessions(metricId: any, filter: any): Promise<any> {
return new Promise((resolve, reject) => {
metricService.fetchSessions(this.metricId, filter).then(response => {
metricService.fetchSessions(metricId, filter).then(response => {
resolve(response.map(cat => {
return {
...cat,
sessions: cat.sessions.map(s => new Session().fromJson(s))
}
}))
}).finally(() => {
this.sessionsLoading = false
})
})
}