-
Notifications
You must be signed in to change notification settings - Fork 448
fix: add user info to app-center #1734
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughAdds a header user area with tenant/org switcher and user menu popovers; wires to meta-driven login state ( Changes
Sequence Diagram(s)sequenceDiagram
participant Header as DesignWorkspace (Header)
participant Meta as Meta API
participant Router as Router
participant Storage as Token Store
Header->>Meta: read userInfo & tenantList on mount
Meta-->>Header: return userInfo, tenantList
Header->>Header: render TinyPopover tenant switcher & user menu
Header->>Meta: changeTenant(tenantId)
Meta->>Storage: (may) update/clear token
Meta-->>Router: provide tenant-scoped URL
Header->>Router: navigate to tenant-scoped URL
Header->>Meta: logOut()
Meta->>Storage: clear token
Header->>Router: navigate to login/start flow
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In @packages/layout/src/DesignWorkspace.vue:
- Around line 122-129: The changeTenant flow calls setTenantInfo(id) but lacks
error handling; wrap the promise with a .catch() (or use try/catch if converting
to async) on setTenantInfo in changeTenant to prevent unhandled rejections, log
the error (e.g., console.error) and surface a user-facing message (use the app's
notification/toast mechanism or fallback to alert) and do not perform
setUserInfo/localStorage/window.location.href redirect on failure; keep
references to setTenantInfo, setUserInfo, localStorage.setItem('engineToken'),
and window.location.href when implementing this fix.
- Around line 116-120: The computed tenantValue can be undefined when
enableLogin is true and tenantList is empty, causing a runtime error when the
template reads tenantValue.label; update the computed or the template to guard
against empty lists: either change the tenantValue computed (referencing
tenantList, enableLogin, getBaseInfo) to return a safe fallback object (e.g.,
baseInfo with label) when no tenant is found, or change the template access to
use optional chaining/null check (e.g., tenantValue?.label) so the UI does not
throw when tenantValue is undefined.
- Around line 235-289: The scoped CSS targets (.user-name, .divider, .user-out,
.dropdown-menu__items) won’t apply to tiny-popover content because it may be
teleported; add a popper-class attribute to each <tiny-popover> instance (e.g.,
popper-class="workspace-popover" and popper-class="workspace-popover-tenant")
and move the related rules into an unscoped style block using those popper-class
prefixes (e.g., .workspace-popover .user-name, .workspace-popover .divider,
.workspace-popover .user-out, .workspace-popover-tenant .dropdown-menu__items
etc.), keeping selectors and styling the same but defined outside the scoped
styles so teleported popover content is styled correctly.
🧹 Nitpick comments (1)
packages/layout/src/DesignWorkspace.vue (1)
14-37: Consider adding loading state during tenant switch.When
changeTenantis called (line 29), there's no visual feedback while awaiting the API response. If the network is slow, users may click multiple times or be confused.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
packages/design-core/assets/log-out.svgis excluded by!**/*.svgpackages/design-core/assets/organize.svgis excluded by!**/*.svg
📒 Files selected for processing (2)
packages/layout/src/DesignWorkspace.vuepackages/layout/src/styles/vars.less
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-01-14T06:49:00.797Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1011
File: packages/configurator/src/router-select-configurator/RouterSelectConfigurator.vue:63-73
Timestamp: 2025-01-14T06:49:00.797Z
Learning: In the tiny-engine project, the SvgIcon component is globally registered and available throughout Vue components without requiring explicit imports.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-14T06:49:00.797Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1011
File: packages/configurator/src/router-select-configurator/RouterSelectConfigurator.vue:63-73
Timestamp: 2025-01-14T06:49:00.797Z
Learning: In the tiny-engine project, the SvgIcon component is globally registered using `app.component('SvgIcon', SvgIcon)` in `packages/svgs/index.js`, making it available throughout Vue components without requiring explicit imports.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-14T06:55:59.692Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1011
File: packages/configurator/src/router-select-configurator/RouterSelectConfigurator.vue:95-98
Timestamp: 2025-01-14T06:55:59.692Z
Learning: The tiny-select component from opentiny/vue library ensures selected options are valid internally, requiring no additional validation in the change handler.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2024-10-10T02:47:46.239Z
Learnt from: yy-wow
Repo: opentiny/tiny-engine PR: 850
File: packages/toolbars/preview/src/Main.vue:16-16
Timestamp: 2024-10-10T02:47:46.239Z
Learning: In `packages/toolbars/preview/src/Main.vue`, within the `preview` function, the `getMergeMeta` method is used at lines 64 and 65 to retrieve `engine.config` configurations.
Applied to files:
packages/layout/src/DesignWorkspace.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: push-check
🔇 Additional comments (1)
packages/layout/src/styles/vars.less (1)
9-19: LGTM!The new CSS variables follow the established naming convention and properly map to global tokens. These support the dropdown styling needs in the workspace header.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In @packages/layout/src/DesignWorkspace.vue:
- Line 22: DesignWorkspace.vue contains hard-coded Chinese strings ("选择组织",
"暂无相关数据", "退出登录"); replace them with i18n lookups (e.g., use $t or i18n.t) and
add corresponding keys to your locale files; update the template locations where
these literals appear in the DesignWorkspace component so they call the
translation function (use consistent keys like workspace.selectOrganization,
workspace.noData, workspace.logout) and ensure the new keys are added to all
locale JSON/YAML files used by the app.
- Around line 139-148: The code in onMounted uses tenantList.value[0].id without
ensuring tenantList has any items, which can throw if empty; update the logic
around enableLogin/getBaseInfo/tenantList so you first read const baseTenant =
getBaseInfo().tenantId and const firstTenant = tenantList?.value &&
tenantList.value.length ? tenantList.value[0].id : undefined, then choose
tenantId = baseTenant || firstTenant (or skip appending if both undefined)
before creating the URL and calling url.searchParams.append; ensure checks use
tenantList (or tenantList.value) existence and length to guard array access in
DesignWorkspace.vue.
- Around line 116-120: tenantValue can become undefined when enableLogin is true
but tenantList.value is empty; update the computed for tenantValue to handle an
empty tenantList by falling back to getBaseInfo() (with label: 'Public' or
appropriate label) when find(...) returns undefined and tenantList.value[0] is
undefined; specifically adjust the computed that references enableLogin,
tenantList, and getBaseInfo so it returns a safe object in all cases to avoid
template errors when accessing tenantValue.label.
- Around line 131-134: The logout handler (logOut) only removes the token and
flips setNeedToLogin, leaving userInfo/tenantInfo in state and risking stale
data; update logOut to explicitly clear all user-related state by calling the
appropriate setters (e.g., setUserInfo to an empty/default object and
setTenantInfo to null/default) immediately after
localStorage.removeItem('engineToken' and before setNeedToLogin) so the app has
no residual user data while transitioning to the login flow.
- Around line 122-128: The changeTenant handler calls setTenantInfo(id) without
error handling; add a .catch on that promise (or convert changeTenant to
async/await with try/catch) to handle API failures, e.g., log the error and
surface user feedback (toast/alert/set an error state) instead of letting the
rejection go unhandled; preserve the existing success flow that calls
setUserInfo(tenantData), stores engineToken, and redirects via
window.location.href.
🧹 Nitpick comments (1)
packages/layout/src/DesignWorkspace.vue (1)
14-52: Add accessibility attributes to interactive elements.The popovers and interactive elements lack ARIA attributes for screen reader accessibility:
- The tenant switcher and user menu triggers should have
aria-labeloraria-labelledbyattributes- The dropdown menu items should have
role="menu"androle="menuitem"attributes- Consider adding
aria-expandedstate to the popover triggers♿ Example accessibility improvements
<tiny-popover :visible-arrow="false" width="150" trigger="click"> <template #reference> - <div class="tenant-wrapper"> + <div class="tenant-wrapper" role="button" aria-label="Switch organization" tabindex="0"> <span>{{ tenantValue.label }}</span> <svg-icon class="expand-icon" name="down-arrow"></svg-icon> </div> </template> - <div class="dropdown-menu__items"> + <div class="dropdown-menu__items" role="menu"> <div class="tenant-title">选择组织</div> <div v-if="tenantList.length"> <div class="dropdown-menu__item" + role="menuitem" + tabindex="0" :class="{ 'active-menu': item.id === tenantValue?.id }" v-for="item in tenantList" :key="item.id" @click="changeTenant(item.id)" + @keydown.enter="changeTenant(item.id)" >
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/layout/src/DesignWorkspace.vue
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-01-14T04:25:46.281Z
Learnt from: rhlin
Repo: opentiny/tiny-engine PR: 1011
File: packages/canvas/render/src/material-function/material-getter.ts:66-80
Timestamp: 2025-01-14T04:25:46.281Z
Learning: In the tiny-engine project, styles from block components are processed through Vite's CSS compilation pipeline, and additional style sanitization libraries should be avoided to maintain consistency with this approach.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-03-19T03:13:51.520Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1226
File: packages/canvas/container/src/components/CanvasDivider.vue:184-185
Timestamp: 2025-03-19T03:13:51.520Z
Learning: The CSS bug in packages/canvas/container/src/components/CanvasDivider.vue where verLeft already includes "px" but is being appended again in the style object will be fixed in a future update, as confirmed by gene9831.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-14T06:49:00.797Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1011
File: packages/configurator/src/router-select-configurator/RouterSelectConfigurator.vue:63-73
Timestamp: 2025-01-14T06:49:00.797Z
Learning: In the tiny-engine project, the SvgIcon component is globally registered and available throughout Vue components without requiring explicit imports.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-15T02:19:06.755Z
Learnt from: yy-wow
Repo: opentiny/tiny-engine PR: 940
File: packages/canvas/DesignCanvas/src/DesignCanvas.vue:0-0
Timestamp: 2025-01-15T02:19:06.755Z
Learning: In Vue components using message subscriptions from opentiny/tiny-engine-meta-register, always clean up subscriptions in the onUnmounted hook using useMessage().unsubscribe() to prevent memory leaks.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-14T06:49:00.797Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1011
File: packages/configurator/src/router-select-configurator/RouterSelectConfigurator.vue:63-73
Timestamp: 2025-01-14T06:49:00.797Z
Learning: In the tiny-engine project, the SvgIcon component is globally registered using `app.component('SvgIcon', SvgIcon)` in `packages/svgs/index.js`, making it available throughout Vue components without requiring explicit imports.
Applied to files:
packages/layout/src/DesignWorkspace.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: push-check
🔇 Additional comments (2)
packages/layout/src/DesignWorkspace.vue (2)
72-80: LGTM: Imports and component registration.The imports and component registration follow Vue 3 best practices. The meta API integration and TinyPopover component are properly set up.
246-300: All CSS custom properties are properly defined inpackages/layout/src/styles/vars.less. No issues found.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/toolbars/user/src/Main.vue (1)
118-124: Verify token handling and consider consolidating duplicate logic.The removal of
localStorage.setItem('engineToken', tenantData.token)conflicts with the PR's stated goal ("fix: token is not changed when tenant is changed"). IfsetTenantInfodoes not internally persist the token to localStorage, tenant switches may fail to update authentication state.Additionally, this
changeTenantimplementation duplicates the one inDesignWorkspace.vue(lines 122-128), creating a maintenance burden.Run the following script to check if
setTenantInfohandles token persistence:#!/bin/bash # Description: Verify whether setTenantInfo internally stores the token in localStorage # Search for setTenantInfo implementation ast-grep --pattern $'setTenantInfo($_) { $$$ }' # Search for localStorage.setItem calls related to engineToken rg -nP --type=ts --type=js -C3 'localStorage\.setItem.*engineToken'
🤖 Fix all issues with AI agents
In @packages/layout/src/DesignWorkspace.vue:
- Around line 116-120: The computed tenantValue can become undefined when
enableLogin is true and tenantList is empty; update the tenantValue computed
(the expression using tenantList.value.find(...) || tenantList.value[0]) to
explicitly guard for an empty tenantList and return a safe fallback object
(e.g., { ...getBaseInfo(), label: 'Public' }) when no matching tenant is found
or tenantList.value.length === 0 so template access like tenantValue.label never
errors.
- Around line 130-133: The logOut function in DesignWorkspace.vue duplicates
behavior already implemented in Main.vue's changeTenant/logOut logic; extract
the shared behavior (clearing 'engineToken' and invoking setNeedToLogin) into a
single exported helper (e.g., authHelpers.clearSession or authHelpers.logOut) in
a new/common module, update DesignWorkspace.vue to import and call that helper
instead of its local logOut, and update packages/toolbars/user/src/Main.vue to
use the same helper for changeTenant/logOut so both components share the single
implementation.
- Around line 138-147: The code in the onMounted block reads
tenantList.value[0].id without ensuring tenantList.value is a non-empty array,
which can throw when a user has no tenants; update the tenantId resolution in
that block (where getBaseInfo() and tenantList are used) to safely access the
first tenant (e.g., check tenantList.value && tenantList.value.length > 0 before
using tenantList.value[0].id or use optional chaining like
tenantList.value?.[0]?.id) and only append the ?tenant param when a valid
tenantId is present.
- Around line 122-128: The changeTenant function lacks error handling and
duplicates logic found in Main.vue; update changeTenant (the function that calls
setTenantInfo and then setUserInfo and redirects via window.location.href) to
attach a .catch handler that logs the error and shows user feedback (e.g., toast
or alert) on failure, and refactor by extracting changeTenant (and related
logout logic like logOut if present) into a shared composable/utility used by
both DesignWorkspace.vue and packages/toolbars/user/src/Main.vue to remove
duplication and centralize error handling.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/layout/src/DesignWorkspace.vuepackages/toolbars/user/src/Main.vue
🧰 Additional context used
🧠 Learnings (10)
📚 Learning: 2025-01-14T04:25:46.281Z
Learnt from: rhlin
Repo: opentiny/tiny-engine PR: 1011
File: packages/canvas/render/src/material-function/material-getter.ts:66-80
Timestamp: 2025-01-14T04:25:46.281Z
Learning: In the tiny-engine project, styles from block components are processed through Vite's CSS compilation pipeline, and additional style sanitization libraries should be avoided to maintain consistency with this approach.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-03-19T03:13:51.520Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1226
File: packages/canvas/container/src/components/CanvasDivider.vue:184-185
Timestamp: 2025-03-19T03:13:51.520Z
Learning: The CSS bug in packages/canvas/container/src/components/CanvasDivider.vue where verLeft already includes "px" but is being appended again in the style object will be fixed in a future update, as confirmed by gene9831.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-14T06:59:23.602Z
Learnt from: rhlin
Repo: opentiny/tiny-engine PR: 1011
File: packages/canvas/render/src/page-block-function/methods.ts:9-21
Timestamp: 2025-01-14T06:59:23.602Z
Learning: The code in packages/canvas/render/src/page-block-function/methods.ts is migrated code that should not be modified during the migration phase. Error handling improvements can be addressed in future PRs.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2024-10-30T02:19:30.876Z
Learnt from: yy-wow
Repo: opentiny/tiny-engine PR: 886
File: packages/toolbars/logout/src/js/http.js:16-16
Timestamp: 2024-10-30T02:19:30.876Z
Learning: In the `packages/toolbars/logout/src/js/http.js` file, errors for the `requestLogout` function are handled by the user, so additional error handling within the function is not necessary.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-14T06:49:00.797Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1011
File: packages/configurator/src/router-select-configurator/RouterSelectConfigurator.vue:63-73
Timestamp: 2025-01-14T06:49:00.797Z
Learning: In the tiny-engine project, the SvgIcon component is globally registered and available throughout Vue components without requiring explicit imports.
Applied to files:
packages/layout/src/DesignWorkspace.vuepackages/toolbars/user/src/Main.vue
📚 Learning: 2025-01-15T02:19:06.755Z
Learnt from: yy-wow
Repo: opentiny/tiny-engine PR: 940
File: packages/canvas/DesignCanvas/src/DesignCanvas.vue:0-0
Timestamp: 2025-01-15T02:19:06.755Z
Learning: In Vue components using message subscriptions from opentiny/tiny-engine-meta-register, always clean up subscriptions in the onUnmounted hook using useMessage().unsubscribe() to prevent memory leaks.
Applied to files:
packages/layout/src/DesignWorkspace.vuepackages/toolbars/user/src/Main.vue
📚 Learning: 2025-01-14T06:49:00.797Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1011
File: packages/configurator/src/router-select-configurator/RouterSelectConfigurator.vue:63-73
Timestamp: 2025-01-14T06:49:00.797Z
Learning: In the tiny-engine project, the SvgIcon component is globally registered using `app.component('SvgIcon', SvgIcon)` in `packages/svgs/index.js`, making it available throughout Vue components without requiring explicit imports.
Applied to files:
packages/layout/src/DesignWorkspace.vuepackages/toolbars/user/src/Main.vue
📚 Learning: 2025-01-14T10:06:25.508Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1041
File: packages/plugins/datasource/src/DataSourceList.vue:138-138
Timestamp: 2025-01-14T10:06:25.508Z
Learning: PR #1041 in opentiny/tiny-engine is specifically for reverting Prettier v3 formatting to v2, without any logical code changes or syntax improvements.
Applied to files:
packages/toolbars/user/src/Main.vue
📚 Learning: 2024-10-10T02:48:10.881Z
Learnt from: yy-wow
Repo: opentiny/tiny-engine PR: 850
File: packages/toolbars/preview/src/Main.vue:0-0
Timestamp: 2024-10-10T02:48:10.881Z
Learning: 在 `packages/toolbars/preview/src/Main.vue` 文件中,使用 `useNotify` 而不是 `console` 来记录错误日志。
Applied to files:
packages/toolbars/user/src/Main.vue
📚 Learning: 2025-01-14T06:55:59.692Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1011
File: packages/configurator/src/router-select-configurator/RouterSelectConfigurator.vue:95-98
Timestamp: 2025-01-14T06:55:59.692Z
Learning: The tiny-select component from opentiny/vue library ensures selected options are valid internally, requiring no additional validation in the change handler.
Applied to files:
packages/toolbars/user/src/Main.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: push-check
🔇 Additional comments (4)
packages/layout/src/DesignWorkspace.vue (4)
72-75: LGTM!The imports are appropriate for the new login state handling and popover UI components.
173-173: LGTM!The styling changes are well-structured, use CSS variables consistently for theming, and follow the project's conventions.
Also applies to: 179-203, 245-299
79-79: LGTM!Component registration and meta API setup are correctly implemented.
Also applies to: 99-101
13-53: The concern about unsafe access touserInfo.usernameis not valid. TheuserState.userInfois initialized with default values includingusername: ''(line 48-53 inpackages/common/composable/defaultGlobalService.ts), andgetUserInfo()always returns this initialized object. Even if thefetchUserInfo()API call fails during service initialization, the default values persist, ensuringuserInfo.usernamealways exists as a property.Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🤖 Fix all issues with AI agents
In @packages/layout/src/DesignWorkspace.vue:
- Around line 44-46: The username display currently renders userInfo.username
directly (in the element with class "user-name" and the svg-icon), which shows
"undefined" when username is missing; update the template to use optional
chaining on userInfo (e.g., userInfo?.username) with a sensible fallback string
like "Guest" or "Anonymous" so the UI never displays "undefined".
- Around line 122-128: The changeTenant function calls setTenantInfo without any
error handling; wrap the async flow so failures from setTenantInfo are caught
and handled (either by using async/await with try/catch or adding a .catch on
the returned promise), call setUserInfo only on success, and on error log the
error and show user-facing feedback (e.g., via an existing toast/notification or
processLogger) to avoid leaving the app in an inconsistent state while
preserving the existing redirect behavior inside the success path.
- Around line 116-120: tenantValue computed can become undefined when
enableLogin is true and tenantList is empty, causing template access to
tenantValue.label to throw; update the computed (tenantValue) to fall back to a
safe object when no match exists (e.g., use getBaseInfo() or a default {
...getBaseInfo(), label: 'Public' } if tenantList.value[0] is undefined) so
tenantValue always has a label property; reference the computed tenantValue,
tenantList, enableLogin, and getBaseInfo when making this change.
- Around line 138-147: The onMounted hook reads tenantList.value[0].id without
ensuring tenantList has elements, which can throw when the list is empty; update
the logic in the onMounted block (where enableLogin, getBaseInfo(), and
tenantList are used) to first check tenantList.value?.length > 0 and only use
tenantList.value[0].id when present, otherwise fall back to a safe default
(e.g., use getBaseInfo().tenantId, null, or skip appending the tenant query
param) and avoid indexing an empty array to prevent the TypeError.
- Around line 48-51: Replace the non-semantic clickable div with a proper button
to make the logout action keyboard accessible: change the element with class
"user-out" that currently has @click="logOut" into a <button type="button">
(keeping the same class and @click binding), ensure it has an accessible label
(e.g., visible text "退出登录" or aria-label) and retains the nested svg-icon with
class "out-icon"; then update the component styles to reset button defaults
(remove browser padding, border, background) so appearance stays the same while
restoring keyboard/focus behavior.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/layout/src/DesignWorkspace.vue
🧰 Additional context used
🧠 Learnings (8)
📚 Learning: 2025-01-14T04:25:46.281Z
Learnt from: rhlin
Repo: opentiny/tiny-engine PR: 1011
File: packages/canvas/render/src/material-function/material-getter.ts:66-80
Timestamp: 2025-01-14T04:25:46.281Z
Learning: In the tiny-engine project, styles from block components are processed through Vite's CSS compilation pipeline, and additional style sanitization libraries should be avoided to maintain consistency with this approach.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-03-19T03:13:51.520Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1226
File: packages/canvas/container/src/components/CanvasDivider.vue:184-185
Timestamp: 2025-03-19T03:13:51.520Z
Learning: The CSS bug in packages/canvas/container/src/components/CanvasDivider.vue where verLeft already includes "px" but is being appended again in the style object will be fixed in a future update, as confirmed by gene9831.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2024-10-30T02:19:30.876Z
Learnt from: yy-wow
Repo: opentiny/tiny-engine PR: 886
File: packages/toolbars/logout/src/js/http.js:16-16
Timestamp: 2024-10-30T02:19:30.876Z
Learning: In the `packages/toolbars/logout/src/js/http.js` file, errors for the `requestLogout` function are handled by the user, so additional error handling within the function is not necessary.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2024-10-15T02:45:17.168Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 830
File: packages/common/component/MetaChildItem.vue:50-56
Timestamp: 2024-10-15T02:45:17.168Z
Learning: In `packages/common/component/MetaChildItem.vue`, when checking if `text` is an object in the computed property `title`, ensure that `text` is not `null` because `typeof null === 'object'` in JavaScript. Use checks like `text && typeof text === 'object'` to safely handle `null` values.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-14T06:50:21.158Z
Learnt from: rhlin
Repo: opentiny/tiny-engine PR: 1011
File: packages/canvas/render/src/data-function/parser.ts:191-195
Timestamp: 2025-01-14T06:50:21.158Z
Learning: The `newFn` function in `packages/canvas/render/src/data-function/parser.ts` has a known security issue with evaluating untrusted code through `data.value`. This was identified during code review but intentionally deferred as the original implementation was kept during code refactoring.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-14T06:49:00.797Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1011
File: packages/configurator/src/router-select-configurator/RouterSelectConfigurator.vue:63-73
Timestamp: 2025-01-14T06:49:00.797Z
Learning: In the tiny-engine project, the SvgIcon component is globally registered and available throughout Vue components without requiring explicit imports.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-15T02:19:06.755Z
Learnt from: yy-wow
Repo: opentiny/tiny-engine PR: 940
File: packages/canvas/DesignCanvas/src/DesignCanvas.vue:0-0
Timestamp: 2025-01-15T02:19:06.755Z
Learning: In Vue components using message subscriptions from opentiny/tiny-engine-meta-register, always clean up subscriptions in the onUnmounted hook using useMessage().unsubscribe() to prevent memory leaks.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-14T06:49:00.797Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1011
File: packages/configurator/src/router-select-configurator/RouterSelectConfigurator.vue:63-73
Timestamp: 2025-01-14T06:49:00.797Z
Learning: In the tiny-engine project, the SvgIcon component is globally registered using `app.component('SvgIcon', SvgIcon)` in `packages/svgs/index.js`, making it available throughout Vue components without requiring explicit imports.
Applied to files:
packages/layout/src/DesignWorkspace.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: push-check
🔇 Additional comments (3)
packages/layout/src/DesignWorkspace.vue (3)
72-75: LGTM!The new imports are appropriate and correctly used throughout the component.
245-299: LGTM on styling!The new dropdown and user menu styles are well-structured and properly use CSS custom properties for theming. The layout is clean and follows the existing design patterns.
125-126: No issue identified.The hard redirect for tenant switching is the correct architectural approach. Tenant switching requires complete application reinitialization with new tenant context (via
setTenantInfoandsetUserInfo), not just route navigation. A full page reload ensures proper security isolation and state cleanup between tenant contexts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In @packages/layout/src/DesignWorkspace.vue:
- Around line 125-128: The logout handler logOut currently removes 'engineToken'
and calls setNeedToLogin(true) immediately; change it to prompt the user for
confirmation first (e.g., via window.confirm or the TinyVue confirmation/modal
component if available) and only run localStorage.removeItem('engineToken') and
setNeedToLogin(true) when the user confirms, otherwise abort the logout; update
the logOut function in DesignWorkspace.vue accordingly and ensure any modal
cleanup or state is handled if you use a component-based dialog.
- Around line 114-118: The computed tenantValue may return undefined when
enableLogin is true and tenantList is empty; update the tenantValue computation
to guard tenantList.value before accessing [0] (use a nullish/fallback when
tenantList.value.length === 0) and/or fall back to a safe object constructed
from getBaseInfo() (including a default label like 'Public' or 'Unknown') so
tenantValue always yields a valid object for the UI; adjust any references to
tenantList.value.find(...) to handle no-match by checking
tenantList.value.length and returning the safe fallback.
- Around line 133-142: The mount logic can crash because tenantList.value[0].id
is accessed without ensuring tenantList has elements; update the onMounted block
(where enableLogin is checked) to compute tenantId safely by preferring
getBaseInfo().tenantId and falling back to the first tenant only if
tenantList.value has length, e.g. check tenantList.value?.length > 0 before
using tenantList.value[0].id, and only append the 'tenant' search param when
tenantId is defined; use optional chaining/nullish checks so no access occurs on
an empty array.
- Around line 120-123: The changeTenant function currently builds a new URL and
clobbers existing query params; update it to read the current URLSearchParams
(via the URL or URLSearchParams APIs), set or update only the "type" and
"tenant" keys (type="app", tenant=id) while preserving all other parameters,
then reconstruct window.location.href using window.location.origin +
window.location.pathname + '?' + params.toString(); keep the function name
changeTenant and only modify its internals to perform this safe param merge.
🧹 Nitpick comments (2)
packages/layout/src/DesignWorkspace.vue (2)
14-52: Consider adding accessibility attributes to popovers.The popovers lack ARIA labels and keyboard navigation hints that would improve accessibility for screen reader users and keyboard-only navigation.
♿ Suggested accessibility improvements
Add descriptive aria-labels to help users understand the purpose of each interactive element:
- <tiny-popover :visible-arrow="false" width="150" trigger="click"> + <tiny-popover :visible-arrow="false" width="150" trigger="click" aria-label="Select organization"> <template #reference> - <div class="tenant-wrapper"> + <div class="tenant-wrapper" role="button" tabindex="0" aria-label="Current organization"> <span>{{ tenantValue.label }}</span>- <tiny-popover :visible-arrow="false" width="150" trigger="click"> + <tiny-popover :visible-arrow="false" width="150" trigger="click" aria-label="User menu"> <template #reference> - <div> + <div role="button" tabindex="0" aria-label="User account"> <svg-icon class="user-icon" name="default-user"></svg-icon>
102-113: Refactor to reuseuserInfocomputed.The
getUserInfo()call on line 103 duplicates the computation already defined in theuserInfocomputed property above. ReusinguserInfo.valueimproves maintainability and performance.♻️ Proposed refactor
const tenantList = computed(() => { - const info = getUserInfo() + const info = userInfo.value return Array.isArray(info?.tenant) ? info.tenant?.map((item) => {
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/layout/src/DesignWorkspace.vuepackages/toolbars/user/src/Main.vue
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/toolbars/user/src/Main.vue
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-01-14T04:25:46.281Z
Learnt from: rhlin
Repo: opentiny/tiny-engine PR: 1011
File: packages/canvas/render/src/material-function/material-getter.ts:66-80
Timestamp: 2025-01-14T04:25:46.281Z
Learning: In the tiny-engine project, styles from block components are processed through Vite's CSS compilation pipeline, and additional style sanitization libraries should be avoided to maintain consistency with this approach.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-03-19T03:13:51.520Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1226
File: packages/canvas/container/src/components/CanvasDivider.vue:184-185
Timestamp: 2025-03-19T03:13:51.520Z
Learning: The CSS bug in packages/canvas/container/src/components/CanvasDivider.vue where verLeft already includes "px" but is being appended again in the style object will be fixed in a future update, as confirmed by gene9831.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2024-10-30T02:19:30.876Z
Learnt from: yy-wow
Repo: opentiny/tiny-engine PR: 886
File: packages/toolbars/logout/src/js/http.js:16-16
Timestamp: 2024-10-30T02:19:30.876Z
Learning: In the `packages/toolbars/logout/src/js/http.js` file, errors for the `requestLogout` function are handled by the user, so additional error handling within the function is not necessary.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-14T06:49:00.797Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1011
File: packages/configurator/src/router-select-configurator/RouterSelectConfigurator.vue:63-73
Timestamp: 2025-01-14T06:49:00.797Z
Learning: In the tiny-engine project, the SvgIcon component is globally registered and available throughout Vue components without requiring explicit imports.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-15T02:19:06.755Z
Learnt from: yy-wow
Repo: opentiny/tiny-engine PR: 940
File: packages/canvas/DesignCanvas/src/DesignCanvas.vue:0-0
Timestamp: 2025-01-15T02:19:06.755Z
Learning: In Vue components using message subscriptions from opentiny/tiny-engine-meta-register, always clean up subscriptions in the onUnmounted hook using useMessage().unsubscribe() to prevent memory leaks.
Applied to files:
packages/layout/src/DesignWorkspace.vue
📚 Learning: 2025-01-14T06:49:00.797Z
Learnt from: gene9831
Repo: opentiny/tiny-engine PR: 1011
File: packages/configurator/src/router-select-configurator/RouterSelectConfigurator.vue:63-73
Timestamp: 2025-01-14T06:49:00.797Z
Learning: In the tiny-engine project, the SvgIcon component is globally registered using `app.component('SvgIcon', SvgIcon)` in `packages/svgs/index.js`, making it available throughout Vue components without requiring explicit imports.
Applied to files:
packages/layout/src/DesignWorkspace.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: push-check
🔇 Additional comments (1)
packages/layout/src/DesignWorkspace.vue (1)
240-294: CSS variables are properly defined. All referenced CSS variables (--te-layout-common-text-color-weaken,--te-layout-common-text-color-secondary,--te-layout-common-border-color,--te-layout-workspace-dropdown-bg-color-hover, and--te-layout-workspace-dropdown-bg-color-active) are defined inpackages/layout/src/styles/vars.lessand will resolve correctly without fallback to browser defaults.
English | 简体中文
PR
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
Background and solution
登录后选择组织

登录后用户信息展示

本地开发选择组织

本地开发用户信息展示

What is the current behavior?
Issue Number: N/A
What is the new behavior?
Does this PR introduce a breaking change?
Other information
Summary by CodeRabbit
New Features
Style
✏️ Tip: You can customize this high-level summary in your review settings.