fix(ui): clean up api calls, remove dead features from dashboards

This commit is contained in:
sylenien 2022-08-23 12:15:37 +02:00
parent 21fb26b60d
commit e02f873970
9 changed files with 235 additions and 253 deletions

View file

@ -36,7 +36,6 @@ function DashbaordListModal(props: Props) {
leading = {(
<div className="ml-2 flex items-center">
{item.isPublic && <div className="p-1"><Icon name="user-friends" color="gray-light" size="16" /></div>}
{item.isPinned && <div className="p-1"><Icon name="pin-fill" size="16" /></div>}
</div>
)}
/>

View file

@ -1,6 +1,6 @@
import React from 'react';
import { observer } from 'mobx-react-lite';
import { Button } from 'UI';
import { Button, Loader } from 'UI';
import WidgetWrapper from 'App/components/Dashboard/components/WidgetWrapper';
import { useStore } from 'App/mstore';
import { useModal } from 'App/components/Modal';
@ -8,16 +8,25 @@ import { dashboardMetricCreate, withSiteId } from 'App/routes';
import { withRouter, RouteComponentProps } from 'react-router-dom';
interface IProps extends RouteComponentProps {
metrics: any[];
siteId: string;
title: string;
description: string;
}
function AddMetric({ metrics, history, siteId, title, description }: IProps) {
function AddMetric({ history, siteId, title, description }: IProps) {
const [metrics, setMetrics] = React.useState<Record<string, any>[]>([]);
const { dashboardStore } = useStore();
const { hideModal } = useModal();
React.useEffect(() => {
dashboardStore?.fetchTemplates(true).then((cats: any[]) => {
const customMetrics = cats.find((category) => category.name === 'custom')?.widgets || [];
setMetrics(customMetrics);
});
}, []);
const dashboard = dashboardStore.selectedDashboard;
const selectedWidgetIds = dashboardStore.selectedWidgets.map((widget: any) => widget.metricId);
const queryParams = new URLSearchParams(location.search);
@ -26,7 +35,7 @@ function AddMetric({ metrics, history, siteId, title, description }: IProps) {
if (selectedWidgetIds.length === 0) return;
dashboardStore
.save(dashboard)
.then(async (syncedDashboard) => {
.then(async (syncedDashboard: Record<string, any>) => {
if (dashboard.exists()) {
await dashboardStore.fetch(dashboard.dashboardId);
}
@ -44,7 +53,10 @@ function AddMetric({ metrics, history, siteId, title, description }: IProps) {
return (
<div style={{ maxWidth: '85vw', width: 1200 }}>
<div className="border-l shadow h-screen" style={{ backgroundColor: '#FAFAFA', zIndex: 999, width: '100%' }}>
<div
className="border-l shadow h-screen"
style={{ backgroundColor: '#FAFAFA', zIndex: 999, width: '100%' }}
>
<div className="mb-6 pt-8 px-8 flex items-start justify-between">
<div className="flex flex-col">
<h1 className="text-2xl">{title}</h1>
@ -54,11 +66,18 @@ function AddMetric({ metrics, history, siteId, title, description }: IProps) {
<Button variant="text-primary" className="font-medium ml-2" onClick={onCreateNew}>
+ Create New
</Button>
</div>
<div className="grid h-full grid-cols-4 gap-4 px-8 items-start py-1" style={{ maxHeight: 'calc(100vh - 160px)', overflowY: 'auto', gridAutoRows: 'max-content' }}>
{metrics ? metrics.map((metric: any) => (
<Loader loading={dashboardStore.loadingTemplates}>
<div
className="grid h-full grid-cols-4 gap-4 px-8 items-start py-1"
style={{
maxHeight: 'calc(100vh - 160px)',
overflowY: 'auto',
gridAutoRows: 'max-content',
}}
>
{metrics ? (
metrics.map((metric: any) => (
<WidgetWrapper
key={metric.metricId}
widget={metric}
@ -67,10 +86,12 @@ function AddMetric({ metrics, history, siteId, title, description }: IProps) {
isWidget={metric.metricType === 'predefined'}
onClick={() => dashboardStore.toggleWidgetSelection(metric)}
/>
)) : (
))
) : (
<div>No custom metrics created.</div>
)}
</div>
</Loader>
<div className="py-4 border-t px-8 bg-white w-full flex items-center justify-between">
<div>

View file

@ -49,13 +49,8 @@ function AddMetricButton({ iconName, title, description, onClick, isPremade, isP
function AddMetricContainer({ siteId, isPopup }: any) {
const { showModal } = useModal();
const [categories, setCategories] = React.useState<Record<string, any>[]>([]);
const { dashboardStore } = useStore();
React.useEffect(() => {
dashboardStore?.fetchTemplates(true).then((cats) => setCategories(cats));
}, []);
const onAddCustomMetrics = () => {
dashboardStore.initDashboard(dashboardStore.selectedDashboard);
showModal(
@ -63,7 +58,6 @@ function AddMetricContainer({ siteId, isPopup }: any) {
siteId={siteId}
title="Custom Metrics"
description="Metrics that are manually created by you or your team."
metrics={categories.find((category) => category.name === 'custom')?.widgets}
/>,
{ right: true }
);
@ -76,7 +70,6 @@ function AddMetricContainer({ siteId, isPopup }: any) {
siteId={siteId}
title="Ready-Made Metrics"
description="Curated metrics predfined by OpenReplay."
categories={categories.filter((category) => category.name !== 'custom')}
/>,
{ right: true }
);

View file

@ -1,6 +1,6 @@
import React from 'react';
import { observer } from 'mobx-react-lite';
import { Button } from 'UI';
import { Button, Loader } from 'UI';
import WidgetWrapper from 'App/components/Dashboard/components/WidgetWrapper';
import { useStore } from 'App/mstore';
import { useModal } from 'App/components/Modal';
@ -9,13 +9,13 @@ import { withRouter, RouteComponentProps } from 'react-router-dom';
import { WidgetCategoryItem } from 'App/components/Dashboard/components/DashboardMetricSelection/DashboardMetricSelection';
interface IProps extends RouteComponentProps {
categories: Record<string, any>[];
siteId: string;
title: string;
description: string;
}
function AddPredefinedMetric({ categories, history, siteId, title, description }: IProps) {
function AddPredefinedMetric({ history, siteId, title, description }: IProps) {
const [categories, setCategories] = React.useState([]);
const { dashboardStore } = useStore();
const { hideModal } = useModal();
const [activeCategory, setActiveCategory] = React.useState<Record<string, any>>();
@ -28,9 +28,11 @@ function AddPredefinedMetric({ categories, history, siteId, title, description }
const totalMetricCount = categories.reduce((acc, category) => acc + category.widgets.length, 0);
React.useEffect(() => {
dashboardStore?.fetchTemplates(true).then((categories) => {
const defaultCategory = categories.filter((category: any) => category.name !== 'custom')[0];
dashboardStore?.fetchTemplates(true).then((categories: any[]) => {
const predefinedCategories = categories.filter((category) => category.name !== 'custom');
const defaultCategory = predefinedCategories[0];
setActiveCategory(defaultCategory);
setCategories(predefinedCategories);
});
}, []);
@ -66,7 +68,10 @@ function AddPredefinedMetric({ categories, history, siteId, title, description }
return (
<div style={{ maxWidth: '85vw', width: 1200 }}>
<div className="border-l shadow h-screen" style={{ backgroundColor: '#FAFAFA', zIndex: 999, width: '100%' }}>
<div
className="border-l shadow h-screen"
style={{ backgroundColor: '#FAFAFA', zIndex: 999, width: '100%' }}
>
<div className="mb-6 pt-8 px-8 flex items-start justify-between">
<div className="flex flex-col">
<h1 className="text-2xl">{title}</h1>
@ -82,7 +87,11 @@ function AddPredefinedMetric({ categories, history, siteId, title, description }
<div style={{ flex: 3 }}>
<div
className="grid grid-cols-1 gap-4 py-1 pr-2"
style={{ maxHeight: 'calc(100vh - 160px)', overflowY: 'auto', gridAutoRows: 'max-content' }}
style={{
maxHeight: 'calc(100vh - 160px)',
overflowY: 'auto',
gridAutoRows: 'max-content',
}}
>
{activeCategory &&
categories.map((category) => (
@ -98,10 +107,15 @@ function AddPredefinedMetric({ categories, history, siteId, title, description }
))}
</div>
</div>
<Loader loading={dashboardStore.loadingTemplates}>
<div
className="grid h-full grid-cols-4 gap-4 p-1 items-start"
style={{ maxHeight: 'calc(100vh - 160px)', overflowY: 'auto', flex: 9, gridAutoRows: 'max-content' }}
style={{
maxHeight: 'calc(100vh - 160px)',
overflowY: 'auto',
flex: 9,
gridAutoRows: 'max-content',
}}
>
{activeCategory &&
activeCategory.widgets.map((metric: any) => (
@ -117,6 +131,7 @@ function AddPredefinedMetric({ categories, history, siteId, title, description }
</React.Fragment>
))}
</div>
</Loader>
</div>
<div className="py-4 border-t px-8 bg-white w-full flex items-center justify-between">

View file

@ -54,7 +54,6 @@ export default class SiteDropdown extends React.PureComponent {
this.props.clearSearchLive();
mstore.initClient();
mstore.dashboardStore.selectDefaultDashboard();
}
render() {

View file

@ -3,7 +3,15 @@ import cn from 'classnames';
import styles from './loader.module.css';
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
const Loader = React.memo(
interface Props {
className?: string
loading?: boolean
children?: React.ReactNode
size?: number
style?: Record<string, any>
}
const Loader = React.memo<Props>(
({
className = '',
loading = true,
@ -12,7 +20,9 @@ const Loader = React.memo(
style = { minHeight: '150px' },
}) =>
!loading ? (
children
<>
{children}
</>
) : (
<div className={cn(styles.wrapper, className)} style={style}>
{/* <div className={ styles.loader } data-size={ size } /> */}

View file

@ -1,8 +1,6 @@
import {
makeAutoObservable,
runInAction,
observable,
action,
} from "mobx";
import Dashboard, { IDashboard } from "./types/dashboard";
import Widget, { IWidget } from "./types/widget";
@ -39,6 +37,7 @@ export interface IDashboardStore {
metricsSearch: string;
isLoading: boolean;
loadingTemplates: boolean;
isSaving: boolean;
isDeleting: boolean;
fetchingDashboard: boolean;
@ -74,7 +73,6 @@ export interface IDashboardStore {
selectDashboardById(dashboardId: string): void;
getDashboardById(dashboardId: string): boolean;
setSiteId(siteId: any): void;
selectDefaultDashboard(): Promise<IDashboard>;
saveMetric(metric: IWidget, dashboardId?: string): Promise<any>;
fetchTemplates(hardRefresh: boolean): Promise<any>;
@ -82,7 +80,6 @@ export interface IDashboardStore {
addWidgetToDashboard(dashboard: IDashboard, metricIds: any): Promise<any>;
setDrillDownPeriod(period: any): void;
updatePinned(dashboardId: string): Promise<any>;
fetchMetricChartData(
metric: IWidget,
data: any,
@ -392,22 +389,6 @@ export default class DashboardStore implements IDashboardStore {
this.siteId = siteId;
};
selectDefaultDashboard = (): Promise<Dashboard> => {
return new Promise((resolve, reject) => {
if (this.dashboards.length > 0) {
const pinnedDashboard = this.dashboards.find((d) => d.isPinned);
if (pinnedDashboard) {
this.selectedDashboard = pinnedDashboard;
} else {
this.selectedDashboard = this.dashboards[0];
}
resolve(this.selectedDashboard);
}
reject(new Error("No dashboards found"));
});
};
fetchTemplates(hardRefresh): Promise<any> {
this.loadingTemplates = true
return new Promise((resolve, reject) => {
@ -473,28 +454,6 @@ export default class DashboardStore implements IDashboardStore {
});
}
updatePinned(dashboardId: string): Promise<any> {
// this.isSaving = true
return dashboardService
.updatePinned(dashboardId)
.then(() => {
toast.success("Dashboard pinned successfully");
this.dashboards.forEach((d) => {
if (d.dashboardId === dashboardId) {
d.isPinned = true;
} else {
d.isPinned = false;
}
});
})
.catch(() => {
toast.error("Dashboard could not be pinned");
})
.finally(() => {
// this.isSaving = false
});
}
setPeriod(period: any) {
this.period = Period({
start: period.start,

View file

@ -12,7 +12,6 @@ export interface IDashboard {
widgets: IWidget[]
metrics: any[]
isValid: boolean
isPinned: boolean
currentWidget: IWidget
config: any
createdAt: Date
@ -43,7 +42,6 @@ export default class Dashboard implements IDashboard {
widgets: IWidget[] = []
metrics: any[] = []
isValid: boolean = false
isPinned: boolean = false
currentWidget: IWidget = new Widget()
config: any = {}
createdAt: Date = new Date()
@ -78,7 +76,6 @@ export default class Dashboard implements IDashboard {
this.name = json.name
this.description = json.description
this.isPublic = json.isPublic
this.isPinned = json.isPinned
this.createdAt = DateTime.fromMillis(new Date(json.createdAt).getTime())
this.widgets = json.widgets ? json.widgets.map((w: Widget) => new Widget().fromJson(w)).sort((a: Widget, b: Widget) => a.position - b.position) : []
})

View file

@ -18,7 +18,6 @@ export interface IDashboardService {
saveWidget(dashboardId: string, widget: IWidget): Promise<any>
deleteWidget(dashboardId: string, widgetId: string): Promise<any>
updatePinned(dashboardId: string): Promise<any>
}
@ -151,14 +150,4 @@ export default class DashboardService implements IDashboardService {
.then(response => response.json())
.then(response => response.data || {});
}
/**
* Update the pinned status of a dashboard.
* @param dashboardId
* @returns
*/
updatePinned(dashboardId: string): Promise<any> {
return this.client.get(`/dashboards/${dashboardId}/pin`, {})
.then(response => response.json())
}
}