Skip to content

Fix third-party binding cards showing incorrect status when disabled - #1900

Closed
RedwindA wants to merge 2 commits into
QuantumNous:mainfrom
RedwindA:fix/wechat-display
Closed

Fix third-party binding cards showing incorrect status when disabled#1900
RedwindA wants to merge 2 commits into
QuantumNous:mainfrom
RedwindA:fix/wechat-display

Conversation

@RedwindA

@RedwindA RedwindA commented Sep 28, 2025

Copy link
Copy Markdown
Contributor

PR 类型

  • Bug 修复
  • 新功能
  • 文档更新
  • 其他

PR 是否包含破坏性更新?

PR 描述

  • Ensure the WeChat binding card respects both the
    provider enable flag and the user’s binding state
    when rendering status and button text
  • Introduce shared helpers so all third-party
    providers show 未启用 when the administrator has
    disabled the integration instead of reporting 未绑 定
  • Align button disabling logic with the normalized
    enablement checks to avoid misleading actions

效果

Before
image

After
image

Summary by CodeRabbit

  • Bug Fixes

    • WeChat binding button now correctly reflects availability and is disabled when WeChat login is off.
    • Clearer binding status text for WeChat.
  • Refactor

    • Unified rendering of account binding sections for WeChat, GitHub, OIDC, Telegram, and LinuxDO.
    • Consistent display of account IDs and statuses, showing “未启用” when a provider is disabled.

@coderabbitai

coderabbitai Bot commented Sep 28, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Refactors AccountManagement.jsx to centralize provider-binding UI logic: derives WeChat flags, adds helper functions for status/button text and generic provider rendering, and updates WeChat, GitHub, OIDC, Telegram, and LinuxDO sections to use these helpers.

Changes

Cohort / File(s) Summary of Changes
Provider binding helpers and refactor
web/src/components/settings/personal/cards/AccountManagement.jsx
Added wechatEnabled and isWeChatBound. Implemented getBindingStatusText, getBindingButtonText, and renderProviderBinding. Replaced inline WeChat status/button text and disabled logic. Unified GitHub/OIDC/Telegram/LinuxDO rendering via renderProviderBinding with "未启用" fallback. Minor structural alignment.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant UI as AccountManagement.jsx
  participant State as status / userState

  User->>UI: Open Account Management
  UI->>State: Read provider configs and user bindings
  Note over UI,State: derive wechatEnabled, isWeChatBound

  UI->>UI: getBindingStatusText(enabled, bound)
  UI->>UI: getBindingButtonText(enabled, bound)
  UI->>UI: renderProviderBinding(enabled, accountId, label)

  alt Provider enabled
    UI->>User: Show account info / bind/unbind button
  else Provider disabled
    UI->>User: Show "未启用"
  end

  Note right of UI: WeChat button disabled state uses wechatEnabled
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

In settings fields where toggles play,
I nibble bindings, hop and sway.
Helpers tidy each binding line,
Status and buttons now align.
A little rabbit clap—bindings shine! 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly and concisely describes the main bug fix in the changeset, specifying which UI component (“third-party binding cards”) and what issue (“incorrect status when disabled”) it addresses, making it immediately informative to reviewers scanning the history.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
web/src/components/settings/personal/cards/AccountManagement.jsx (2)

89-108: Helpers are correct; consider hoisting to module scope.

Pure helpers recreate every render. Hoist them outside the component (no props capture) to avoid churn and ease reuse across providers.


96-102: Optional: make button text helper reusable for OAuth providers.

Add a modifiable = true flag so bound-but-not-editable providers show “已绑定” instead of “修改绑定”, and reuse everywhere for consistency.

-const getBindingButtonText = (enabled, bound) => {
-  if (bound) {
-    return t('修改绑定');
-  }
-  return enabled ? t('绑定') : t('未启用');
-};
+const getBindingButtonText = (enabled, bound, modifiable = true) => {
+  if (!enabled) return t('未启用');
+  if (bound) return modifiable ? t('修改绑定') : t('已绑定');
+  return t('绑定');
+};

Example (GitHub) button label:

- {status.github_oauth ? t('绑定') : t('未启用')}
+ {getBindingButtonText(Boolean(status.github_oauth), Boolean(userState.user?.github_id), false)}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 045ba23 and cfc92f0.

📒 Files selected for processing (1)
  • web/src/components/settings/personal/cards/AccountManagement.jsx (8 hunks)
🔇 Additional comments (2)
web/src/components/settings/personal/cards/AccountManagement.jsx (2)

191-204: WeChat status/button now respect enablement and bind state.

This meets the PR goal (“未启用” when disabled; “已/未绑定” otherwise) and disables actions when not enabled.


62-63: Confirm status.wechat_login is the only WeChat enable flag. Verified that status.wechat_login is mapped from common.WeChatAuthEnabled in controller/misc.go and no other wechat_oauth or wechat_enabled flags exist.

Comment on lines +224 to 228
{renderProviderBinding(
status.github_oauth,
userState.user?.github_id,
t('GitHub ID'),
)}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard against undefined IDs in button disable logic (GitHub).

Elsewhere you compare to '', which disables the button if the field is undefined. Use a boolean check.

Apply inline change near the button:

- disabled={
-   (userState.user && userState.user.github_id !== '') ||
-   !status.github_oauth
- }
+ disabled={Boolean(userState.user?.github_id) || !status.github_oauth}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In web/src/components/settings/personal/cards/AccountManagement.jsx around lines
224 to 228, the button disable logic currently compares the GitHub ID to an
empty string which fails when the ID is undefined; change the condition to a
boolean check so the button is disabled when the ID is falsy (e.g. use
!userState.user?.github_id or Boolean(userState.user?.github_id) accordingly)
and apply this inline where the button's disabled prop is set.

Comment on lines +266 to 270
{renderProviderBinding(
status.oidc_enabled,
userState.user?.oidc_id,
t('OIDC ID'),
)}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Same undefined check for OIDC button.

- disabled={
-   (userState.user && userState.user.oidc_id !== '') ||
-   !status.oidc_enabled
- }
+ disabled={Boolean(userState.user?.oidc_id) || !status.oidc_enabled}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In web/src/components/settings/personal/cards/AccountManagement.jsx around lines
266 to 270, the OIDC provider binding button is rendered without the same
undefined/user existence guard used for other provider buttons; update the code
to only call renderProviderBinding when status.oidc_enabled is true and
userState.user exists and userState.user.oidc_id is defined (mirror the same
conditional check pattern used for the other provider buttons) so the component
isn’t invoked with an undefined ID.

Comment thread web/src/components/settings/personal/cards/AccountManagement.jsx
Comment thread web/src/components/settings/personal/cards/AccountManagement.jsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/components/settings/personal/cards/AccountManagement.jsx (1)

62-118: Replace direct string checks and unguarded user ID accesses with Boolean() + optional chaining
– In AccountManagement.jsx, the provider buttons still use patterns like

(userState.user && userState.user.github_id !== '')  
userState.user.telegram_id !== ''  
(userState.user && userState.user.linux_do_id !== '')  

– Update each to use Boolean(userState.user?.<provider>_id) instead, matching the wechatEnabled/isWeChatBound pattern and removing fragile !== '' checks.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cfc92f0 and 6e64473.

📒 Files selected for processing (1)
  • web/src/components/settings/personal/cards/AccountManagement.jsx (8 hunks)
🔇 Additional comments (6)
web/src/components/settings/personal/cards/AccountManagement.jsx (6)

62-63: LGTM on normalized WeChat flags.

Booleans read cleanly and align with the PR goal.


201-214: WeChat block: good use of helpers and disable logic.

Status/label now consistent and button disables only when integration is off.


234-238: Fix undefined-ID check in GitHub button; consider unifying label via helper.

userState.user.github_id !== '' incorrectly disables when the ID is undefined. Use a boolean cast. Optionally, reuse getBindingButtonText for label consistency.

-                      disabled={
-                        (userState.user && userState.user.github_id !== '') ||
-                        !status.github_oauth
-                      }
+                      disabled={
+                        Boolean(userState.user?.github_id) || !status.github_oauth
+                      }

Optional label unification:

-                      {status.github_oauth ? t('绑定') : t('未启用')}
+                      {getBindingButtonText(
+                        Boolean(status.github_oauth),
+                        Boolean(userState.user?.github_id)
+                      )}

Also applies to: 251-256


276-280: Same undefined-ID guard and label consistency for OIDC.

Mirror the GitHub fix.

-                      disabled={
-                        (userState.user && userState.user.oidc_id !== '') ||
-                        !status.oidc_enabled
-                      }
+                      disabled={
+                        Boolean(userState.user?.oidc_id) || !status.oidc_enabled
+                      }

Optional:

-                      {status.oidc_enabled ? t('绑定') : t('未启用')}
+                      {getBindingButtonText(
+                        Boolean(status.oidc_enabled),
+                        Boolean(userState.user?.oidc_id)
+                      )}

Also applies to: 295-301


321-325: Telegram block can throw when userState.user is null.

Direct access to userState.user.telegram_id risks a crash; use optional chaining + boolean.

-                    {status.telegram_oauth ? (
-                      userState.user.telegram_id !== '' ? (
+                    {status.telegram_oauth ? (
+                      Boolean(userState.user?.telegram_id) ? (
                         <Button disabled={true} size='small'>
                           {t('已绑定')}
                         </Button>
                       ) : (

Also applies to: 330-347


367-371: Same undefined-ID guard and label consistency for LinuxDO.

Mirror the GitHub/OIDC fixes.

-                      disabled={
-                        (userState.user && userState.user.linux_do_id !== '') ||
-                        !status.linuxdo_oauth
-                      }
+                      disabled={
+                        Boolean(userState.user?.linux_do_id) || !status.linuxdo_oauth
+                      }

Optional:

-                      {status.linuxdo_oauth ? t('绑定') : t('未启用')}
+                      {getBindingButtonText(
+                        Boolean(status.linuxdo_oauth),
+                        Boolean(userState.user?.linux_do_id)
+                      )}

Also applies to: 383-389

Comment on lines +89 to +97
const getBindingStatusText = (enabled, bound) => {
if (bound) {
return t('已绑定');
}
if (!enabled) {
return t('未启用');
}
return t('未绑定');
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Make “未启用” take precedence in status text.

When a provider is disabled, show “未启用” even if the user had bound previously (matches PR intent).

Apply:

-  const getBindingStatusText = (enabled, bound) => {
-    if (bound) {
-      return t('已绑定');
-    }
-    if (!enabled) {
-      return t('未启用');
-    }
-    return t('未绑定');
-  };
+  const getBindingStatusText = (enabled, bound) => {
+    if (!enabled) return t('未启用');
+    return bound ? t('已绑定') : t('未绑定');
+  };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const getBindingStatusText = (enabled, bound) => {
if (bound) {
return t('已绑定');
}
if (!enabled) {
return t('未启用');
}
return t('未绑定');
};
const getBindingStatusText = (enabled, bound) => {
if (!enabled) return t('未启用');
return bound ? t('已绑定') : t('未绑定');
};
🤖 Prompt for AI Agents
In web/src/components/settings/personal/cards/AccountManagement.jsx around lines
89 to 97, the status text currently returns '已绑定' before checking whether the
provider is enabled; change the logic so the "not enabled" case takes precedence
by checking if (!enabled) first and returning t('未启用'), then check bound to
return t('已绑定') and finally return t('未绑定') as the fallback.

Comment on lines +99 to +105
const getBindingButtonText = (enabled, bound) => {
if (bound) {
return t('修改绑定');
}
return enabled ? t('绑定') : t('未启用');
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Button label should also prioritize “未启用”.

Avoid showing “修改绑定/绑定” when disabled.

-  const getBindingButtonText = (enabled, bound) => {
-    if (bound) {
-      return t('修改绑定');
-    }
-    return enabled ? t('绑定') : t('未启用');
-  };
+  const getBindingButtonText = (enabled, bound) => {
+    if (!enabled) return t('未启用');
+    return bound ? t('修改绑定') : t('绑定');
+  };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const getBindingButtonText = (enabled, bound) => {
if (bound) {
return t('修改绑定');
}
return enabled ? t('绑定') : t('未启用');
};
const getBindingButtonText = (enabled, bound) => {
if (!enabled) return t('未启用');
return bound ? t('修改绑定') : t('绑定');
};
🤖 Prompt for AI Agents
In web/src/components/settings/personal/cards/AccountManagement.jsx around lines
99 to 105, the getBindingButtonText currently returns '修改绑定' when bound even if
the feature is disabled; change the logic to first check if enabled is false and
return t('未启用'), otherwise if bound return t('修改绑定'), else return t('绑定') so the
button never shows bind/modify when the feature is disabled.

Comment on lines +106 to +118
const renderProviderBinding = (enabled, accountId, label) => {
const hasAccountId = Boolean(accountId && accountId !== '');

if (hasAccountId) {
return renderAccountInfo(accountId, label);
}

if (!enabled) {
return <span className='text-gray-500'>{t('未启用')}</span>;
}

return renderAccountInfo(accountId, label);
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

renderProviderBinding should show “未启用” even if bound.

Current check renders the account ID when disabled; flip the order.

   const renderProviderBinding = (enabled, accountId, label) => {
     const hasAccountId = Boolean(accountId && accountId !== '');
-
-    if (hasAccountId) {
-      return renderAccountInfo(accountId, label);
-    }
-
-    if (!enabled) {
-      return <span className='text-gray-500'>{t('未启用')}</span>;
-    }
-
-    return renderAccountInfo(accountId, label);
+    if (!enabled) {
+      return <span className='text-gray-500'>{t('未启用')}</span>;
+    }
+    return renderAccountInfo(accountId, label);
   };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const renderProviderBinding = (enabled, accountId, label) => {
const hasAccountId = Boolean(accountId && accountId !== '');
if (hasAccountId) {
return renderAccountInfo(accountId, label);
}
if (!enabled) {
return <span className='text-gray-500'>{t('未启用')}</span>;
}
return renderAccountInfo(accountId, label);
};
const renderProviderBinding = (enabled, accountId, label) => {
const hasAccountId = Boolean(accountId && accountId !== '');
if (!enabled) {
return <span className='text-gray-500'>{t('未启用')}</span>;
}
return renderAccountInfo(accountId, label);
};
🤖 Prompt for AI Agents
In web/src/components/settings/personal/cards/AccountManagement.jsx around lines
106 to 118, the rendering logic currently checks for accountId before enabled;
change the order so that if enabled is false you immediately return the "未启用"
span (even if accountId exists), otherwise proceed to check hasAccountId and
renderAccountInfo when present, falling back to your existing empty/default
rendering when enabled but no accountId. Ensure the enabled-check is evaluated
first so disabled providers always show "未启用".

@RedwindA
RedwindA marked this pull request as draft September 28, 2025 09:04
@RedwindA RedwindA closed this Sep 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant