feat: improve Select component performance (#1472)

This commit is contained in:
Yaodong Yu 2023-01-12 23:11:11 +08:00 committed by GitHub
parent 6d4f94986e
commit fcdf1e8dd2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 115 additions and 159 deletions

View File

@ -343,12 +343,9 @@ class ApplicationEditPage extends React.Component {
{Setting.getLabel(i18next.t("application:Token format"), i18next.t("application:Token format - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.application.tokenFormat} onChange={(value => {this.updateApplicationField("tokenFormat", value);})}>
{
["JWT", "JWT-Empty"]
.map((item, index) => <Option key={index} value={item}>{item}</Option>)
}
</Select>
<Select virtual={false} style={{width: "100%"}} value={this.state.application.tokenFormat} onChange={(value => {this.updateApplicationField("tokenFormat", value);})}
options={["JWT", "JWT-Empty"].map((item) => Setting.getOption(item, item))}
/>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >

View File

@ -153,7 +153,7 @@ export const CropperDiv = (props) => {
<Row style={{width: "100%", marginBottom: "20px"}}>
<input style={{display: "none"}} ref={input => uploadButton = input} type="file" accept="image/*" onChange={onChange} />
<Button block onClick={selectFile}>{i18next.t("user:Select a photo...")}</Button>
<Select
<Select virtual={false}
style={{width: "100%"}}
loading={loading}
placeholder={i18next.t("user:Please select avatar from resources")}

View File

@ -165,12 +165,9 @@ class OrganizationEditPage extends React.Component {
{Setting.getLabel(i18next.t("general:Password type"), i18next.t("general:Password type - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.organization.passwordType} onChange={(value => {this.updateOrganizationField("passwordType", value);})}>
{
["plain", "salt", "md5-salt", "bcrypt", "pbkdf2-salt", "argon2id"]
.map((item, index) => <Option key={index} value={item}>{item}</Option>)
}
</Select>
<Select virtual={false} style={{width: "100%"}} value={this.state.organization.passwordType} onChange={(value => {this.updateOrganizationField("passwordType", value);})}
options={["plain", "salt", "md5-salt", "bcrypt", "pbkdf2-salt", "argon2id"].map(item => Setting.getOption(item, item))}
/>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
@ -225,11 +222,9 @@ class OrganizationEditPage extends React.Component {
{Setting.getLabel(i18next.t("general:Default application"), i18next.t("general:Default application - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.organization.defaultApplication} onChange={(value => {this.updateOrganizationField("defaultApplication", value);})}>
{
this.state.applications?.map((item, index) => <Option key={index} value={item.name}>{item.name}</Option>)
}
</Select>
<Select virtual={false} style={{width: "100%"}} value={this.state.organization.defaultApplication} onChange={(value => {this.updateOrganizationField("defaultApplication", value);})}
options={this.state.applications?.map((item) => Setting.getOption(item.name, item.name))
} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >

View File

@ -302,7 +302,7 @@ class PaymentEditPage extends React.Component {
{Setting.getLabel(i18next.t("payment:Invoice type"), i18next.t("payment:Invoice type - Tooltip"))} :
</Col>
<Col span={22} >
<Select disabled={this.state.payment.invoiceUrl !== ""} virtual={false} style={{width: "100%"}} value={this.state.payment.invoiceType} onChange={(value => {
<Select virtual={false} disabled={this.state.payment.invoiceUrl !== ""} style={{width: "100%"}} value={this.state.payment.invoiceType} onChange={(value => {
this.updatePaymentField("invoiceType", value);
if (value === "Individual") {
this.updatePaymentField("invoiceTitle", this.state.payment.personName);

View File

@ -24,8 +24,6 @@ import * as ModelBackend from "./backend/ModelBackend";
import * as ApplicationBackend from "./backend/ApplicationBackend";
import moment from "moment/moment";
const {Option} = Select;
class PermissionEditPage extends React.Component {
constructor(props) {
super(props);
@ -163,16 +161,13 @@ class PermissionEditPage extends React.Component {
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.permission.owner} onChange={(owner => {
this.updatePermissionField("owner", owner);
this.getUsers(owner);
this.getRoles(owner);
this.getModels(owner);
this.getResources(owner);
})}>
{
this.state.organizations.map((organization, index) => <Option key={index} value={organization.name}>{organization.name}</Option>)
}
</Select>
})}
options={this.state.organizations.map((organization) => Setting.getOption(organization.name, organization.name))
} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
@ -202,11 +197,9 @@ class PermissionEditPage extends React.Component {
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.permission.model} onChange={(model => {
this.updatePermissionField("model", model);
})}>
{
this.state.models.map((model, index) => <Option key={index} value={model.name}>{model.name}</Option>)
}
</Select>
})}
options={this.state.models.map((model) => Setting.getOption(model.name, model.name))
} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
@ -224,11 +217,10 @@ class PermissionEditPage extends React.Component {
{Setting.getLabel(i18next.t("role:Sub users"), i18next.t("role:Sub users - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.permission.users} onChange={(value => {this.updatePermissionField("users", value);})}>
{
this.state.users.map((user, index) => <Option key={index} value={`${user.owner}/${user.name}`}>{`${user.owner}/${user.name}`}</Option>)
}
</Select>
<Select mode="tags" style={{width: "100%"}} value={this.state.permission.users}
onChange={(value => {this.updatePermissionField("users", value);})}
options={this.state.users.map((user) => Setting.getOption(`${user.owner}/${user.name}`, `${user.owner}/${user.name}`))}
/>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
@ -236,11 +228,10 @@ class PermissionEditPage extends React.Component {
{Setting.getLabel(i18next.t("role:Sub roles"), i18next.t("role:Sub roles - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} disabled={!this.hasRoleDefinition(this.state.model)} mode="tags" style={{width: "100%"}} value={this.state.permission.roles} onChange={(value => {this.updatePermissionField("roles", value);})}>
{
this.state.roles.filter(roles => (roles.owner !== this.state.roles.owner || roles.name !== this.state.roles.name)).map((permission, index) => <Option key={index} value={`${permission.owner}/${permission.name}`}>{`${permission.owner}/${permission.name}`}</Option>)
}
</Select>
<Select virtual={false} disabled={!this.hasRoleDefinition(this.state.model)} mode="tags" style={{width: "100%"}} value={this.state.permission.roles}
onChange={(value => {this.updatePermissionField("roles", value);})}
options={this.state.roles.filter(roles => (roles.owner !== this.state.roles.owner || roles.name !== this.state.roles.name)).map((permission) => Setting.getOption(`${permission.owner}/${permission.name}`, `${permission.owner}/${permission.name}`))
} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
@ -248,13 +239,12 @@ class PermissionEditPage extends React.Component {
{Setting.getLabel(i18next.t("role:Sub domains"), i18next.t("role:Sub domains - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.permission.domains} onChange={(value => {
this.updatePermissionField("domains", value);
})}>
{
this.state.permission.domains.map((domain, index) => <Option key={index} value={domain}>{domain}</Option>)
}
</Select>
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.permission.domains}
onChange={(value => {
this.updatePermissionField("domains", value);
})}
options={this.state.permission.domains.map((domain) => Setting.getOption(domain, domain))
} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
@ -264,14 +254,12 @@ class PermissionEditPage extends React.Component {
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.permission.resourceType} onChange={(value => {
this.updatePermissionField("resourceType", value);
})}>
{
[
{id: "Application", name: i18next.t("general:Application")},
{id: "TreeNode", name: i18next.t("permission:TreeNode")},
].map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
})}
options={[
{value: "Application", name: i18next.t("general:Application")},
{value: "TreeNode", name: i18next.t("permission:TreeNode")},
].map((item) => Setting.getOption(item.name, item.value))}
/>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
@ -279,11 +267,10 @@ class PermissionEditPage extends React.Component {
{Setting.getLabel(i18next.t("permission:Resources"), i18next.t("permission:Resources - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.permission.resources} onChange={(value => {this.updatePermissionField("resources", value);})}>
{
this.state.resources.map((resource, index) => <Option key={index} value={`${resource.name}`}>{`${resource.name}`}</Option>)
}
</Select>
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.permission.resources}
onChange={(value => {this.updatePermissionField("resources", value);})}
options={this.state.resources.map((resource) => Setting.getOption(`${resource.name}`, `${resource.name}`))
} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
@ -293,15 +280,13 @@ class PermissionEditPage extends React.Component {
<Col span={22} >
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.permission.actions} onChange={(value => {
this.updatePermissionField("actions", value);
})}>
{
[
{id: "Read", name: i18next.t("permission:Read")},
{id: "Write", name: i18next.t("permission:Write")},
{id: "Admin", name: i18next.t("permission:Admin")},
].map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
})}
options={[
{value: "Read", name: i18next.t("permission:Read")},
{value: "Write", name: i18next.t("permission:Write")},
{value: "Admin", name: i18next.t("permission:Admin")},
].map((item) => Setting.getOption(item.name, item.value))}
/>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
@ -311,14 +296,12 @@ class PermissionEditPage extends React.Component {
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.permission.effect} onChange={(value => {
this.updatePermissionField("effect", value);
})}>
{
[
{id: "Allow", name: i18next.t("permission:Allow")},
{id: "Deny", name: i18next.t("permission:Deny")},
].map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
})}
options={[
{value: "Allow", name: i18next.t("permission:Allow")},
{value: "Deny", name: i18next.t("permission:Deny")},
].map((item) => Setting.getOption(item.name, item.value))}
/>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
@ -366,7 +349,7 @@ class PermissionEditPage extends React.Component {
{Setting.getLabel(i18next.t("permission:State"), i18next.t("permission:State - Tooltip"))} :
</Col>
<Col span={22} >
<Select disabled={!Setting.isLocalAdminUser(this.props.account)} virtual={false} style={{width: "100%"}} value={this.state.permission.state} onChange={(value => {
<Select virtual={false} disabled={!Setting.isLocalAdminUser(this.props.account)} style={{width: "100%"}} value={this.state.permission.state} onChange={(value => {
if (this.state.permission.state !== value) {
if (value === "Approved") {
this.updatePermissionField("approver", this.props.account.name);
@ -378,14 +361,12 @@ class PermissionEditPage extends React.Component {
}
this.updatePermissionField("state", value);
})}>
{
[
{id: "Approved", name: i18next.t("permission:Approved")},
{id: "Pending", name: i18next.t("permission:Pending")},
].map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
})}
options={[
{value: "Approved", name: i18next.t("permission:Approved")},
{value: "Pending", name: i18next.t("permission:Pending")},
].map((item) => Setting.getOption(item.name, item.value))}
/>
</Col>
</Row>
</Card>

View File

@ -179,7 +179,7 @@ class ProviderTable extends React.Component {
// width: '120px',
// render: (text, record, index) => {
// return (
// <Select virtual={false} style={{width: '100%'}} value={text} onChange={(value => {
// <Select virtual={false} style={{width: '100%'}} value={text} onChange={(value => {
// this.updateField(table, index, 'alertType', value);
// })}>
// {

View File

@ -16,11 +16,9 @@ import React from "react";
import {Button, Card, Col, Input, Row, Select, Switch} from "antd";
import * as RoleBackend from "./backend/RoleBackend";
import * as OrganizationBackend from "./backend/OrganizationBackend";
import * as UserBackend from "./backend/UserBackend";
import * as Setting from "./Setting";
import i18next from "i18next";
const {Option} = Select;
import * as UserBackend from "./backend/UserBackend";
class RoleEditPage extends React.Component {
constructor(props) {
@ -113,11 +111,9 @@ class RoleEditPage extends React.Component {
{Setting.getLabel(i18next.t("general:Organization"), i18next.t("general:Organization - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.role.owner} onChange={(value => {this.updateRoleField("owner", value);})}>
{
this.state.organizations.map((organization, index) => <Option key={index} value={organization.name}>{organization.name}</Option>)
}
</Select>
<Select virtual={false} style={{width: "100%"}} value={this.state.role.owner} onChange={(value => {this.updateRoleField("owner", value);})}
options={this.state.organizations.map((organization) => Setting.getOption(organization.name, organization.name))
} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
@ -145,11 +141,10 @@ class RoleEditPage extends React.Component {
{Setting.getLabel(i18next.t("role:Sub users"), i18next.t("role:Sub users - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.role.users} onChange={(value => {this.updateRoleField("users", value);})}>
{
this.state.users.map((user, index) => <Option key={index} value={`${user.owner}/${user.name}`}>{`${user.owner}/${user.name}`}</Option>)
}
</Select>
<Select mode="tags" style={{width: "100%"}} value={this.state.role.users}
onChange={(value => {this.updateRoleField("users", value);})}
options={this.state.users.map((user) => Setting.getOption(`${user.owner}/${user.name}`, `${user.owner}/${user.name}`))}
/>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
@ -157,11 +152,9 @@ class RoleEditPage extends React.Component {
{Setting.getLabel(i18next.t("role:Sub roles"), i18next.t("role:Sub roles - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.role.roles} onChange={(value => {this.updateRoleField("roles", value);})}>
{
this.state.roles.filter(role => (role.owner !== this.state.role.owner || role.name !== this.state.role.name)).map((role, index) => <Option key={index} value={`${role.owner}/${role.name}`}>{`${role.owner}/${role.name}`}</Option>)
}
</Select>
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.role.roles} onChange={(value => {this.updateRoleField("roles", value);})}
options={this.state.roles.filter(role => (role.owner !== this.state.role.owner || role.name !== this.state.role.name)).map((role) => Setting.getOption(`${role.owner}/${role.name}`, `${role.owner}/${role.name}`))
} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
@ -171,11 +164,9 @@ class RoleEditPage extends React.Component {
<Col span={22} >
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.role.domains} onChange={(value => {
this.updateRoleField("domains", value);
})}>
{
this.state.role.domains?.map((domain, index) => <Option key={index} value={domain}>{domain}</Option>)
}
</Select>
})}
options={this.state.role.domains?.map((domain) => Setting.getOption(domain, domain))
} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >

View File

@ -924,6 +924,14 @@ export function getItem(label, key, icon, children, type) {
type,
};
}
export function getOption(label, value) {
return {
label,
value,
};
}
function repeat(str, len) {
while (str.length < len) {
str += str.substr(0, len - str.length);

View File

@ -195,11 +195,7 @@ class SignupTable extends React.Component {
return (
<Select virtual={false} style={{width: "100%"}} value={text} onChange={(value => {
this.updateField(table, index, "rule", value);
})}>
{
options.map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
})} options={options.map(item => Setting.getOption(item.name, item.id))} />
);
},
},

View File

@ -257,12 +257,9 @@ class UserEditPage extends React.Component {
{Setting.getLabel(i18next.t("general:User type"), i18next.t("general:User type - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.user.type} onChange={(value => {this.updateUserField("type", value);})}>
{
["normal-user"]
.map((item, index) => <Option key={index} value={item}>{item}</Option>)
}
</Select>
<Select virtual={false} style={{width: "100%"}} value={this.state.user.type} onChange={(value => {this.updateUserField("type", value);})}
options={["normal-user"].map(item => Setting.getOption(item, item))}
/>
</Col>
</Row>
);
@ -290,7 +287,7 @@ class UserEditPage extends React.Component {
onChange={e => {
this.updateUserField("email", e.target.value);
}} />) :
(<Select value={this.state.user.email}
(<Select virtual={false} value={this.state.user.email}
options={[Setting.getItem(this.state.user.email, this.state.user.email)]}
disabled={disabled}
onChange={e => {
@ -317,7 +314,7 @@ class UserEditPage extends React.Component {
onChange={e => {
this.updateUserField("phone", e.target.value);
}} /> :
(<Select value={`+${this.state.application?.organizationObj.phonePrefix} ${this.state.user.phone}`}
(<Select virtual={false} value={`+${this.state.application?.organizationObj.phonePrefix} ${this.state.user.phone}`}
options={[Setting.getItem(`+${this.state.application?.organizationObj.phonePrefix} ${this.state.user.phone}`, this.state.user.phone)]}
disabled={disabled}
onChange={e => {
@ -409,16 +406,14 @@ class UserEditPage extends React.Component {
<Col span={22} >
{
this.state.application?.organizationObj.tags?.length > 0 ? (
<Select virtual={false} style={{width: "100%"}} value={this.state.user.tag} onChange={(value => {this.updateUserField("tag", value);})}>
{
this.state.application.organizationObj.tags?.map((tag, index) => {
const tokens = tag.split("|");
const value = tokens[0];
const displayValue = Setting.getLanguage() !== "zh" ? tokens[0] : tokens[1];
return <Option key={index} value={value}>{displayValue}</Option>;
})
}
</Select>
<Select virtual={false} style={{width: "100%"}} value={this.state.user.tag}
onChange={(value => {this.updateUserField("tag", value);})}
options={this.state.application.organizationObj.tags?.map((tag) => {
const tokens = tag.split("|");
const value = tokens[0];
const displayValue = Setting.getLanguage() !== "zh" ? tokens[0] : tokens[1];
return Setting.getOption(displayValue, value);
})} />
) : (
<Input value={this.state.user.tag} onChange={e => {
this.updateUserField("tag", e.target.value);
@ -435,11 +430,10 @@ class UserEditPage extends React.Component {
{Setting.getLabel(i18next.t("general:Signup application"), i18next.t("general:Signup application - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} disabled={disabled} value={this.state.user.signupApplication} onChange={(value => {this.updateUserField("signupApplication", value);})}>
{
this.state.applications.map((application, index) => <Option key={index} value={application.name}>{application.name}</Option>)
}
</Select>
<Select virtual={false} style={{width: "100%"}} disabled={disabled} value={this.state.user.signupApplication}
onChange={(value => {this.updateUserField("signupApplication", value);})}
options={this.state.applications.map((application) => Setting.getOption(application.name, application.name))
} />
</Col>
</Row>
);
@ -480,7 +474,7 @@ class UserEditPage extends React.Component {
<div style={{marginBottom: 20}}>
{
(this.state.application === null || this.state.user === null) ? null : (
this.state.application?.providers.filter(providerItem => Setting.isProviderVisible(providerItem)).map((providerItem, index) =>
this.state.application?.providers.filter(providerItem => Setting.isProviderVisible(providerItem)).map((providerItem) =>
(providerItem.provider.category === "OAuth") ? (
<OAuthWidget key={providerItem.name} labelSpan={(Setting.isMobile()) ? 10 : 3} user={this.state.user} application={this.state.application} providerItem={providerItem} account={this.props.account} onUnlinked={() => {return this.unlinked();}} />
) : (

View File

@ -320,9 +320,9 @@ class ForgetPage extends React.Component {
>
{
this.state.isFixed ? <Input disabled /> :
<Select
<Select virtual={false}
key={this.state.verifyType}
virtual={false} style={{textAlign: "left"}}
style={{textAlign: "left"}}
defaultValue={this.state.verifyType}
disabled={this.state.username === ""}
placeholder={i18next.t("forget:Choose email or phone")}

View File

@ -18,8 +18,6 @@ import i18next from "i18next";
import * as UserBackend from "../backend/UserBackend";
import * as Setting from "../Setting";
const {Option} = Select;
class AffiliationSelect extends React.Component {
constructor(props) {
super(props);
@ -99,20 +97,16 @@ class AffiliationSelect extends React.Component {
this.updateUserField("affiliation", e.target.value);
}} />
) : (
<Select virtual={false} style={{width: "100%"}} value={this.props.user.affiliation} onChange={(value => {
const name = value;
const affiliationOption = Setting.getArrayItem(this.state.affiliationOptions, "name", name);
const id = affiliationOption.id;
this.updateUserField("affiliation", name);
this.updateUserField("score", id);
})}>
{
<Option key={0} value={""}>(empty)</Option>
}
{
this.state.affiliationOptions.map((affiliationOption, index) => <Option key={affiliationOption.id} value={affiliationOption.name}>{affiliationOption.name}</Option>)
}
</Select>
<Select virtual={false} style={{width: "100%"}} value={this.props.user.affiliation}
onChange={(value => {
const name = value;
const affiliationOption = Setting.getArrayItem(this.state.affiliationOptions, "name", name);
const id = affiliationOption.id;
this.updateUserField("affiliation", name);
this.updateUserField("score", id);
})}
options={[Setting.getOption("(empty)", "")].concat(this.state.affiliationOptions.map((affiliationOption) => Setting.getOption(affiliationOption.name, affiliationOption.name))
)} />
)
}
</Col>