fix(ui) - widget change detection on route change

This commit is contained in:
Shekar Siri 2022-06-23 18:59:21 +02:00
parent b22f1488a6
commit a63ff8ae12
5 changed files with 26 additions and 15 deletions

View file

@ -36,22 +36,24 @@ function FilterSeries(props: Props) {
const [expanded, setExpanded] = useState(true)
const { series, seriesIndex } = props;
useEffect(observeChanges, [series.filter]);
const onAddFilter = (filter: any) => {
series.filter.addFilter(filter)
observeChanges()
}
const onUpdateFilter = (filterIndex: any, filter: any) => {
series.filter.updateFilter(filterIndex, filter)
observeChanges()
}
const onChangeEventsOrder = (e, { name, value }: any) => {
series.filter.updateKey(name, value)
observeChanges()
}
const onRemoveFilter = (filterIndex: any) => {
series.filter.removeFilter(filterIndex)
observeChanges()
}
return (
@ -80,7 +82,6 @@ function FilterSeries(props: Props) {
onUpdateFilter={onUpdateFilter}
onRemoveFilter={onRemoveFilter}
onChangeEventsOrder={onChangeEventsOrder}
observeChanges={observeChanges}
/>
): (
<div className="color-gray-medium">{emptyMessage}</div>

View file

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { metricTypes, metricOf, issueOptions } from 'App/constants/filterOptions';
import { FilterKey } from 'Types/filter/filterType';
import { useStore } from 'App/mstore';
@ -31,7 +31,6 @@ function WidgetForm(props: Props) {
const canAddToDashboard = metric.exists() && dashboards.length > 0;
const canAddSeries = metric.series.length < 3;
// const write = ({ target: { value, name } }) => metricStore.merge({ [ name ]: value });
const writeOption = ({ value, name }: any) => {
value = Array.isArray(value) ? value : value.value
const obj: any = { [ name ]: value };
@ -170,6 +169,7 @@ function WidgetForm(props: Props) {
{metric.series.length > 0 && metric.series.slice(0, (isTable || isFunnel) ? 1 : metric.series.length).map((series: any, index: number) => (
<div className="mb-2">
<FilterSeries
observeChanges={() => metric.updateKey('hasChanged', true)}
hideHeader={ isTable }
seriesIndex={index}
series={series}

View file

@ -11,6 +11,7 @@ import { withSiteId } from 'App/routes';
import FunnelIssues from '../Funnels/FunnelIssues/FunnelIssues';
import Breadcrumb from 'Shared/Breadcrumb';
import { FilterKey } from 'Types/filter/filterType';
import { Prompt } from 'react-router'
interface Props {
history: any;
@ -23,12 +24,13 @@ function WidgetView(props: Props) {
const widget = useObserver(() => metricStore.instance);
const loading = useObserver(() => metricStore.isLoading);
const [expanded, setExpanded] = useState(!metricId || metricId === 'create');
const hasChanged = useObserver(() => widget.hasChanged)
console.log('hasChanged', hasChanged)
const dashboards = useObserver(() => dashboardStore.dashboards);
const dashboard = useObserver(() => dashboards.find((d: any) => d.dashboardId == dashboardId));
const dashboardName = dashboard ? dashboard.name : null;
React.useEffect(() => {
if (metricId && metricId !== 'create') {
metricStore.fetch(metricId, dashboardStore.period);
@ -48,6 +50,15 @@ function WidgetView(props: Props) {
return useObserver(() => (
<Loader loading={loading}>
<Prompt
when={hasChanged}
message={(location: any) => {
if (location.pathname.includes('/metrics/') || location.pathname.includes('/metric/')) {
return true;
}
return 'You have unsaved changes. Are you sure you want to leave?';
}}
/>
<div className="relative pb-10">
<Breadcrumb
items={[

View file

@ -35,8 +35,8 @@ export interface IMetricStore {
// API
save(metric: IWidget, dashboardId?: string): Promise<any>
fetchList(): void
fetch(metricId: string)
delete(metric: IWidget)
fetch(metricId: string, period?: any): Promise<any>
delete(metric: IWidget): Promise<any>
}
export default class MetricStore implements IMetricStore {
@ -98,6 +98,7 @@ export default class MetricStore implements IMetricStore {
merge(object: any) {
Object.assign(this.instance, object)
this.instance.updateKey('hasChanged', true)
}
reset(id: string) {
@ -153,6 +154,7 @@ export default class MetricStore implements IMetricStore {
toast.error('Error saving metric')
reject()
}).finally(() => {
this.instance.updateKey('hasChanged', false)
this.isSaving = false
})
})
@ -172,9 +174,6 @@ export default class MetricStore implements IMetricStore {
this.isLoading = true
return metricService.getMetric(id)
.then((metric: any) => {
// if (period) {
// metric.period = period
// }
return this.instance = new Widget().fromJson(metric, period)
}).finally(() => {
this.isLoading = false

View file

@ -40,13 +40,13 @@ export interface IWidget {
limit: number
params: any
period: any
hasChanges: boolean
hasChanged: boolean
updateKey(key: string, value: any): void
removeSeries(index: number): void
addSeries(): void
fromJson(json: any): void
toJsonDrilldown(json: any): void
toJsonDrilldown(): void
toJson(): any
validate(): void
update(data: any): void
@ -54,7 +54,7 @@ export interface IWidget {
toWidget(): any
setData(data: any): void
fetchSessions(metricId: any, filter: any): Promise<any>
setPeriod(period: Period): void
setPeriod(period: any): void
}
export default class Widget implements IWidget {
public static get ID_KEY():string { return "metricId" }
@ -80,7 +80,7 @@ export default class Widget implements IWidget {
params: any = { density: 70 }
period: any = Period({ rangeName: LAST_24_HOURS }) // temp value in detail view
hasChanges: boolean = false
hasChanged: boolean = false
sessionsLoading: boolean = false