change(ui): small ui fixes, new border for assist etc

This commit is contained in:
sylenien 2022-09-21 15:10:13 +02:00 committed by Delirium
parent e8c9e95dca
commit 9e25f8ef69
13 changed files with 91 additions and 84 deletions

View file

@ -9,7 +9,7 @@ import DashboardListItem from './DashboardListItem';
function DashboardList() {
const { dashboardStore } = useStore();
const [shownDashboards, setDashboards] = React.useState([]);
const dashboards = dashboardStore.dashboards;
const dashboards = dashboardStore.sortedDashboards;
const dashboardsSearch = dashboardStore.dashboardsSearch;
React.useEffect(() => {

View file

@ -74,11 +74,13 @@ function DashboardRouter(props: Props) {
<Alerts siteId={siteId} />
</Route>
<Route exact strict path={withSiteId(alertCreate(), siteId)}>
<CreateAlert siteId={siteId} />
<Route exact path={withSiteId(alertCreate(), siteId)}>
{/* @ts-ignore */}
<CreateAlert siteId={siteId as string} />
</Route>
<Route exact strict path={withSiteId(alertEdit(), siteId)}>
<Route exact path={withSiteId(alertEdit(), siteId)}>
{/* @ts-ignore */}
<CreateAlert siteId={siteId} {...props} />
</Route>
</Switch>

View file

@ -1,18 +1,18 @@
import { useObserver } from 'mobx-react-lite';
import { observer } from 'mobx-react-lite';
import React, { useEffect } from 'react';
import { NoContent, Pagination, Icon } from 'UI';
import { useStore } from 'App/mstore';
import { filterList } from 'App/utils';
import MetricListItem from '../MetricListItem';
import { sliceListPerPage } from 'App/utils';
import { IWidget } from 'App/mstore/types/widget';
import Widget from 'App/mstore/types/widget';
function MetricsList({ siteId }: { siteId: string }) {
const { metricStore } = useStore();
const metrics = useObserver(() => metricStore.metrics);
const metricsSearch = useObserver(() => metricStore.metricsSearch);
const metrics = metricStore.sortedWidgets;
const metricsSearch = metricStore.metricsSearch;
const filterByDashboard = (item: IWidget, searchRE: RegExp) => {
const filterByDashboard = (item: Widget, searchRE: RegExp) => {
const dashboardsStr = item.dashboards.map((d: any) => d.name).join(' ');
return searchRE.test(dashboardsStr);
};
@ -26,7 +26,7 @@ function MetricsList({ siteId }: { siteId: string }) {
metricStore.updateKey('sessionsPage', 1);
}, []);
return useObserver(() => (
return (
<NoContent
show={lenth === 0}
title={
@ -68,7 +68,7 @@ function MetricsList({ siteId }: { siteId: string }) {
/>
</div>
</NoContent>
));
);
}
export default MetricsList;
export default observer(MetricsList);

View file

@ -8,6 +8,7 @@ import {
assist,
client,
dashboard,
alerts,
withSiteId,
CLIENT_DEFAULT_TAB,
} from 'App/routes';
@ -28,6 +29,7 @@ import { useStore } from 'App/mstore';
import { useObserver } from 'mobx-react-lite';
const DASHBOARD_PATH = dashboard();
const ALERTS_PATH = alerts();
const METRICS_PATH = metrics();
const SESSIONS_PATH = sessions();
const ASSIST_PATH = assist();
@ -101,7 +103,9 @@ const Header = (props) => {
className={ styles.nav }
activeClassName={ styles.active }
isActive={ (_, location) => {
return location.pathname.includes(DASHBOARD_PATH) || location.pathname.includes(METRICS_PATH);
return location.pathname.includes(DASHBOARD_PATH)
|| location.pathname.includes(METRICS_PATH)
|| location.pathname.includes(ALERTS_PATH)
}}
>
<span>{ 'Dashboards' }</span>

View file

@ -1,9 +1,8 @@
import React from 'react';
import cn from "classnames";
import { connect } from 'react-redux';
import { } from 'Player';
import {
NONE, OVERVIEW,
NONE,
} from 'Duck/components/player';
import Player from './Player';
import SubHeader from './Subheader';

View file

@ -1,6 +1,7 @@
import {
makeAutoObservable,
runInAction,
computed,
} from "mobx";
import Dashboard from "./types/dashboard";
import Widget from "./types/widget";
@ -64,6 +65,11 @@ export default class DashboardStore {
this.drillDownFilter.updateKey("endTimestamp", timeStamps.endTimestamp);
}
@computed
get sortedDashboards() {
return [...this.dashboards].sort((a, b) => b.createdAt - a.createdAt)
}
toggleAllSelectedWidgets(isSelected: boolean) {
if (isSelected) {
const allWidgets = this.widgetCategories.reduce((acc, cat) => {
@ -89,7 +95,7 @@ export default class DashboardStore {
}
removeSelectedWidgetByCategory = (category: any) => {
const categoryWidgetIds = category.widgets.map((w) => w.metricId);
const categoryWidgetIds = category.widgets.map((w: Widget) => w.metricId);
this.selectedWidgets = this.selectedWidgets.filter(
(widget: any) => !categoryWidgetIds.includes(widget.metricId)
);
@ -119,7 +125,8 @@ export default class DashboardStore {
this.selectedWidgets = [];
}
updateKey(key: any, value: any) {
updateKey(key: string, value: any) {
// @ts-ignore
this[key] = value;
}
@ -138,7 +145,7 @@ export default class DashboardStore {
.getDashboards()
.then((list: any) => {
runInAction(() => {
this.dashboards = list.map((d) =>
this.dashboards = list.map((d: Record<string, any>) =>
new Dashboard().fromJson(d)
);
});
@ -168,7 +175,7 @@ export default class DashboardStore {
this.fetchingDashboard = value;
}
save(dashboard: IDashboard): Promise<any> {
save(dashboard: Dashboard): Promise<any> {
this.isSaving = true;
const isCreating = !dashboard.dashboardId;
@ -205,7 +212,7 @@ export default class DashboardStore {
});
}
saveMetric(metric: IWidget, dashboardId: string): Promise<any> {
saveMetric(metric: Widget, dashboardId: string): Promise<any> {
const isCreating = !metric.widgetId;
return dashboardService
.saveMetric(metric, dashboardId)
@ -252,7 +259,7 @@ export default class DashboardStore {
fromJson(json: any) {
runInAction(() => {
this.dashboards = json.dashboards.map((d) =>
this.dashboards = json.dashboards.map((d: Record<string, any>) =>
new Dashboard().fromJson(d)
);
});
@ -367,7 +374,7 @@ export default class DashboardStore {
});
}
addWidgetToDashboard(dashboard: IDashboard, metricIds: any): Promise<any> {
addWidgetToDashboard(dashboard: Dashboard, metricIds: any): Promise<any> {
this.isSaving = true;
return dashboardService
.addWidget(dashboard, metricIds)
@ -399,7 +406,7 @@ export default class DashboardStore {
}
fetchMetricChartData(
metric: IWidget,
metric: Widget,
data: any,
isWidget: boolean = false,
period: Record<string, any>

View file

@ -1,5 +1,5 @@
import { makeAutoObservable, runInAction, observable, action, reaction, computed } from "mobx"
import Widget, { IWidget } from "./types/widget";
import { makeAutoObservable, computed } from "mobx"
import Widget from "./types/widget";
import { metricService, errorService } from "App/services";
import { toast } from 'react-toastify';
import Error from "./types/error";
@ -8,8 +8,8 @@ export default class MetricStore {
isLoading: boolean = false
isSaving: boolean = false
metrics: IWidget[] = []
instance: IWidget = new Widget()
metrics: Widget[] = []
instance = new Widget()
page: number = 1
pageSize: number = 10
@ -20,41 +20,21 @@ export default class MetricStore {
sessionsPageSize: number = 10
constructor() {
makeAutoObservable(this, {
isLoading: observable,
metrics: observable,
instance: observable,
page: observable,
pageSize: observable,
metricsSearch: observable,
sort: observable,
makeAutoObservable(this)
}
init: action,
updateKey: action,
merge: action,
reset: action,
addToList: action,
updateInList: action,
findById: action,
removeById: action,
save: action,
fetchList: action,
fetch: action,
delete: action,
fetchError: action,
paginatedList: computed,
})
@computed
get sortedWidgets() {
return [...this.metrics].sort((a, b) => b.lastModified - a.lastModified)
}
// State Actions
init(metric?: IWidget|null) {
init(metric?: Widget | null) {
this.instance.update(metric || new Widget())
}
updateKey(key: string, value: any) {
// @ts-ignore
this[key] = value
}
@ -70,33 +50,36 @@ export default class MetricStore {
}
}
addToList(metric: IWidget) {
addToList(metric: Widget) {
this.metrics.push(metric)
}
updateInList(metric: IWidget) {
const index = this.metrics.findIndex((m: IWidget) => m[Widget.ID_KEY] === metric[Widget.ID_KEY])
updateInList(metric: Widget) {
// @ts-ignore
const index = this.metrics.findIndex((m: Widget) => m[Widget.ID_KEY] === metric[Widget.ID_KEY])
if (index >= 0) {
this.metrics[index] = metric
}
}
findById(id: string) {
// @ts-ignore
return this.metrics.find(m => m[Widget.ID_KEY] === id)
}
removeById(id: string): void {
// @ts-ignore
this.metrics = this.metrics.filter(m => m[Widget.ID_KEY] !== id)
}
get paginatedList(): IWidget[] {
get paginatedList(): Widget[] {
const start = (this.page - 1) * this.pageSize
const end = start + this.pageSize
return this.metrics.slice(start, end)
}
// API Communication
save(metric: IWidget, dashboardId?: string): Promise<any> {
save(metric: Widget, dashboardId?: string): Promise<any> {
const wasCreating = !metric.exists()
this.isSaving = true
return new Promise((resolve, reject) => {
@ -143,10 +126,12 @@ export default class MetricStore {
})
}
delete(metric: IWidget) {
delete(metric: Widget) {
this.isSaving = true
// @ts-ignore
return metricService.deleteMetric(metric[Widget.ID_KEY])
.then(() => {
// @ts-ignore
this.removeById(metric[Widget.ID_KEY])
toast.success('Metric deleted successfully')
}).finally(() => {

View file

@ -15,7 +15,7 @@ export default class Dashboard {
isValid: boolean = false
currentWidget: Widget = new Widget()
config: any = {}
createdAt: Date = new Date()
createdAt: number = new Date().getTime()
constructor() {
makeAutoObservable(this)

View file

@ -24,7 +24,7 @@ export default class Widget {
sessions: [] = []
isPublic: boolean = true
owner: string = ""
lastModified: Date = new Date()
lastModified: number = new Date().getTime()
dashboards: any[] = []
dashboardIds: any[] = []
config: any = {}

View file

@ -53,10 +53,13 @@ function isIframe(el: Element): el is HTMLIFrameElement {
}
export default abstract class BaseScreen {
public readonly overlay: HTMLDivElement;
private readonly iframe: HTMLIFrameElement;
protected readonly screen: HTMLDivElement;
public readonly overlay: HTMLDivElement;
private readonly iframe: HTMLIFrameElement;
protected readonly screen: HTMLDivElement;
protected readonly controlButton: HTMLDivElement;
protected parentElement: HTMLElement | null = null;
constructor() {
const iframe = document.createElement('iframe');
iframe.className = styles.iframe;
@ -101,6 +104,11 @@ export default abstract class BaseScreen {
})
}
toggleRemoteControlStatus(isEnabled: boolean ) {
const styles = isEnabled ? { border: '2px dashed blue' } : { border: 'unset'}
return Object.assign(this.screen.style, styles)
}
get window(): WindowProxy | null {
return this.iframe.contentWindow;
}

View file

@ -295,11 +295,13 @@ export default class AssistManager {
this.md.overlay.addEventListener("mousemove", this.onMouseMove)
this.md.overlay.addEventListener("click", this.onMouseClick)
this.md.overlay.addEventListener("wheel", this.onWheel)
this.md.toggleRemoteControlStatus(true)
update({ remoteControl: RemoteControlStatus.Enabled })
} else {
this.md.overlay.removeEventListener("mousemove", this.onMouseMove)
this.md.overlay.removeEventListener("click", this.onMouseClick)
this.md.overlay.removeEventListener("wheel", this.onWheel)
this.md.toggleRemoteControlStatus(false)
update({ remoteControl: RemoteControlStatus.Disabled })
this.toggleAnnotation(false)
}