refactor: add new editable text component which allow to change group title

This commit is contained in:
moonrailgun 2024-09-16 21:50:22 +08:00
parent 946ecaf9f9
commit e323e104e0
3 changed files with 72 additions and 36 deletions

View File

@ -1,38 +1,46 @@
import { Input } from 'antd';
import clsx from 'clsx';
import React, { useState } from 'react';
import { useWatch } from '../hooks/useWatch';
import { Input } from './ui/input';
import { useEvent } from '@/hooks/useEvent';
import { cn } from '@/utils/style';
interface EditableTextProps {
className?: string;
enable?: boolean;
defaultValue: string;
onSave: (text: string) => void;
}
export const EditableText: React.FC<EditableTextProps> = React.memo((props) => {
const [text, setText] = useState(props.defaultValue);
const enable = props.enable ?? true;
const [editing, setEditing] = useState(false);
const inputRef = React.useRef<HTMLInputElement>(null);
useWatch([props.defaultValue], () => {
setText(props.defaultValue);
});
const handleClick = useEvent(() => {
setEditing(true);
});
return (
<>
{enable ? (
<div className={cn('cursor-text', props.className)}>
{editing ? (
<Input
className={clsx(
props.className,
'rounded-none border-0 p-0 !shadow-none outline-0'
)}
ref={inputRef}
autoFocus={true}
type="text"
className="h-[1.5em] border-none p-0 text-base shadow-none focus-visible:ring-0"
value={text}
onChange={(e) => setText(e.target.value)}
onBlur={(e) => props.onSave(e.target.value)}
onBlur={() => {
setEditing(false);
props.onSave(text);
}}
/>
) : (
<span className={props.className}>{text}</span>
<span onClick={handleClick}>{text}</span>
)}
</>
</div>
);
});
EditableText.displayName = 'EditableText';

View File

@ -12,6 +12,7 @@ import { Separator } from '@/components/ui/separator';
import { MonitorPicker } from '../MonitorPicker';
import { Switch } from '@/components/ui/switch';
import { set } from 'lodash-es';
import { EditableText } from '@/components/EditableText';
export const leafItemSchema = z.object({
key: z.string(),
@ -90,6 +91,24 @@ export const MonitorStatusPageServiceList: React.FC<MonitorStatusPageServiceList
props.onChange(newList);
});
const handleChangeGroupTitle = useEvent(
(groupKey: string, title: string) => {
const index = props.value.findIndex((item) => item.key === groupKey);
if (index === -1) {
return;
}
const newList = [...props.value];
if (!('children' in newList[index])) {
return;
}
newList[index].title = title;
props.onChange(newList);
}
);
const handleDeleteItem = useEvent((groupKey: string, itemKey: string) => {
const newList = [...props.value];
const groupIndex = newList.findIndex((item) => item.key === groupKey);
@ -145,11 +164,14 @@ export const MonitorStatusPageServiceList: React.FC<MonitorStatusPageServiceList
onChange={props.onChange}
renderGroup={(group, children, level) => (
<div>
<div className={cn('flex items-center gap-2')}>
<span>{group.title}</span>
{level > 0 && (
<>
<div className={cn('flex items-center gap-2')}>
<EditableText
className="flex-1 overflow-hidden text-ellipsis text-nowrap"
defaultValue={group.title}
onSave={(text) => handleChangeGroupTitle(group.key, text)}
/>
<Button
className="h-6 w-6"
variant="outline"
@ -167,9 +189,9 @@ export const MonitorStatusPageServiceList: React.FC<MonitorStatusPageServiceList
Icon={LuTrash}
onClick={() => handleDeleteGroup(group.key)}
/>
</>
)}
</div>
)}
<div
className={cn(level > 0 && 'border-l-4 border-gray-600 p-2')}
>

View File

@ -5,6 +5,7 @@ import {
MonitorStatusPageServiceList,
} from '@/components/monitor/StatusPage/ServiceList';
import { useState } from 'react';
import { EditableText } from '@/components/EditableText';
export const Route = createFileRoute('/playground')({
beforeLoad: () => {
@ -45,6 +46,11 @@ function PageComponent() {
return (
<div>
<EditableText
defaultValue="fooooooooo"
onSave={() => console.log('save')}
/>
<MonitorStatusPageServiceList value={list} onChange={setList} />
</div>
);