refactor: change edit style and logic, create new MonitorPicker component

This commit is contained in:
moonrailgun 2024-09-16 17:08:58 +08:00
parent ed2141af22
commit 72a1e7b024
5 changed files with 116 additions and 49 deletions

View File

@ -1,12 +1,23 @@
import { Select, SelectProps } from 'antd'; import { Select as AntdSelect, SelectProps as AntdSelectProps } from 'antd';
import React from 'react'; import React from 'react';
import { trpc } from '../../api/trpc'; import { trpc } from '../../api/trpc';
import { useCurrentWorkspaceId } from '../../store/user'; import { useCurrentWorkspaceId } from '../../store/user';
import { ColorTag } from '../ColorTag'; import { ColorTag } from '../ColorTag';
import { useTranslation } from '@i18next-toolkit/react'; import { useTranslation } from '@i18next-toolkit/react';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '../ui/select';
import { PropsOf } from '@/utils/type';
interface MonitorPickerProps extends SelectProps<string> {} interface MonitorPickerOldProps extends AntdSelectProps<string> {}
export const MonitorPicker: React.FC<MonitorPickerProps> = React.memo( /**
* @deprecated please use MonitorPicker
*/
export const MonitorPickerOld: React.FC<MonitorPickerOldProps> = React.memo(
(props) => { (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
const workspaceId = useCurrentWorkspaceId(); const workspaceId = useCurrentWorkspaceId();
@ -15,13 +26,40 @@ export const MonitorPicker: React.FC<MonitorPickerProps> = React.memo(
}); });
return ( return (
<Select placeholder={t('Select monitor')} {...props}> <AntdSelect placeholder={t('Select monitor')} {...props}>
{allMonitor.map((m) => ( {allMonitor.map((m) => (
<Select.Option key={m.id} value={m.id}> <AntdSelect.Option key={m.id} value={m.id}>
<ColorTag label={m.type} /> <ColorTag label={m.type} />
{m.name} {m.name}
</Select.Option> </AntdSelect.Option>
))} ))}
</AntdSelect>
);
}
);
MonitorPickerOld.displayName = 'MonitorPickerOld';
export const MonitorPicker: React.FC<PropsOf<typeof Select>> = React.memo(
(props) => {
const { t } = useTranslation();
const workspaceId = useCurrentWorkspaceId();
const { data: allMonitor = [] } = trpc.monitor.all.useQuery({
workspaceId,
});
return (
<Select {...props}>
<SelectTrigger>
<SelectValue placeholder={t('Select monitor')} />
</SelectTrigger>
<SelectContent>
{allMonitor.map((m) => (
<SelectItem key={m.id} value={m.id}>
<ColorTag label={m.type} />
{m.name}
</SelectItem>
))}
</SelectContent>
</Select> </Select>
); );
} }

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { MonitorPicker } from '../MonitorPicker'; import { MonitorPicker, MonitorPickerOld } from '../MonitorPicker';
import { useTranslation } from '@i18next-toolkit/react'; import { useTranslation } from '@i18next-toolkit/react';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { LuMinusCircle, LuPlus } from 'react-icons/lu'; import { LuMinusCircle, LuPlus } from 'react-icons/lu';
@ -23,6 +23,17 @@ import { domainRegex, slugRegex } from '@tianji/shared';
import { useElementSize } from '@/hooks/useResizeObserver'; import { useElementSize } from '@/hooks/useResizeObserver';
import { Switch } from '@/components/ui/switch'; import { Switch } from '@/components/ui/switch';
import { Separator } from '@/components/ui/separator'; import { Separator } from '@/components/ui/separator';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { ColorTag } from '@/components/ColorTag';
import { Collapsible, CollapsibleContent } from '@/components/ui/collapsible';
import { CollapsibleTrigger } from '@radix-ui/react-collapsible';
import { CaretSortIcon } from '@radix-ui/react-icons';
const Text = Typography.Text; const Text = Typography.Text;
@ -135,42 +146,50 @@ export const MonitorStatusPageEditForm: React.FC<MonitorStatusPageEditFormProps>
)} )}
/> />
{/* Description */} <Collapsible>
<FormField <CollapsibleTrigger className="flex w-full items-center justify-between">
control={form.control} <span className="text-sm">{t('Advanced')}</span>
name="description" <CaretSortIcon className="h-4 w-4" />
render={({ field }) => ( </CollapsibleTrigger>
<FormItem> <CollapsibleContent>
<FormLabel optional={true}>{t('Description')}</FormLabel> {/* Description */}
<FormControl> <FormField
<MarkdownEditorFormItem {...field} /> control={form.control}
</FormControl> name="description"
<FormMessage /> render={({ field }) => (
</FormItem> <FormItem>
)} <FormLabel optional={true}>{t('Description')}</FormLabel>
/> <FormControl>
<MarkdownEditorFormItem {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{/* Custom Domain */} {/* Custom Domain */}
<FormField <FormField
control={form.control} control={form.control}
name="domain" name="domain"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel optional={true}>{t('Custom Domain')}</FormLabel> <FormLabel optional={true}>{t('Custom Domain')}</FormLabel>
<FormControl> <FormControl>
<Input {...field} /> <Input {...field} />
</FormControl> </FormControl>
<FormDescription> <FormDescription>
<div> <div>
{t( {t(
'You can config your status page in your own domain, for example: status.example.com' 'You can config your status page in your own domain, for example: status.example.com'
)} )}
</div> </div>
</FormDescription> </FormDescription>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> />
</CollapsibleContent>
</Collapsible>
{/* MonitorList */} {/* MonitorList */}
<FormField <FormField
@ -181,13 +200,19 @@ export const MonitorStatusPageEditForm: React.FC<MonitorStatusPageEditFormProps>
<FormLabel>{t('Monitor List')}</FormLabel> <FormLabel>{t('Monitor List')}</FormLabel>
{fields.map((field, i) => ( {fields.map((field, i) => (
<> <>
{i !== 0 && <Separator className="my-0.5" />} {i !== 0 && <Separator />}
<div key={field.key} className="mb-2 flex flex-col gap-1"> <div key={field.key} className="mb-2 flex flex-col gap-2">
<Controller <Controller
control={form.control} control={form.control}
name={`monitorList.${i}.id`} name={`monitorList.${i}.id`}
render={({ field }) => <MonitorPicker {...field} />} render={({ field }) => (
<MonitorPicker
{...field}
value={field.value}
onValueChange={field.onChange}
/>
)}
/> />
<div className="flex flex-1 items-center"> <div className="flex flex-1 items-center">
@ -214,6 +239,7 @@ export const MonitorStatusPageEditForm: React.FC<MonitorStatusPageEditFormProps>
</div> </div>
</> </>
))} ))}
<FormMessage /> <FormMessage />
<Button <Button

View File

@ -6,7 +6,7 @@ import { useCurrentWorkspaceId } from '../../store/user';
import { ErrorTip } from '../ErrorTip'; import { ErrorTip } from '../ErrorTip';
import { Loading } from '../Loading'; import { Loading } from '../Loading';
import { NoWorkspaceTip } from '../NoWorkspaceTip'; import { NoWorkspaceTip } from '../NoWorkspaceTip';
import { MonitorPicker } from '../monitor/MonitorPicker'; import { MonitorPickerOld } from '../monitor/MonitorPicker';
import { import {
defaultErrorHandler, defaultErrorHandler,
defaultSuccessHandler, defaultSuccessHandler,
@ -141,7 +141,7 @@ export const WebsiteConfig: React.FC<{ websiteId: string }> = React.memo(
'You can bind a monitor which will display health status in website overview' 'You can bind a monitor which will display health status in website overview'
)} )}
> >
<MonitorPicker size="large" allowClear={true} /> <MonitorPickerOld size="large" allowClear={true} />
</Form.Item> </Form.Item>
<Form.Item> <Form.Item>

View File

@ -7,7 +7,7 @@ import { useCurrentWorkspaceId } from '../../store/user';
import { ErrorTip } from '../ErrorTip'; import { ErrorTip } from '../ErrorTip';
import { Loading } from '../Loading'; import { Loading } from '../Loading';
import { NoWorkspaceTip } from '../NoWorkspaceTip'; import { NoWorkspaceTip } from '../NoWorkspaceTip';
import { MonitorPicker } from '../monitor/MonitorPicker'; import { MonitorPickerOld } from '../monitor/MonitorPicker';
import { import {
defaultErrorHandler, defaultErrorHandler,
defaultSuccessHandler, defaultSuccessHandler,
@ -126,7 +126,7 @@ export const WebsiteInfo: React.FC = React.memo(() => {
'You can bind a monitor which will display health status in website overview' 'You can bind a monitor which will display health status in website overview'
)} )}
> >
<MonitorPicker size="large" allowClear={true} /> <MonitorPickerOld size="large" allowClear={true} />
</Form.Item> </Form.Item>
<Form.Item> <Form.Item>

3
src/client/utils/type.ts Normal file
View File

@ -0,0 +1,3 @@
import React from 'react';
export type PropsOf<T> = T extends React.ComponentType<infer P> ? P : never;