import { useManagerStore } from './store'; import { useEffect, useMemo, useState } from 'react'; import { useShallow } from 'zustand/shallow'; import { ManagerProvider } from './Provider'; import { ChevronDown, ChevronLeft, X, Edit, Plus, Search, Trash, Menu as MenuIcon, MenuSquare } from 'lucide-react'; import dayjs from 'dayjs'; import { useTranslation } from 'react-i18next'; import { EditMark as EditMarkComponent } from './edit/Edit'; import { toast } from 'react-toastify'; import clsx from 'clsx'; import { Controller, useForm } from 'react-hook-form'; import { Button, TextField, InputAdornment, IconButton, Menu, MenuItem } from '@mui/material'; import { MarkType } from '@kevisual/query-mark'; type ManagerProps = { showSearch?: boolean; showAdd?: boolean; onClick?: (data?: any) => void; markType?: MarkType; showSelect?: boolean; }; export const Manager = (props: ManagerProps) => { const { showSearch = true, showAdd = false, onClick, showSelect = true } = props; const { control } = useForm({ defaultValues: { search: '' } }); const { list, init, setCurrentMarkId, currentMarkId, markData, deleteMark, getMark, setMarkData, pagination, setPagination, getList, search, setSearch } = useManagerStore( useShallow((state) => { return { list: state.list, init: state.init, markData: state.markData, currentMarkId: state.currentMarkId, setCurrentMarkId: state.setCurrentMarkId, deleteMark: state.deleteMark, getMark: state.getMark, setMarkData: state.setMarkData, pagination: state.pagination, setPagination: state.setPagination, search: state.search, setSearch: state.setSearch, getList: state.getList, }; }), ); const { t } = useTranslation(); const [anchorEl, setAnchorEl] = useState(null); const open = Boolean(anchorEl); const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); }; const handleClose = () => { setAnchorEl(null); }; const handleMenuItemClick = (option: string) => { handleClose(); console.log('option', option); init(option as any); }; useEffect(() => { const url = new URL(window.location.href); let markType = url.searchParams.get('markType') || ''; if (!markType && props.markType) { markType = props.markType; } init((markType as any) || 'md'); }, []); useEffect(() => { if (search) { getList(); } else if (pagination.current > 1) { getList(); } }, [pagination.current, search]); const onEditMark = async (markId: string) => { setCurrentMarkId(markId); const res = await getMark(markId); console.log('mark', res); if (res.code === 200) { setMarkData(res.data!); } }; const onDeleteMark = async (markId: string) => { const res = await deleteMark(markId); if (res.code === 200) { toast.success(t('deleteMarkSuccess')); } }; console.log('list', list.length, pagination.total); return (
( setSearch(field.value)} /> ), onKeyDown: (event) => { if (event.key === 'Enter') { setSearch(field.value); } }, }, }} /> )} />
{showSelect && ( <> { console.log('e', e); }}> {['md', 'mdx', 'wallnote', 'excalidraw'].map((option) => ( { handleMenuItemClick(option); }}> {option} ))} )} {markData && ( )}
{list.map((item, index) => { const isCurrent = item.id === currentMarkId; return (
{ onClick?.(item); }}>
{item.title}
{t('markType')}: {item.markType}
{t('summary')}: {item.summary}
{t('tags')}: {item.tags?.join?.(', ')}
{t('description')}: {item.description}
{ window.open(item.link, '_blank'); }}> {t('link')}: {item.link}
{t('createdAt')}: {dayjs(item.createdAt).format('YYYY-MM-DD HH:mm:ss')}
{t('updatedAt')}: {dayjs(item.updatedAt).format('YYYY-MM-DD HH:mm:ss')}
); })}
{list.length < pagination.total && ( )}
); }; export const EditMark = () => { const { markData } = useManagerStore( useShallow((state) => { return { markData: state.markData, }; }), ); const mark = markData; if (!mark) { return null; } if (mark) { return ; } return
; }; export const LayoutMain = (props: { children?: React.ReactNode; expandChildren?: React.ReactNode }) => { const [openMenu, setOpenMenu] = useState(false); const getDocumentHeight = () => { return document.documentElement.scrollHeight; }; const markData = useManagerStore((state) => state.markData); const isEdit = !!markData; const hasExpandChildren = !!props.expandChildren; const style = useMemo(() => { if (!hasExpandChildren || openMenu) { return {}; } return { top: getDocumentHeight() / 2 + 10, }; }, [getDocumentHeight, hasExpandChildren, openMenu]); return (
{props.children}
{(!props.expandChildren || isEdit) && ( )} {props.expandChildren &&
{props.expandChildren}
}
); }; export type AppProps = { /** * 标记类型, wallnote md excalidraw */ markType?: MarkType; /** * 是否显示搜索框 */ showSearch?: boolean; /** * 是否显示添加按钮 */ showAdd?: boolean; /** * 点击事件 */ onClick?: (data?: any) => void; /** * 管理器id, 存储到store的id */ managerId?: string; children?: React.ReactNode; showSelect?: boolean; }; export const App = (props: AppProps) => { return ( ); };