|
|
@@ -1,7 +1,11 @@
|
|
|
-import { Button, List, Tag, Typography } from "antd";
|
|
|
+import { Badge, Button, Card, Checkbox, Select, Space, Typography } from "antd";
|
|
|
+import { DownOutlined, UpOutlined } from "@ant-design/icons";
|
|
|
import { useEffect, useState } from "react";
|
|
|
+
|
|
|
import { get } from "../../request";
|
|
|
-import { ICaseListResponse } from "../api/Dict";
|
|
|
+import { ICaseItem, ICaseListResponse } from "../api/Dict";
|
|
|
+import { CheckboxValueType } from "antd/lib/checkbox/Group";
|
|
|
+import { CheckboxChangeEvent } from "antd/es/checkbox";
|
|
|
const { Text } = Typography;
|
|
|
|
|
|
export interface ICaseListData {
|
|
|
@@ -12,12 +16,37 @@ export interface ICaseListData {
|
|
|
interface IWidget {
|
|
|
word?: string;
|
|
|
lines?: number;
|
|
|
+ onChange?: Function;
|
|
|
}
|
|
|
-const CaseListWidget = ({ word, lines }: IWidget) => {
|
|
|
+const CaseListWidget = ({ word, lines, onChange }: IWidget) => {
|
|
|
const [caseData, setCaseData] = useState<ICaseListData[]>();
|
|
|
- const [first, setFirst] = useState<string>();
|
|
|
- const [count, setCount] = useState<number>();
|
|
|
const [showAll, setShowAll] = useState(lines ? false : true);
|
|
|
+ const [words, setWords] = useState<ICaseItem[]>();
|
|
|
+ const [currWord, setCurrWord] = useState<string>();
|
|
|
+ const [checkedList, setCheckedList] = useState<CheckboxValueType[]>([]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ setCaseData(
|
|
|
+ words
|
|
|
+ ?.find((value) => value.word === currWord)
|
|
|
+ ?.case.sort((a, b) => b.count - a.count)
|
|
|
+ );
|
|
|
+ }, [currWord, words]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (typeof onChange !== "undefined" && checkedList.length > 0) {
|
|
|
+ onChange(checkedList);
|
|
|
+ }
|
|
|
+ }, [checkedList]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (caseData) {
|
|
|
+ setCheckedList(caseData?.map((item) => item.word));
|
|
|
+ } else {
|
|
|
+ setCheckedList([]);
|
|
|
+ }
|
|
|
+ }, [caseData]);
|
|
|
+
|
|
|
useEffect(() => {
|
|
|
if (typeof word === "undefined") {
|
|
|
return;
|
|
|
@@ -25,41 +54,114 @@ const CaseListWidget = ({ word, lines }: IWidget) => {
|
|
|
get<ICaseListResponse>(`/v2/case/${word}`).then((json) => {
|
|
|
console.log("case", json);
|
|
|
if (json.ok && json.data.rows.length > 0) {
|
|
|
+ setWords(json.data.rows);
|
|
|
const first = json.data.rows.sort((a, b) => b.count - a.count)[0];
|
|
|
- setCaseData(first.case.sort((a, b) => b.count - a.count));
|
|
|
- setCount(first.count);
|
|
|
- setFirst(first.word);
|
|
|
+ setCurrWord(first.word);
|
|
|
}
|
|
|
});
|
|
|
}, [word]);
|
|
|
+
|
|
|
+ let checkAll = true;
|
|
|
+ let indeterminate = false;
|
|
|
+ if (caseData && checkedList) {
|
|
|
+ checkAll = caseData?.length === checkedList?.length;
|
|
|
+ indeterminate =
|
|
|
+ checkedList.length > 0 && checkedList.length < caseData.length;
|
|
|
+ }
|
|
|
+
|
|
|
+ const onWordChange = (list: CheckboxValueType[]) => {
|
|
|
+ setCheckedList(list);
|
|
|
+ };
|
|
|
+
|
|
|
+ const onCheckAllChange = (e: CheckboxChangeEvent) => {
|
|
|
+ if (caseData) {
|
|
|
+ setCheckedList(
|
|
|
+ e.target.checked ? caseData?.map((item) => item.word) : []
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ setCheckedList([]);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const showWords = showAll ? caseData : caseData?.slice(0, lines);
|
|
|
return (
|
|
|
<div style={{ padding: 4 }}>
|
|
|
- <List
|
|
|
- header={`${first}:${count}`}
|
|
|
- footer={
|
|
|
+ <Card
|
|
|
+ size="small"
|
|
|
+ extra={
|
|
|
lines ? (
|
|
|
<Button type="link" onClick={() => setShowAll(!showAll)}>
|
|
|
- {showAll ? "折叠" : "展开"}
|
|
|
+ {showAll ? (
|
|
|
+ <Space>
|
|
|
+ {"折叠"}
|
|
|
+ <UpOutlined />
|
|
|
+ </Space>
|
|
|
+ ) : (
|
|
|
+ <Space>
|
|
|
+ {"展开"}
|
|
|
+ <DownOutlined />
|
|
|
+ </Space>
|
|
|
+ )}
|
|
|
</Button>
|
|
|
- ) : undefined
|
|
|
+ ) : (
|
|
|
+ <></>
|
|
|
+ )
|
|
|
}
|
|
|
- size="small"
|
|
|
- dataSource={showAll ? caseData : caseData?.slice(0, lines)}
|
|
|
- renderItem={(item) => (
|
|
|
- <List.Item>
|
|
|
- <div
|
|
|
- style={{
|
|
|
- display: "flex",
|
|
|
- justifyContent: "space-between",
|
|
|
- width: "100%",
|
|
|
- }}
|
|
|
- >
|
|
|
- <Text strong={item.bold > 0 ? true : false}>{item.word}</Text>
|
|
|
- <Tag>{item.count}</Tag>
|
|
|
- </div>
|
|
|
- </List.Item>
|
|
|
- )}
|
|
|
- />
|
|
|
+ title={
|
|
|
+ <Select
|
|
|
+ value={currWord}
|
|
|
+ bordered={false}
|
|
|
+ onChange={(value: string) => {
|
|
|
+ setCurrWord(value);
|
|
|
+ }}
|
|
|
+ options={words?.map((item, id) => {
|
|
|
+ return {
|
|
|
+ label: (
|
|
|
+ <Space>
|
|
|
+ {item.word}
|
|
|
+ <Badge
|
|
|
+ count={item.count}
|
|
|
+ color={"lime"}
|
|
|
+ status="default"
|
|
|
+ size="small"
|
|
|
+ />
|
|
|
+ </Space>
|
|
|
+ ),
|
|
|
+ value: item.word,
|
|
|
+ };
|
|
|
+ })}
|
|
|
+ />
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <Checkbox
|
|
|
+ indeterminate={indeterminate}
|
|
|
+ onChange={onCheckAllChange}
|
|
|
+ checked={checkAll}
|
|
|
+ >
|
|
|
+ Check all
|
|
|
+ </Checkbox>
|
|
|
+ <Checkbox.Group
|
|
|
+ style={{ display: "grid" }}
|
|
|
+ options={showWords?.map((item, id) => {
|
|
|
+ return {
|
|
|
+ label: (
|
|
|
+ <Space>
|
|
|
+ <Text strong={item.bold > 0 ? true : false}>{item.word}</Text>
|
|
|
+ <Badge
|
|
|
+ size="small"
|
|
|
+ count={item.count}
|
|
|
+ overflowCount={9999}
|
|
|
+ status="default"
|
|
|
+ />
|
|
|
+ </Space>
|
|
|
+ ),
|
|
|
+ value: item.word,
|
|
|
+ };
|
|
|
+ })}
|
|
|
+ value={checkedList}
|
|
|
+ onChange={onWordChange}
|
|
|
+ />
|
|
|
+ </Card>
|
|
|
</div>
|
|
|
);
|
|
|
};
|