feat(ui) - insights - data format
This commit is contained in:
parent
0200442732
commit
d15f5e779c
4 changed files with 178 additions and 181 deletions
|
|
@ -8,6 +8,7 @@ interface Props {
|
|||
function InsightItem(props: Props) {
|
||||
const { item, onClick = () => {} } = props;
|
||||
return (
|
||||
// TODO update according to the new response format
|
||||
<div
|
||||
className="flex items-center py-4 hover:bg-active-blue -mx-4 px-4 border-b last:border-transparent cursor-pointer"
|
||||
onClick={onClick}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,9 @@
|
|||
import { NoContent } from 'App/components/ui';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import React from 'react';
|
||||
import InsightItem from './InsightItem';
|
||||
|
||||
const data = [
|
||||
{ icon: 'dizzy', ratio: 'Click Rage', increase: 10, iconColor: 'red' },
|
||||
{ icon: 'dizzy', ratio: 'Click Rage', increase: 10, iconColor: 'yello' },
|
||||
{ icon: 'dizzy', ratio: 'Click Rage', increase: 10, iconColor: 'green' },
|
||||
{ icon: 'dizzy', ratio: 'Click Rage', increase: 10, iconColor: 'gray' },
|
||||
{ icon: 'dizzy', ratio: 'Click Rage', increase: 10, iconColor: 'red' },
|
||||
];
|
||||
interface Props {}
|
||||
function InsightsCard(props: Props) {
|
||||
const { metricStore, dashboardStore } = useStore();
|
||||
|
|
@ -29,11 +23,11 @@ function InsightsCard(props: Props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
{data.map((item) => (
|
||||
<NoContent>
|
||||
{metric.data.issues.map((item: any) => (
|
||||
<InsightItem item={item} onClick={clickHanddler} />
|
||||
))}
|
||||
</div>
|
||||
</NoContent>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -429,77 +429,8 @@ export default class DashboardStore {
|
|||
return metricService
|
||||
.getMetricChartData(metric, params, isWidget)
|
||||
.then((data: any) => {
|
||||
if (
|
||||
metric.metricType === "predefined" &&
|
||||
metric.viewType === "overview"
|
||||
) {
|
||||
const _data = {
|
||||
...data,
|
||||
chart: getChartFormatter(period)(data.chart),
|
||||
};
|
||||
metric.setData(_data);
|
||||
resolve(_data);
|
||||
} else if (metric.metricType === "funnel") {
|
||||
const _data = { ...data };
|
||||
_data.funnel = new Funnel().fromJSON(data);
|
||||
metric.setData(_data);
|
||||
resolve(_data);
|
||||
} else {
|
||||
const _data = {
|
||||
...data,
|
||||
};
|
||||
|
||||
// TODO refactor to widget class
|
||||
if (metric.metricOf === FilterKey.SESSIONS) {
|
||||
_data["sessions"] = data.sessions.map((s: any) =>
|
||||
new Session().fromJson(s)
|
||||
);
|
||||
} else if (metric.metricOf === FilterKey.ERRORS) {
|
||||
_data["errors"] = data.errors.map((s: any) =>
|
||||
new Error().fromJSON(s)
|
||||
);
|
||||
} else {
|
||||
if (data.hasOwnProperty("chart")) {
|
||||
_data["chart"] = getChartFormatter(period)(
|
||||
data.chart
|
||||
);
|
||||
_data["namesMap"] = data.chart
|
||||
.map((i: any) => Object.keys(i))
|
||||
.flat()
|
||||
.filter(
|
||||
(i: any) => i !== "time" && i !== "timestamp"
|
||||
)
|
||||
.reduce((unique: any, item: any) => {
|
||||
if (!unique.includes(item)) {
|
||||
unique.push(item);
|
||||
}
|
||||
return unique;
|
||||
}, []);
|
||||
} else {
|
||||
_data["chart"] = getChartFormatter(period)(
|
||||
Array.isArray(data) ? data : []
|
||||
);
|
||||
_data["namesMap"] = Array.isArray(data)
|
||||
? data
|
||||
.map((i) => Object.keys(i))
|
||||
.flat()
|
||||
.filter(
|
||||
(i) =>
|
||||
i !== "time" &&
|
||||
i !== "timestamp"
|
||||
)
|
||||
.reduce((unique: any, item: any) => {
|
||||
if (!unique.includes(item)) {
|
||||
unique.push(item);
|
||||
}
|
||||
return unique;
|
||||
}, [])
|
||||
: [];
|
||||
}
|
||||
}
|
||||
metric.setData(_data);
|
||||
resolve(_data);
|
||||
}
|
||||
metric.setData(data, period);
|
||||
resolve(metric.data);
|
||||
})
|
||||
.catch((err: any) => {
|
||||
reject(err);
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
import { makeAutoObservable, runInAction } from "mobx"
|
||||
import FilterSeries from "./filterSeries";
|
||||
import { makeAutoObservable, runInAction } from 'mobx';
|
||||
import FilterSeries from './filterSeries';
|
||||
import { DateTime } from 'luxon';
|
||||
import Session from "App/mstore/types/session";
|
||||
import Session from 'App/mstore/types/session';
|
||||
import Funnelissue from 'App/mstore/types/funnelIssue';
|
||||
import { issueOptions, issueCategories } from 'App/constants/filterOptions';
|
||||
import { FilterKey } from 'Types/filter/filterType';
|
||||
import Period, { LAST_24_HOURS } from 'Types/app/period';
|
||||
import { metricService } from "App/services";
|
||||
import { INSIGHTS, TABLE, WEB_VITALS } from "App/constants/card";
|
||||
import { metricService } from 'App/services';
|
||||
import { INSIGHTS, TABLE, WEB_VITALS } from 'App/constants/card';
|
||||
import Error from '../types/error';
|
||||
import { getChartFormatter } from 'Types/dashboard/helper';
|
||||
|
||||
export default class Widget {
|
||||
public static get ID_KEY():string { return "metricId" }
|
||||
|
|
@ -33,12 +35,13 @@ export default class Widget {
|
|||
thumbnail?: string
|
||||
params: any = { density: 70 }
|
||||
|
||||
period: Record<string, any> = Period({ rangeName: LAST_24_HOURS }) // temp value in detail view
|
||||
hasChanged: boolean = false
|
||||
period: Record<string, any> = Period({ rangeName: LAST_24_HOURS }); // temp value in detail view
|
||||
hasChanged: boolean = false;
|
||||
|
||||
position: number = 0
|
||||
data: any = {
|
||||
sessions: [],
|
||||
issues: [],
|
||||
total: 0,
|
||||
chart: [],
|
||||
namesMap: {},
|
||||
|
|
@ -50,54 +53,59 @@ export default class Widget {
|
|||
dashboardId: any = undefined
|
||||
predefinedKey: string = ''
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this)
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
|
||||
const filterSeries = new FilterSeries()
|
||||
this.series.push(filterSeries)
|
||||
}
|
||||
const filterSeries = new FilterSeries();
|
||||
this.series.push(filterSeries);
|
||||
}
|
||||
|
||||
updateKey(key: string, value: any) {
|
||||
this[key] = value
|
||||
}
|
||||
updateKey(key: string, value: any) {
|
||||
this[key] = value;
|
||||
}
|
||||
|
||||
removeSeries(index: number) {
|
||||
this.series.splice(index, 1)
|
||||
}
|
||||
removeSeries(index: number) {
|
||||
this.series.splice(index, 1);
|
||||
}
|
||||
|
||||
addSeries() {
|
||||
const series = new FilterSeries()
|
||||
series.name = "Series " + (this.series.length + 1)
|
||||
this.series.push(series)
|
||||
}
|
||||
addSeries() {
|
||||
const series = new FilterSeries();
|
||||
series.name = 'Series ' + (this.series.length + 1);
|
||||
this.series.push(series);
|
||||
}
|
||||
|
||||
fromJson(json: any, period?: any) {
|
||||
json.config = json.config || {}
|
||||
runInAction(() => {
|
||||
this.metricId = json.metricId
|
||||
this.widgetId = json.widgetId
|
||||
this.metricValue = this.metricValueFromArray(json.metricValue, json.metricType)
|
||||
this.metricOf = json.metricOf
|
||||
this.metricType = json.metricType
|
||||
this.metricFormat = json.metricFormat
|
||||
this.viewType = json.viewType
|
||||
this.name = json.name
|
||||
this.series = json.series ? json.series.map((series: any) => new FilterSeries().fromJson(series)) : []
|
||||
this.dashboards = json.dashboards || []
|
||||
this.owner = json.ownerEmail
|
||||
this.lastModified = json.editedAt || json.createdAt ? DateTime.fromMillis(json.editedAt || json.createdAt) : null
|
||||
this.config = json.config
|
||||
this.position = json.config.position
|
||||
this.predefinedKey = json.predefinedKey
|
||||
this.category = json.category
|
||||
this.thumbnail = json.thumbnail
|
||||
fromJson(json: any, period?: any) {
|
||||
json.config = json.config || {};
|
||||
runInAction(() => {
|
||||
this.metricId = json.metricId;
|
||||
this.widgetId = json.widgetId;
|
||||
this.metricValue = this.metricValueFromArray(json.metricValue, json.metricType);
|
||||
this.metricOf = json.metricOf;
|
||||
this.metricType = json.metricType;
|
||||
this.metricFormat = json.metricFormat;
|
||||
this.viewType = json.viewType;
|
||||
this.name = json.name;
|
||||
this.series = json.series
|
||||
? json.series.map((series: any) => new FilterSeries().fromJson(series))
|
||||
: [];
|
||||
this.dashboards = json.dashboards || [];
|
||||
this.owner = json.ownerEmail;
|
||||
this.lastModified =
|
||||
json.editedAt || json.createdAt
|
||||
? DateTime.fromMillis(json.editedAt || json.createdAt)
|
||||
: null;
|
||||
this.config = json.config;
|
||||
this.position = json.config.position;
|
||||
this.predefinedKey = json.predefinedKey;
|
||||
this.category = json.category;
|
||||
this.thumbnail = json.thumbnail;
|
||||
|
||||
if (period) {
|
||||
this.period = period
|
||||
}
|
||||
})
|
||||
return this
|
||||
}
|
||||
if (period) {
|
||||
this.period = period;
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
toWidget(): any {
|
||||
return {
|
||||
|
|
@ -128,61 +136,124 @@ export default class Widget {
|
|||
}
|
||||
}
|
||||
|
||||
validate() {
|
||||
this.isValid = this.name.length > 0
|
||||
validate() {
|
||||
this.isValid = this.name.length > 0;
|
||||
}
|
||||
|
||||
update(data: any) {
|
||||
runInAction(() => {
|
||||
Object.assign(this, data);
|
||||
});
|
||||
}
|
||||
|
||||
exists() {
|
||||
return this.metricId !== undefined;
|
||||
}
|
||||
|
||||
setData(data: any, period: any) {
|
||||
const _data: any = {};
|
||||
|
||||
if (this.metricOf === FilterKey.ERRORS) {
|
||||
_data['errors'] = data.errors.map((s: any) => new Error().fromJSON(s));
|
||||
} else if (this.metricType === INSIGHTS) {
|
||||
// TODO read fromt the response
|
||||
_data['issues'] = [1, 2, 3].map((i: any) => ({
|
||||
icon: 'dizzy',
|
||||
ratio: 'Click Rage',
|
||||
increase: 10,
|
||||
iconColor: 'red',
|
||||
}));
|
||||
} else {
|
||||
if (data.hasOwnProperty('chart')) {
|
||||
_data['chart'] = getChartFormatter(period)(data.chart);
|
||||
_data['namesMap'] = data.chart
|
||||
.map((i: any) => Object.keys(i))
|
||||
.flat()
|
||||
.filter((i: any) => i !== 'time' && i !== 'timestamp')
|
||||
.reduce((unique: any, item: any) => {
|
||||
if (!unique.includes(item)) {
|
||||
unique.push(item);
|
||||
}
|
||||
return unique;
|
||||
}, []);
|
||||
} else {
|
||||
_data['chart'] = getChartFormatter(period)(Array.isArray(data) ? data : []);
|
||||
_data['namesMap'] = Array.isArray(data)
|
||||
? data
|
||||
.map((i) => Object.keys(i))
|
||||
.flat()
|
||||
.filter((i) => i !== 'time' && i !== 'timestamp')
|
||||
.reduce((unique: any, item: any) => {
|
||||
if (!unique.includes(item)) {
|
||||
unique.push(item);
|
||||
}
|
||||
return unique;
|
||||
}, [])
|
||||
: [];
|
||||
}
|
||||
}
|
||||
|
||||
update(data: any) {
|
||||
runInAction(() => {
|
||||
Object.assign(this, data)
|
||||
this.data = _data;
|
||||
}
|
||||
|
||||
fetchSessions(metricId: any, filter: any): Promise<any> {
|
||||
return new Promise((resolve) => {
|
||||
metricService.fetchSessions(metricId, filter).then((response: any[]) => {
|
||||
resolve(
|
||||
response.map((cat: { sessions: any[] }) => {
|
||||
return {
|
||||
...cat,
|
||||
sessions: cat.sessions.map((s: any) => new Session().fromJson(s)),
|
||||
};
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fetchIssues(filter: any): Promise<any> {
|
||||
return new Promise((resolve) => {
|
||||
metricService.fetchIssues(filter).then((response: any) => {
|
||||
const significantIssues = response.issues.significant
|
||||
? response.issues.significant.map((issue: any) => new Funnelissue().fromJSON(issue))
|
||||
: [];
|
||||
const insignificantIssues = response.issues.insignificant
|
||||
? response.issues.insignificant.map((issue: any) => new Funnelissue().fromJSON(issue))
|
||||
: [];
|
||||
resolve({
|
||||
issues: significantIssues.length > 0 ? significantIssues : insignificantIssues,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fetchIssue(funnelId: any, issueId: any, params: any): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
metricService
|
||||
.fetchIssue(funnelId, issueId, params)
|
||||
.then((response: any) => {
|
||||
resolve({
|
||||
issue: new Funnelissue().fromJSON(response.issue),
|
||||
sessions: response.sessions.sessions.map((s: any) => new Session().fromJson(s)),
|
||||
});
|
||||
})
|
||||
}
|
||||
.catch((error: any) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
exists() {
|
||||
return this.metricId !== undefined
|
||||
private metricValueFromArray(metricValue: any, metricType: string) {
|
||||
if (!Array.isArray(metricValue)) return metricValue;
|
||||
if (metricType === TABLE) {
|
||||
return issueOptions.filter((i: any) => metricValue.includes(i.value));
|
||||
} else if (metricType === INSIGHTS) {
|
||||
return issueCategories.filter((i: any) => metricValue.includes(i.value));
|
||||
}
|
||||
}
|
||||
|
||||
setData(data: any) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
fetchSessions(metricId: any, filter: any): Promise<any> {
|
||||
return new Promise((resolve) => {
|
||||
metricService.fetchSessions(metricId, filter).then((response: any[]) => {
|
||||
resolve(response.map((cat: { sessions: any[]; }) => {
|
||||
return {
|
||||
...cat,
|
||||
sessions: cat.sessions.map((s: any) => new Session().fromJson(s))
|
||||
}
|
||||
}))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fetchIssue(funnelId: any, issueId: any, params: any): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
metricService.fetchIssue(funnelId, issueId, params).then((response: any) => {
|
||||
resolve({
|
||||
issue: new Funnelissue().fromJSON(response.issue),
|
||||
sessions: response.sessions.sessions.map((s: any) => new Session().fromJson(s)),
|
||||
})
|
||||
}).catch((error: any) => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
private metricValueFromArray(metricValue: any, metricType: string) {
|
||||
if (!Array.isArray(metricValue)) return metricValue;
|
||||
if (metricType === TABLE) {
|
||||
return issueOptions.filter((i: any) => metricValue.includes(i.value))
|
||||
} else if (metricType === INSIGHTS) {
|
||||
return issueCategories.filter((i: any) => metricValue.includes(i.value))
|
||||
}
|
||||
}
|
||||
|
||||
private metricValueToArray(metricValue: any) {
|
||||
if (!Array.isArray(metricValue)) return metricValue;
|
||||
return metricValue.map((i: any) => i.value)
|
||||
}
|
||||
private metricValueToArray(metricValue: any) {
|
||||
if (!Array.isArray(metricValue)) return metricValue;
|
||||
return metricValue.map((i: any) => i.value);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue