* feat(client-v2): add standalone settings SPA
* style(client-v2): use primary header color
* fix(plugin-ui-layout): hide mobile menu
* style(client-v2): regroup settings action
* fix(client-v2): match settings header color
* fix(client-v2): group portal manager
* fix(client-v2): group topbar managers
* feat(multi-portal): add portal routes
* feat(client-v2): rework settings center into a portal-first admin console
Settings V2 is currently shaped as "one sidebar + horizontal tabs in the content
area": you land on System settings after signing in, and the topbar is deep blue.
This reshapes it into an application-first admin console.
- Land on the portal center by default: `getDefaultSettingsPath` now prefers
`multi-portal`, so signing in shows the application entry first and system
configuration is a drill-down from there.
- Turn the portal manager from a table into a gallery: cover, title, access path,
type tag and enabled switch, four icon actions in the hover row, and a dashed
add card at the end. Portals without a cover get a low-saturation gradient
derived from a hash of their uid, stable across refreshes.
- Split navigation into two levels: top-level groups (Applications / Data /
Automation / Users & Permissions / System) in the topbar, nested second- and
third-level menus of the active group in the sidebar, and drop the horizontal
tabs from the content area. Group membership resolves from the setting's own
`group` field, then a built-in map, then falls back to System, so third-party
plugins still show up without any code change. When a group holds a single
entry with no children the sidebar is not rendered, avoiding one lonely item
that just repeats the group name in the topbar.
- Collapse the theme to neutral grays: container background with a hairline
divider in the topbar, neutral dark gray for primary / link / switch, flipped
to light gray under a dark theme. This exposed two white-on-white cases, both
fixed: the site logo is forced to a single tone (the default logo is a white
mark drawn for the deep blue topbar), and `colorTextHeaderMenu` is overridden
to the body text color inside the settings shell.
- Add a muted `Settings` suffix after the topbar logo. It is part of the product
mark and is deliberately not translated — flipping between "设置 / 設定 /
Settings" with the UI language makes the brand area unstable.
- Rearrange the portal form: type choice on top, new portals default to AI
portal. For AI portals an optional git repository URL follows immediately —
filling it in auto-derives title and name (and stops overriding them once the
user edits either) and reveals branch / path; leaving it empty means the source
is managed inside NocoBase. The old "source storage" radio group is gone, the
value is derived from whether a repository URL was entered.
- Add a portal cover stored under `options.cover` (a json column, no schema
change). The upload control is extracted from the logo upload in
`SystemSettingsPage` into a shared `AttachmentUpload` that validates size and
mimetype against the real rules of the default storage; both call sites now
share one implementation.
No server-side changes; `@nocobase/client-v2` gains `AttachmentUpload` and
`useACLSnippets` and removes nothing.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3FeT65Q1iyGpbAZb9J8qr
* fix(app): normalize settings dev root
* feat(auth): add settings SPA sign-in
* docs(auth): add settings sign-in plan
* fix(client-v2): align settings embed layout
* fix(client-v2): normalize settings app URLs
* feat(multi-portal): unify client v2 portals
* fix(ci): repair PR validation failures
* fix(client-v2): flatten scoped settings URLs
* fix(client-v2): redirect roots to settings
* fix(cli): initialize AI portal env defaults
* fix(cli): remove portal setup from init
* fix(cli): skip unsupported portal registry sync
* fix(cli): narrow init env config types
* refactor(multi-portal): use fixed portal uids
* fix(client-v2): follow the shared header theme and add settings search
Header theme
- Settings header now uses the shared `colorBgHeader` / `colorTextHeaderMenu`
tokens instead of a pinned brand color, so the theme editor drives it the
same way it drives the business-side header.
- Drops the logo single-tone filter and the topbar icon color overrides that
only existed to compensate for the pinned light header.
- Sets `colorTextLightSolid` alongside the neutral primary so primary buttons
keep their contrast in dark themes.
Settings search
- Adds a header search entry (Cmd/Ctrl+K) over the whole visible settings
tree, with recently visited items as its empty state.
- Deduplicates the index-tab entries that share their parent menu's title.
Fixes
- `useACLSnippets` now ensures the ACL store exists, so callers rendered
outside `ACLRolesCheckProvider` subscribe to it on the first render instead
of freezing on empty snippets.
- Sidebar selection resolves collapsed menu levels, so routes matching a
folded child still highlight their rendered ancestor.
- Portal options are merged over the stored value instead of being rebuilt
from the form, keeping unknown keys and legacy git config intact.
- Portal form drafts (`cover`, `git*`) no longer leak into the create/update
payload as top-level columns.
- The layout select stays editable when the edited portal has no layout yet;
required + disabled + empty used to deadlock the edit form.
- Portal card actions get accessible names.
Attachment upload
- `AttachmentUpload` now renders antd's picture-card, matching the native
attachment field: thumbnail with hover preview/remove instead of separate
upload and delete buttons.
Tests
- Rewrites the portal table assertions against the gallery, covers git URL
autofill, and stubs `AttachmentUpload` in the multi-portal suite.
- Updates the settings shell test that pinned the header to the brand color.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3FeT65Q1iyGpbAZb9J8qr
* fix(cli): skip portal registry sync during install
* feat(client-v2): regroup settings navigation and restore the portal form
Navigation
- Top level is now Applications, Plugin manager and System settings. The
first two own a single page each and render without a sidebar; everything
else falls into System settings, which is also the fallback for plugins
that declare no group.
- System settings leads with Data sources, Users & permissions, Workflow and
AI employees, separated from the rest by a divider. The divider shows both
in the sidebar and in the topbar dropdown.
- Hovering the System settings entry opens a dropdown of the same tree, so
deep pages stay one hop away.
Portal form
- Restores the explicit NocoBase / Git source storage choice for AI portals
instead of inferring it from whether a repository URL was typed; the git
fields appear once Git is picked, and filling the URL still derives the
title and name.
- Portal name moves to the top, followed by title, type and source storage.
- `Layout` becomes `Device` and now applies to both portal types: no-code
portals render with that device's components, AI portals use it for
grouping in the upcoming app switcher.
- The cover upload stays.
Portal gallery
- The open action no longer uses `href`: an anchor-rendered antd Button loses
the icon-only sizing and takes the link color, so it was visibly wider and
a different shade than the other four icons.
- The routes action no longer shows a tooltip while disabled.
Theme
- The settings header keeps its own neutral surface instead of following the
business-side `colorBgHeader`; header text, logo and the topbar icons all
use the body text color again.
Fixes
- `sourceStorage` joined `cover` and `git*` in leaking into the create/update
payload as a top-level column.
- The portal type and source storage radio groups shared an implicit name, so
the browser treated them as one mutually exclusive group and picking a
source storage cleared the portal type.
- Clearing a git repository URL no longer resurfaces the stored repository on
the next edit, which used to silently switch source storage back to git.
- `AttachmentUpload` disables itself while uploading, so a second pick cannot
be overwritten by the first request finishing late.
- The settings search shortcut yields to components that already handled
Cmd/Ctrl+K, and recently visited entries are de-duplicated on read.
Tests
- multi-portal 42/42, settings-shell 5/5, settings-center 14/14.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3FeT65Q1iyGpbAZb9J8qr
* feat(client-v2): 设置中心导航重组 + 中性主题 + 门户文案
导航:数据源 / 用户和权限 / 工作流 / AI 员工 提到顶栏一级,只有系统设置
分组还铺左栏;左栏不再下钻二级菜单,模块内部的子页面统一走页头 Tab,
和 v1 设置中心保持一致。当前分组已激活时顶栏不再弹下拉。
主题:设置中心自己套一层 ConfigProvider,把选中态、链接、开关、页签、
Spin 收成黑白灰。antd 会拿主色派生一整套色板,近黑主色派生出来的浅底是
中灰,会造成深底深字,所以派生的那几个 token 显式钉住。自绘选中态的页面
(角色列表、部门树)改读新增的 colorBgItemActive / colorTextItemActive。
文案:Portal 统一译成门户,无代码 / AI 标签改成模式,License 改许可协议;
门户卡片上显示实际可访问地址(带 /v 或 /x 前缀)而不是库里的裸 routePath。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3FeT65Q1iyGpbAZb9J8qr
* feat(theme-editor): 设置中心外观改由主题记录约束
新增一条内置主题 uid=settings,把原来写死在 settingsTheme 里的中性配色
落成 themeConfig 记录:主色收成黑白后 antd 派生出来的中灰色板会造成深底深字,
所以派生的那几个显式钉住;顶栏图标色、Menu / Select / Switch / Tabs / Spin /
Layout 的组件配置一并进记录。optional=false,不进用户的主题下拉框——
它约束的是设置中心这个作用域,不是某个人的业务端偏好。
设置中心启动时读这条记录塞进自己的 ConfigProvider;读不到(插件没启、
老实例没迁移、请求失败)回落到代码里的中性配色,不会突然变回一片蓝。
新装实例 install 时写入,老实例走 migration 补。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3FeT65Q1iyGpbAZb9J8qr
* refactor(theme-editor): 设置中心那条主题改名简约并开放复用
主题按观感命名而不是按用途:Settings → Minimal(简约),uid 跟着改成 minimal。
optional 打开,它就是一条普通的可选主题——用户想让业务端也用这套黑白观感直接选它,
以后每个应用有自己的主题时也能指向同一条记录,不用各复制一份。
设置中心只是默认指向它。
主题列表页给它挂一个「设置中心」标签,标明当前是谁在约束设置中心;
「当前主题」那个标签仍然只表示登录用户给业务端选的主题,两者互不干扰。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3FeT65Q1iyGpbAZb9J8qr
* fix(theme-editor): 简约主题默认不可选,顶栏 token 移回设置中心
optional 改回 false:这条主题约束的是设置中心这个作用域,不该混进用户的
个人偏好下拉框;要给别的应用复用时在主题编辑器里打开「可被用户选择」即可。
顶栏那几个 token(colorBgHeader / colorTextHeaderMenu 系列 / Layout.headerBg)
从记录里拿掉,移回 settingsTheme 的 withSettingsHeaderTheme。原因是记录本身通用:
业务端顶栏是深色的、logo 和图标都按深底做的,记录里把文字改成深色而底色不变,
顶栏就成了深底深字;连底色一起翻白又得给 logo 反色。设置中心的白顶栏是它自己的事,
放在壳层补,不牵连用这套主题的其他应用。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3FeT65Q1iyGpbAZb9J8qr
* fix(theme-editor): 简约主题补上紧凑算法
主题记录是整套替换而不是叠加,不带 algorithm 就退回 antd 默认的宽松间距,
比平台其他地方明显松一圈。跟「紧凑」对齐:compactAlgorithm + fontSize 16。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3FeT65Q1iyGpbAZb9J8qr
* fix(client-v2): 设置中心外观与业务端主题解耦 + 若干选中态调整
SettingsShell 里的 useToken 取的是它自己 ConfigProvider **外面**的 token,
也就是业务端主题。顶栏底色、文字色、分割线和补丁 CSS 都从那儿算,
业务端一切暗黑,顶栏就跟着变黑而内容区还是简约的白。改成先用
theme.getDesignToken() 算出简约主题自己的 token,顶栏和补丁样式都按它来。
选中态与控件:
- Select 下拉选中项从黑底白字改成浅灰底 + 正文色,下拉里压一条纯黑太重
- 左栏选中项去掉左侧竖线,只留浅底 + 加粗
- 开关禁用态改成「跟未启用同档灰的滑轨 + 更淡的圆点」。之前未启用被做成
白底描边、本身就够淡,禁用再叠透明度,两者几乎分不出来
品牌区后缀改为走多语言:中文「设置中心」,英文仍是 Settings。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3FeT65Q1iyGpbAZb9J8qr
* fix(client-v2): 登录页与 body 底色也归设置中心主题管
三处残留的耦合:
- 登录 / 二次验证页走的是 `return children`,落在设置中心的 ConfigProvider 外面,
跟的是业务端主题。业务端切暗黑后登录页是暗的、登进去又变浅,中间闪一下。
外面那层用 display:contents,只为让 .nb-settings-shell 的补丁样式命中,不动布局。
- 最外层 body 底色仍来自业务端主题;内容一般盖得住,但不满屏或橡皮筋回弹时会漏出来。
- 顶栏动作条读的 --nb-topbar-action-hover-bg 兜底值是按深色顶栏写死的浅色,一并覆盖。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3FeT65Q1iyGpbAZb9J8qr
* feat(client-v2): 设置中心兜底分组改名「其他设置」
分组原名和它下面那个「系统设置」配置项重名,容易让人以为点分组进去
就是那一页。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3FeT65Q1iyGpbAZb9J8qr
* feat(settings): 门户身份字段编辑态锁定 + 设置中心去掉主题切换入口
- 门户名 / 门户类型建好之后就是身份(名字在访问路径里、类型决定 /v 还是 /x),
编辑抽屉里一律禁用,只在新建时可填
- 门户页说明文案换成有信息量的一句
- 设置中心外观固定跟「简约」主题,用户中心里的主题切换在这里点了没反应,
只保留在业务端
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3FeT65Q1iyGpbAZb9J8qr
* fix(plugin-theme-editor): type built-in theme algorithms
---------
Co-authored-by: Zeke Zhang <958414905@qq.com>
Co-authored-by: chenos <chenlinxh@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor(plugin-ai): simplify knowledge base vector config
* feat(cli): add AI and knowledge base API commands
* fix(cli): support fields projection for AI list commands
* docs(ai-employees): simplify knowledge base vector configuration
* docs(ai-employees): sync knowledge base vector config translations
* refactor(cli): simplify AI command descriptions