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>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'mx-auto overflow-auto px-4 py-8',
|
'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 WebsiteImport } from './routes/website'
|
||||||
import { Route as TelemetryImport } from './routes/telemetry'
|
import { Route as TelemetryImport } from './routes/telemetry'
|
||||||
import { Route as RegisterImport } from './routes/register'
|
import { Route as RegisterImport } from './routes/register'
|
||||||
|
import { Route as PageImport } from './routes/page'
|
||||||
import { Route as MonitorImport } from './routes/monitor'
|
import { Route as MonitorImport } from './routes/monitor'
|
||||||
import { Route as LoginImport } from './routes/login'
|
import { Route as LoginImport } from './routes/login'
|
||||||
import { Route as DashboardImport } from './routes/dashboard'
|
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 WebsiteWebsiteIdImport } from './routes/website/$websiteId'
|
||||||
import { Route as TelemetryAddImport } from './routes/telemetry/add'
|
import { Route as TelemetryAddImport } from './routes/telemetry/add'
|
||||||
import { Route as TelemetryTelemetryIdImport } from './routes/telemetry/$telemetryId'
|
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 MonitorAddImport } from './routes/monitor/add'
|
||||||
import { Route as MonitorMonitorIdImport } from './routes/monitor/$monitorId'
|
import { Route as MonitorMonitorIdImport } from './routes/monitor/$monitorId'
|
||||||
|
|
||||||
@ -42,6 +45,11 @@ const RegisterRoute = RegisterImport.update({
|
|||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
} as any)
|
} as any)
|
||||||
|
|
||||||
|
const PageRoute = PageImport.update({
|
||||||
|
path: '/page',
|
||||||
|
getParentRoute: () => rootRoute,
|
||||||
|
} as any)
|
||||||
|
|
||||||
const MonitorRoute = MonitorImport.update({
|
const MonitorRoute = MonitorImport.update({
|
||||||
path: '/monitor',
|
path: '/monitor',
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
@ -82,6 +90,16 @@ const TelemetryTelemetryIdRoute = TelemetryTelemetryIdImport.update({
|
|||||||
getParentRoute: () => TelemetryRoute,
|
getParentRoute: () => TelemetryRoute,
|
||||||
} as any)
|
} 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({
|
const MonitorAddRoute = MonitorAddImport.update({
|
||||||
path: '/add',
|
path: '/add',
|
||||||
getParentRoute: () => MonitorRoute,
|
getParentRoute: () => MonitorRoute,
|
||||||
@ -112,6 +130,10 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof MonitorImport
|
preLoaderRoute: typeof MonitorImport
|
||||||
parentRoute: typeof rootRoute
|
parentRoute: typeof rootRoute
|
||||||
}
|
}
|
||||||
|
'/page': {
|
||||||
|
preLoaderRoute: typeof PageImport
|
||||||
|
parentRoute: typeof rootRoute
|
||||||
|
}
|
||||||
'/register': {
|
'/register': {
|
||||||
preLoaderRoute: typeof RegisterImport
|
preLoaderRoute: typeof RegisterImport
|
||||||
parentRoute: typeof rootRoute
|
parentRoute: typeof rootRoute
|
||||||
@ -132,6 +154,14 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof MonitorAddImport
|
preLoaderRoute: typeof MonitorAddImport
|
||||||
parentRoute: typeof MonitorImport
|
parentRoute: typeof MonitorImport
|
||||||
}
|
}
|
||||||
|
'/page/$slug': {
|
||||||
|
preLoaderRoute: typeof PageSlugImport
|
||||||
|
parentRoute: typeof PageImport
|
||||||
|
}
|
||||||
|
'/page/add': {
|
||||||
|
preLoaderRoute: typeof PageAddImport
|
||||||
|
parentRoute: typeof PageImport
|
||||||
|
}
|
||||||
'/telemetry/$telemetryId': {
|
'/telemetry/$telemetryId': {
|
||||||
preLoaderRoute: typeof TelemetryTelemetryIdImport
|
preLoaderRoute: typeof TelemetryTelemetryIdImport
|
||||||
parentRoute: typeof TelemetryImport
|
parentRoute: typeof TelemetryImport
|
||||||
@ -158,6 +188,7 @@ export const routeTree = rootRoute.addChildren([
|
|||||||
DashboardRoute,
|
DashboardRoute,
|
||||||
LoginRoute,
|
LoginRoute,
|
||||||
MonitorRoute.addChildren([MonitorMonitorIdRoute, MonitorAddRoute]),
|
MonitorRoute.addChildren([MonitorMonitorIdRoute, MonitorAddRoute]),
|
||||||
|
PageRoute.addChildren([PageSlugRoute, PageAddRoute]),
|
||||||
RegisterRoute,
|
RegisterRoute,
|
||||||
TelemetryRoute.addChildren([TelemetryTelemetryIdRoute, TelemetryAddRoute]),
|
TelemetryRoute.addChildren([TelemetryTelemetryIdRoute, TelemetryAddRoute]),
|
||||||
WebsiteRoute.addChildren([WebsiteWebsiteIdRoute, WebsiteAddRoute]),
|
WebsiteRoute.addChildren([WebsiteWebsiteIdRoute, WebsiteAddRoute]),
|
||||||
|
@ -6,8 +6,6 @@ interface RouterContext {
|
|||||||
userInfo: any;
|
userInfo: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultLayout: [number, number, number] = [265, 440, 655];
|
|
||||||
|
|
||||||
export const Route = createRootRouteWithContext<RouterContext>()({
|
export const Route = createRootRouteWithContext<RouterContext>()({
|
||||||
component: () => {
|
component: () => {
|
||||||
return (
|
return (
|
||||||
|
@ -21,9 +21,9 @@ export const Route = createFileRoute('/monitor/add')({
|
|||||||
function MonitorAddComponent() {
|
function MonitorAddComponent() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const workspaceId = useCurrentWorkspaceId();
|
const workspaceId = useCurrentWorkspaceId();
|
||||||
const addWebsiteMutation = trpc.website.add.useMutation();
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const mutation = useMonitorUpsert();
|
const mutation = useMonitorUpsert();
|
||||||
|
const utils = trpc.useUtils();
|
||||||
|
|
||||||
const handleSubmit = useEvent(async (values: MonitorInfoEditorValues) => {
|
const handleSubmit = useEvent(async (values: MonitorInfoEditorValues) => {
|
||||||
const res = await mutation.mutateAsync({
|
const res = await mutation.mutateAsync({
|
||||||
@ -31,6 +31,8 @@ function MonitorAddComponent() {
|
|||||||
workspaceId,
|
workspaceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
utils.monitor.all.refetch();
|
||||||
|
|
||||||
navigate({
|
navigate({
|
||||||
to: '/monitor/$monitorId',
|
to: '/monitor/$monitorId',
|
||||||
params: {
|
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: {
|
where: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
},
|
},
|
||||||
|
orderBy: {
|
||||||
|
updatedAt: 'desc',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
getPageInfo: publicProcedure
|
getPageInfo: publicProcedure
|
||||||
|
Loading…
Reference in New Issue
Block a user