feat: add status page basic info change

This commit is contained in:
moonrailgun 2023-12-16 14:43:17 +08:00
parent b324536726
commit c68d27a6d3
4 changed files with 114 additions and 34 deletions

View File

@ -5,21 +5,28 @@ import { z } from 'zod';
const { Text } = Typography; const { Text } = Typography;
interface Values { export interface MonitorStatusPageEditFormValues {
title: string; title: string;
slug: string; slug: string;
} }
interface MonitorStatusPageEditFormProps { interface MonitorStatusPageEditFormProps {
isLoading?: boolean; isLoading?: boolean;
onFinish: (values: Values) => void; initialValues?: Partial<MonitorStatusPageEditFormValues>;
onFinish: (values: MonitorStatusPageEditFormValues) => void;
onCancel?: () => void;
saveButtonLabel?: string;
} }
export const MonitorStatusPageEditForm: React.FC<MonitorStatusPageEditFormProps> = export const MonitorStatusPageEditForm: React.FC<MonitorStatusPageEditFormProps> =
React.memo((props) => { React.memo((props) => {
return ( return (
<div> <div>
<Form<Values> layout="vertical" onFinish={props.onFinish}> <Form<MonitorStatusPageEditFormValues>
layout="vertical"
initialValues={props.initialValues}
onFinish={props.onFinish}
>
<Form.Item <Form.Item
label="Title" label="Title"
name="title" name="title"
@ -64,9 +71,18 @@ export const MonitorStatusPageEditForm: React.FC<MonitorStatusPageEditFormProps>
> >
<Input addonBefore={`${window.origin}/status/`} /> <Input addonBefore={`${window.origin}/status/`} />
</Form.Item> </Form.Item>
<Button type="primary" htmlType="submit" loading={props.isLoading}>
Next <div className="flex gap-4">
</Button> <Button type="primary" htmlType="submit" loading={props.isLoading}>
{props.saveButtonLabel ?? 'Save'}
</Button>
{props.onCancel && (
<Button htmlType="button" onClick={props.onCancel}>
Cancel
</Button>
)}
</div>
</Form> </Form>
</div> </div>
); );

View File

@ -1,8 +1,15 @@
import { Button, Empty } from 'antd'; import { Button, Empty } from 'antd';
import React from 'react'; import React, { useState } from 'react';
import { trpc } from '../../../api/trpc'; import { trpc } from '../../../api/trpc';
import { MonitorHealthBar } from '../MonitorHealthBar'; import { MonitorHealthBar } from '../MonitorHealthBar';
import { useAllowEdit } from './useAllowEdit'; import { useAllowEdit } from './useAllowEdit';
import {
MonitorStatusPageEditForm,
MonitorStatusPageEditFormValues,
} from './EditForm';
import clsx from 'clsx';
import { useRequest } from '../../../hooks/useRequest';
import { useNavigate } from 'react-router';
interface MonitorStatusPageProps { interface MonitorStatusPageProps {
slug: string; slug: string;
@ -15,41 +22,94 @@ export const MonitorStatusPage: React.FC<MonitorStatusPageProps> = React.memo(
const { data: info } = trpc.monitor.getPageInfo.useQuery({ const { data: info } = trpc.monitor.getPageInfo.useQuery({
slug, slug,
}); });
const editPageMutation = trpc.monitor.editPage.useMutation();
const trpcUtils = trpc.useContext();
const navigate = useNavigate();
const allowEdit = useAllowEdit(info?.workspaceId); const allowEdit = useAllowEdit(info?.workspaceId);
const [editMode, setEditMode] = useState(false);
const monitorList = info?.monitorList ?? []; const monitorList = info?.monitorList ?? [];
const [{ loading }, handleSave] = useRequest(
async (values: MonitorStatusPageEditFormValues) => {
if (!info) {
return;
}
const newPageInfo = await editPageMutation.mutateAsync({
id: info.id,
workspaceId: info.workspaceId,
...values,
});
trpcUtils.monitor.getPageInfo.setData(
{
slug,
},
newPageInfo
);
setEditMode(false);
if (info.slug !== newPageInfo.slug) {
// if slug is changed, should to navigate to new url
navigate(`/status/${newPageInfo.slug}`);
}
}
);
return ( return (
<div className="w-4/5 mx-auto py-8 "> <div className="w-full h-full flex gap-6">
<div className="text-2xl mb-4">{info?.title}</div> {editMode && (
<div className="w-1/3 overflow-auto py-8 px-4 border-r border-gray-600">
<div>{allowEdit && <Button type="primary">Edit</Button>}</div> <MonitorStatusPageEditForm
isLoading={loading}
<div className="text-lg mb-2">Services</div> initialValues={info ?? {}}
onFinish={handleSave}
{info && ( />
<div className="shadow-2xl p-2.5">
{monitorList.length > 0 ? (
monitorList.map((item) => (
<div
key={item.id}
className="hover:bg-black hover:bg-opacity-20"
>
<MonitorHealthBar
workspaceId={info.workspaceId}
monitorId={item.id}
count={40}
size="large"
showCurrentStatus={true}
/>
</div>
))
) : (
<Empty description="No any monitor has been set" />
)}
</div> </div>
)} )}
<div
className={clsx(
'mx-auto py-8 overflow-auto',
!editMode ? 'w-4/5' : 'w-2/3'
)}
>
<div className="text-2xl mb-4">{info?.title}</div>
<div>
{allowEdit && !editMode && (
<Button type="primary" onClick={() => setEditMode(true)}>
Edit
</Button>
)}
</div>
<div className="text-lg mb-2">Services</div>
{info && (
<div className="shadow-2xl p-2.5">
{monitorList.length > 0 ? (
monitorList.map((item) => (
<div
key={item.id}
className="hover:bg-black hover:bg-opacity-20"
>
<MonitorHealthBar
workspaceId={info.workspaceId}
monitorId={item.id}
count={40}
size="large"
showCurrentStatus={true}
/>
</div>
))
) : (
<Empty description="No any monitor has been set" />
)}
</div>
)}
</div>
</div> </div>
); );
} }

View File

@ -32,6 +32,7 @@ export const MonitorPageAdd: React.FC = React.memo(() => {
return ( return (
<div className="px-8 py-4"> <div className="px-8 py-4">
<MonitorStatusPageEditForm <MonitorStatusPageEditForm
saveButtonLabel="Next"
isLoading={createPageMutation.isLoading} isLoading={createPageMutation.isLoading}
onFinish={handleFinish} onFinish={handleFinish}
/> />

View File

@ -523,6 +523,9 @@ export const monitorRouter = router({
const existSlugCount = await prisma.monitorStatusPage.count({ const existSlugCount = await prisma.monitorStatusPage.count({
where: { where: {
slug, slug,
id: {
not: id,
},
}, },
}); });