Skip to content

Commit

Permalink
Add accountTable.
Browse files Browse the repository at this point in the history
  • Loading branch information
nomeguy committed Jun 17, 2022
1 parent 065b235 commit ae4ab99
Show file tree
Hide file tree
Showing 14 changed files with 566 additions and 130 deletions.
25 changes: 25 additions & 0 deletions object/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,31 @@ func initBuiltInOrganization() bool {
PhonePrefix: "86",
DefaultAvatar: "https://casbin.org/img/casbin.svg",
Tags: []string{},
AccountItems: []*AccountItem{
{Name: "Organization", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
{Name: "ID", Visible: true, ViewRule: "Public", ModifyRule: "Immutable"},
{Name: "Name", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
{Name: "Display name", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
{Name: "Avatar", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
{Name: "User type", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
{Name: "Password", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
{Name: "Email", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
{Name: "Phone", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
{Name: "Country/Region", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
{Name: "Location", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
{Name: "Affiliation", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
{Name: "Title", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
{Name: "Homepage", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
{Name: "Bio", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
{Name: "Tag", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
{Name: "Signup application", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
{Name: "3rd-party logins", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
{Name: "Properties", Visible: false, ViewRule: "Admin", ModifyRule: "Admin"},
{Name: "Is admin", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
{Name: "Is global admin", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
{Name: "Is forbidden", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
{Name: "Is deleted", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
},
}
AddOrganization(organization)
return false
Expand Down
9 changes: 9 additions & 0 deletions object/organization.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ import (
"xorm.io/core"
)

type AccountItem struct {
Name string `json:"name"`
Visible bool `json:"visible"`
ViewRule string `json:"viewRule"`
ModifyRule string `json:"modifyRule"`
}

type Organization struct {
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
Name string `xorm:"varchar(100) notnull pk" json:"name"`
Expand All @@ -36,6 +43,8 @@ type Organization struct {
MasterPassword string `xorm:"varchar(100)" json:"masterPassword"`
EnableSoftDeletion bool `json:"enableSoftDeletion"`
IsProfilePublic bool `json:"isProfilePublic"`

AccountItems []*AccountItem `xorm:"varchar(2000)" json:"accountItems"`
}

func GetOrganizationCount(owner, field, value string) int {
Expand Down
242 changes: 242 additions & 0 deletions web/src/AccountTable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
// Copyright 2022 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 {DownOutlined, DeleteOutlined, UpOutlined} from '@ant-design/icons';
import {Button, Col, Row, Select, Switch, Table, Tooltip} from 'antd';
import * as Setting from "./Setting";
import i18next from "i18next";

const { Option } = Select;

class AccountTable extends React.Component {
constructor(props) {
super(props);
this.state = {
classes: props,
};
}

updateTable(table) {
this.props.onUpdateTable(table);
}

updateField(table, index, key, value) {
table[index][key] = value;
this.updateTable(table);
}

addRow(table) {
let row = {name: Setting.getNewRowNameForTable(table, "Please select an account item"), visible: true};
if (table === undefined) {
table = [];
}
table = Setting.addRow(table, row);
this.updateTable(table);
}

deleteRow(table, i) {
table = Setting.deleteRow(table, i);
this.updateTable(table);
}

upRow(table, i) {
table = Setting.swapRow(table, i - 1, i);
this.updateTable(table);
}

downRow(table, i) {
table = Setting.swapRow(table, i, i + 1);
this.updateTable(table);
}

renderTable(table) {
const columns = [
{
title: i18next.t("provider:Name"),
dataIndex: 'name',
key: 'name',
render: (text, record, index) => {
const items = [
{name: "Organization", displayName: i18next.t("general:Organization")},
{name: "ID", displayName: i18next.t("general:ID")},
{name: "Name", displayName: i18next.t("general:Name")},
{name: "Display name", displayName: i18next.t("general:Display name")},
{name: "Avatar", displayName: i18next.t("general:Avatar")},
{name: "User type", displayName: i18next.t("general:User type")},
{name: "Password", displayName: i18next.t("general:Password")},
{name: "Email", displayName: i18next.t("general:Email")},
{name: "Phone", displayName: i18next.t("general:Phone")},
{name: "Country/Region", displayName: i18next.t("user:Country/Region")},
{name: "Location", displayName: i18next.t("user:Location")},
{name: "Affiliation", displayName: i18next.t("user:Affiliation")},
{name: "Title", displayName: i18next.t("user:Title")},
{name: "Homepage", displayName: i18next.t("user:Homepage")},
{name: "Bio", displayName: i18next.t("user:Bio")},
{name: "Tag", displayName: i18next.t("user:Tag")},
{name: "Signup application", displayName: i18next.t("general:Signup application")},
{name: "3rd-party logins", displayName: i18next.t("user:3rd-party logins")},
{name: "Properties", displayName: i18next.t("user:Properties")},
{name: "Is admin", displayName: i18next.t("user:Is admin")},
{name: "Is global admin", displayName: i18next.t("user:Is global admin")},
{name: "Is forbidden", displayName: i18next.t("user:Is forbidden")},
{name: "Is deleted", displayName: i18next.t("user:Is deleted")},
];

const getItemDisplayName = (text) => {
const item = items.filter(item => item.name === text);
if (item.length === 0) {
return "";
}
return item[0].displayName;
};

return (
<Select virtual={false} style={{width: '100%'}}
value={getItemDisplayName(text)}
onChange={value => {
this.updateField(table, index, 'name', value);
}} >
{
Setting.getDeduplicatedArray(items, table, "name").map((item, index) => <Option key={index} value={item.name}>{item.displayName}</Option>)
}
</Select>
)
}
},
{
title: i18next.t("provider:visible"),
dataIndex: 'visible',
key: 'visible',
width: '120px',
render: (text, record, index) => {
return (
<Switch checked={text} onChange={checked => {
this.updateField(table, index, 'visible', checked);
}} />
)
}
},
{
title: i18next.t("organization:viewRule"),
dataIndex: 'viewRule',
key: 'viewRule',
width: '155px',
render: (text, record, index) => {
if (!record.visible) {
return null;
}

let options = [
{id: 'Public', name: 'Public'},
{id: 'Self', name: 'Self'},
{id: 'Admin', name: 'Admin'},
];

return (
<Select virtual={false} style={{width: '100%'}} value={text} onChange={(value => {
this.updateField(table, index, 'viewRule', value);
})}>
{
options.map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
)
}
},
{
title: i18next.t("organization:modifyRule"),
dataIndex: 'modifyRule',
key: 'modifyRule',
width: '155px',
render: (text, record, index) => {
if (!record.visible) {
return null;
}

let options;
if (record.viewRule === "Admin") {
options = [
{id: 'Admin', name: 'Admin'},
{id: 'Immutable', name: 'Immutable'},
];
} else {
options = [
{id: 'Self', name: 'Self'},
{id: 'Admin', name: 'Admin'},
{id: 'Immutable', name: 'Immutable'},
];
}

return (
<Select virtual={false} style={{width: '100%'}} value={text} onChange={(value => {
this.updateField(table, index, 'modifyRule', value);
})}>
{
options.map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
)
}
},
{
title: i18next.t("general:Action"),
key: 'action',
width: '100px',
render: (text, record, index) => {
return (
<div>
<Tooltip placement="bottomLeft" title={i18next.t("general:Up")}>
<Button style={{marginRight: "5px"}} disabled={index === 0} icon={<UpOutlined />} size="small" onClick={() => this.upRow(table, index)} />
</Tooltip>
<Tooltip placement="topLeft" title={i18next.t("general:Down")}>
<Button style={{marginRight: "5px"}} disabled={index === table.length - 1} icon={<DownOutlined />} size="small" onClick={() => this.downRow(table, index)} />
</Tooltip>
<Tooltip placement="topLeft" title={i18next.t("general:Delete")}>
<Button icon={<DeleteOutlined />} size="small" onClick={() => this.deleteRow(table, index)} />
</Tooltip>
</div>
);
}
},
];

return (
<Table scroll={{x: 'max-content'}} rowKey="name" columns={columns} dataSource={table} size="middle" bordered pagination={false}
title={() => (
<div>
{this.props.title}&nbsp;&nbsp;&nbsp;&nbsp;
<Button style={{marginRight: "5px"}} type="primary" size="small" onClick={() => this.addRow(table)}>{i18next.t("general:Add")}</Button>
</div>
)}
/>
);
}

render() {
return (
<div>
<Row style={{marginTop: '20px'}} >
<Col span={24}>
{
this.renderTable(this.props.table)
}
</Col>
</Row>
</div>
)
}
}

export default AccountTable;
13 changes: 13 additions & 0 deletions web/src/OrganizationEditPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import * as Setting from "./Setting";
import i18next from "i18next";
import {LinkOutlined} from "@ant-design/icons";
import LdapTable from "./LdapTable";
import AccountTable from "./AccountTable";

const { Option } = Select;

Expand Down Expand Up @@ -250,6 +251,18 @@ class OrganizationEditPage extends React.Component {
}} />
</Col>
</Row>
<Row style={{marginTop: '20px'}} >
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("organization:Account items"), i18next.t("organization:Account items - Tooltip"))} :
</Col>
<Col span={22} >
<AccountTable
title={i18next.t("organization:Account items")}
table={this.state.organization.accountItems}
onUpdateTable={(value) => { this.updateOrganizationField('accountItems', value)}}
/>
</Col>
</Row>
<Row style={{marginTop: '20px'}}>
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:LDAPs"), i18next.t("general:LDAPs - Tooltip"))} :
Expand Down
25 changes: 25 additions & 0 deletions web/src/OrganizationListPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,31 @@ class OrganizationListPage extends BaseListPage {
masterPassword: "",
enableSoftDeletion: false,
isProfilePublic: true,
accountItems: [
{name: "Organization", visible: true, viewRule: "Public", modifyRule: "Admin"},
{name: "ID", visible: true, viewRule: "Public", modifyRule: "Immutable"},
{name: "Name", visible: true, viewRule: "Public", modifyRule: "Admin"},
{name: "Display name", visible: true, viewRule: "Public", modifyRule: "Self"},
{name: "Avatar", visible: true, viewRule: "Public", modifyRule: "Self"},
{name: "User type", visible: true, viewRule: "Public", modifyRule: "Admin"},
{name: "Password", visible: true, viewRule: "Self", modifyRule: "Self"},
{name: "Email", visible: true, viewRule: "Public", modifyRule: "Self"},
{name: "Phone", visible: true, viewRule: "Public", modifyRule: "Self"},
{name: "Country/Region", visible: true, viewRule: "Public", modifyRule: "Self"},
{name: "Location", visible: true, viewRule: "Public", modifyRule: "Self"},
{name: "Affiliation", visible: true, viewRule: "Public", modifyRule: "Self"},
{name: "Title", visible: true, viewRule: "Public", modifyRule: "Self"},
{name: "Homepage", visible: true, viewRule: "Public", modifyRule: "Self"},
{name: "Bio", visible: true, viewRule: "Public", modifyRule: "Self"},
{name: "Tag", visible: true, viewRule: "Public", modifyRule: "Admin"},
{name: "Signup application", visible: true, viewRule: "Public", modifyRule: "Admin"},
{name: "3rd-party logins", visible: true, viewRule: "Self", modifyRule: "Self"},
{name: "Properties", visible: false, viewRule: "Admin", modifyRule: "Admin"},
{name: "Is admin", visible: true, viewRule: "Admin", modifyRule: "Admin"},
{name: "Is global admin", visible: true, viewRule: "Admin", modifyRule: "Admin"},
{name: "Is forbidden", visible: true, viewRule: "Admin", modifyRule: "Admin"},
{name: "Is deleted", visible: true, viewRule: "Admin", modifyRule: "Admin"},
],
}
}

Expand Down
2 changes: 1 addition & 1 deletion web/src/SignupTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class SignupTable extends React.Component {
}
},
{
title: i18next.t("provider:rule"),
title: i18next.t("application:rule"),
dataIndex: 'rule',
key: 'rule',
width: '155px',
Expand Down
Loading

0 comments on commit ae4ab99

Please sign in to comment.