chore: fix ci problem

This commit is contained in:
moonrailgun 2024-08-03 00:04:54 +08:00
parent e5c2b9484f
commit c7ff3666a7
13 changed files with 1 additions and 551 deletions

View File

@ -1,167 +0,0 @@
import { Button, Dropdown, MenuProps, Space } from 'antd';
import React, { useState } from 'react';
import { trpc } from '../../api/trpc';
import { useCurrentWorkspaceId } from '../../store/user';
import { useDashboardStore } from '../../store/dashboard';
import { DownOutlined } from '@ant-design/icons';
import clsx from 'clsx';
import { useTranslation } from '@i18next-toolkit/react';
export const DashboardItemAddButton: React.FC = React.memo(() => {
const { t } = useTranslation();
const workspaceId = useCurrentWorkspaceId();
const { data: websites = [], isLoading: isWebsiteLoading } =
trpc.website.all.useQuery({
workspaceId,
});
const { data: monitors = [], isLoading: isMonitorLoading } =
trpc.monitor.all.useQuery({
workspaceId,
});
const { addItem } = useDashboardStore();
const [open, setOpen] = useState(false);
const isLoading = isWebsiteLoading || isMonitorLoading;
const menu: MenuProps = {
items: [
{
key: 'website',
label: t('Website'),
children:
websites.length > 0
? websites.map((website) => ({
key: `website#${website.id}`,
label: website.name,
children: [
{
key: `website#${website.id}#overview`,
label: t('Overview'),
onClick: () => {
addItem(
'websiteOverview',
website.id,
`${website.name}'s Overview`
);
},
},
{
key: `website#${website.id}#events`,
label: t('Events'),
onClick: () => {
addItem(
'websiteEvents',
website.id,
`${website.name}'s Events`
);
},
},
],
}))
: [
{
key: `website#none`,
label: t('(None)'),
disabled: true,
},
],
},
{
key: 'monitor',
label: t('Monitor'),
children:
monitors.length > 0
? monitors.map((monitor) => ({
key: `monitor#${monitor.id}`,
label: monitor.name,
children: [
{
key: `monitor#${monitor.id}#healthBar`,
label: t('Health Bar'),
onClick: () => {
addItem(
'monitorHealthBar',
monitor.id,
t("{{monitorName}}'s Health", {
monitorName: monitor.name,
})
);
},
},
{
key: `monitor#${monitor.id}#metrics`,
label: t('Metrics'),
onClick: () => {
addItem(
'monitorMetrics',
monitor.id,
t("{{monitorName}}'s Metrics", {
monitorName: monitor.name,
})
);
},
},
{
key: `monitor#${monitor.id}#chart`,
label: t('Chart'),
onClick: () => {
addItem(
'monitorChart',
monitor.id,
t("{{monitorName}}'s Chart", {
monitorName: monitor.name,
})
);
},
},
{
key: `monitor#${monitor.id}#events`,
label: t('Events'),
onClick: () => {
addItem(
'monitorEvents',
monitor.id,
t("{{monitorName}}'s Events", {
monitorName: monitor.name,
})
);
},
},
],
}))
: [
{
key: `monitor#none`,
label: t('(None)'),
disabled: true,
},
],
},
],
};
return (
<div>
<Dropdown
trigger={['click']}
disabled={isLoading}
menu={menu}
open={open}
onOpenChange={setOpen}
>
<Button type="primary" size="large" className="w-32">
<Space>
<span>{t('Add')}</span>
<DownOutlined
className={clsx(
'scale-y-75 transition-transform',
open && 'rotate-180'
)}
/>
</Space>
</Button>
</Dropdown>
</div>
);
});
DashboardItemAddButton.displayName = 'DashboardItemAddButton';

View File

@ -1,102 +0,0 @@
import React, { useEffect } from 'react';
import { DashboardGrid } from './Grid';
import { DashboardItemAddButton } from './AddButton';
import { defaultBlankLayouts, useDashboardStore } from '../../store/dashboard';
import { useEvent } from '../../hooks/useEvent';
import { Layouts } from 'react-grid-layout';
import { Button, Empty, message } from 'antd';
import { DateFilter } from '../DateFilter';
import { trpc } from '../../api/trpc';
import { useCurrentWorkspace, useCurrentWorkspaceId } from '../../store/user';
import clsx from 'clsx';
import { useTranslation } from '@i18next-toolkit/react';
export const Dashboard: React.FC = React.memo(() => {
const { t } = useTranslation();
const { isEditMode, switchEditMode, layouts, items } = useDashboardStore();
const mutation = trpc.workspace.saveDashboardLayout.useMutation();
const workspaceId = useCurrentWorkspaceId();
const workspace = useCurrentWorkspace();
useEffect(() => {
// Init on mount
const { items = [], layouts = defaultBlankLayouts } =
workspace.dashboardLayout ?? {};
useDashboardStore.setState({
items,
layouts,
});
}, []);
const handleChangeLayouts = useEvent((layouts: Layouts) => {
useDashboardStore.setState({
layouts,
});
});
const handleSaveDashboardLayout = useEvent(async () => {
await mutation.mutateAsync({
workspaceId,
dashboardLayout: {
layouts,
items,
},
});
switchEditMode();
message.success(t('Layout saved success'));
});
return (
<div className="py-4">
<div
className={clsx(
'flex justify-end gap-2 bg-white py-2 dark:bg-gray-900',
isEditMode && 'sticky top-0 z-10'
)}
>
{isEditMode ? (
<>
<DashboardItemAddButton />
<Button
className="w-32"
size="large"
loading={mutation.isLoading}
disabled={mutation.isLoading}
onClick={handleSaveDashboardLayout}
>
{t('Done')}
</Button>
</>
) : (
<>
<DateFilter />
<Button
className="w-32"
type="primary"
size="large"
onClick={switchEditMode}
>
{t('Edit')}
</Button>
</>
)}
</div>
<DashboardGrid
layouts={layouts}
onChangeLayouts={handleChangeLayouts}
items={items}
isEditMode={isEditMode}
/>
{items.length === 0 && (
<Empty
description={t(
'You have not dashboard item yet, please enter edit mode and add you item.'
)}
/>
)}
</div>
);
});
Dashboard.displayName = 'Dashboard';

View File

@ -1,44 +0,0 @@
import React from 'react';
import { Layouts, Responsive, WidthProvider } from 'react-grid-layout';
import clsx from 'clsx';
import { DashboardGridItem } from './items';
import { DashboardItem } from '../../store/dashboard';
import 'react-grid-layout/css/styles.css';
import 'react-resizable/css/styles.css';
const ResponsiveGridLayout = WidthProvider(Responsive);
interface DashboardGridProps {
isEditMode: boolean;
items: DashboardItem[];
layouts: Layouts;
onChangeLayouts: (layouts: Layouts) => void;
}
export const DashboardGrid: React.FC<DashboardGridProps> = React.memo(
(props) => {
const { layouts, onChangeLayouts, items, isEditMode } = props;
return (
<ResponsiveGridLayout
className={clsx('layout', isEditMode && 'select-none')}
layouts={layouts}
rowHeight={50}
draggableCancel=".non-draggable"
isDraggable={isEditMode}
isResizable={isEditMode}
breakpoints={{ lg: 1200, md: 768, sm: 0 }}
cols={{ lg: 4, md: 3, sm: 2 }}
onLayoutChange={(currentLayout, allLayouts) => {
onChangeLayouts(allLayouts);
}}
>
{items.map((item) => (
<div key={item.key}>
<DashboardGridItem item={item} />
</div>
))}
</ResponsiveGridLayout>
);
}
);
DashboardGrid.displayName = 'DashboardGrid';

View File

@ -1,9 +0,0 @@
import React from 'react';
import { MonitorDataChart } from '../../monitor/MonitorDataChart';
export const MonitorChartItem: React.FC<{
monitorId: string;
}> = React.memo((props) => {
return <MonitorDataChart monitorId={props.monitorId} />;
});
MonitorChartItem.displayName = 'MonitorChartItem';

View File

@ -1,9 +0,0 @@
import React from 'react';
import { MonitorEventList } from '../../monitor/MonitorEventList';
export const MonitorEventsItem: React.FC<{
monitorId: string;
}> = React.memo((props) => {
return <MonitorEventList monitorId={props.monitorId} />;
});
MonitorEventsItem.displayName = 'MonitorEventsItem';

View File

@ -1,20 +0,0 @@
import React from 'react';
import { MonitorHealthBar } from '../../monitor/MonitorHealthBar';
import { useCurrentWorkspaceId } from '../../../store/user';
export const MonitorHealthBarItem: React.FC<{
monitorId: string;
}> = React.memo((props) => {
const workspaceId = useCurrentWorkspaceId();
return (
<MonitorHealthBar
workspaceId={workspaceId}
monitorId={props.monitorId}
count={40}
size="large"
showCurrentStatus={true}
/>
);
});
MonitorHealthBarItem.displayName = 'MonitorHealthBarItem';

View File

@ -1,33 +0,0 @@
import React from 'react';
import { trpc } from '../../../api/trpc';
import { NotFoundTip } from '../../NotFoundTip';
import { useCurrentWorkspaceId } from '../../../store/user';
import { Loading } from '../../Loading';
import { MonitorDataMetrics } from '../../monitor/MonitorDataMetrics';
export const MonitorMetricsItem: React.FC<{
monitorId: string;
}> = React.memo((props) => {
const workspaceId = useCurrentWorkspaceId();
const { data: monitorInfo, isLoading } = trpc.monitor.get.useQuery({
workspaceId,
monitorId: props.monitorId,
});
if (isLoading) {
return <Loading />;
}
if (!monitorInfo) {
return <NotFoundTip />;
}
return (
<MonitorDataMetrics
monitorId={monitorInfo.id}
monitorType={monitorInfo.type}
/>
);
});
MonitorMetricsItem.displayName = 'MonitorMetricsItem';

View File

@ -1,24 +0,0 @@
import React from 'react';
import { WebsiteMetricsTable } from '../../website/WebsiteMetricsTable';
import { useGlobalRangeDate } from '../../../hooks/useGlobalRangeDate';
import { useTranslation } from '@i18next-toolkit/react';
export const WebsiteEventItem: React.FC<{
websiteId: string;
}> = React.memo((props) => {
const { t } = useTranslation();
const { startDate, endDate } = useGlobalRangeDate();
const startAt = startDate.valueOf();
const endAt = endDate.valueOf();
return (
<WebsiteMetricsTable
websiteId={props.websiteId}
type="event"
title={[t('Events'), t('Actions')]}
startAt={startAt}
endAt={endAt}
/>
);
});
WebsiteEventItem.displayName = 'WebsiteEventItem';

View File

@ -1,46 +0,0 @@
import React from 'react';
import { trpc } from '../../../api/trpc';
import { useCurrentWorkspaceId } from '../../../store/user';
import { Loading } from '../../Loading';
import { NotFoundTip } from '../../NotFoundTip';
import { WebsiteOverview } from '../../website/WebsiteOverview';
import { Button } from 'antd';
import { ArrowRightOutlined } from '@ant-design/icons';
import { useTranslation } from '@i18next-toolkit/react';
import { Link } from '@tanstack/react-router';
export const WebsiteOverviewItem: React.FC<{
websiteId: string;
}> = React.memo((props) => {
const { t } = useTranslation();
const workspaceId = useCurrentWorkspaceId();
const { data: websiteInfo, isLoading } = trpc.website.info.useQuery({
workspaceId,
websiteId: props.websiteId,
});
if (isLoading) {
return <Loading />;
}
if (!websiteInfo) {
return <NotFoundTip />;
}
return (
<WebsiteOverview
website={websiteInfo}
actions={
<>
<Link to="/website/$websiteId" params={{ websiteId: websiteInfo.id }}>
<Button type="primary" size="large">
{t('View Details')} <ArrowRightOutlined />
</Button>
</Link>
</>
}
/>
);
});
WebsiteOverviewItem.displayName = 'WebsiteOverviewItem';

View File

@ -1,77 +0,0 @@
import { useMemo } from 'react';
import { DashboardItem, useDashboardStore } from '../../../store/dashboard';
import { WebsiteOverviewItem } from './WebsiteOverviewItem';
import { NotFoundTip } from '../../NotFoundTip';
import { Button, Card, Input, Typography } from 'antd';
import React from 'react';
import { DeleteOutlined } from '@ant-design/icons';
import { useEvent } from '../../../hooks/useEvent';
import { WebsiteEventItem } from './WebsiteEventItem';
import { MonitorHealthBarItem } from './MonitorHealthBarItem';
import { MonitorMetricsItem } from './MonitorMetricsItem';
import { MonitorChartItem } from './MonitorChartItem';
import { MonitorEventsItem } from './MonitorEventsItem';
import { EditableText } from '../../EditableText';
interface DashboardGridItemProps {
item: DashboardItem;
}
export const DashboardGridItem: React.FC<DashboardGridItemProps> = React.memo(
(props) => {
const { isEditMode, removeItem, changeItemTitle } = useDashboardStore();
const { key, id, title, type } = props.item;
const inner = useMemo(() => {
if (type === 'websiteOverview') {
return <WebsiteOverviewItem websiteId={id} />;
} else if (type === 'websiteEvents') {
return <WebsiteEventItem websiteId={id} />;
} else if (type === 'monitorHealthBar') {
return <MonitorHealthBarItem monitorId={id} />;
} else if (type === 'monitorMetrics') {
return <MonitorMetricsItem monitorId={id} />;
} else if (type === 'monitorChart') {
return <MonitorChartItem monitorId={id} />;
} else if (type === 'monitorEvents') {
return <MonitorEventsItem monitorId={id} />;
} else {
return <NotFoundTip />;
}
}, [id, type]);
const handleDelete = useEvent(
(e: React.MouseEvent<HTMLElement, MouseEvent>) => {
e.stopPropagation();
removeItem(key);
}
);
return (
<Card
className="h-full w-full overflow-auto"
title={
<EditableText
className="non-draggable"
enable={isEditMode}
defaultValue={title}
onSave={(text) => changeItemTitle(key, text)}
/>
}
headStyle={{ padding: 10, minHeight: 40 }}
bodyStyle={{ padding: 10 }}
extra={
isEditMode && (
<Button
shape="circle"
icon={<DeleteOutlined />}
onClick={handleDelete}
/>
)
}
>
{inner}
</Card>
);
}
);
DashboardGridItem.displayName = 'DashboardGridItem';

View File

@ -21,7 +21,6 @@ import { Route as PageImport } from './routes/page'
import { Route as MonitorImport } from './routes/monitor'
import { Route as LoginImport } from './routes/login'
import { Route as FeedImport } from './routes/feed'
import { Route as DashboardImport } from './routes/dashboard'
import { Route as IndexImport } from './routes/index'
import { Route as WebsiteOverviewImport } from './routes/website/overview'
import { Route as WebsiteAddImport } from './routes/website/add'
@ -98,11 +97,6 @@ const FeedRoute = FeedImport.update({
getParentRoute: () => rootRoute,
} as any)
const DashboardRoute = DashboardImport.update({
path: '/dashboard',
getParentRoute: () => rootRoute,
} as any)
const IndexRoute = IndexImport.update({
path: '/',
getParentRoute: () => rootRoute,
@ -226,10 +220,6 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof IndexImport
parentRoute: typeof rootRoute
}
'/dashboard': {
preLoaderRoute: typeof DashboardImport
parentRoute: typeof rootRoute
}
'/feed': {
preLoaderRoute: typeof FeedImport
parentRoute: typeof rootRoute
@ -365,7 +355,6 @@ declare module '@tanstack/react-router' {
export const routeTree = rootRoute.addChildren([
IndexRoute,
DashboardRoute,
FeedRoute.addChildren([
FeedAddRoute,
FeedChannelIdEditRoute,

View File

@ -1,9 +0,0 @@
import { createFileRoute, redirect } from '@tanstack/react-router';
export const Route = createFileRoute('/dashboard')({
beforeLoad: () => {
redirect({
to: '/',
});
},
});

View File

@ -8,6 +8,7 @@ export default defineConfig({
root: __dirname,
plugins: [
react(),
// @ts-ignore
TanStackRouterVite({
routesDirectory: './routes',
generatedRouteTree: './routeTree.gen.ts',