mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-08 09:01:00 +08:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
af9ae7dbb7 | |||
e266696b32 | |||
e108d26ec7 | |||
349ce7f1d4 | |||
8da50b7893 | |||
2394c8e2b4 | |||
c62983d734 | |||
5948782cdd | |||
674d1619dd | |||
11b8b65ca0 | |||
411d76798d |
4
build.sh
4
build.sh
@ -4,8 +4,8 @@ curl www.google.com -o /dev/null --connect-timeout 5 2 > /dev/null
|
||||
if [ $? == 0 ]
|
||||
then
|
||||
echo "Successfully connected to Google, no need to use Go proxy"
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o server .
|
||||
else
|
||||
echo "Google is blocked, Go proxy is enabled: GOPROXY=https://goproxy.cn,direct"
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOPROXY=https://goproxy.cn,direct go build -ldflags="-w -s" -o server .
|
||||
GO_PROXY_SETTING=$(GOPROXY=https://goproxy.cn,direct)
|
||||
fi
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $GO_PROXY_SETTING go build -ldflags="-w -s" -o server .
|
||||
|
10
conf/conf.go
10
conf/conf.go
@ -28,7 +28,15 @@ func GetConfigString(key string) string {
|
||||
if value, ok := os.LookupEnv(key); ok {
|
||||
return value
|
||||
}
|
||||
return beego.AppConfig.String(key)
|
||||
|
||||
res := beego.AppConfig.String(key)
|
||||
if res == "" {
|
||||
if key == "staticBaseUrl" {
|
||||
res = "https://cdn.casbin.org"
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func GetConfigBool(key string) (bool, error) {
|
||||
|
@ -269,6 +269,11 @@ func (c *ApiController) GetAccount() {
|
||||
return
|
||||
}
|
||||
|
||||
managedAccounts := c.Input().Get("managedAccounts")
|
||||
if managedAccounts == "1" {
|
||||
user = object.ExtendManagedAccountsWithUser(user)
|
||||
}
|
||||
|
||||
organization := object.GetMaskedOrganization(object.GetOrganizationByUser(user))
|
||||
resp := Response{
|
||||
Status: "ok",
|
||||
|
@ -362,3 +362,34 @@ func IsAllowOrigin(origin string) bool {
|
||||
|
||||
return allowOrigin
|
||||
}
|
||||
|
||||
func getApplicationMap(organization string) map[string]*Application {
|
||||
applications := GetApplicationsByOrganizationName("admin", organization)
|
||||
|
||||
applicationMap := make(map[string]*Application)
|
||||
for _, application := range applications {
|
||||
applicationMap[application.Name] = application
|
||||
}
|
||||
|
||||
return applicationMap
|
||||
}
|
||||
|
||||
func ExtendManagedAccountsWithUser(user *User) *User {
|
||||
if user.ManagedAccounts == nil || len(user.ManagedAccounts) == 0 {
|
||||
return user
|
||||
}
|
||||
|
||||
applicationMap := getApplicationMap(user.Owner)
|
||||
|
||||
var managedAccounts []ManagedAccount
|
||||
for _, managedAccount := range user.ManagedAccounts {
|
||||
application := applicationMap[managedAccount.Application]
|
||||
if application != nil {
|
||||
managedAccount.SigninUrl = application.SigninUrl
|
||||
managedAccounts = append(managedAccounts, managedAccount)
|
||||
}
|
||||
}
|
||||
user.ManagedAccounts = managedAccounts
|
||||
|
||||
return user
|
||||
}
|
||||
|
@ -302,6 +302,10 @@ func CheckAccessPermission(userId string, application *Application) (bool, error
|
||||
}
|
||||
|
||||
if isHit {
|
||||
containsAsterisk := ContainsAsterisk(userId, permission.Users)
|
||||
if containsAsterisk {
|
||||
return true, err
|
||||
}
|
||||
enforcer := getEnforcer(permission)
|
||||
allowed, err = enforcer.Enforce(userId, application.Name, "read")
|
||||
break
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/duo-labs/webauthn/webauthn"
|
||||
)
|
||||
@ -39,8 +39,6 @@ func InitDb() {
|
||||
initWebAuthn()
|
||||
}
|
||||
|
||||
var staticBaseUrl = beego.AppConfig.String("staticBaseUrl")
|
||||
|
||||
func initBuiltInOrganization() bool {
|
||||
organization := getOrganization("admin", "built-in")
|
||||
if organization != nil {
|
||||
@ -53,10 +51,10 @@ func initBuiltInOrganization() bool {
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
DisplayName: "Built-in Organization",
|
||||
WebsiteUrl: "https://example.com",
|
||||
Favicon: fmt.Sprintf("%s/img/casbin/favicon.ico", staticBaseUrl),
|
||||
Favicon: fmt.Sprintf("%s/img/casbin/favicon.ico", conf.GetConfigString("staticBaseUrl")),
|
||||
PasswordType: "plain",
|
||||
PhonePrefix: "86",
|
||||
DefaultAvatar: fmt.Sprintf("%s/img/casbin.svg", staticBaseUrl),
|
||||
DefaultAvatar: fmt.Sprintf("%s/img/casbin.svg", conf.GetConfigString("staticBaseUrl")),
|
||||
Tags: []string{},
|
||||
AccountItems: []*AccountItem{
|
||||
{Name: "Organization", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
|
||||
@ -106,7 +104,7 @@ func initBuiltInUser() {
|
||||
Type: "normal-user",
|
||||
Password: "123",
|
||||
DisplayName: "Admin",
|
||||
Avatar: fmt.Sprintf("%s/img/casbin.svg", staticBaseUrl),
|
||||
Avatar: fmt.Sprintf("%s/img/casbin.svg", conf.GetConfigString("staticBaseUrl")),
|
||||
Email: "admin@example.com",
|
||||
Phone: "12345678910",
|
||||
Address: []string{},
|
||||
@ -136,7 +134,7 @@ func initBuiltInApplication() {
|
||||
Name: "app-built-in",
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
DisplayName: "Casdoor",
|
||||
Logo: fmt.Sprintf("%s/img/casdoor-logo_1185x256.png", staticBaseUrl),
|
||||
Logo: fmt.Sprintf("%s/img/casdoor-logo_1185x256.png", conf.GetConfigString("staticBaseUrl")),
|
||||
HomepageUrl: "https://casdoor.org",
|
||||
Organization: "built-in",
|
||||
Cert: "cert-built-in",
|
||||
@ -278,7 +276,7 @@ func initBuiltInPermission() {
|
||||
Name: "permission-built-in",
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
DisplayName: "Built-in Permission",
|
||||
Users: []string{"built-in/admin"},
|
||||
Users: []string{"built-in/*"},
|
||||
Roles: []string{},
|
||||
Domains: []string{},
|
||||
Model: "model-built-in",
|
||||
|
@ -207,3 +207,17 @@ func GetPermissionsBySubmitter(owner string, submitter string) []*Permission {
|
||||
|
||||
return permissions
|
||||
}
|
||||
|
||||
func ContainsAsterisk(userId string, users []string) bool {
|
||||
containsAsterisk := false
|
||||
group, _ := util.GetOwnerAndNameFromId(userId)
|
||||
for _, user := range users {
|
||||
permissionGroup, permissionUserName := util.GetOwnerAndNameFromId(user)
|
||||
if permissionGroup == group && permissionUserName == "*" {
|
||||
containsAsterisk = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return containsAsterisk
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/RobotsAndPencils/go-saml"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/beevik/etree"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
dsig "github.com/russellhaering/goxmldsig"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
@ -181,7 +181,7 @@ func GetSamlMeta(application *Application, host string) (*IdpEntityDescriptor, e
|
||||
block, _ := pem.Decode([]byte(cert.Certificate))
|
||||
certificate := base64.StdEncoding.EncodeToString(block.Bytes)
|
||||
|
||||
origin := beego.AppConfig.String("origin")
|
||||
origin := conf.GetConfigString("origin")
|
||||
originFrontend, originBackend := getOriginFromHost(host)
|
||||
if origin != "" {
|
||||
originBackend = origin
|
||||
|
@ -103,6 +103,11 @@ func uploadFile(provider *Provider, fullFilePath string, fileBuffer *bytes.Buffe
|
||||
}
|
||||
|
||||
func UploadFileSafe(provider *Provider, fullFilePath string, fileBuffer *bytes.Buffer) (string, string, error) {
|
||||
// check fullFilePath is there security issue
|
||||
if strings.Contains(fullFilePath, "..") {
|
||||
return "", "", fmt.Errorf("the fullFilePath: %s is not allowed", fullFilePath)
|
||||
}
|
||||
|
||||
var fileUrl string
|
||||
var objectKey string
|
||||
var err error
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/duo-labs/webauthn/protocol"
|
||||
"github.com/duo-labs/webauthn/webauthn"
|
||||
)
|
||||
@ -27,7 +27,7 @@ import (
|
||||
func GetWebAuthnObject(host string) *webauthn.WebAuthn {
|
||||
var err error
|
||||
|
||||
origin := beego.AppConfig.String("origin")
|
||||
origin := conf.GetConfigString("origin")
|
||||
if origin == "" {
|
||||
_, origin = getOriginFromHost(host)
|
||||
}
|
||||
@ -38,7 +38,7 @@ func GetWebAuthnObject(host string) *webauthn.WebAuthn {
|
||||
}
|
||||
|
||||
webAuthn, err := webauthn.New(&webauthn.Config{
|
||||
RPDisplayName: beego.AppConfig.String("appname"), // Display Name for your site
|
||||
RPDisplayName: conf.GetConfigString("appname"), // Display Name for your site
|
||||
RPID: strings.Split(localUrl.Host, ":")[0], // Generally the domain name for your site, it's ok because splits cannot return empty array
|
||||
RPOrigin: origin, // The origin URL for WebAuthn requests
|
||||
// RPIcon: "https://duo.com/logo.png", // Optional icon URL for your site
|
||||
|
@ -19,14 +19,14 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/context"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
var (
|
||||
oldStaticBaseUrl = "https://cdn.casbin.org"
|
||||
newStaticBaseUrl = beego.AppConfig.String("staticBaseUrl")
|
||||
newStaticBaseUrl = conf.GetConfigString("staticBaseUrl")
|
||||
)
|
||||
|
||||
func StaticFilter(ctx *context.Context) {
|
||||
|
@ -4,12 +4,18 @@
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"parser": "@babel/eslint-parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 12,
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
"requireConfigFile": false,
|
||||
"babelOptions": {
|
||||
"babelrc": false,
|
||||
"configFile": false,
|
||||
"presets": ["@babel/preset-react"]
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
|
6
web/.stylelintrc.json
Normal file
6
web/.stylelintrc.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": [
|
||||
"stylelint-config-standard",
|
||||
"stylelint-config-recommended-less"
|
||||
]
|
||||
}
|
17
web/babel.config.json
Normal file
17
web/babel.config.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": {
|
||||
"edge": "17",
|
||||
"firefox": "60",
|
||||
"chrome": "67",
|
||||
"safari": "11.1"
|
||||
},
|
||||
"useBuiltIns": "usage",
|
||||
"corejs": "3.6.5"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
@ -3,35 +3,35 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.6.2",
|
||||
"@craco/craco": "^6.1.1",
|
||||
"@crowdin/cli": "^3.6.4",
|
||||
"@ant-design/icons": "^4.7.0",
|
||||
"@craco/craco": "^6.4.5",
|
||||
"@crowdin/cli": "^3.7.10",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.3.2",
|
||||
"@testing-library/user-event": "^7.1.2",
|
||||
"antd": "^4.15.5",
|
||||
"antd": "^4.22.8",
|
||||
"codemirror": "^5.61.1",
|
||||
"copy-to-clipboard": "^3.3.1",
|
||||
"core-js": "^3.21.1",
|
||||
"craco-less": "^1.17.1",
|
||||
"core-js": "^3.25.0",
|
||||
"craco-less": "^2.0.0",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"i18n-iso-countries": "^7.0.0",
|
||||
"i18next": "^19.8.9",
|
||||
"moment": "^2.29.1",
|
||||
"qs": "^6.10.2",
|
||||
"react": "^17.0.2",
|
||||
"react": "^18.2.0",
|
||||
"react-app-polyfill": "^3.0.0",
|
||||
"react-codemirror2": "^7.2.1",
|
||||
"react-cropper": "^2.1.7",
|
||||
"react-device-detect": "^1.14.0",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-device-detect": "^2.2.2",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-github-corner": "^2.5.0",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-highlight-words": "^0.17.0",
|
||||
"react-highlight-words": "^0.18.0",
|
||||
"react-i18next": "^11.8.7",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "4.0.3",
|
||||
"react-router-dom": "^5.3.3",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-social-login-buttons": "^3.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
@ -41,7 +41,8 @@
|
||||
"eject": "craco eject",
|
||||
"crowdin:sync": "crowdin upload && crowdin download",
|
||||
"preinstall": "node -e \"if (process.env.npm_execpath.indexOf('yarn') === -1) throw new Error('Use yarn for installing: https://yarnpkg.com/en/docs/install')\"",
|
||||
"fix": "eslint --fix ."
|
||||
"fix": "eslint --fix src/**/*.{js,jsx,ts,tsx}",
|
||||
"lint:css": "stylelint src/**/*.{css,less} --fix"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
@ -61,15 +62,24 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.18.13",
|
||||
"@babel/eslint-parser": "^7.18.9",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^7.11.0",
|
||||
"eslint-plugin-react": "^7.30.1",
|
||||
"eslint": "8.22.0",
|
||||
"eslint-plugin-react": "^7.31.1",
|
||||
"husky": "^4.3.8",
|
||||
"lint-staged": "^13.0.3"
|
||||
"lint-staged": "^13.0.3",
|
||||
"stylelint": "^14.11.0",
|
||||
"stylelint-config-recommended-less": "^1.0.4",
|
||||
"stylelint-config-standard": "^28.0.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.{js,jsx,css,sass,ts,tsx}": [
|
||||
"yarn fix"
|
||||
"src/**/*.{css,less}": [
|
||||
"stylelint --fix"
|
||||
],
|
||||
"src/**/*.{js,jsx,ts,tsx}": [
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"husky": {
|
||||
|
@ -595,7 +595,7 @@ class App extends Component {
|
||||
// theme="dark"
|
||||
mode={(Setting.isMobile() && this.isStartPages()) ? "inline" : "horizontal"}
|
||||
selectedKeys={[`${this.state.selectedMenuKey}`]}
|
||||
style={{lineHeight: "64px", width: "80%", position: "absolute"}}
|
||||
style={{lineHeight: "64px", width: "80%", position: "absolute", left: "145px"}}
|
||||
>
|
||||
{
|
||||
this.renderMenu()
|
||||
|
@ -1,6 +1,8 @@
|
||||
@import '~antd/dist/antd.less';
|
||||
/* stylelint-disable at-rule-name-case */
|
||||
/* stylelint-disable selector-class-pattern */
|
||||
@import "~antd/dist/antd.less";
|
||||
|
||||
@StaticBaseUrl:"https://cdn.casbin.org";
|
||||
@StaticBaseUrl: "https://cdn.casbin.org";
|
||||
|
||||
.App {
|
||||
text-align: center;
|
||||
@ -69,8 +71,8 @@
|
||||
}
|
||||
|
||||
.content-warp-card {
|
||||
box-shadow: 0 1px 5px 0 rgba(51, 51, 51, 0.14);
|
||||
margin: 5px 5px 5px 5px;
|
||||
box-shadow: 0 1px 5px 0 rgb(51 51 51 / 14%);
|
||||
margin: 5px;
|
||||
flex: 1;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
@ -39,101 +39,102 @@ class BaseListPage extends React.Component {
|
||||
this.fetch({pagination});
|
||||
}
|
||||
|
||||
getColumnSearchProps = dataIndex => ({
|
||||
filterDropdown: ({setSelectedKeys, selectedKeys, confirm, clearFilters}) => (
|
||||
<div style={{padding: 8}}>
|
||||
<Input
|
||||
ref={node => {
|
||||
this.searchInput = node;
|
||||
}}
|
||||
placeholder={`Search ${dataIndex}`}
|
||||
value={selectedKeys[0]}
|
||||
onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
|
||||
onPressEnter={() => this.handleSearch(selectedKeys, confirm, dataIndex)}
|
||||
style={{marginBottom: 8, display: "block"}}
|
||||
/>
|
||||
<Space>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => this.handleSearch(selectedKeys, confirm, dataIndex)}
|
||||
icon={<SearchOutlined />}
|
||||
size="small"
|
||||
style={{width: 90}}
|
||||
>
|
||||
getColumnSearchProps = dataIndex => ({
|
||||
filterDropdown: ({setSelectedKeys, selectedKeys, confirm, clearFilters}) => (
|
||||
<div style={{padding: 8}}>
|
||||
<Input
|
||||
ref={node => {
|
||||
this.searchInput = node;
|
||||
}}
|
||||
placeholder={`Search ${dataIndex}`}
|
||||
value={selectedKeys[0]}
|
||||
onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
|
||||
onPressEnter={() => this.handleSearch(selectedKeys, confirm, dataIndex)}
|
||||
style={{marginBottom: 8, display: "block"}}
|
||||
/>
|
||||
|
||||
<Space>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => this.handleSearch(selectedKeys, confirm, dataIndex)}
|
||||
icon={<SearchOutlined />}
|
||||
size="small"
|
||||
style={{width: 90}}
|
||||
>
|
||||
Search
|
||||
</Button>
|
||||
<Button onClick={() => this.handleReset(clearFilters)} size="small" style={{width: 90}}>
|
||||
</Button>
|
||||
<Button onClick={() => this.handleReset(clearFilters)} size="small" style={{width: 90}}>
|
||||
Reset
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
confirm({closeDropdown: false});
|
||||
this.setState({
|
||||
searchText: selectedKeys[0],
|
||||
searchedColumn: dataIndex,
|
||||
});
|
||||
}}
|
||||
>
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
confirm({closeDropdown: false});
|
||||
this.setState({
|
||||
searchText: selectedKeys[0],
|
||||
searchedColumn: dataIndex,
|
||||
});
|
||||
}}
|
||||
>
|
||||
Filter
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
),
|
||||
filterIcon: filtered => <SearchOutlined style={{color: filtered ? "#1890ff" : undefined}} />,
|
||||
onFilter: (value, record) =>
|
||||
record[dataIndex]
|
||||
? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
|
||||
: "",
|
||||
onFilterDropdownVisibleChange: visible => {
|
||||
if (visible) {
|
||||
setTimeout(() => this.searchInput.select(), 100);
|
||||
}
|
||||
},
|
||||
render: text =>
|
||||
this.state.searchedColumn === dataIndex ? (
|
||||
<Highlighter
|
||||
highlightStyle={{backgroundColor: "#ffc069", padding: 0}}
|
||||
searchWords={[this.state.searchText]}
|
||||
autoEscape
|
||||
textToHighlight={text ? text.toString() : ""}
|
||||
/>
|
||||
) : (
|
||||
text
|
||||
),
|
||||
filterIcon: filtered => <SearchOutlined style={{color: filtered ? "#1890ff" : undefined}} />,
|
||||
onFilter: (value, record) =>
|
||||
record[dataIndex]
|
||||
? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
|
||||
: "",
|
||||
onFilterDropdownVisibleChange: visible => {
|
||||
if (visible) {
|
||||
setTimeout(() => this.searchInput.select(), 100);
|
||||
}
|
||||
},
|
||||
render: text =>
|
||||
this.state.searchedColumn === dataIndex ? (
|
||||
<Highlighter
|
||||
highlightStyle={{backgroundColor: "#ffc069", padding: 0}}
|
||||
searchWords={[this.state.searchText]}
|
||||
autoEscape
|
||||
textToHighlight={text ? text.toString() : ""}
|
||||
/>
|
||||
) : (
|
||||
text
|
||||
),
|
||||
});
|
||||
|
||||
handleSearch = (selectedKeys, confirm, dataIndex) => {
|
||||
this.fetch({searchText: selectedKeys[0], searchedColumn: dataIndex, pagination: this.state.pagination});
|
||||
};
|
||||
|
||||
handleReset = clearFilters => {
|
||||
clearFilters();
|
||||
const {pagination} = this.state;
|
||||
this.fetch({pagination});
|
||||
};
|
||||
|
||||
handleTableChange = (pagination, filters, sorter) => {
|
||||
this.fetch({
|
||||
sortField: sorter.field,
|
||||
sortOrder: sorter.order,
|
||||
pagination,
|
||||
...filters,
|
||||
searchText: this.state.searchText,
|
||||
searchedColumn: this.state.searchedColumn,
|
||||
});
|
||||
};
|
||||
|
||||
handleSearch = (selectedKeys, confirm, dataIndex) => {
|
||||
this.fetch({searchText: selectedKeys[0], searchedColumn: dataIndex, pagination: this.state.pagination});
|
||||
};
|
||||
|
||||
handleReset = clearFilters => {
|
||||
clearFilters();
|
||||
const {pagination} = this.state;
|
||||
this.fetch({pagination});
|
||||
};
|
||||
|
||||
handleTableChange = (pagination, filters, sorter) => {
|
||||
this.fetch({
|
||||
sortField: sorter.field,
|
||||
sortOrder: sorter.order,
|
||||
pagination,
|
||||
...filters,
|
||||
searchText: this.state.searchText,
|
||||
searchedColumn: this.state.searchedColumn,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
this.renderTable(this.state.data)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
this.renderTable(this.state.data)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default BaseListPage;
|
||||
|
@ -38,7 +38,7 @@ class ManagedAccountTable extends React.Component {
|
||||
}
|
||||
|
||||
addRow(table) {
|
||||
const row = {application: "", username: "", password: "", signinUrl: ""};
|
||||
const row = {application: "", username: "", password: ""};
|
||||
if (table === undefined || table === null) {
|
||||
table = [];
|
||||
}
|
||||
@ -69,16 +69,11 @@ class ManagedAccountTable extends React.Component {
|
||||
key: "application",
|
||||
render: (text, record, index) => {
|
||||
const items = this.props.applications;
|
||||
const signinUrlMap = new Map();
|
||||
for (const application of items) {
|
||||
signinUrlMap.set(application.name, application.signinUrl);
|
||||
}
|
||||
return (
|
||||
<Select virtual={false} style={{width: "100%"}}
|
||||
value={text}
|
||||
onChange={value => {
|
||||
this.updateField(table, index, "application", value);
|
||||
this.updateField(table, index, "signinUrl", signinUrlMap.get(value));
|
||||
}} >
|
||||
{
|
||||
items.map((item, index) => <Option key={index} value={item.name}>{item.name}</Option>)
|
||||
|
@ -1,14 +1,28 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
font-family:
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
"Segoe UI",
|
||||
Roboto,
|
||||
Oxygen,
|
||||
Ubuntu,
|
||||
Cantarell,
|
||||
"Fira Sans",
|
||||
"Droid Sans",
|
||||
"Helvetica Neue",
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
font-family:
|
||||
source-code-pro,
|
||||
Menlo,
|
||||
Monaco,
|
||||
Consolas,
|
||||
"Courier New",
|
||||
monospace;
|
||||
}
|
||||
|
||||
@ -17,12 +31,14 @@ code {
|
||||
background-size: 130px, 27px;
|
||||
width: 130px;
|
||||
height: 27px;
|
||||
/*background: rgba(0, 0, 0, 0.2);*/
|
||||
margin: 17px 10px 16px 20px;
|
||||
margin: 17px 0 16px 15px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ant-table.ant-table-middle .ant-table-title, .ant-table.ant-table-middle .ant-table-footer, .ant-table.ant-table-middle thead > tr > th, .ant-table.ant-table-middle tbody > tr > td {
|
||||
.ant-table.ant-table-middle .ant-table-title,
|
||||
.ant-table.ant-table-middle .ant-table-footer,
|
||||
.ant-table.ant-table-middle thead > tr > th,
|
||||
.ant-table.ant-table-middle tbody > tr > td {
|
||||
padding: 1px 8px !important;
|
||||
}
|
||||
|
||||
|
@ -16,18 +16,19 @@ import "core-js/es";
|
||||
import "react-app-polyfill/ie9";
|
||||
import "react-app-polyfill/stable";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import {createRoot} from "react-dom/client";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
import * as serviceWorker from "./serviceWorker";
|
||||
import {BrowserRouter} from "react-router-dom";
|
||||
|
||||
ReactDOM.render(
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>,
|
||||
document.getElementById("root")
|
||||
);
|
||||
const container = document.getElementById("root");
|
||||
|
||||
const app = createRoot(container);
|
||||
|
||||
app.render(<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>);
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
|
9191
web/yarn.lock
9191
web/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user