feat: add status page basic info change
This commit is contained in:
parent
b324536726
commit
c68d27a6d3
@ -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>
|
||||||
);
|
);
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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}
|
||||||
/>
|
/>
|
||||||
|
@ -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,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user