// Copyright 2021 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 React from "react";
import {Link} from "react-router-dom";
import {Button, Space, Switch, Table, Upload} from "antd";
import {UploadOutlined} from "@ant-design/icons";
import moment from "moment";
import * as OrganizationBackend from "./backend/OrganizationBackend";
import * as Setting from "./Setting";
import * as UserBackend from "./backend/UserBackend";
import i18next from "i18next";
import BaseListPage from "./BaseListPage";
import PopconfirmModal from "./common/modal/PopconfirmModal";
import AccountAvatar from "./account/AccountAvatar";
class UserListPage extends BaseListPage {
constructor(props) {
super(props);
this.state = {
...this.state,
organization: null,
};
}
UNSAFE_componentWillMount() {
super.UNSAFE_componentWillMount();
this.getOrganization(this.state.organizationName);
}
componentDidUpdate(prevProps, prevState) {
if (this.props.match.path !== prevProps.match.path || this.props.organizationName !== prevProps.organizationName) {
this.setState({
organizationName: this.props.organizationName ?? this.props.match?.params.organizationName,
});
}
if (this.state.organizationName !== prevState.organizationName) {
this.getOrganization(this.state.organizationName);
}
if (prevProps.groupName !== this.props.groupName || this.state.organizationName !== prevState.organizationName) {
this.fetch({
pagination: this.state.pagination,
searchText: this.state.searchText,
searchedColumn: this.state.searchedColumn,
});
}
}
newUser() {
const randomName = Setting.getRandomName();
const owner = (Setting.isDefaultOrganizationSelected(this.props.account) || this.props.groupName) ? this.state.organizationName : Setting.getRequestOrganization(this.props.account);
return {
owner: owner,
name: `user_${randomName}`,
createdTime: moment().format(),
type: "normal-user",
password: "123",
passwordSalt: "",
displayName: `New User - ${randomName}`,
avatar: this.state.organization.defaultAvatar ?? `${Setting.StaticBaseUrl}/img/casbin.svg`,
email: `${randomName}@example.com`,
phone: Setting.getRandomNumber(),
countryCode: this.state.organization.countryCodes?.length > 0 ? this.state.organization.countryCodes[0] : "",
address: [],
groups: this.props.groupName ? [`${owner}/${this.props.groupName}`] : [],
affiliation: "Example Inc.",
tag: "staff",
region: "",
isAdmin: (owner === "built-in"),
IsForbidden: false,
score: this.state.organization.initScore,
isDeleted: false,
properties: {},
signupApplication: this.state.organization.defaultApplication,
};
}
addUser() {
const newUser = this.newUser();
UserBackend.addUser(newUser)
.then((res) => {
if (res.status === "ok") {
sessionStorage.setItem("userListUrl", window.location.pathname);
this.props.history.push({pathname: `/users/${newUser.owner}/${newUser.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}`);
});
}
deleteUser(i) {
UserBackend.deleteUser(this.state.data[i])
.then((res) => {
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
this.fetch({
pagination: {
...this.state.pagination,
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
},
});
} 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}`);
});
}
removeUserFromGroup(i) {
const user = this.state.data[i];
const group = this.props.groupName;
UserBackend.removeUserFromGroup({groupName: group, owner: user.owner, name: user.name})
.then((res) => {
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully removed"));
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to remove")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
uploadFile(info) {
const {status, response: res} = info.file;
if (status === "done") {
if (res.status === "ok") {
Setting.showMessage("success", "Users uploaded successfully, refreshing the page");
const {pagination} = this.state;
this.fetch({pagination});
} else {
Setting.showMessage("error", `Users failed to upload: ${res.msg}`);
}
} else if (status === "error") {
Setting.showMessage("error", "File failed to upload");
}
}
getOrganization(organizationName) {
OrganizationBackend.getOrganization("admin", organizationName)
.then((res) => {
if (res.status === "ok") {
this.setState({
organization: res.data,
});
} else {
Setting.showMessage("error", `Failed to get organization: ${res.msg}`);
}
});
}
renderUpload() {
const props = {
name: "file",
accept: ".xlsx",
method: "post",
action: `${Setting.ServerUrl}/api/upload-users`,
withCredentials: true,
onChange: (info) => {
this.uploadFile(info);
},
};
return (