feat: add organization context select box for admin (#2013)

* feat: organization as context

* feat: organization as context with backend filtration

* Update app.conf

* update app.conf and hide organization select for mobile.

---------

Co-authored-by: dplynsky <dplynsky@ptsecurity.com>
Co-authored-by: hsluoyz <hsluoyz@qq.com>
This commit is contained in:
Denis Plynskiy
2023-06-29 20:32:34 +03:00
committed by GitHub
parent 91cb5f393a
commit eee9b8b9fe
46 changed files with 207 additions and 76 deletions

View File

@@ -37,6 +37,7 @@ func (c *ApiController) GetOrganizations() {
value := c.Input().Get("value") value := c.Input().Get("value")
sortField := c.Input().Get("sortField") sortField := c.Input().Get("sortField")
sortOrder := c.Input().Get("sortOrder") sortOrder := c.Input().Get("sortOrder")
organizationName := c.Input().Get("organizationName")
isGlobalAdmin := c.IsGlobalAdmin() isGlobalAdmin := c.IsGlobalAdmin()
if limit == "" || page == "" { if limit == "" || page == "" {
@@ -73,7 +74,7 @@ func (c *ApiController) GetOrganizations() {
} }
paginator := pagination.SetPaginator(c.Ctx, limit, count) paginator := pagination.SetPaginator(c.Ctx, limit, count)
organizations, err := object.GetMaskedOrganizations(object.GetPaginationOrganizations(owner, paginator.Offset(), limit, field, value, sortField, sortOrder)) organizations, err := object.GetMaskedOrganizations(object.GetPaginationOrganizations(owner, organizationName, paginator.Offset(), limit, field, value, sortField, sortOrder))
if err != nil { if err != nil {
c.ResponseError(err.Error()) c.ResponseError(err.Error())
return return

View File

@@ -42,6 +42,7 @@ func (c *ApiController) GetRecords() {
value := c.Input().Get("value") value := c.Input().Get("value")
sortField := c.Input().Get("sortField") sortField := c.Input().Get("sortField")
sortOrder := c.Input().Get("sortOrder") sortOrder := c.Input().Get("sortOrder")
organizationName := c.Input().Get("organizationName")
if limit == "" || page == "" { if limit == "" || page == "" {
records, err := object.GetRecords() records, err := object.GetRecords()
@@ -54,6 +55,9 @@ func (c *ApiController) GetRecords() {
c.ServeJSON() c.ServeJSON()
} else { } else {
limit := util.ParseInt(limit) limit := util.ParseInt(limit)
if c.IsGlobalAdmin() && organizationName != "" {
organization = organizationName
}
filterRecord := &object.Record{Organization: organization} filterRecord := &object.Record{Organization: organization}
count, err := object.GetRecordCount(field, value, filterRecord) count, err := object.GetRecordCount(field, value, filterRecord)
if err != nil { if err != nil {

View File

@@ -104,10 +104,15 @@ func GetOrganizationsByFields(owner string, fields ...string) ([]*Organization,
return organizations, nil return organizations, nil
} }
func GetPaginationOrganizations(owner string, offset, limit int, field, value, sortField, sortOrder string) ([]*Organization, error) { func GetPaginationOrganizations(owner string, name string, offset, limit int, field, value, sortField, sortOrder string) ([]*Organization, error) {
organizations := []*Organization{} organizations := []*Organization{}
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder) session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
err := session.Find(&organizations) var err error
if name != "" {
err = session.Find(&organizations, &Organization{Name: name})
} else {
err = session.Find(&organizations)
}
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -25,8 +25,9 @@ import PopconfirmModal from "./common/modal/PopconfirmModal";
class AdapterListPage extends BaseListPage { class AdapterListPage extends BaseListPage {
newAdapter() { newAdapter() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const owner = Setting.getRequestOrganization(this.props.account);
return { return {
owner: this.props.account.owner, owner: owner,
name: `adapter_${randomName}`, name: `adapter_${randomName}`,
createdTime: moment().format(), createdTime: moment().format(),
type: "Database", type: "Database",
@@ -87,7 +88,7 @@ class AdapterListPage extends BaseListPage {
...this.getColumnSearchProps("name"), ...this.getColumnSearchProps("name"),
render: (text, record, index) => { render: (text, record, index) => {
return ( return (
<Link to={`/adapters/${record.organization}/${text}`}> <Link to={`/adapters/${record.owner}/${text}`}>
{text} {text}
</Link> </Link>
); );
@@ -246,7 +247,7 @@ class AdapterListPage extends BaseListPage {
value = params.type; value = params.type;
} }
this.setState({loading: true}); this.setState({loading: true});
AdapterBackend.getAdapters(Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) AdapterBackend.getAdapters(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -86,6 +86,7 @@ import {withTranslation} from "react-i18next";
import ThemeSelect from "./common/select/ThemeSelect"; import ThemeSelect from "./common/select/ThemeSelect";
import SessionListPage from "./SessionListPage"; import SessionListPage from "./SessionListPage";
import MfaSetupPage from "./auth/MfaSetupPage"; import MfaSetupPage from "./auth/MfaSetupPage";
import OrganizationSelect from "./common/select/OrganizationSelect";
const {Header, Footer, Content} = Layout; const {Header, Footer, Content} = Layout;
@@ -398,6 +399,17 @@ class App extends Component {
}); });
}} /> }} />
<LanguageSelect languages={this.state.account.organization.languages} /> <LanguageSelect languages={this.state.account.organization.languages} />
{Setting.isAdminUser(this.state.account) && !Setting.isMobile() &&
<OrganizationSelect
initValue={Setting.getOrganization()}
withAll={true}
style={{width: "15%", display: "flex"}}
onChange={(value) => {
Setting.setOrganization(value);
}}
className="select-box"
/>
}
</React.Fragment> </React.Fragment>
); );
} }
@@ -611,7 +623,7 @@ class App extends Component {
<Route exact path="/subscriptions" render={(props) => this.renderLoginIfNotLoggedIn(<SubscriptionListPage account={this.state.account} {...props} />)} /> <Route exact path="/subscriptions" render={(props) => this.renderLoginIfNotLoggedIn(<SubscriptionListPage account={this.state.account} {...props} />)} />
<Route exact path="/subscriptions/:organizationName/:subscriptionName" render={(props) => this.renderLoginIfNotLoggedIn(<SubscriptionEditPage account={this.state.account} {...props} />)} /> <Route exact path="/subscriptions/:organizationName/:subscriptionName" render={(props) => this.renderLoginIfNotLoggedIn(<SubscriptionEditPage account={this.state.account} {...props} />)} />
<Route exact path="/products" render={(props) => this.renderLoginIfNotLoggedIn(<ProductListPage account={this.state.account} {...props} />)} /> <Route exact path="/products" render={(props) => this.renderLoginIfNotLoggedIn(<ProductListPage account={this.state.account} {...props} />)} />
<Route exact path="/products/:productName" render={(props) => this.renderLoginIfNotLoggedIn(<ProductEditPage account={this.state.account} {...props} />)} /> <Route exact path="/products/:organizationName/:productName" render={(props) => this.renderLoginIfNotLoggedIn(<ProductEditPage account={this.state.account} {...props} />)} />
<Route exact path="/products/:productName/buy" render={(props) => this.renderLoginIfNotLoggedIn(<ProductBuyPage account={this.state.account} {...props} />)} /> <Route exact path="/products/:productName/buy" render={(props) => this.renderLoginIfNotLoggedIn(<ProductBuyPage account={this.state.account} {...props} />)} />
<Route exact path="/payments" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentListPage account={this.state.account} {...props} />)} /> <Route exact path="/payments" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentListPage account={this.state.account} {...props} />)} />
<Route exact path="/payments/:paymentName" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentEditPage account={this.state.account} {...props} />)} /> <Route exact path="/payments/:paymentName" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentEditPage account={this.state.account} {...props} />)} />
@@ -651,6 +663,7 @@ class App extends Component {
this.props.history.push(key); this.props.history.push(key);
} }
}; };
const menuStyleRight = Setting.isAdminUser(this.state.account) && !Setting.isMobile() ? "calc(15% + 260px)" : "260px";
return ( return (
<Layout id="parent-area"> <Layout id="parent-area">
<Header style={{padding: "0", marginBottom: "3px", backgroundColor: this.state.themeAlgorithm.includes("dark") ? "black" : "white"}}> <Header style={{padding: "0", marginBottom: "3px", backgroundColor: this.state.themeAlgorithm.includes("dark") ? "black" : "white"}}>
@@ -680,7 +693,7 @@ class App extends Component {
items={this.getMenuItems()} items={this.getMenuItems()}
mode={"horizontal"} mode={"horizontal"}
selectedKeys={[this.state.selectedMenuKey]} selectedKeys={[this.state.selectedMenuKey]}
style={{position: "absolute", left: "145px", right: "260px"}} style={{position: "absolute", left: "145px", right: menuStyleRight}}
/> />
} }
{ {

View File

@@ -28,18 +28,13 @@ class ApplicationListPage extends BaseListPage {
super(props); super(props);
} }
componentDidMount() {
this.setState({
organizationName: this.props.account.owner,
});
}
newApplication() { newApplication() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const organizationName = Setting.getRequestOrganization(this.props.account);
return { return {
owner: "admin", // this.props.account.applicationName, owner: "admin", // this.props.account.applicationName,
name: `application_${randomName}`, name: `application_${randomName}`,
organization: this.state.organizationName, organization: organizationName,
createdTime: moment().format(), createdTime: moment().format(),
displayName: `New Application - ${randomName}`, displayName: `New Application - ${randomName}`,
logo: `${Setting.StaticBaseUrl}/img/casdoor-logo_1185x256.png`, logo: `${Setting.StaticBaseUrl}/img/casdoor-logo_1185x256.png`,
@@ -273,8 +268,8 @@ class ApplicationListPage extends BaseListPage {
const field = params.searchedColumn, value = params.searchText; const field = params.searchedColumn, value = params.searchText;
const sortField = params.sortField, sortOrder = params.sortOrder; const sortField = params.sortField, sortOrder = params.sortOrder;
this.setState({loading: true}); this.setState({loading: true});
(Setting.isAdminUser(this.props.account) ? ApplicationBackend.getApplications("admin", params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) : (Setting.isDefaultOrganizationSelected(this.props.account) ? ApplicationBackend.getApplications("admin", params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) :
ApplicationBackend.getApplicationsByOrganization("admin", this.props.account.organization.name, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)) ApplicationBackend.getApplicationsByOrganization("admin", Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder))
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -17,6 +17,9 @@ import {Button, Input, Result, Space} from "antd";
import {SearchOutlined} from "@ant-design/icons"; import {SearchOutlined} from "@ant-design/icons";
import Highlighter from "react-highlight-words"; import Highlighter from "react-highlight-words";
import i18next from "i18next"; import i18next from "i18next";
import * as Setting from "./Setting";
import * as Conf from "./Conf";
import {DefaultOrganization} from "./Conf";
class BaseListPage extends React.Component { class BaseListPage extends React.Component {
constructor(props) { constructor(props) {
@@ -35,6 +38,22 @@ class BaseListPage extends React.Component {
}; };
} }
handleOrganizationChange = () => {
const {pagination} = this.state;
this.fetch({pagination});
};
componentDidMount() {
window.addEventListener(Conf.StorageOrganizationChangedEvent, this.handleOrganizationChange);
if (!Setting.isAdminUser(this.props.account)) {
Setting.setOrganization(DefaultOrganization);
}
}
componentWillUnmount() {
window.removeEventListener(Conf.StorageOrganizationChangedEvent, this.handleOrganizationChange);
}
UNSAFE_componentWillMount() { UNSAFE_componentWillMount() {
const {pagination} = this.state; const {pagination} = this.state;
this.fetch({pagination}); this.fetch({pagination});

View File

@@ -28,6 +28,7 @@ class CertListPage extends BaseListPage {
} }
componentDidMount() { componentDidMount() {
super.componentDidMount();
this.setState({ this.setState({
owner: Setting.isAdminUser(this.props.account) ? "admin" : this.props.account.owner, owner: Setting.isAdminUser(this.props.account) ? "admin" : this.props.account.owner,
}); });
@@ -35,8 +36,9 @@ class CertListPage extends BaseListPage {
newCert() { newCert() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const owner = Setting.isDefaultOrganizationSelected(this.props.account) ? this.state.owner : Setting.getRequestOrganization(this.props.account);
return { return {
owner: this.state.owner, owner: owner,
name: `cert_${randomName}`, name: `cert_${randomName}`,
createdTime: moment().format(), createdTime: moment().format(),
displayName: `New Cert - ${randomName}`, displayName: `New Cert - ${randomName}`,
@@ -236,8 +238,8 @@ class CertListPage extends BaseListPage {
value = params.type; value = params.type;
} }
this.setState({loading: true}); this.setState({loading: true});
(Setting.isAdminUser(this.props.account) ? CertBackend.getGlobleCerts(params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) (Setting.isDefaultOrganizationSelected(this.props.account) ? CertBackend.getGlobleCerts(params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
: CertBackend.getCerts(this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)) : CertBackend.getCerts(Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder))
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -25,12 +25,13 @@ import PopconfirmModal from "./common/modal/PopconfirmModal";
class ChatListPage extends BaseListPage { class ChatListPage extends BaseListPage {
newChat() { newChat() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const organizationName = Setting.getRequestOrganization(this.props.account);
return { return {
owner: "admin", // this.props.account.applicationName, owner: "admin", // this.props.account.applicationName,
name: `chat_${randomName}`, name: `chat_${randomName}`,
createdTime: moment().format(), createdTime: moment().format(),
updatedTime: moment().format(), updatedTime: moment().format(),
organization: this.props.account.owner, organization: organizationName,
displayName: `New Chat - ${randomName}`, displayName: `New Chat - ${randomName}`,
type: "Single", type: "Single",
category: "Chat Category - 1", category: "Chat Category - 1",

View File

@@ -32,3 +32,8 @@ export const ThemeDefault = {
}; };
export const CustomFooter = null; export const CustomFooter = null;
export const DefaultOrganization = "All"; // i18next.t("organization:All")
export const StorageOrganizationChangedEvent = "storageOrganizationChanged";
export const StorageOrganizationsChangedEvent = "storageOrganizationsChanged";

View File

@@ -49,8 +49,9 @@ class GroupListPage extends BaseListPage {
newGroup() { newGroup() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const owner = Setting.getRequestOrganization(this.props.account);
return { return {
owner: this.props.account.owner, owner: owner,
name: `group_${randomName}`, name: `group_${randomName}`,
createdTime: moment().format(), createdTime: moment().format(),
updatedTime: moment().format(), updatedTime: moment().format(),
@@ -251,7 +252,7 @@ class GroupListPage extends BaseListPage {
value = params.type; value = params.type;
} }
this.setState({loading: true}); this.setState({loading: true});
GroupBackend.getGroups(this.state.owner, false, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) GroupBackend.getGroups(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), false, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -25,11 +25,12 @@ import PopconfirmModal from "./common/modal/PopconfirmModal";
class MessageListPage extends BaseListPage { class MessageListPage extends BaseListPage {
newMessage() { newMessage() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const organizationName = Setting.getRequestOrganization(this.props.account);
return { return {
owner: "admin", // this.props.account.messagename, owner: "admin", // this.props.account.messagename,
name: `message_${randomName}`, name: `message_${randomName}`,
createdTime: moment().format(), createdTime: moment().format(),
organization: this.props.account.owner, organization: organizationName,
chat: "", chat: "",
replyTo: "", replyTo: "",
author: `${this.props.account.owner}/${this.props.account.name}`, author: `${this.props.account.owner}/${this.props.account.name}`,
@@ -208,7 +209,7 @@ class MessageListPage extends BaseListPage {
value = params.type; value = params.type;
} }
this.setState({loading: true}); this.setState({loading: true});
MessageBackend.getMessages("admin", Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) MessageBackend.getMessages("admin", Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -40,8 +40,9 @@ m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act`;
class ModelListPage extends BaseListPage { class ModelListPage extends BaseListPage {
newModel() { newModel() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const owner = Setting.getRequestOrganization(this.props.account);
return { return {
owner: this.props.account.owner, owner: owner,
name: `model_${randomName}`, name: `model_${randomName}`,
createdTime: moment().format(), createdTime: moment().format(),
displayName: `New Model - ${randomName}`, displayName: `New Model - ${randomName}`,
@@ -202,7 +203,7 @@ class ModelListPage extends BaseListPage {
value = params.type; value = params.type;
} }
this.setState({loading: true}); this.setState({loading: true});
ModelBackend.getModels(Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) ModelBackend.getModels(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -427,6 +427,7 @@ class OrganizationEditPage extends React.Component {
this.setState({ this.setState({
organizationName: this.state.organization.name, organizationName: this.state.organization.name,
}); });
window.dispatchEvent(new Event(Conf.StorageOrganizationsChangedEvent));
if (willExist) { if (willExist) {
this.props.history.push("/organizations"); this.props.history.push("/organizations");
@@ -448,6 +449,7 @@ class OrganizationEditPage extends React.Component {
.then((res) => { .then((res) => {
if (res.status === "ok") { if (res.status === "ok") {
this.props.history.push("/organizations"); this.props.history.push("/organizations");
window.dispatchEvent(new Event(Conf.StorageOrganizationsChangedEvent));
} else { } else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`); Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
} }

View File

@@ -21,6 +21,7 @@ import * as OrganizationBackend from "./backend/OrganizationBackend";
import i18next from "i18next"; import i18next from "i18next";
import BaseListPage from "./BaseListPage"; import BaseListPage from "./BaseListPage";
import PopconfirmModal from "./common/modal/PopconfirmModal"; import PopconfirmModal from "./common/modal/PopconfirmModal";
import * as Conf from "./Conf";
class OrganizationListPage extends BaseListPage { class OrganizationListPage extends BaseListPage {
newOrganization() { newOrganization() {
@@ -83,6 +84,7 @@ class OrganizationListPage extends BaseListPage {
if (res.status === "ok") { if (res.status === "ok") {
this.props.history.push({pathname: `/organizations/${newOrganization.name}`, mode: "add"}); this.props.history.push({pathname: `/organizations/${newOrganization.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added")); Setting.showMessage("success", i18next.t("general:Successfully added"));
window.dispatchEvent(new Event(Conf.StorageOrganizationsChangedEvent));
} else { } else {
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`); Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
} }
@@ -99,8 +101,11 @@ class OrganizationListPage extends BaseListPage {
Setting.showMessage("success", i18next.t("general:Successfully deleted")); Setting.showMessage("success", i18next.t("general:Successfully deleted"));
this.setState({ this.setState({
data: Setting.deleteRow(this.state.data, i), data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1}, pagination: {
...this.state.pagination,
total: this.state.pagination.total - 1},
}); });
window.dispatchEvent(new Event(Conf.StorageOrganizationsChangedEvent));
} else { } else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`); Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
} }
@@ -275,7 +280,7 @@ class OrganizationListPage extends BaseListPage {
value = params.passwordType; value = params.passwordType;
} }
this.setState({loading: true}); this.setState({loading: true});
OrganizationBackend.getOrganizations("admin", params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) OrganizationBackend.getOrganizations("admin", Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -26,6 +26,7 @@ import PopconfirmModal from "./common/modal/PopconfirmModal";
class PaymentListPage extends BaseListPage { class PaymentListPage extends BaseListPage {
newPayment() { newPayment() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const organizationName = Setting.getRequestOrganization(this.props.account);
return { return {
owner: "admin", owner: "admin",
name: `payment_${randomName}`, name: `payment_${randomName}`,
@@ -33,7 +34,7 @@ class PaymentListPage extends BaseListPage {
displayName: `New Payment - ${randomName}`, displayName: `New Payment - ${randomName}`,
provider: "provider_pay_paypal", provider: "provider_pay_paypal",
type: "PayPal", type: "PayPal",
organization: this.props.account.owner, organization: organizationName,
user: "admin", user: "admin",
productName: "computer-1", productName: "computer-1",
productDisplayName: "A notebook computer", productDisplayName: "A notebook computer",
@@ -265,7 +266,7 @@ class PaymentListPage extends BaseListPage {
value = params.type; value = params.type;
} }
this.setState({loading: true}); this.setState({loading: true});
PaymentBackend.getPayments("admin", Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) PaymentBackend.getPayments("admin", Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -26,8 +26,9 @@ import {UploadOutlined} from "@ant-design/icons";
class PermissionListPage extends BaseListPage { class PermissionListPage extends BaseListPage {
newPermission() { newPermission() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const owner = Setting.getRequestOrganization(this.props.account);
return { return {
owner: this.props.account.owner, owner: owner,
name: `permission_${randomName}`, name: `permission_${randomName}`,
createdTime: moment().format(), createdTime: moment().format(),
displayName: `New Permission - ${randomName}`, displayName: `New Permission - ${randomName}`,
@@ -383,7 +384,7 @@ class PermissionListPage extends BaseListPage {
this.setState({loading: true}); this.setState({loading: true});
const getPermissions = Setting.isLocalAdminUser(this.props.account) ? PermissionBackend.getPermissions : PermissionBackend.getPermissionsBySubmitter; const getPermissions = Setting.isLocalAdminUser(this.props.account) ? PermissionBackend.getPermissions : PermissionBackend.getPermissionsBySubmitter;
getPermissions(Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) getPermissions(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -25,8 +25,7 @@ import PopconfirmModal from "./common/modal/PopconfirmModal";
class PlanListPage extends BaseListPage { class PlanListPage extends BaseListPage {
newPlan() { newPlan() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const owner = (this.state.organizationName !== undefined) ? this.state.organizationName : this.props.account.owner; const owner = Setting.getRequestOrganization(this.props.account);
return { return {
owner: owner, owner: owner,
name: `plan_${randomName}`, name: `plan_${randomName}`,
@@ -219,7 +218,7 @@ class PlanListPage extends BaseListPage {
value = params.type; value = params.type;
} }
this.setState({loading: true}); this.setState({loading: true});
PlanBackend.getPlans(Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) PlanBackend.getPlans(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -25,8 +25,7 @@ import PopconfirmModal from "./common/modal/PopconfirmModal";
class PricingListPage extends BaseListPage { class PricingListPage extends BaseListPage {
newPricing() { newPricing() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const owner = (this.state.organizationName !== undefined) ? this.state.organizationName : this.props.account.owner; const owner = Setting.getRequestOrganization(this.props.account);
return { return {
owner: owner, owner: owner,
name: `pricing_${randomName}`, name: `pricing_${randomName}`,
@@ -188,7 +187,7 @@ class PricingListPage extends BaseListPage {
value = params.type; value = params.type;
} }
this.setState({loading: true}); this.setState({loading: true});
PricingBackend.getPricings(Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) PricingBackend.getPricings(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -20,6 +20,7 @@ import i18next from "i18next";
import {LinkOutlined} from "@ant-design/icons"; import {LinkOutlined} from "@ant-design/icons";
import * as ProviderBackend from "./backend/ProviderBackend"; import * as ProviderBackend from "./backend/ProviderBackend";
import ProductBuyPage from "./ProductBuyPage"; import ProductBuyPage from "./ProductBuyPage";
import * as OrganizationBackend from "./backend/OrganizationBackend";
const {Option} = Select; const {Option} = Select;
@@ -39,11 +40,12 @@ class ProductEditPage extends React.Component {
UNSAFE_componentWillMount() { UNSAFE_componentWillMount() {
this.getProduct(); this.getProduct();
this.getOrganizations();
this.getPaymentProviders(); this.getPaymentProviders();
} }
getProduct() { getProduct() {
ProductBackend.getProduct(this.props.account.owner, this.state.productName) ProductBackend.getProduct(this.state.organizationName, this.state.productName)
.then((product) => { .then((product) => {
if (product === null) { if (product === null) {
this.props.history.push("/404"); this.props.history.push("/404");
@@ -56,6 +58,15 @@ class ProductEditPage extends React.Component {
}); });
} }
getOrganizations() {
OrganizationBackend.getOrganizations("admin")
.then((res) => {
this.setState({
organizations: (res.msg === undefined) ? res : [],
});
});
}
getPaymentProviders() { getPaymentProviders() {
ProviderBackend.getProviders(this.props.account.owner) ProviderBackend.getProviders(this.props.account.owner)
.then((res) => { .then((res) => {
@@ -312,7 +323,7 @@ class ProductEditPage extends React.Component {
if (willExist) { if (willExist) {
this.props.history.push("/products"); this.props.history.push("/products");
} else { } else {
this.props.history.push(`/products/${this.state.product.name}`); this.props.history.push(`/products/${this.state.product.owner}/${this.state.product.name}`);
} }
} else { } else {
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`); Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);

View File

@@ -26,8 +26,9 @@ import PopconfirmModal from "./common/modal/PopconfirmModal";
class ProductListPage extends BaseListPage { class ProductListPage extends BaseListPage {
newProduct() { newProduct() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const owner = Setting.getRequestOrganization(this.props.account);
return { return {
owner: this.props.account.owner, owner: owner,
name: `product_${randomName}`, name: `product_${randomName}`,
createdTime: moment().format(), createdTime: moment().format(),
displayName: `New Product - ${randomName}`, displayName: `New Product - ${randomName}`,
@@ -47,7 +48,7 @@ class ProductListPage extends BaseListPage {
ProductBackend.addProduct(newProduct) ProductBackend.addProduct(newProduct)
.then((res) => { .then((res) => {
if (res.status === "ok") { if (res.status === "ok") {
this.props.history.push({pathname: `/products/${newProduct.name}`, mode: "add"}); this.props.history.push({pathname: `/products/${newProduct.owner}/${newProduct.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added")); Setting.showMessage("success", i18next.t("general:Successfully added"));
} else { } else {
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`); Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
@@ -88,7 +89,7 @@ class ProductListPage extends BaseListPage {
...this.getColumnSearchProps("name"), ...this.getColumnSearchProps("name"),
render: (text, record, index) => { render: (text, record, index) => {
return ( return (
<Link to={`/products/${text}`}> <Link to={`/products/${record.owner}/${text}`}>
{text} {text}
</Link> </Link>
); );
@@ -201,7 +202,7 @@ class ProductListPage extends BaseListPage {
size="small" size="small"
locale={{emptyText: " "}} locale={{emptyText: " "}}
dataSource={providers} dataSource={providers}
renderItem={(providerName, i) => { renderItem={(providerName, record, i) => {
return ( return (
<List.Item> <List.Item>
<div style={{display: "inline"}}> <div style={{display: "inline"}}>
@@ -247,7 +248,7 @@ class ProductListPage extends BaseListPage {
return ( return (
<div> <div>
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} onClick={() => this.props.history.push(`/products/${record.name}/buy`)}>{i18next.t("product:Buy")}</Button> <Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} onClick={() => this.props.history.push(`/products/${record.name}/buy`)}>{i18next.t("product:Buy")}</Button>
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/products/${record.name}`)}>{i18next.t("general:Edit")}</Button> <Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/products/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
<PopconfirmModal <PopconfirmModal
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`} title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
onConfirm={() => this.deleteProduct(index)} onConfirm={() => this.deleteProduct(index)}
@@ -268,7 +269,7 @@ class ProductListPage extends BaseListPage {
return ( return (
<div> <div>
<Table scroll={{x: "max-content"}} columns={columns} dataSource={products} rowKey="name" size="middle" bordered pagination={paginationProps} <Table scroll={{x: "max-content"}} columns={columns} dataSource={products} rowKey={(record) => `${record.owner}/${record.name}`} size="middle" bordered pagination={paginationProps}
title={() => ( title={() => (
<div> <div>
{i18next.t("general:Products")}&nbsp;&nbsp;&nbsp;&nbsp; {i18next.t("general:Products")}&nbsp;&nbsp;&nbsp;&nbsp;
@@ -290,7 +291,7 @@ class ProductListPage extends BaseListPage {
value = params.type; value = params.type;
} }
this.setState({loading: true}); this.setState({loading: true});
ProductBackend.getProducts(Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) ProductBackend.getProducts(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -29,6 +29,7 @@ class ProviderListPage extends BaseListPage {
} }
componentDidMount() { componentDidMount() {
super.componentDidMount();
this.setState({ this.setState({
owner: Setting.isAdminUser(this.props.account) ? "admin" : this.props.account.owner, owner: Setting.isAdminUser(this.props.account) ? "admin" : this.props.account.owner,
}); });
@@ -36,8 +37,9 @@ class ProviderListPage extends BaseListPage {
newProvider() { newProvider() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const owner = Setting.isDefaultOrganizationSelected(this.props.account) ? this.state.owner : Setting.getRequestOrganization();
return { return {
owner: this.state.owner, owner: owner,
name: `provider_${randomName}`, name: `provider_${randomName}`,
createdTime: moment().format(), createdTime: moment().format(),
displayName: `New Provider - ${randomName}`, displayName: `New Provider - ${randomName}`,
@@ -256,8 +258,8 @@ class ProviderListPage extends BaseListPage {
value = params.type; value = params.type;
} }
this.setState({loading: true}); this.setState({loading: true});
(Setting.isAdminUser(this.props.account) ? ProviderBackend.getGlobalProviders(params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) (Setting.isDefaultOrganizationSelected(this.props.account) ? ProviderBackend.getGlobalProviders(params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
: ProviderBackend.getProviders(this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)) : ProviderBackend.getProviders(Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder))
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -209,7 +209,7 @@ class RecordListPage extends BaseListPage {
value = params.method; value = params.method;
} }
this.setState({loading: true}); this.setState({loading: true});
RecordBackend.getRecords(params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) RecordBackend.getRecords(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -309,7 +309,7 @@ class ResourceListPage extends BaseListPage {
const field = params.searchedColumn, value = params.searchText; const field = params.searchedColumn, value = params.searchText;
const sortField = params.sortField, sortOrder = params.sortOrder; const sortField = params.sortField, sortOrder = params.sortOrder;
this.setState({loading: true}); this.setState({loading: true});
ResourceBackend.getResources(Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, this.props.account.name, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) ResourceBackend.getResources(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), this.props.account.name, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -26,8 +26,9 @@ import {UploadOutlined} from "@ant-design/icons";
class RoleListPage extends BaseListPage { class RoleListPage extends BaseListPage {
newRole() { newRole() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const owner = Setting.getRequestOrganization(this.props.account);
return { return {
owner: this.props.account.owner, owner: owner,
name: `role_${randomName}`, name: `role_${randomName}`,
createdTime: moment().format(), createdTime: moment().format(),
displayName: `New Role - ${randomName}`, displayName: `New Role - ${randomName}`,
@@ -258,7 +259,7 @@ class RoleListPage extends BaseListPage {
value = params.type; value = params.type;
} }
this.setState({loading: true}); this.setState({loading: true});
RoleBackend.getRoles(Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) RoleBackend.getRoles(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -22,7 +22,6 @@ import * as SessionBackend from "./backend/SessionBackend";
import PopconfirmModal from "./common/modal/PopconfirmModal"; import PopconfirmModal from "./common/modal/PopconfirmModal";
class SessionListPage extends BaseListPage { class SessionListPage extends BaseListPage {
deleteSession(i) { deleteSession(i) {
SessionBackend.deleteSession(this.state.data[i]) SessionBackend.deleteSession(this.state.data[i])
.then((res) => { .then((res) => {
@@ -134,7 +133,7 @@ class SessionListPage extends BaseListPage {
value = params.contentType; value = params.contentType;
} }
this.setState({loading: true}); this.setState({loading: true});
SessionBackend.getSessions(Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) SessionBackend.getSessions(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -25,6 +25,7 @@ import {Helmet} from "react-helmet";
import * as Conf from "./Conf"; import * as Conf from "./Conf";
import * as phoneNumber from "libphonenumber-js"; import * as phoneNumber from "libphonenumber-js";
import moment from "moment"; import moment from "moment";
import {DefaultOrganization} from "./Conf";
const {Option} = Select; const {Option} = Select;
@@ -1164,3 +1165,27 @@ export function inIframe() {
return true; return true;
} }
} }
export function getOrganization() {
const organization = localStorage.getItem("organization");
return organization !== null ? organization : DefaultOrganization;
}
export function setOrganization(organization) {
localStorage.setItem("organization", organization);
window.dispatchEvent(new Event(Conf.StorageOrganizationChangedEvent));
}
export function getRequestOrganization(account) {
if (isAdminUser(account)) {
return getOrganization() === DefaultOrganization ? account.owner : getOrganization();
}
return account.owner;
}
export function isDefaultOrganizationSelected(account) {
if (isAdminUser(account)) {
return getOrganization() === DefaultOrganization;
}
return false;
}

View File

@@ -25,7 +25,7 @@ import PopconfirmModal from "./common/modal/PopconfirmModal";
class SubscriptionListPage extends BaseListPage { class SubscriptionListPage extends BaseListPage {
newSubscription() { newSubscription() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const owner = (this.state.organizationName !== undefined) ? this.state.organizationName : this.props.account.owner; const owner = Setting.getRequestOrganization(this.props.account);
const defaultDuration = 365; const defaultDuration = 365;
return { return {
@@ -237,7 +237,7 @@ class SubscriptionListPage extends BaseListPage {
value = params.type; value = params.type;
} }
this.setState({loading: true}); this.setState({loading: true});
SubscriptionBackend.getSubscriptions(Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) SubscriptionBackend.getSubscriptions(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -25,11 +25,12 @@ import PopconfirmModal from "./common/modal/PopconfirmModal";
class SyncerListPage extends BaseListPage { class SyncerListPage extends BaseListPage {
newSyncer() { newSyncer() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const organizationName = Setting.getRequestOrganization(this.props.account);
return { return {
owner: "admin", owner: "admin",
name: `syncer_${randomName}`, name: `syncer_${randomName}`,
createdTime: moment().format(), createdTime: moment().format(),
organization: this.props.account.owner, organization: organizationName,
type: "Database", type: "Database",
host: "localhost", host: "localhost",
port: 3306, port: 3306,
@@ -276,7 +277,7 @@ class SyncerListPage extends BaseListPage {
value = params.type; value = params.type;
} }
this.setState({loading: true}); this.setState({loading: true});
SyncerBackend.getSyncers("admin", Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) SyncerBackend.getSyncers("admin", Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -25,12 +25,13 @@ import PopconfirmModal from "./common/modal/PopconfirmModal";
class TokenListPage extends BaseListPage { class TokenListPage extends BaseListPage {
newToken() { newToken() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const organizationName = Setting.getRequestOrganization(this.props.account);
return { return {
owner: "admin", // this.props.account.tokenname, owner: "admin", // this.props.account.tokenname,
name: `token_${randomName}`, name: `token_${randomName}`,
createdTime: moment().format(), createdTime: moment().format(),
application: "app-built-in", application: "app-built-in",
organization: this.props.account.owner, organization: organizationName,
user: "admin", user: "admin",
accessToken: "", accessToken: "",
expiresIn: 7200, expiresIn: 7200,
@@ -240,7 +241,7 @@ class TokenListPage extends BaseListPage {
const field = params.searchedColumn, value = params.searchText; const field = params.searchedColumn, value = params.searchText;
const sortField = params.sortField, sortOrder = params.sortOrder; const sortField = params.sortField, sortOrder = params.sortOrder;
this.setState({loading: true}); this.setState({loading: true});
TokenBackend.getTokens("admin", Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) TokenBackend.getTokens("admin", Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -61,7 +61,7 @@ class UserListPage extends BaseListPage {
newUser() { newUser() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const owner = this.state.organizationName; const owner = Setting.isDefaultOrganizationSelected(this.props.account) ? this.state.organizationName : Setting.getRequestOrganization(this.props.account);
return { return {
owner: owner, owner: owner,
name: `user_${randomName}`, name: `user_${randomName}`,
@@ -456,7 +456,7 @@ class UserListPage extends BaseListPage {
const sortField = params.sortField, sortOrder = params.sortOrder; const sortField = params.sortField, sortOrder = params.sortOrder;
this.setState({loading: true}); this.setState({loading: true});
if (this.props.match?.path === "/users") { if (this.props.match?.path === "/users") {
(Setting.isAdminUser(this.props.account) ? UserBackend.getGlobalUsers(params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) : UserBackend.getUsers(this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)) (Setting.isDefaultOrganizationSelected(this.props.account) ? UserBackend.getGlobalUsers(params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) : UserBackend.getUsers(Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder))
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -25,11 +25,12 @@ import PopconfirmModal from "./common/modal/PopconfirmModal";
class WebhookListPage extends BaseListPage { class WebhookListPage extends BaseListPage {
newWebhook() { newWebhook() {
const randomName = Setting.getRandomName(); const randomName = Setting.getRandomName();
const organizationName = Setting.getRequestOrganization(this.props.account);
return { return {
owner: "admin", // this.props.account.webhookname, owner: "admin", // this.props.account.webhookname,
name: `webhook_${randomName}`, name: `webhook_${randomName}`,
createdTime: moment().format(), createdTime: moment().format(),
organization: this.props.account.owner, organization: organizationName,
url: "https://example.com/callback", url: "https://example.com/callback",
method: "POST", method: "POST",
contentType: "application/json", contentType: "application/json",
@@ -240,7 +241,7 @@ class WebhookListPage extends BaseListPage {
value = params.contentType; value = params.contentType;
} }
this.setState({loading: true}); this.setState({loading: true});
WebhookBackend.getWebhooks("admin", Setting.isAdminUser(this.props.account) ? "" : this.props.account.owner, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder) WebhookBackend.getWebhooks("admin", Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => { .then((res) => {
this.setState({ this.setState({
loading: false, loading: false,

View File

@@ -14,8 +14,8 @@
import * as Setting from "../Setting"; import * as Setting from "../Setting";
export function getOrganizations(owner, page = "", pageSize = "", field = "", value = "", sortField = "", sortOrder = "") { export function getOrganizations(owner, organizationName = "", page = "", pageSize = "", field = "", value = "", sortField = "", sortOrder = "") {
return fetch(`${Setting.ServerUrl}/api/get-organizations?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, { return fetch(`${Setting.ServerUrl}/api/get-organizations?owner=${owner}&organizationName=${organizationName}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
method: "GET", method: "GET",
credentials: "include", credentials: "include",
headers: { headers: {

View File

@@ -14,8 +14,8 @@
import * as Setting from "../Setting"; import * as Setting from "../Setting";
export function getRecords(page, pageSize, field = "", value = "", sortField = "", sortOrder = "") { export function getRecords(organizationName, page, pageSize, field = "", value = "", sortField = "", sortOrder = "") {
return fetch(`${Setting.ServerUrl}/api/get-records?pageSize=${pageSize}&p=${page}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, { return fetch(`${Setting.ServerUrl}/api/get-records?organizationName=${organizationName}&pageSize=${pageSize}&p=${page}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
method: "GET", method: "GET",
credentials: "include", credentials: "include",
headers: { headers: {

View File

@@ -17,9 +17,10 @@ import {Select} from "antd";
import i18next from "i18next"; import i18next from "i18next";
import * as OrganizationBackend from "../../backend/OrganizationBackend"; import * as OrganizationBackend from "../../backend/OrganizationBackend";
import * as Setting from "../../Setting"; import * as Setting from "../../Setting";
import * as Conf from "../../Conf";
function OrganizationSelect(props) { function OrganizationSelect(props) {
const {onChange, initValue, style, onSelect} = props; const {onChange, initValue, style, onSelect, withAll, className} = props;
const [organizations, setOrganizations] = React.useState([]); const [organizations, setOrganizations] = React.useState([]);
const [value, setValue] = React.useState(initValue); const [value, setValue] = React.useState(initValue);
@@ -27,15 +28,20 @@ function OrganizationSelect(props) {
if (props.organizations === undefined) { if (props.organizations === undefined) {
getOrganizations(); getOrganizations();
} }
}, []); window.addEventListener(Conf.StorageOrganizationsChangedEvent, getOrganizations);
return function() {
window.removeEventListener(Conf.StorageOrganizationsChangedEvent, getOrganizations);
};
}, [value]);
const getOrganizations = () => { const getOrganizations = () => {
OrganizationBackend.getOrganizationNames("admin") OrganizationBackend.getOrganizationNames("admin")
.then((res) => { .then((res) => {
if (res.status === "ok") { if (res.status === "ok") {
setOrganizations(res.data); setOrganizations(res.data);
if (initValue === undefined) { const selectedValueExist = res.data.filter(organization => organization.name === value).length > 0;
setValue(organizations.length > 0 ? organizations[0] : ""); if (initValue === undefined || !selectedValueExist) {
handleOnChange(getOrganizationItems().length > 0 ? getOrganizationItems()[0].value : "");
} }
} }
}); });
@@ -46,9 +52,24 @@ function OrganizationSelect(props) {
onChange?.(value); onChange?.(value);
}; };
const getOrganizationItems = () => {
const items = [];
organizations.forEach((organization) => items.push(Setting.getOption(organization.displayName, organization.name)));
if (withAll) {
items.unshift({
label: i18next.t(`organization:${Conf.DefaultOrganization}`),
value: Conf.DefaultOrganization,
});
}
return items;
};
return ( return (
<Select <Select
options={organizations.map((organization) => Setting.getOption(organization.displayName, organization.name))} options={getOrganizationItems()}
virtual={false} virtual={false}
placeholder={i18next.t("login:Please select an organization")} placeholder={i18next.t("login:Please select an organization")}
value={value} value={value}
@@ -56,6 +77,7 @@ function OrganizationSelect(props) {
filterOption={(input, option) => (option?.label ?? "").toLowerCase().includes(input.toLowerCase())} filterOption={(input, option) => (option?.label ?? "").toLowerCase().includes(input.toLowerCase())}
style={style} style={style}
onSelect={onSelect} onSelect={onSelect}
className={className}
> >
</Select> </Select>
); );

View File

@@ -467,6 +467,7 @@
"organization": { "organization": {
"Account items": "Konto Items", "Account items": "Konto Items",
"Account items - Tooltip": "Elemente auf der persönlichen Einstellungsseite", "Account items - Tooltip": "Elemente auf der persönlichen Einstellungsseite",
"All": "Alle",
"Edit Organization": "Organisation bearbeiten", "Edit Organization": "Organisation bearbeiten",
"Follow global theme": "Folge dem globalen Theme", "Follow global theme": "Folge dem globalen Theme",
"Init score": "Initialer Score", "Init score": "Initialer Score",

View File

@@ -467,6 +467,7 @@
"organization": { "organization": {
"Account items": "Account items", "Account items": "Account items",
"Account items - Tooltip": "Items in the Personal settings page", "Account items - Tooltip": "Items in the Personal settings page",
"All": "All",
"Edit Organization": "Edit Organization", "Edit Organization": "Edit Organization",
"Follow global theme": "Follow global theme", "Follow global theme": "Follow global theme",
"Init score": "Init score", "Init score": "Init score",

View File

@@ -467,6 +467,7 @@
"organization": { "organization": {
"Account items": "Elementos de la cuenta", "Account items": "Elementos de la cuenta",
"Account items - Tooltip": "Elementos en la página de configuración personal", "Account items - Tooltip": "Elementos en la página de configuración personal",
"All": "Toda",
"Edit Organization": "Editar organización", "Edit Organization": "Editar organización",
"Follow global theme": "Seguir el tema global", "Follow global theme": "Seguir el tema global",
"Init score": "Puntuación de inicio", "Init score": "Puntuación de inicio",

View File

@@ -467,6 +467,7 @@
"organization": { "organization": {
"Account items": "Articles de compte", "Account items": "Articles de compte",
"Account items - Tooltip": "Éléments de la page des paramètres personnels", "Account items - Tooltip": "Éléments de la page des paramètres personnels",
"All": "Tout",
"Edit Organization": "Modifier l'organisation", "Edit Organization": "Modifier l'organisation",
"Follow global theme": "Suivre le thème global", "Follow global theme": "Suivre le thème global",
"Init score": "Score initial", "Init score": "Score initial",

View File

@@ -467,6 +467,7 @@
"organization": { "organization": {
"Account items": "Item akun", "Account items": "Item akun",
"Account items - Tooltip": "Item pada halaman pengaturan personal", "Account items - Tooltip": "Item pada halaman pengaturan personal",
"All": "Semua",
"Edit Organization": "Edit Organisasi", "Edit Organization": "Edit Organisasi",
"Follow global theme": "Ikuti tema global", "Follow global theme": "Ikuti tema global",
"Init score": "Skor awal", "Init score": "Skor awal",

View File

@@ -467,6 +467,7 @@
"organization": { "organization": {
"Account items": "アカウントアイテム", "Account items": "アカウントアイテム",
"Account items - Tooltip": "個人設定ページのアイテム", "Account items - Tooltip": "個人設定ページのアイテム",
"All": "全て",
"Edit Organization": "組織の編集", "Edit Organization": "組織の編集",
"Follow global theme": "グローバルテーマに従ってください", "Follow global theme": "グローバルテーマに従ってください",
"Init score": "イニットスコア", "Init score": "イニットスコア",

View File

@@ -467,6 +467,7 @@
"organization": { "organization": {
"Account items": "계정 항목들", "Account items": "계정 항목들",
"Account items - Tooltip": "개인 설정 페이지의 항목들", "Account items - Tooltip": "개인 설정 페이지의 항목들",
"All": "모두",
"Edit Organization": "단체 수정", "Edit Organization": "단체 수정",
"Follow global theme": "글로벌 테마를 따르세요", "Follow global theme": "글로벌 테마를 따르세요",
"Init score": "처음 점수", "Init score": "처음 점수",

View File

@@ -467,6 +467,7 @@
"organization": { "organization": {
"Account items": "Itens da Conta", "Account items": "Itens da Conta",
"Account items - Tooltip": "Itens na página de Configurações Pessoais", "Account items - Tooltip": "Itens na página de Configurações Pessoais",
"All": "Todos",
"Edit Organization": "Editar Organização", "Edit Organization": "Editar Organização",
"Follow global theme": "Seguir tema global", "Follow global theme": "Seguir tema global",
"Init score": "Pontuação inicial", "Init score": "Pontuação inicial",

View File

@@ -467,6 +467,7 @@
"organization": { "organization": {
"Account items": "Элементы учета", "Account items": "Элементы учета",
"Account items - Tooltip": "Элементы на странице личных настроек", "Account items - Tooltip": "Элементы на странице личных настроек",
"All": "Все",
"Edit Organization": "Редактировать организацию", "Edit Organization": "Редактировать организацию",
"Follow global theme": "Следуйте глобальной теме", "Follow global theme": "Следуйте глобальной теме",
"Init score": "Начальный балл", "Init score": "Начальный балл",

View File

@@ -467,6 +467,7 @@
"organization": { "organization": {
"Account items": "Mục tài khoản", "Account items": "Mục tài khoản",
"Account items - Tooltip": "Các mục trong trang Cài đặt cá nhân", "Account items - Tooltip": "Các mục trong trang Cài đặt cá nhân",
"All": "Tất cả",
"Edit Organization": "Chỉnh sửa tổ chức", "Edit Organization": "Chỉnh sửa tổ chức",
"Follow global theme": "Theo chủ đề toàn cầu", "Follow global theme": "Theo chủ đề toàn cầu",
"Init score": "Điểm khởi tạo", "Init score": "Điểm khởi tạo",

View File

@@ -467,6 +467,7 @@
"organization": { "organization": {
"Account items": "个人页设置项", "Account items": "个人页设置项",
"Account items - Tooltip": "用户的个人设置页面中可配置的选项", "Account items - Tooltip": "用户的个人设置页面中可配置的选项",
"All": "全部",
"Edit Organization": "编辑组织", "Edit Organization": "编辑组织",
"Follow global theme": "使用全局默认主题", "Follow global theme": "使用全局默认主题",
"Init score": "初始积分", "Init score": "初始积分",