1 | import React, { useState, useEffect } from "react";
|
2 | import { Popover, Button, message } from "antd";
|
3 | import { CloseCircleOutlined, PlusCircleOutlined } from "@ant-design/icons";
|
4 | import { EditOutlined } from "@ant-design/icons";
|
5 | import styled from "styled-components";
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | export default function RolesChoose({
|
16 | datas = [],
|
17 | value = [],
|
18 | onChange,
|
19 | uniq = false,
|
20 | }) {
|
21 | const [byId, setById] = useState({});
|
22 |
|
23 | useEffect(() => {
|
24 | setById(
|
25 | datas.reduce((p, c) => {
|
26 | p[c._id] = c;
|
27 | return p;
|
28 | }, {})
|
29 | );
|
30 | }, [datas]);
|
31 |
|
32 | const onClickAdd = id => {
|
33 | if (uniq && value.includes(id)) {
|
34 | return message.info("已存在");
|
35 | }
|
36 | onChange([...value, id]);
|
37 | };
|
38 |
|
39 | const onClickRemove = removeId => {
|
40 | onChange(value.filter(id => id !== removeId));
|
41 | };
|
42 |
|
43 | const Content = () => {
|
44 | return (
|
45 | <SBox>
|
46 | {datas.map(item => (
|
47 | <SItem key={item._id} onClick={() => onClickAdd(item._id)}>
|
48 | <PlusCircleOutlined /> <span>{item.name}</span>
|
49 | </SItem>
|
50 | ))}
|
51 | </SBox>
|
52 | );
|
53 | };
|
54 |
|
55 | return (
|
56 | <div>
|
57 | <Popover content={Content} trigger="click">
|
58 | <Button type="link" icon={<EditOutlined />}>
|
59 | 请选择
|
60 | </Button>
|
61 | </Popover>
|
62 | <SRoles>
|
63 | {(value || []).map((id, i) => (
|
64 | <SRoleItem key={id + i} onClick={() => onClickRemove(id)}>
|
65 | <SIndex>{i + 1}.</SIndex> {byId[id]?.name}
|
66 | <span style={{ flex: 1 }} />
|
67 | <CloseCircleOutlined />
|
68 | </SRoleItem>
|
69 | ))}
|
70 | </SRoles>
|
71 | </div>
|
72 | );
|
73 | }
|
74 |
|
75 | const SBox = styled.div`
|
76 | width: 300px;
|
77 | height: 150px;
|
78 | overflow: auto;
|
79 | `;
|
80 |
|
81 | const SItem = styled.div`
|
82 | padding: 6px;
|
83 | cursor: pointer;
|
84 | &:active {
|
85 | color: red;
|
86 | }
|
87 | `;
|
88 |
|
89 | const SRoles = styled.div`
|
90 | background-color: rgb(245, 245, 245);
|
91 | `;
|
92 |
|
93 | const SRoleItem = styled.div`
|
94 | padding: 5px 10px;
|
95 | cursor: pointer;
|
96 | display: flex;
|
97 | align-items: center;
|
98 | border-bottom: 1px solid rgb(240, 240, 240);
|
99 | user-select: none;
|
100 | &:hover {
|
101 | background-color: rgb(240, 240, 240);
|
102 | }
|
103 | `;
|
104 |
|
105 | const SIndex = styled.div`
|
106 | font-size: 15px;
|
107 | margin-right: 7px;
|
108 | `;
|