feat(v2): add page list/add/detail
This commit is contained in:
parent
f27f3f2f11
commit
d97c671913
@ -75,6 +75,7 @@ export const MonitorStatusPage: React.FC<MonitorStatusPageProps> = React.memo(
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
className={clsx(
|
||||
'mx-auto overflow-auto px-4 py-8',
|
||||
|
@ -14,6 +14,7 @@ import { Route as rootRoute } from './routes/__root'
|
||||
import { Route as WebsiteImport } from './routes/website'
|
||||
import { Route as TelemetryImport } from './routes/telemetry'
|
||||
import { Route as RegisterImport } from './routes/register'
|
||||
import { Route as PageImport } from './routes/page'
|
||||
import { Route as MonitorImport } from './routes/monitor'
|
||||
import { Route as LoginImport } from './routes/login'
|
||||
import { Route as DashboardImport } from './routes/dashboard'
|
||||
@ -22,6 +23,8 @@ import { Route as WebsiteAddImport } from './routes/website/add'
|
||||
import { Route as WebsiteWebsiteIdImport } from './routes/website/$websiteId'
|
||||
import { Route as TelemetryAddImport } from './routes/telemetry/add'
|
||||
import { Route as TelemetryTelemetryIdImport } from './routes/telemetry/$telemetryId'
|
||||
import { Route as PageAddImport } from './routes/page/add'
|
||||
import { Route as PageSlugImport } from './routes/page/$slug'
|
||||
import { Route as MonitorAddImport } from './routes/monitor/add'
|
||||
import { Route as MonitorMonitorIdImport } from './routes/monitor/$monitorId'
|
||||
|
||||
@ -42,6 +45,11 @@ const RegisterRoute = RegisterImport.update({
|
||||
getParentRoute: () => rootRoute,
|
||||
} as any)
|
||||
|
||||
const PageRoute = PageImport.update({
|
||||
path: '/page',
|
||||
getParentRoute: () => rootRoute,
|
||||
} as any)
|
||||
|
||||
const MonitorRoute = MonitorImport.update({
|
||||
path: '/monitor',
|
||||
getParentRoute: () => rootRoute,
|
||||
@ -82,6 +90,16 @@ const TelemetryTelemetryIdRoute = TelemetryTelemetryIdImport.update({
|
||||
getParentRoute: () => TelemetryRoute,
|
||||
} as any)
|
||||
|
||||
const PageAddRoute = PageAddImport.update({
|
||||
path: '/add',
|
||||
getParentRoute: () => PageRoute,
|
||||
} as any)
|
||||
|
||||
const PageSlugRoute = PageSlugImport.update({
|
||||
path: '/$slug',
|
||||
getParentRoute: () => PageRoute,
|
||||
} as any)
|
||||
|
||||
const MonitorAddRoute = MonitorAddImport.update({
|
||||
path: '/add',
|
||||
getParentRoute: () => MonitorRoute,
|
||||
@ -112,6 +130,10 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof MonitorImport
|
||||
parentRoute: typeof rootRoute
|
||||
}
|
||||
'/page': {
|
||||
preLoaderRoute: typeof PageImport
|
||||
parentRoute: typeof rootRoute
|
||||
}
|
||||
'/register': {
|
||||
preLoaderRoute: typeof RegisterImport
|
||||
parentRoute: typeof rootRoute
|
||||
@ -132,6 +154,14 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof MonitorAddImport
|
||||
parentRoute: typeof MonitorImport
|
||||
}
|
||||
'/page/$slug': {
|
||||
preLoaderRoute: typeof PageSlugImport
|
||||
parentRoute: typeof PageImport
|
||||
}
|
||||
'/page/add': {
|
||||
preLoaderRoute: typeof PageAddImport
|
||||
parentRoute: typeof PageImport
|
||||
}
|
||||
'/telemetry/$telemetryId': {
|
||||
preLoaderRoute: typeof TelemetryTelemetryIdImport
|
||||
parentRoute: typeof TelemetryImport
|
||||
@ -158,6 +188,7 @@ export const routeTree = rootRoute.addChildren([
|
||||
DashboardRoute,
|
||||
LoginRoute,
|
||||
MonitorRoute.addChildren([MonitorMonitorIdRoute, MonitorAddRoute]),
|
||||
PageRoute.addChildren([PageSlugRoute, PageAddRoute]),
|
||||
RegisterRoute,
|
||||
TelemetryRoute.addChildren([TelemetryTelemetryIdRoute, TelemetryAddRoute]),
|
||||
WebsiteRoute.addChildren([WebsiteWebsiteIdRoute, WebsiteAddRoute]),
|
||||
|
@ -6,8 +6,6 @@ interface RouterContext {
|
||||
userInfo: any;
|
||||
}
|
||||
|
||||
const defaultLayout: [number, number, number] = [265, 440, 655];
|
||||
|
||||
export const Route = createRootRouteWithContext<RouterContext>()({
|
||||
component: () => {
|
||||
return (
|
||||
|
@ -21,9 +21,9 @@ export const Route = createFileRoute('/monitor/add')({
|
||||
function MonitorAddComponent() {
|
||||
const { t } = useTranslation();
|
||||
const workspaceId = useCurrentWorkspaceId();
|
||||
const addWebsiteMutation = trpc.website.add.useMutation();
|
||||
const navigate = useNavigate();
|
||||
const mutation = useMonitorUpsert();
|
||||
const utils = trpc.useUtils();
|
||||
|
||||
const handleSubmit = useEvent(async (values: MonitorInfoEditorValues) => {
|
||||
const res = await mutation.mutateAsync({
|
||||
@ -31,6 +31,8 @@ function MonitorAddComponent() {
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
utils.monitor.all.refetch();
|
||||
|
||||
navigate({
|
||||
to: '/monitor/$monitorId',
|
||||
params: {
|
||||
|
86
src/client/routes/page.tsx
Normal file
86
src/client/routes/page.tsx
Normal file
@ -0,0 +1,86 @@
|
||||
import { trpc } from '@/api/trpc';
|
||||
import { CommonHeader } from '@/components/CommonHeader';
|
||||
import { CommonList } from '@/components/CommonList';
|
||||
import { CommonWrapper } from '@/components/CommonWrapper';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { useDataReady } from '@/hooks/useDataReady';
|
||||
import { useEvent } from '@/hooks/useEvent';
|
||||
import { LayoutV2 } from '@/pages/LayoutV2';
|
||||
import { useCurrentWorkspaceId } from '@/store/user';
|
||||
import { routeAuthBeforeLoad } from '@/utils/route';
|
||||
import { useTranslation } from '@i18next-toolkit/react';
|
||||
import {
|
||||
createFileRoute,
|
||||
useNavigate,
|
||||
useRouterState,
|
||||
} from '@tanstack/react-router';
|
||||
import { LuPlus } from 'react-icons/lu';
|
||||
|
||||
export const Route = createFileRoute('/page')({
|
||||
beforeLoad: routeAuthBeforeLoad,
|
||||
component: PageComponent,
|
||||
});
|
||||
|
||||
function PageComponent() {
|
||||
const workspaceId = useCurrentWorkspaceId();
|
||||
const { t } = useTranslation();
|
||||
const { data = [] } = trpc.monitor.getAllPages.useQuery({
|
||||
workspaceId,
|
||||
});
|
||||
const navigate = useNavigate();
|
||||
const pathname = useRouterState({
|
||||
select: (state) => state.location.pathname,
|
||||
});
|
||||
|
||||
const items = data.map((item) => ({
|
||||
id: item.id,
|
||||
title: item.title,
|
||||
content: item.slug,
|
||||
href: `/page/${item.slug}`,
|
||||
}));
|
||||
|
||||
useDataReady(
|
||||
() => data.length > 0,
|
||||
() => {
|
||||
if (pathname === Route.fullPath) {
|
||||
navigate({
|
||||
to: '/page/$slug',
|
||||
params: {
|
||||
slug: data[0].slug,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const handleClickAdd = useEvent(() => {
|
||||
navigate({
|
||||
to: '/page/add',
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<LayoutV2
|
||||
list={
|
||||
<CommonWrapper
|
||||
header={
|
||||
<CommonHeader
|
||||
title={t('Pages')}
|
||||
actions={
|
||||
<Button
|
||||
variant="outline"
|
||||
Icon={LuPlus}
|
||||
onClick={handleClickAdd}
|
||||
>
|
||||
{t('Add')}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<CommonList hasSearch={true} items={items} />
|
||||
</CommonWrapper>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
42
src/client/routes/page/$slug.tsx
Normal file
42
src/client/routes/page/$slug.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
import { trpc } from '@/api/trpc';
|
||||
import { CommonHeader } from '@/components/CommonHeader';
|
||||
import { CommonWrapper } from '@/components/CommonWrapper';
|
||||
import { ErrorTip } from '@/components/ErrorTip';
|
||||
import { Loading } from '@/components/Loading';
|
||||
import { NotFoundTip } from '@/components/NotFoundTip';
|
||||
import { MonitorStatusPage } from '@/components/monitor/StatusPage';
|
||||
import { ScrollArea } from '@/components/ui/scroll-area';
|
||||
import { routeAuthBeforeLoad } from '@/utils/route';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
||||
export const Route = createFileRoute('/page/$slug')({
|
||||
beforeLoad: routeAuthBeforeLoad,
|
||||
component: PageDetailComponent,
|
||||
});
|
||||
|
||||
function PageDetailComponent() {
|
||||
const { slug } = Route.useParams<{ slug: string }>();
|
||||
const { data: pageInfo, isLoading } = trpc.monitor.getPageInfo.useQuery({
|
||||
slug,
|
||||
});
|
||||
|
||||
if (!slug) {
|
||||
return <ErrorTip />;
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
if (!pageInfo) {
|
||||
return <NotFoundTip />;
|
||||
}
|
||||
|
||||
return (
|
||||
<CommonWrapper header={<CommonHeader title={pageInfo.title} />}>
|
||||
{/* <ScrollArea className="h-full overflow-hidden"> */}
|
||||
<MonitorStatusPage slug={slug} />
|
||||
{/* </ScrollArea> */}
|
||||
</CommonWrapper>
|
||||
);
|
||||
}
|
61
src/client/routes/page/add.tsx
Normal file
61
src/client/routes/page/add.tsx
Normal file
@ -0,0 +1,61 @@
|
||||
import { createFileRoute, useNavigate } from '@tanstack/react-router';
|
||||
import { useTranslation } from '@i18next-toolkit/react';
|
||||
import { useEvent } from '@/hooks/useEvent';
|
||||
import { useCurrentWorkspaceId } from '@/store/user';
|
||||
import { trpc } from '@/api/trpc';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { CommonWrapper } from '@/components/CommonWrapper';
|
||||
import { routeAuthBeforeLoad } from '@/utils/route';
|
||||
import {
|
||||
MonitorStatusPageEditForm,
|
||||
MonitorStatusPageEditFormValues,
|
||||
} from '@/components/monitor/StatusPage/EditForm';
|
||||
|
||||
export const Route = createFileRoute('/page/add')({
|
||||
beforeLoad: routeAuthBeforeLoad,
|
||||
component: PageAddComponent,
|
||||
});
|
||||
|
||||
function PageAddComponent() {
|
||||
const { t } = useTranslation();
|
||||
const workspaceId = useCurrentWorkspaceId();
|
||||
const createPageMutation = trpc.monitor.createPage.useMutation();
|
||||
const navigate = useNavigate();
|
||||
const utils = trpc.useUtils();
|
||||
|
||||
const handleSubmit = useEvent(
|
||||
async (values: MonitorStatusPageEditFormValues) => {
|
||||
const res = await createPageMutation.mutateAsync({
|
||||
...values,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
utils.monitor.getAllPages.refetch();
|
||||
|
||||
navigate({
|
||||
to: '/page/$slug',
|
||||
params: {
|
||||
slug: res.slug,
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<CommonWrapper
|
||||
header={<h1 className="text-xl font-bold">{t('Add Page')}</h1>}
|
||||
>
|
||||
<div className="p-4">
|
||||
<Card>
|
||||
<CardContent className="pt-4">
|
||||
<MonitorStatusPageEditForm
|
||||
saveButtonLabel="Next"
|
||||
isLoading={createPageMutation.isLoading}
|
||||
onFinish={handleSubmit}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</CommonWrapper>
|
||||
);
|
||||
}
|
@ -554,6 +554,9 @@ export const monitorRouter = router({
|
||||
where: {
|
||||
workspaceId,
|
||||
},
|
||||
orderBy: {
|
||||
updatedAt: 'desc',
|
||||
},
|
||||
});
|
||||
}),
|
||||
getPageInfo: publicProcedure
|
||||
|
Loading…
Reference in New Issue
Block a user