// Copyright 2023 The Casdoor Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import {DeleteOutlined, EditOutlined, HolderOutlined, PlusOutlined, UsergroupAddOutlined} from "@ant-design/icons"; import {Button, Col, Empty, Row, Space, Tree} from "antd"; import i18next from "i18next"; import moment from "moment/moment"; import React from "react"; import * as GroupBackend from "./backend/GroupBackend"; import * as Setting from "./Setting"; import OrganizationSelect from "./common/select/OrganizationSelect"; import UserListPage from "./UserListPage"; class GroupTreePage extends React.Component { constructor(props) { super(props); this.state = { classes: props, owner: Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, organizationName: props.organizationName !== undefined ? props.organizationName : props.match.params.organizationName, groupName: this.props.match?.params.groupName, treeData: [], selectedKeys: [this.props.match?.params.groupName], }; } UNSAFE_componentWillMount() { this.getTreeData(); } componentDidUpdate(prevProps, prevState, snapshot) { if (this.state.organizationName !== prevState.organizationName) { this.getTreeData(); } if (prevState.treeData !== this.state.treeData) { this.setTreeExpandedKeys(); } } getTreeData() { GroupBackend.getGroups(this.state.organizationName, true).then((res) => { if (res.status === "ok") { this.setState({ treeData: res.data, }); } else { Setting.showMessage("error", res.msg); } }); } setTreeTitle(treeData) { const haveChildren = Array.isArray(treeData.children) && treeData.children.length > 0; const isSelected = this.state.groupName === treeData.key; return { key: treeData.key, title: {treeData.type === "Physical" ? : } {treeData.title} {isSelected && ( { e.currentTarget.style.color = "rgba(89,54,213,0.6)"; }} onMouseLeave={(e) => { e.currentTarget.style.color = "inherit"; }} onMouseDown={(e) => { e.currentTarget.style.color = "rgba(89,54,213,0.4)"; }} onMouseUp={(e) => { e.currentTarget.style.color = "rgba(89,54,213,0.6)"; }} onClick={(e) => { e.stopPropagation(); sessionStorage.setItem("groupTreeUrl", window.location.pathname); this.addGroup(); }} /> { e.currentTarget.style.color = "rgba(89,54,213,0.6)"; }} onMouseLeave={(e) => { e.currentTarget.style.color = "inherit"; }} onMouseDown={(e) => { e.currentTarget.style.color = "rgba(89,54,213,0.4)"; }} onMouseUp={(e) => { e.currentTarget.style.color = "rgba(89,54,213,0.6)"; }} onClick={(e) => { e.stopPropagation(); sessionStorage.setItem("groupTreeUrl", window.location.pathname); this.props.history.push(`/groups/${this.state.organizationName}/${treeData.key}`); }} /> {!haveChildren && { e.currentTarget.style.color = "rgba(89,54,213,0.6)"; }} onMouseLeave={(e) => { e.currentTarget.style.color = "inherit"; }} onMouseDown={(e) => { e.currentTarget.style.color = "rgba(89,54,213,0.4)"; }} onMouseUp={(e) => { e.currentTarget.style.color = "rgba(89,54,213,0.6)"; }} onClick={(e) => { e.stopPropagation(); GroupBackend.deleteGroup({owner: treeData.owner, name: treeData.key}) .then((res) => { if (res.status === "ok") { Setting.showMessage("success", i18next.t("general:Successfully deleted")); this.getTreeData(); } else { Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`); } }) .catch(error => { Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`); }); }} /> } )} , children: haveChildren ? treeData.children.map(i => this.setTreeTitle(i)) : [], }; } setTreeExpandedKeys = () => { const expandedKeys = []; const setExpandedKeys = (nodes) => { for (const node of nodes) { expandedKeys.push(node.key); if (node.children) { setExpandedKeys(node.children); } } }; setExpandedKeys(this.state.treeData); this.setState({ expandedKeys: expandedKeys, }); }; renderTree() { const onSelect = (selectedKeys, info) => { this.setState({ selectedKeys: selectedKeys, groupName: info.node.key, }); this.props.history.push(`/trees/${this.state.organizationName}/${info.node.key}`); }; const onExpand = (expandedKeysValue) => { this.setState({ expandedKeys: expandedKeysValue, }); }; if (this.state.treeData.length === 0) { return ; } const treeData = this.state.treeData.map(i => this.setTreeTitle(i)); return ( ); } renderOrganizationSelect() { if (Setting.isAdminUser(this.props.account)) { return ( { this.setState({ organizationName: value, }); this.props.history.push(`/trees/${value}`); }} /> ); } } newGroup(isRoot) { const randomName = Setting.getRandomName(); return { owner: this.state.organizationName, name: `group_${randomName}`, createdTime: moment().format(), updatedTime: moment().format(), displayName: `New Group - ${randomName}`, type: "Virtual", parentId: isRoot ? this.state.organizationName : this.state.groupName, isTopGroup: isRoot, isEnabled: true, }; } addGroup(isRoot = false) { const newGroup = this.newGroup(isRoot); GroupBackend.addGroup(newGroup) .then((res) => { if (res.status === "ok") { sessionStorage.setItem("groupTreeUrl", window.location.pathname); this.props.history.push({pathname: `/groups/${newGroup.owner}/${newGroup.name}`, mode: "add"}); Setting.showMessage("success", i18next.t("general:Successfully added")); } else { Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`); } }) .catch(error => { Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`); }); } render() { return (
{this.renderOrganizationSelect()} {this.renderTree()}
); } } export default GroupTreePage;