feat(ui) - dashboard - ui review and fixes
This commit is contained in:
parent
af39480e09
commit
2c3c0c30c0
9 changed files with 114 additions and 19 deletions
|
|
@ -20,6 +20,7 @@ function CPULoad(props: Props) {
|
|||
<NoContent
|
||||
size="small"
|
||||
show={ metric.data.chart.length === 0 }
|
||||
style={ { height: '240px' } }
|
||||
>
|
||||
<ResponsiveContainer height={ 240 } width="100%">
|
||||
<AreaChart
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ function Crashes(props: Props) {
|
|||
<NoContent
|
||||
size="small"
|
||||
show={ metric.data.chart.length === 0 }
|
||||
style={ { height: '240px' } }
|
||||
>
|
||||
<ResponsiveContainer height={ 240 } width="100%">
|
||||
<AreaChart
|
||||
|
|
|
|||
|
|
@ -8,14 +8,18 @@ import { useModal } from 'App/components/Modal';
|
|||
import DashbaordListModal from '../DashbaordListModal';
|
||||
import DashboardModal from '../DashboardModal';
|
||||
import cn from 'classnames';
|
||||
import { Tooltip } from 'react-tippy';
|
||||
import { connect } from 'react-redux';
|
||||
import { setShowAlerts } from 'Duck/dashboard';
|
||||
|
||||
const SHOW_COUNT = 5;
|
||||
const SHOW_COUNT = 8;
|
||||
interface Props {
|
||||
siteId: string
|
||||
history: any
|
||||
setShowAlerts: (show: boolean) => void
|
||||
}
|
||||
function DashboardSideMenu(props: Props) {
|
||||
const { history, siteId } = props;
|
||||
const { history, siteId, setShowAlerts } = props;
|
||||
const { hideModal, showModal } = useModal();
|
||||
const { dashboardStore } = useStore();
|
||||
const dashboardId = useObserver(() => dashboardStore.selectedDashboard?.dashboardId);
|
||||
|
|
@ -54,9 +58,19 @@ function DashboardSideMenu(props: Props) {
|
|||
onClick={() => onItemClick(item)}
|
||||
className="group"
|
||||
leading = {(
|
||||
<div className="ml-2 flex items-center">
|
||||
<div className="ml-2 flex items-center cursor-default">
|
||||
{item.isPublic && <div className="p-1"><Icon name="user-friends" color="gray-light" size="16" /></div>}
|
||||
{<div className={cn("p-1 group-hover:visible", { 'invisible' : !item.isPinned })} onClick={() => togglePinned(item)}><Icon name="pin-fill" size="16" /></div>}
|
||||
{item.isPinned && <div className="p-1 pointer-events-none"><Icon name="pin-fill" size="16" /></div>}
|
||||
{!item.isPinned && (
|
||||
<Tooltip delay={500} arrow title="Set as default dashboard" hideOnClick={true}>
|
||||
<div
|
||||
className={cn("p-1 invisible group-hover:visible cursor-pointer")}
|
||||
onClick={() => togglePinned(item)}
|
||||
>
|
||||
<Icon name="pin-fill" size="16" color="gray-light" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
|
|
@ -96,11 +110,12 @@ function DashboardSideMenu(props: Props) {
|
|||
id="menu-manage-alerts"
|
||||
title="Alerts"
|
||||
iconName="bell-plus"
|
||||
// onClick={() => setShowAlerts(true)}
|
||||
onClick={() => setShowAlerts(true)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
));
|
||||
}
|
||||
|
||||
export default withRouter(DashboardSideMenu);
|
||||
export default connect((state) => {
|
||||
}, { setShowAlerts })(withRouter(DashboardSideMenu));
|
||||
|
|
@ -11,6 +11,7 @@ import { useModal } from 'App/components/Modal';
|
|||
import DashboardModal from '../DashboardModal';
|
||||
import DashboardEditModal from '../DashboardEditModal';
|
||||
import DateRange from 'Shared/DateRange';
|
||||
import AlertFormModal from 'App/components/Alerts/AlertFormModal';
|
||||
|
||||
interface Props {
|
||||
siteId: number;
|
||||
|
|
@ -22,6 +23,7 @@ function DashboardView(props: Props) {
|
|||
const { siteId, dashboardId } = props;
|
||||
const { dashboardStore } = useStore();
|
||||
const { hideModal, showModal } = useModal();
|
||||
const showAlertModal = useObserver(() => dashboardStore.showAlertModal);
|
||||
const loading = useObserver(() => dashboardStore.fetchingDashboard);
|
||||
const dashboards = useObserver(() => dashboardStore.dashboards);
|
||||
const dashboard: any = useObserver(() => dashboardStore.selectedDashboard);
|
||||
|
|
@ -98,18 +100,11 @@ function DashboardView(props: Props) {
|
|||
</div>
|
||||
<div className="mx-4" />
|
||||
<div className="flex items-center">
|
||||
{/* <span className="mr-1 color-gray-medium">Options</span> */}
|
||||
<ItemMenu
|
||||
label="Options"
|
||||
items={[
|
||||
{
|
||||
text: 'Rename',
|
||||
onClick: onEdit
|
||||
},
|
||||
{
|
||||
text: 'Delete',
|
||||
onClick: onDelete
|
||||
},
|
||||
{ text: 'Rename', onClick: onEdit },
|
||||
{ text: 'Delete', onClick: onDelete },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -120,6 +115,10 @@ function DashboardView(props: Props) {
|
|||
dashboardId={dashboardId}
|
||||
onEditHandler={onAddWidgets}
|
||||
/>
|
||||
<AlertFormModal
|
||||
showModal={showAlertModal}
|
||||
onClose={() => dashboardStore.updateKey('showAlertModal', false)}
|
||||
/>
|
||||
</div>
|
||||
</NoContent>
|
||||
</Loader>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import WidgetIcon from './WidgetIcon';
|
||||
import { init as initAlert } from 'Duck/alerts';
|
||||
import { useStore } from 'App/mstore';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
||||
initAlert: Function;
|
||||
}
|
||||
function AlertButton(props: Props) {
|
||||
const { seriesId, initAlert } = props;
|
||||
const { dashboardStore } = useStore();
|
||||
const onClick = () => {
|
||||
initAlert({ query: { left: seriesId }})
|
||||
dashboardStore.updateKey('showAlertModal', true);
|
||||
}
|
||||
return (
|
||||
<WidgetIcon
|
||||
className="cursor-pointer"
|
||||
icon="bell-plus"
|
||||
tooltip="Set Alert"
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(null, { initAlert })(AlertButton);
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import React from 'react';
|
||||
import { Icon } from 'UI';
|
||||
import { Tooltip } from 'react-tippy';
|
||||
|
||||
interface Props {
|
||||
className: string
|
||||
onClick: () => void
|
||||
icon: string
|
||||
tooltip: string
|
||||
}
|
||||
function WidgetIcon(props: Props) {
|
||||
const { className, onClick, icon, tooltip } = props;
|
||||
return (
|
||||
<Tooltip
|
||||
arrow
|
||||
size="small"
|
||||
title={tooltip}
|
||||
position="top"
|
||||
>
|
||||
<div className={className} onClick={onClick}>
|
||||
<Icon name={icon} size="14" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
export default WidgetIcon;
|
||||
|
|
@ -4,12 +4,14 @@ import { ItemMenu } from 'UI';
|
|||
import { useDrag, useDrop } from 'react-dnd';
|
||||
import WidgetChart from '../WidgetChart';
|
||||
import { useObserver } from 'mobx-react-lite';
|
||||
import { confirm } from 'UI/Confirmation';
|
||||
// import { confirm } from 'UI/Confirmation';
|
||||
import { useStore } from 'App/mstore';
|
||||
import LazyLoad from 'react-lazyload';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { withSiteId, dashboardMetricDetails } from 'App/routes';
|
||||
import TemplateOverlay from './TemplateOverlay';
|
||||
import WidgetIcon from './WidgetIcon';
|
||||
import AlertButton from './AlertButton';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
|
|
@ -29,6 +31,7 @@ function WidgetWrapper(props: Props) {
|
|||
const { dashboardStore } = useStore();
|
||||
const { isWidget = false, active = false, index = 0, moveListItem = null, isPreview = false, isTemplate = false, dashboardId, siteId } = props;
|
||||
const widget: any = useObserver(() => props.widget);
|
||||
const isPredefined = widget.metricType === 'predefined';
|
||||
|
||||
const [{ opacity, isDragging }, dragRef] = useDrag({
|
||||
type: 'item',
|
||||
|
|
@ -63,7 +66,7 @@ function WidgetWrapper(props: Props) {
|
|||
}
|
||||
|
||||
const onChartClick = () => {
|
||||
if (!isWidget || widget.metricType === 'predefined') return;
|
||||
if (!isWidget || isPredefined) return;
|
||||
|
||||
props.history.push(withSiteId(dashboardMetricDetails(dashboardId, widget.metricId),siteId));
|
||||
}
|
||||
|
|
@ -88,7 +91,14 @@ function WidgetWrapper(props: Props) {
|
|||
>
|
||||
<h3 className="capitalize">{widget.name}</h3>
|
||||
{isWidget && (
|
||||
<div>
|
||||
<div className="flex items-center">
|
||||
{!isPredefined && (
|
||||
<>
|
||||
<AlertButton seriesId={widget.series[0] && widget.series[0].seriesId} />
|
||||
<div className='mx-2'/>
|
||||
</>
|
||||
)}
|
||||
|
||||
<ItemMenu
|
||||
items={[
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,18 +9,28 @@ const ModalContext = createContext({
|
|||
});
|
||||
|
||||
export class ModalProvider extends Component {
|
||||
|
||||
handleKeyDown = (e: any) => {
|
||||
if (e.keyCode === 27) {
|
||||
this.hideModal();
|
||||
}
|
||||
}
|
||||
|
||||
showModal = (component, props = {}) => {
|
||||
this.setState({
|
||||
component,
|
||||
props
|
||||
});
|
||||
document.addEventListener('keydown', this.handleKeyDown);
|
||||
};
|
||||
|
||||
hideModal = () =>
|
||||
hideModal = () => {
|
||||
this.setState({
|
||||
component: null,
|
||||
props: {}
|
||||
});
|
||||
document.removeEventListener('keydown', this.handleKeyDown);
|
||||
}
|
||||
|
||||
state = {
|
||||
component: null,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ export interface IDashboardSotre {
|
|||
fetchingDashboard: boolean
|
||||
sessionsLoading: boolean
|
||||
|
||||
showAlertModal: boolean
|
||||
|
||||
selectWidgetsByCategory: (category: string) => void
|
||||
toggleAllSelectedWidgets: (isSelected: boolean) => void
|
||||
removeSelectedWidgetByCategory(category: string): void
|
||||
|
|
@ -93,6 +95,8 @@ export default class DashboardStore implements IDashboardSotre {
|
|||
fetchingDashboard: boolean = false
|
||||
sessionsLoading: boolean = false;
|
||||
|
||||
showAlertModal: boolean = false;
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this, {
|
||||
drillDownFilter: observable.ref,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue