Compare commits

...

5 Commits

Author SHA1 Message Date
Yang Luo
269485f2ea Update UserEditPage.js 2026-01-26 23:07:02 +08:00
copilot-swe-agent[bot]
fbdf013382 Refactor visibility logic into helper method and handle edge cases
Co-authored-by: hsluoyz <3787410+hsluoyz@users.noreply.github.com>
2026-01-25 03:12:03 +00:00
copilot-swe-agent[bot]
08897b8ab2 Address code review comments - remove unused imports and fix formatting
Co-authored-by: hsluoyz <3787410+hsluoyz@users.noreply.github.com>
2026-01-25 03:11:14 +00:00
copilot-swe-agent[bot]
7d6c9c85d0 Add tab field to AccountItem and implement tab-based navigation in UserEditPage
Co-authored-by: hsluoyz <3787410+hsluoyz@users.noreply.github.com>
2026-01-25 03:06:55 +00:00
copilot-swe-agent[bot]
9921623551 Initial plan 2026-01-25 03:02:48 +00:00
3 changed files with 142 additions and 38 deletions

View File

@@ -32,6 +32,7 @@ type AccountItem struct {
ViewRule string `json:"viewRule"`
ModifyRule string `json:"modifyRule"`
Regex string `json:"regex"`
Tab string `json:"tab"`
}
type ThemeData struct {

View File

@@ -13,7 +13,7 @@
// limitations under the License.
import React from "react";
import {Button, Card, Col, Form, Input, InputNumber, List, Result, Row, Select, Space, Spin, Switch, Tag, Tooltip} from "antd";
import {Button, Card, Col, Form, Input, InputNumber, Layout, List, Result, Row, Select, Space, Spin, Switch, Tabs, Tag, Tooltip} from "antd";
import {withRouter} from "react-router-dom";
import {TotpMfaType} from "./auth/MfaSetupPage";
import * as GroupBackend from "./backend/GroupBackend";
@@ -45,6 +45,7 @@ import MfaAccountTable from "./table/MfaAccountTable";
import MfaTable from "./table/MfaTable";
import TransactionTable from "./table/TransactionTable";
import * as TransactionBackend from "./backend/TransactionBackend";
import {Content, Header} from "antd/es/layout/layout";
const {Option} = Select;
@@ -66,6 +67,7 @@ class UserEditPage extends React.Component {
idCardInfo: ["ID card front", "ID card back", "ID card with person"],
openFaceRecognitionModal: false,
transactions: [],
activeMenuKey: "",
};
}
@@ -1322,6 +1324,129 @@ class UserEditPage extends React.Component {
);
}
isAccountItemVisible(item) {
if (!item.visible) {
return false;
}
const isAdmin = Setting.isLocalAdminUser(this.props.account);
if (item.viewRule === "Self") {
if (!this.isSelfOrAdmin()) {
return false;
}
} else if (item.viewRule === "Admin") {
if (!isAdmin) {
return false;
}
}
return true;
}
getAccountItemsByTab(tab) {
const accountItems = this.getUserOrganization()?.accountItems || [];
return accountItems.filter(item => {
if (!this.isAccountItemVisible(item)) {
return false;
}
const itemTab = item.tab || "";
return itemTab === tab;
});
}
getUniqueTabs() {
const accountItems = this.getUserOrganization()?.accountItems || [];
const tabs = new Set();
accountItems.forEach(item => {
if (this.isAccountItemVisible(item)) {
tabs.add(item.tab || "");
}
});
return Array.from(tabs).sort((a, b) => {
// Empty string (default tab) comes first
if (a === "") {
return -1;
}
if (b === "") {
return 1;
}
return a.localeCompare(b);
});
}
renderUserForm() {
const tabs = this.getUniqueTabs();
// If there are no tabs or only one tab (default), render without tab navigation
if (tabs.length === 0 || (tabs.length === 1 && tabs[0] === "")) {
const accountItems = this.getAccountItemsByTab("");
return (
<Form>
{accountItems.map(accountItem => (
<React.Fragment key={accountItem.name}>
<Form.Item name={accountItem.name}
validateTrigger="onChange"
rules={[
{
pattern: accountItem.regex ? new RegExp(accountItem.regex, "g") : null,
message: i18next.t("user:This field value doesn't match the pattern rule"),
},
]}
style={{margin: 0}}>
{this.renderAccountItem(accountItem)}
</Form.Item>
</React.Fragment>
))}
</Form>
);
}
// Render with tabs
const activeKey = this.state.activeMenuKey || tabs[0] || "";
return (
<Layout style={{background: "inherit"}}>
<Header style={{background: "inherit", padding: "0px"}}>
<Tabs
onChange={(key) => {
this.setState({activeMenuKey: key});
}}
type="card"
activeKey={activeKey}
items={tabs.map(tab => ({
label: tab === "" ? i18next.t("user:Default") : tab,
key: tab,
}))}
/>
</Header>
<Layout style={{background: "inherit", maxHeight: "70vh", overflow: "auto"}}>
<Content style={{padding: "15px"}}>
<Form>
{this.getAccountItemsByTab(activeKey).map(accountItem => (
<React.Fragment key={accountItem.name}>
<Form.Item name={accountItem.name}
validateTrigger="onChange"
rules={[
{
pattern: accountItem.regex ? new RegExp(accountItem.regex, "g") : null,
message: i18next.t("user:This field value doesn't match the pattern rule"),
},
]}
style={{margin: 0}}>
{this.renderAccountItem(accountItem)}
</Form.Item>
</React.Fragment>
))}
</Form>
</Content>
</Layout>
</Layout>
);
}
renderUser() {
return (
<div>
@@ -1335,42 +1460,7 @@ class UserEditPage extends React.Component {
</div>
)
} style={(Setting.isMobile()) ? {margin: "5px"} : {}} type="inner">
<Form>
{
this.getUserOrganization()?.accountItems?.map(accountItem => {
if (!accountItem.visible) {
return null;
}
const isAdmin = Setting.isLocalAdminUser(this.props.account);
if (accountItem.viewRule === "Self") {
if (!this.isSelfOrAdmin()) {
return null;
}
} else if (accountItem.viewRule === "Admin") {
if (!isAdmin) {
return null;
}
}
return (
<React.Fragment key={accountItem.name}>
<Form.Item name={accountItem.name}
validateTrigger="onChange"
rules={[
{
pattern: accountItem.regex ? new RegExp(accountItem.regex, "g") : null,
message: i18next.t("user:This field value doesn't match the pattern rule"),
},
]}
style={{margin: 0}}>
{this.renderAccountItem(accountItem)}
</Form.Item>
</React.Fragment>
);
})
}
</Form>
{this.renderUserForm()}
</Card>
</div>
);

View File

@@ -38,7 +38,7 @@ class AccountTable extends React.Component {
}
addRow(table) {
const row = {name: Setting.getNewRowNameForTable(table, "Please select an account item"), visible: true, viewRule: "Public", modifyRule: "Self"};
const row = {name: Setting.getNewRowNameForTable(table, "Please select an account item"), visible: true, viewRule: "Public", modifyRule: "Self", tab: ""};
if (table === undefined) {
table = [];
}
@@ -93,6 +93,19 @@ class AccountTable extends React.Component {
);
},
},
{
title: i18next.t("general:Tab"),
dataIndex: "tab",
key: "tab",
width: "150px",
render: (text, record, index) => {
return (
<Input value={text} placeholder={i18next.t("user:Default")} onChange={e => {
this.updateField(table, index, "tab", e.target.value);
}} />
);
},
},
{
title: i18next.t("signup:Regex"),
dataIndex: "regex",