ui: some dashboard issues with card selection modal and empty states
This commit is contained in:
parent
486ffc7764
commit
7b0a41b743
4 changed files with 110 additions and 104 deletions
|
|
@ -207,72 +207,74 @@ function CategoryTab({ tab, inCards }: { tab: string; inCards?: boolean }) {
|
|||
);
|
||||
}
|
||||
|
||||
const AddCardSection = observer(({ inCards }: { inCards?: boolean }) => {
|
||||
const { showModal } = useModal();
|
||||
const { metricStore, dashboardStore, projectsStore } = useStore();
|
||||
const [tab, setTab] = React.useState('product_analytics');
|
||||
const options = [
|
||||
{ label: 'Product Analytics', value: 'product_analytics' },
|
||||
{ label: 'Monitors', value: 'monitors' },
|
||||
{ label: 'Web Analytics', value: 'web_analytics' },
|
||||
];
|
||||
const AddCardSection = observer(
|
||||
({ inCards, fit }: { fit?: boolean; inCards?: boolean }) => {
|
||||
const { showModal } = useModal();
|
||||
const { metricStore, dashboardStore, projectsStore } = useStore();
|
||||
const [tab, setTab] = React.useState('product_analytics');
|
||||
const options = [
|
||||
{ label: 'Product Analytics', value: 'product_analytics' },
|
||||
{ label: 'Monitors', value: 'monitors' },
|
||||
{ label: 'Web Analytics', value: 'web_analytics' },
|
||||
];
|
||||
|
||||
const originStr = window.env.ORIGIN || window.location.origin;
|
||||
const isSaas = /api\.openreplay\.com/.test(originStr);
|
||||
const onExistingClick = () => {
|
||||
const dashboardId = dashboardStore.selectedDashboard?.dashboardId;
|
||||
const siteId = projectsStore.activeSiteId;
|
||||
showModal(
|
||||
<MetricsLibraryModal siteId={siteId} dashboardId={dashboardId} />,
|
||||
{
|
||||
right: true,
|
||||
width: 800,
|
||||
onClose: () => {
|
||||
metricStore.updateKey('metricsSearch', '');
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
'py-8 px-8 rounded-xl bg-white border border-gray-lighter flex flex-col gap-4'
|
||||
}
|
||||
style={{ width: 520, height: 400 }}
|
||||
>
|
||||
<div
|
||||
className={'flex justify-between border-b border-b-gray-lighter p-2'}
|
||||
>
|
||||
<div className={'font-semibold text-lg'}>Add a card to dashboard</div>
|
||||
{isSaas ? (
|
||||
<div
|
||||
className={'font-semibold flex items-center gap-2 cursor-pointer'}
|
||||
>
|
||||
<Sparkles color={'#3C00FFD8'} size={16} />
|
||||
<div className={'ai-gradient'}>Ask AI</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div>
|
||||
<Segmented
|
||||
options={options}
|
||||
value={tab}
|
||||
onChange={(value) => setTab(value)}
|
||||
/>
|
||||
</div>
|
||||
<CategoryTab tab={tab} inCards={inCards} />
|
||||
const originStr = window.env.ORIGIN || window.location.origin;
|
||||
const isSaas = /api\.openreplay\.com/.test(originStr);
|
||||
const onExistingClick = () => {
|
||||
const dashboardId = dashboardStore.selectedDashboard?.dashboardId;
|
||||
const siteId = projectsStore.activeSiteId;
|
||||
showModal(
|
||||
<MetricsLibraryModal siteId={siteId} dashboardId={dashboardId} />,
|
||||
{
|
||||
right: true,
|
||||
width: 800,
|
||||
onClose: () => {
|
||||
metricStore.updateKey('metricsSearch', '');
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
'w-full flex items-center justify-center border-t mt-auto border-t-gray-lighter gap-2 pt-2 cursor-pointer'
|
||||
'py-8 px-8 rounded-xl bg-white border border-gray-lighter flex flex-col gap-4'
|
||||
}
|
||||
style={{ width: fit ? 390 : 520, height: 400 }}
|
||||
>
|
||||
<FolderOutlined />
|
||||
<div className={'font-semibold'} onClick={onExistingClick}>
|
||||
Add existing card
|
||||
<div
|
||||
className={'flex justify-between border-b border-b-gray-lighter p-2'}
|
||||
>
|
||||
<div className={'font-semibold text-lg'}>Add a card to dashboard</div>
|
||||
{isSaas ? (
|
||||
<div
|
||||
className={'font-semibold flex items-center gap-2 cursor-pointer'}
|
||||
>
|
||||
<Sparkles color={'#3C00FFD8'} size={16} />
|
||||
<div className={'ai-gradient'}>Ask AI</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div>
|
||||
<Segmented
|
||||
options={options}
|
||||
value={tab}
|
||||
onChange={(value) => setTab(value)}
|
||||
/>
|
||||
</div>
|
||||
<CategoryTab tab={tab} inCards={inCards} />
|
||||
<div
|
||||
className={
|
||||
'w-full flex items-center justify-center border-t mt-auto border-t-gray-lighter gap-2 pt-2 cursor-pointer'
|
||||
}
|
||||
>
|
||||
<FolderOutlined />
|
||||
<div className={'font-semibold'} onClick={onExistingClick}>
|
||||
Add existing card
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default AddCardSection;
|
||||
|
|
|
|||
|
|
@ -1,25 +1,45 @@
|
|||
import React from "react";
|
||||
import {PlusOutlined} from "@ant-design/icons";
|
||||
import NewDashboardModal from "Components/Dashboard/components/DashboardList/NewDashModal";
|
||||
import {Button} from "antd";
|
||||
import React from 'react';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { Button } from 'antd';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
interface Props {
|
||||
disabled?: boolean;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
function CreateDashboardButton({disabled = false}: Props) {
|
||||
const [showModal, setShowModal] = React.useState(false);
|
||||
function CreateDashboardButton({ disabled }: Props) {
|
||||
const [dashboardCreating, setDashboardCreating] = React.useState(false);
|
||||
const { projectsStore, dashboardStore } = useStore();
|
||||
const siteId = projectsStore.siteId;
|
||||
const history = useHistory();
|
||||
|
||||
return <>
|
||||
<Button
|
||||
icon={<PlusOutlined/>}
|
||||
type="primary"
|
||||
onClick={() => setShowModal(true)}
|
||||
>
|
||||
Create Dashboard
|
||||
</Button>
|
||||
<NewDashboardModal onClose={() => setShowModal(false)} open={showModal}/>
|
||||
</>;
|
||||
const createNewDashboard = async () => {
|
||||
setDashboardCreating(true);
|
||||
dashboardStore.initDashboard();
|
||||
await dashboardStore
|
||||
.save(dashboardStore.dashboardInstance)
|
||||
.then(async (syncedDashboard) => {
|
||||
dashboardStore.selectDashboardById(syncedDashboard.dashboardId);
|
||||
history.push(`/${siteId}/dashboard/${syncedDashboard.dashboardId}`);
|
||||
})
|
||||
.finally(() => {
|
||||
setDashboardCreating(false);
|
||||
});
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
loading={dashboardCreating}
|
||||
icon={<PlusOutlined />}
|
||||
disabled={disabled}
|
||||
type="primary"
|
||||
onClick={createNewDashboard}
|
||||
>
|
||||
Create Dashboard
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default CreateDashboardButton;
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ export const CARD_LIST: CardType[] = [
|
|||
example: ExamplePath
|
||||
},
|
||||
{
|
||||
title: 'Sessions Trend',
|
||||
title: 'Trend',
|
||||
key: TIMESERIES,
|
||||
cardType: TIMESERIES,
|
||||
metricOf: 'sessionCount',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { PageTitle, Icon } from 'UI';
|
||||
import { Segmented, Button } from 'antd';
|
||||
import { Segmented, Button, Popover } from 'antd';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import AddCardSection from '../AddCardSection/AddCardSection';
|
||||
import MetricsSearch from '../MetricsSearch';
|
||||
|
|
@ -8,7 +8,6 @@ import Select from 'Shared/Select';
|
|||
import { useStore } from 'App/mstore';
|
||||
import { observer, useObserver } from 'mobx-react-lite';
|
||||
import { DROPDOWN_OPTIONS } from 'App/constants/card';
|
||||
import { INDEXES } from "App/constants/zindex";
|
||||
|
||||
function MetricViewHeader() {
|
||||
const { metricStore } = useStore();
|
||||
|
|
@ -28,13 +27,15 @@ function MetricViewHeader() {
|
|||
<PageTitle title="Cards" className="" />
|
||||
</div>
|
||||
<div className="ml-auto flex items-center">
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => setShowAddCardModal(true)}
|
||||
icon={<PlusOutlined />}
|
||||
>
|
||||
Create Card
|
||||
</Button>
|
||||
<Popover arrow={false} overlayInnerStyle={{ padding: 0, borderRadius: '0.75rem' }} content={<AddCardSection fit inCards />} trigger={'click'}>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => setShowAddCardModal(true)}
|
||||
icon={<PlusOutlined />}
|
||||
>
|
||||
Create Card
|
||||
</Button>
|
||||
</Popover>
|
||||
<div className="ml-4 w-1/4" style={{ minWidth: 300 }}>
|
||||
<MetricsSearch />
|
||||
</div>
|
||||
|
|
@ -78,23 +79,6 @@ function MetricViewHeader() {
|
|||
}
|
||||
/> */}
|
||||
</div>
|
||||
|
||||
{showAddCardModal ? (
|
||||
<div
|
||||
ref={modalBgRef}
|
||||
onClick={(e) => {
|
||||
if (modalBgRef.current === e.target) {
|
||||
setShowAddCardModal(false);
|
||||
}
|
||||
}}
|
||||
className={
|
||||
'fixed top-0 left-0 w-screen h-screen flex items-center justify-center bg-gray-lightest'
|
||||
}
|
||||
style={{ background: 'rgba(0,0,0,0.5)', zIndex: INDEXES.POPUP_GUIDE_BG }}
|
||||
>
|
||||
<AddCardSection inCards />
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue