ui: some dashboard issues with card selection modal and empty states

This commit is contained in:
nick-delirium 2024-12-04 13:35:26 +01:00
parent 486ffc7764
commit 7b0a41b743
No known key found for this signature in database
GPG key ID: 93ABD695DF5FDBA0
4 changed files with 110 additions and 104 deletions

View file

@ -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;

View file

@ -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;

View file

@ -107,7 +107,7 @@ export const CARD_LIST: CardType[] = [
example: ExamplePath
},
{
title: 'Sessions Trend',
title: 'Trend',
key: TIMESERIES,
cardType: TIMESERIES,
metricOf: 'sessionCount',

View file

@ -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>
);