feat: add duplicate feature for monitor

This commit is contained in:
moonrailgun 2024-07-27 22:11:08 +08:00
parent 05c358b2e5
commit 827cf07c2a
3 changed files with 65 additions and 8 deletions

View File

@ -121,7 +121,7 @@ export const MonitorInfoEditor: React.FC<MonitorInfoEditorProps> = React.memo(
</Form.Item> </Form.Item>
<Button type="primary" htmlType="submit" loading={isLoading}> <Button type="primary" htmlType="submit" loading={isLoading}>
{t('Save')} {isEdit ? t('Save') : t('Create')}
</Button> </Button>
</Form> </Form>
</div> </div>

View File

@ -5,10 +5,20 @@ import { ErrorTip } from '@/components/ErrorTip';
import { Loading } from '@/components/Loading'; import { Loading } from '@/components/Loading';
import { NotFoundTip } from '@/components/NotFoundTip'; import { NotFoundTip } from '@/components/NotFoundTip';
import { MonitorInfo } from '@/components/monitor/MonitorInfo'; import { MonitorInfo } from '@/components/monitor/MonitorInfo';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { ScrollArea } from '@/components/ui/scroll-area'; import { ScrollArea } from '@/components/ui/scroll-area';
import { useCurrentWorkspaceId } from '@/store/user'; import { useCurrentWorkspaceId } from '@/store/user';
import { routeAuthBeforeLoad } from '@/utils/route'; import { routeAuthBeforeLoad } from '@/utils/route';
import { createFileRoute } from '@tanstack/react-router'; import { useTranslation } from '@i18next-toolkit/react';
import { createFileRoute, useNavigate } from '@tanstack/react-router';
import { pick } from 'lodash-es';
import { LuCopy, LuMoreVertical } from 'react-icons/lu';
export const Route = createFileRoute('/monitor/$monitorId/')({ export const Route = createFileRoute('/monitor/$monitorId/')({
beforeLoad: routeAuthBeforeLoad, beforeLoad: routeAuthBeforeLoad,
@ -22,6 +32,8 @@ function MonitorDetailComponent() {
workspaceId, workspaceId,
monitorId, monitorId,
}); });
const { t } = useTranslation();
const navigate = useNavigate();
if (!monitorId) { if (!monitorId) {
return <ErrorTip />; return <ErrorTip />;
@ -36,7 +48,44 @@ function MonitorDetailComponent() {
} }
return ( return (
<CommonWrapper header={<CommonHeader title={monitor.name} />}> <CommonWrapper
header={
<CommonHeader
title={monitor.name}
actions={
<DropdownMenu>
<DropdownMenuTrigger asChild={true} className="cursor-pointer">
<Button variant="outline" size="icon" className="shrink-0">
<LuMoreVertical />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem
onClick={() =>
navigate({
to: '/monitor/add',
search: pick(monitor, [
'name',
'type',
'notifications',
'interval',
'maxRetries',
'trendingMode',
'payload',
]),
})
}
>
<LuCopy className="mr-2" />
{t('Duplicate')}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
}
/>
}
>
<ScrollArea className="h-full overflow-hidden p-4"> <ScrollArea className="h-full overflow-hidden p-4">
<MonitorInfo monitorId={monitor.id} /> <MonitorInfo monitorId={monitor.id} />
</ScrollArea> </ScrollArea>

View File

@ -1,10 +1,8 @@
import { createFileRoute, useNavigate } from '@tanstack/react-router'; import { createFileRoute, useNavigate } from '@tanstack/react-router';
import { t, useTranslation } from '@i18next-toolkit/react'; import { useTranslation } from '@i18next-toolkit/react';
import { Button } from '@/components/ui/button';
import { useEvent } from '@/hooks/useEvent'; import { useEvent } from '@/hooks/useEvent';
import { useCurrentWorkspaceId } from '@/store/user'; import { useCurrentWorkspaceId } from '@/store/user';
import { trpc } from '@/api/trpc'; import { Card, CardContent } from '@/components/ui/card';
import { Card, CardContent, CardFooter } from '@/components/ui/card';
import { CommonWrapper } from '@/components/CommonWrapper'; import { CommonWrapper } from '@/components/CommonWrapper';
import { import {
MonitorInfoEditor, MonitorInfoEditor,
@ -14,6 +12,8 @@ import { routeAuthBeforeLoad } from '@/utils/route';
import { useMonitorUpsert } from '@/api/model/monitor'; import { useMonitorUpsert } from '@/api/model/monitor';
import { CommonHeader } from '@/components/CommonHeader'; import { CommonHeader } from '@/components/CommonHeader';
import { ScrollArea } from '@/components/ui/scroll-area'; import { ScrollArea } from '@/components/ui/scroll-area';
import { useMemo } from 'react';
import { isEmpty } from 'lodash-es';
export const Route = createFileRoute('/monitor/add')({ export const Route = createFileRoute('/monitor/add')({
beforeLoad: routeAuthBeforeLoad, beforeLoad: routeAuthBeforeLoad,
@ -25,6 +25,11 @@ function MonitorAddComponent() {
const workspaceId = useCurrentWorkspaceId(); const workspaceId = useCurrentWorkspaceId();
const navigate = useNavigate(); const navigate = useNavigate();
const mutation = useMonitorUpsert(); const mutation = useMonitorUpsert();
const search = Route.useSearch();
const initialValues = useMemo(
() => (isEmpty(search) ? undefined : (search as MonitorInfoEditorValues)),
[]
);
const handleSubmit = useEvent(async (values: MonitorInfoEditorValues) => { const handleSubmit = useEvent(async (values: MonitorInfoEditorValues) => {
const res = await mutation.mutateAsync({ const res = await mutation.mutateAsync({
@ -45,7 +50,10 @@ function MonitorAddComponent() {
<ScrollArea className="h-full overflow-hidden p-4"> <ScrollArea className="h-full overflow-hidden p-4">
<Card> <Card>
<CardContent className="pt-4"> <CardContent className="pt-4">
<MonitorInfoEditor onSave={handleSubmit} /> <MonitorInfoEditor
initialValues={initialValues}
onSave={handleSubmit}
/>
</CardContent> </CardContent>
</Card> </Card>
</ScrollArea> </ScrollArea>