import { Autocomplete, AutocompleteOption, Button, Checkbox, Chip, IconButton } from "@mui/joy"; import React, { useState } from "react"; import { toast } from "react-hot-toast"; import useDebounce from "react-use/lib/useDebounce"; import { memoServiceClient } from "@/grpcweb"; import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts"; import { getDateTimeString } from "@/helpers/datetime"; import useCurrentUser from "@/hooks/useCurrentUser"; import { Memo } from "@/types/proto/api/v2/memo_service"; import { useTranslate } from "@/utils/i18n"; import { generateDialog } from "./Dialog"; import Icon from "./Icon"; interface Props extends DialogProps { onConfirm: (memoIdList: number[], embedded?: boolean) => void; } const CreateMemoRelationDialog: React.FC = (props: Props) => { const { destroy, onConfirm } = props; const t = useTranslate(); const user = useCurrentUser(); const [searchText, setSearchText] = useState(""); const [isFetching, setIsFetching] = useState(true); const [fetchedMemos, setFetchedMemos] = useState([]); const [selectedMemos, setSelectedMemos] = useState([]); const [embedded, setEmbedded] = useState(false); const filteredMemos = fetchedMemos.filter((memo) => !selectedMemos.includes(memo)); useDebounce( async () => { setIsFetching(true); try { const filters = [`creator == "${user.name}"`, `row_status == "NORMAL"`]; if (searchText) { filters.push(`content_search == [${JSON.stringify(searchText)}]`); } const { memos } = await memoServiceClient.listMemos({ pageSize: DEFAULT_MEMO_LIMIT, filter: filters.length > 0 ? filters.join(" && ") : undefined, }); setFetchedMemos(memos); } catch (error: any) { console.error(error); toast.error(error.response.data.message); } setIsFetching(false); }, 300, [searchText], ); const getHighlightedContent = (content: string) => { const index = content.toLowerCase().indexOf(searchText.toLowerCase()); if (index === -1) { return content; } let before = content.slice(0, index); if (before.length > 20) { before = "..." + before.slice(before.length - 20); } const highlighted = content.slice(index, index + searchText.length); let after = content.slice(index + searchText.length); if (after.length > 20) { after = after.slice(0, 20) + "..."; } return ( <> {before} {highlighted} {after} ); }; const handleCloseDialog = () => { destroy(); }; const handleConfirmBtnClick = async () => { onConfirm( selectedMemos.map((memo) => memo.id), embedded, ); destroy(); }; return ( <>

{"Add references"}

destroy()}>
setSearchText(value.trim())} getOptionKey={(option) => option.name} getOptionLabel={(option) => option.content} isOptionEqualToValue={(option, value) => option.id === value.id} renderOption={(props, option) => (

{getDateTimeString(option.displayTime)}

{searchText ? getHighlightedContent(option.content) : option.content}

)} renderTags={(memos) => memos.map((memo) => (

{getDateTimeString(memo.displayTime)}

{memo.content}
)) } onChange={(_, value) => setSelectedMemos(value)} />
setEmbedded(e.target.checked)} />
); }; function showCreateMemoRelationDialog(props: Omit) { generateDialog( { className: "create-memo-relation-dialog", dialogName: "create-memo-relation-dialog", }, CreateMemoRelationDialog, props, ); } export default showCreateMemoRelationDialog;