@nocobase/portal-template-default 1.0.9 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (304) hide show
  1. package/.env.example +5 -0
  2. package/.github/workflows/publish.yml +106 -0
  3. package/.gitignore +33 -0
  4. package/AGENTS.md +19 -0
  5. package/README.MD +61 -180
  6. package/package.json +3 -5
  7. package/scripts/build-html.mjs +12 -0
  8. package/src/App.css +2 -0
  9. package/src/App.tsx +35 -186
  10. package/src/app/development.tsx +154 -0
  11. package/src/app/extension.ts +5 -0
  12. package/src/app/extensions.tsx +18 -4
  13. package/src/app/routes.tsx +65 -0
  14. package/src/components/access-control/acl-bootstrap.tsx +11 -3
  15. package/src/components/access-control/acl-gate.tsx +7 -6
  16. package/src/components/access-control/can-access.tsx +17 -0
  17. package/src/components/access-control/navigate-to-accessible-resource.tsx +8 -3
  18. package/src/components/app-shell/sidebar.tsx +21 -5
  19. package/src/components/auth/auto-redirect-provider.tsx +2 -1
  20. package/src/extensions/nocobase-acl/README.md +74 -0
  21. package/{registry → src/extensions}/nocobase-acl/components/acl-boundary.tsx +22 -25
  22. package/{registry → src/extensions}/nocobase-acl/components/role-switcher.tsx +26 -23
  23. package/src/extensions/nocobase-acl/demo/acl-preview-provider.tsx +81 -0
  24. package/{registry → src/extensions}/nocobase-acl/demo/boundary-api.tsx +58 -0
  25. package/{registry → src/extensions}/nocobase-acl/demo/index.tsx +243 -105
  26. package/{registry → src/extensions}/nocobase-acl/demo/prompt-generator.tsx +3 -1
  27. package/src/extensions/nocobase-acl/extension.tsx +73 -0
  28. package/{registry → src/extensions}/nocobase-ai/README.md +21 -5
  29. package/{registry → src/extensions}/nocobase-ai/components/chat/chat-composer.tsx +3 -1
  30. package/{registry → src/extensions}/nocobase-ai/components/chat/chat-messages.tsx +38 -3
  31. package/{registry → src/extensions}/nocobase-ai/components/chat/tool-call-card.tsx +1 -9
  32. package/{registry → src/extensions}/nocobase-ai/components/index.ts +5 -0
  33. package/src/extensions/nocobase-ai/components/surfaces/chat-dialog.tsx +17 -0
  34. package/src/extensions/nocobase-ai/components/surfaces/chat-side-panel.tsx +35 -0
  35. package/src/extensions/nocobase-ai/components/surfaces/chat-surface.tsx +108 -0
  36. package/{registry → src/extensions}/nocobase-ai/components/triggers/ai-chat-floating-trigger.tsx +2 -2
  37. package/{registry → src/extensions}/nocobase-ai/demo/configuration-gate.tsx +4 -1
  38. package/{registry → src/extensions}/nocobase-ai/demo/container-showcase.tsx +2 -2
  39. package/{registry → src/extensions}/nocobase-ai/demo/floating.tsx +45 -15
  40. package/{registry → src/extensions}/nocobase-ai/demo/index.tsx +116 -74
  41. package/{registry → src/extensions}/nocobase-ai/demo/prompt-generator.tsx +3 -3
  42. package/{registry → src/extensions}/nocobase-ai/demo/tool-cards.tsx +2 -3
  43. package/src/extensions/nocobase-ai/extension.tsx +160 -0
  44. package/{registry → src/extensions}/nocobase-ai/global-ai-chat.tsx +12 -28
  45. package/{registry → src/extensions}/nocobase-ai/providers/ai-provider.tsx +14 -1
  46. package/{registry → src/extensions}/nocobase-ai/providers/chat-context.tsx +1 -0
  47. package/{registry → src/extensions}/nocobase-ai/providers/chat-provider.tsx +29 -8
  48. package/{registry → src/extensions}/nocobase-ai/providers/use-chat-attachments.ts +6 -1
  49. package/{registry → src/extensions}/nocobase-ai/providers/use-chat-work-context.ts +4 -1
  50. package/{registry → src/extensions}/nocobase-route-surfaces/README.md +2 -1
  51. package/{registry → src/extensions}/nocobase-route-surfaces/demo/index.tsx +33 -7
  52. package/{registry → src/extensions}/nocobase-route-surfaces/demo/scenarios.ts +20 -14
  53. package/{registry → src/extensions}/nocobase-route-surfaces/extension.tsx +55 -52
  54. package/src/{pages/users → extensions/nocobase-users-example}/create.tsx +4 -4
  55. package/src/{pages/users → extensions/nocobase-users-example}/edit.tsx +5 -9
  56. package/src/extensions/nocobase-users-example/extension.tsx +109 -0
  57. package/src/{pages/users → extensions/nocobase-users-example}/form-context.ts +11 -9
  58. package/src/extensions/nocobase-users-example/layout.tsx +16 -0
  59. package/src/{pages/users → extensions/nocobase-users-example}/list.tsx +1 -1
  60. package/src/extensions/nocobase-users-example/locales/en-US.ts +77 -0
  61. package/src/extensions/nocobase-users-example/locales/index.ts +8 -0
  62. package/src/extensions/nocobase-users-example/locales/zh-CN.ts +73 -0
  63. package/src/extensions/nocobase-users-example/optional-ai.ts +67 -0
  64. package/src/{pages/users → extensions/nocobase-users-example}/role-detail.tsx +4 -15
  65. package/src/{pages/users → extensions/nocobase-users-example}/routes.ts +1 -4
  66. package/src/extensions/nocobase-users-example/show.tsx +266 -0
  67. package/src/lib/nocobase/acl/context.ts +32 -0
  68. package/src/lib/nocobase/acl/evaluator.ts +186 -0
  69. package/src/lib/nocobase/acl/hooks.ts +40 -0
  70. package/src/lib/nocobase/acl/index.ts +4 -1
  71. package/src/lib/nocobase/acl/menu.ts +6 -6
  72. package/src/lib/nocobase/acl/record-permissions.ts +37 -7
  73. package/src/lib/nocobase/acl/store-provider.tsx +14 -0
  74. package/src/lib/nocobase/acl/store.ts +92 -86
  75. package/src/lib/nocobase/acl/types.ts +52 -32
  76. package/src/lib/nocobase/auth-session.ts +128 -0
  77. package/src/lib/nocobase/client.ts +48 -50
  78. package/src/locales/en-US.ts +0 -78
  79. package/src/locales/index.ts +2 -7
  80. package/src/locales/zh-CN.ts +0 -74
  81. package/src/providers/access-control.ts +43 -8
  82. package/src/providers/auth-callback.ts +1 -0
  83. package/src/providers/auth.ts +24 -26
  84. package/src/providers/constants.ts +0 -4
  85. package/src/providers/data.ts +14 -26
  86. package/src/providers/runtime-config.ts +40 -0
  87. package/src/vite-env.d.ts +9 -0
  88. package/tests/auth-session-regression.mjs +101 -0
  89. package/tsconfig.json +2 -1
  90. package/vite.config.ts +9 -1
  91. package/dist/assets/CoordinateSystem-C8P-Cleg.js +0 -1
  92. package/dist/assets/LegendVisualProvider-Bdgkckq-.js +0 -1
  93. package/dist/assets/LineDraw-C0m1GONT.js +0 -1
  94. package/dist/assets/SymbolDraw-CCospe5G.js +0 -1
  95. package/dist/assets/VisualMapping-Cbv1v7Cd.js +0 -1
  96. package/dist/assets/ai-employee-shortcut-B253WWow.js +0 -1
  97. package/dist/assets/calendar-B3dXXyIv.js +0 -1
  98. package/dist/assets/chat-inline-xpQ9iq4p.js +0 -1
  99. package/dist/assets/chat-side-panel-layout-BVWsp5rr.js +0 -1
  100. package/dist/assets/components-ChhJaNRc.js +0 -20
  101. package/dist/assets/configuration-gate-Dwdq_lxf.js +0 -1
  102. package/dist/assets/createClipPathFromCoordSys-uEftn1Mq.js +0 -1
  103. package/dist/assets/createSeriesDataSimply-CI7l7Ufv.js +0 -1
  104. package/dist/assets/customGraphicKeyframeAnimation-DE3jSfMd.js +0 -3
  105. package/dist/assets/echarts-preview-C-cNUtJF.js +0 -1
  106. package/dist/assets/echarts-runtime-CEgJbv68.js +0 -58
  107. package/dist/assets/echarts-runtime-advanced-Buhm2BHz.js +0 -1
  108. package/dist/assets/echarts-runtime-common-DLAdBAIa.js +0 -1
  109. package/dist/assets/echarts-runtime-components-ypnyLkYx.js +0 -1
  110. package/dist/assets/echarts-runtime-hierarchy-ClStquCF.js +0 -1
  111. package/dist/assets/floating-BarTmn-b.js +0 -13
  112. package/dist/assets/index-BJIcYTdc.js +0 -53
  113. package/dist/assets/index-C6xNKxpg.js +0 -656
  114. package/dist/assets/index-D4JQi1TM.js +0 -54
  115. package/dist/assets/index-YA7-AUO8.css +0 -1
  116. package/dist/assets/index-g8zWVpP9.js +0 -23
  117. package/dist/assets/labelHelper-C137W5gU.js +0 -1
  118. package/dist/assets/nocobase-ai-chat-VTMaZFQB.svg +0 -50
  119. package/dist/assets/page-context-Cxx11gzg.js +0 -73
  120. package/dist/assets/prompt-card-BsYMW_rq.js +0 -1
  121. package/dist/assets/sectorHelper-Fqgz3uEk.js +0 -1
  122. package/dist/assets/shortcut-xtghDP63.js +0 -47
  123. package/dist/assets/static.browser-CfQQzERe.js +0 -30
  124. package/dist/assets/switch-DrxImI8F.js +0 -1
  125. package/dist/assets/tool-cards-BGfsY8JF.js +0 -41
  126. package/dist/favicon.ico +0 -0
  127. package/dist/index.html +0 -40
  128. package/dist/index.raw.html +0 -46
  129. package/dist/logo-dark.png +0 -0
  130. package/dist/logo-mark-dark.png +0 -0
  131. package/dist/logo-mark.png +0 -0
  132. package/dist/logo.png +0 -0
  133. package/registry/nocobase-acl/README.md +0 -19
  134. package/registry/nocobase-acl/extension.tsx +0 -71
  135. package/registry/nocobase-acl/tests/acl-regression.mjs +0 -314
  136. package/registry/nocobase-ai/components/surfaces/chat-dialog.tsx +0 -31
  137. package/registry/nocobase-ai/components/surfaces/chat-side-panel.tsx +0 -74
  138. package/registry/nocobase-ai/extension.tsx +0 -158
  139. package/registry/nocobase-ai/tests/business-report-regression.mjs +0 -70
  140. package/registry/nocobase-ai/tests/form-filler-regression.mjs +0 -129
  141. package/registry/nocobase-ai/tests/frontend-tool-regression.mjs +0 -128
  142. package/registry/nocobase-ai/tests/page-context-regression.mjs +0 -48
  143. package/registry/nocobase-ai/tests/stream-regression.mjs +0 -207
  144. package/registry/nocobase-auth-cas/README.md +0 -6
  145. package/registry/nocobase-auth-cas/cas-sign-in-button.tsx +0 -41
  146. package/registry/nocobase-auth-cas/demo.tsx +0 -20
  147. package/registry/nocobase-auth-cas/extension.tsx +0 -46
  148. package/registry/nocobase-auth-cas/index.ts +0 -1
  149. package/registry/nocobase-auth-cas/use-cas-sign-in.ts +0 -29
  150. package/registry/nocobase-auth-dingtalk/README.md +0 -7
  151. package/registry/nocobase-auth-dingtalk/auto-login-provider.tsx +0 -154
  152. package/registry/nocobase-auth-dingtalk/demo.tsx +0 -23
  153. package/registry/nocobase-auth-dingtalk/dingtalk-sign-in-button.tsx +0 -45
  154. package/registry/nocobase-auth-dingtalk/extension.tsx +0 -55
  155. package/registry/nocobase-auth-dingtalk/index.ts +0 -4
  156. package/registry/nocobase-auth-dingtalk/use-dingtalk-sign-in.ts +0 -64
  157. package/registry/nocobase-auth-ldap/README.md +0 -6
  158. package/registry/nocobase-auth-ldap/demo.tsx +0 -21
  159. package/registry/nocobase-auth-ldap/extension.tsx +0 -46
  160. package/registry/nocobase-auth-ldap/index.ts +0 -1
  161. package/registry/nocobase-auth-ldap/ldap-sign-in-form.tsx +0 -69
  162. package/registry/nocobase-auth-ldap/use-ldap-sign-in.ts +0 -5
  163. package/registry/nocobase-auth-oidc/README.md +0 -11
  164. package/registry/nocobase-auth-oidc/auto-redirect-provider.tsx +0 -13
  165. package/registry/nocobase-auth-oidc/demo.tsx +0 -20
  166. package/registry/nocobase-auth-oidc/extension.tsx +0 -51
  167. package/registry/nocobase-auth-oidc/index.ts +0 -1
  168. package/registry/nocobase-auth-oidc/oidc-sign-in-button.tsx +0 -44
  169. package/registry/nocobase-auth-oidc/use-oidc-sign-in.ts +0 -58
  170. package/registry/nocobase-auth-saml/README.md +0 -6
  171. package/registry/nocobase-auth-saml/auto-redirect-provider.tsx +0 -13
  172. package/registry/nocobase-auth-saml/demo.tsx +0 -20
  173. package/registry/nocobase-auth-saml/extension.tsx +0 -51
  174. package/registry/nocobase-auth-saml/index.ts +0 -1
  175. package/registry/nocobase-auth-saml/saml-sign-in-button.tsx +0 -43
  176. package/registry/nocobase-auth-saml/use-saml-sign-in.ts +0 -51
  177. package/registry/nocobase-auth-sms/README.md +0 -7
  178. package/registry/nocobase-auth-sms/demo.tsx +0 -25
  179. package/registry/nocobase-auth-sms/extension.tsx +0 -46
  180. package/registry/nocobase-auth-sms/index.ts +0 -1
  181. package/registry/nocobase-auth-sms/sms-sign-in-form.tsx +0 -107
  182. package/registry/nocobase-auth-sms/use-sms-sign-in.ts +0 -88
  183. package/registry/nocobase-auth-wecom/README.md +0 -6
  184. package/registry/nocobase-auth-wecom/auto-login-provider.tsx +0 -21
  185. package/registry/nocobase-auth-wecom/demo.tsx +0 -23
  186. package/registry/nocobase-auth-wecom/extension.tsx +0 -49
  187. package/registry/nocobase-auth-wecom/index.ts +0 -1
  188. package/registry/nocobase-auth-wecom/use-wecom-sign-in.ts +0 -62
  189. package/registry/nocobase-auth-wecom/wecom-sign-in-button.tsx +0 -70
  190. package/registry/nocobase-i18n/README.md +0 -44
  191. package/registry/nocobase-i18n/components/index.ts +0 -1
  192. package/registry/nocobase-i18n/components/language-switcher.tsx +0 -138
  193. package/registry/nocobase-i18n/demo/index.tsx +0 -209
  194. package/registry/nocobase-i18n/demo/prompt-generator.tsx +0 -132
  195. package/registry/nocobase-i18n/extension.tsx +0 -45
  196. package/registry/nocobase-i18n/index.ts +0 -7
  197. package/registry/nocobase-i18n/locales/en-US.ts +0 -39
  198. package/registry/nocobase-i18n/locales/index.ts +0 -8
  199. package/registry/nocobase-i18n/locales/zh-CN.ts +0 -35
  200. package/registry/nocobase-i18n/provider.tsx +0 -44
  201. package/registry/nocobase-i18n/server-resources.ts +0 -166
  202. package/registry/nocobase-i18n/tests/i18n-regression.mjs +0 -51
  203. package/registry.config.json +0 -302
  204. package/scripts/registry.mjs +0 -164
  205. package/src/components/access-control/resource-access-guard.tsx +0 -21
  206. package/src/components/access-control/use-acl-runtime.ts +0 -28
  207. package/src/lib/nocobase/acl/action.ts +0 -147
  208. package/src/pages/users/layout.tsx +0 -15
  209. package/src/pages/users/show.tsx +0 -278
  210. /package/{registry → src/extensions}/nocobase-acl/components/index.ts +0 -0
  211. /package/{registry → src/extensions}/nocobase-acl/components/role-options.ts +0 -0
  212. /package/{registry → src/extensions}/nocobase-acl/demo/components.tsx +0 -0
  213. /package/{registry → src/extensions}/nocobase-acl/demo/lazy-route.tsx +0 -0
  214. /package/{registry → src/extensions}/nocobase-acl/demo/role-switcher-prompt-generator.tsx +0 -0
  215. /package/{registry → src/extensions}/nocobase-acl/demo/scenario-section.tsx +0 -0
  216. /package/{registry → src/extensions}/nocobase-acl/index.ts +0 -0
  217. /package/{registry → src/extensions}/nocobase-ai/adapters/react-hook-form.ts +0 -0
  218. /package/{registry → src/extensions}/nocobase-ai/assets/nocobase-ai-chat.svg +0 -0
  219. /package/{registry → src/extensions}/nocobase-ai/components/ai-root-provider.tsx +0 -0
  220. /package/{registry → src/extensions}/nocobase-ai/components/chat/ai-employee-avatar.tsx +0 -0
  221. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-attachment.tsx +0 -0
  222. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-compact.tsx +0 -0
  223. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-empty-state.tsx +0 -0
  224. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-header.tsx +0 -0
  225. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-history-dialog.tsx +0 -0
  226. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-message.tsx +0 -0
  227. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-window.tsx +0 -0
  228. /package/{registry → src/extensions}/nocobase-ai/components/chat/conversation-list.tsx +0 -0
  229. /package/{registry → src/extensions}/nocobase-ai/components/chat/markdown-message.tsx +0 -0
  230. /package/{registry → src/extensions}/nocobase-ai/components/chat/model-select-options.tsx +0 -0
  231. /package/{registry → src/extensions}/nocobase-ai/components/chat/reasoning-panel.tsx +0 -0
  232. /package/{registry → src/extensions}/nocobase-ai/components/chat/sub-agent-conversation.tsx +0 -0
  233. /package/{registry → src/extensions}/nocobase-ai/components/chat/user-prompt-editor.tsx +0 -0
  234. /package/{registry → src/extensions}/nocobase-ai/components/chat/work-context-chip.tsx +0 -0
  235. /package/{registry → src/extensions}/nocobase-ai/components/page-elements/ai-form.tsx +0 -0
  236. /package/{registry → src/extensions}/nocobase-ai/components/page-elements/page-element-provider.tsx +0 -0
  237. /package/{registry → src/extensions}/nocobase-ai/components/surfaces/chat-inline.tsx +0 -0
  238. /package/{registry → src/extensions}/nocobase-ai/components/surfaces/chat-page.tsx +0 -0
  239. /package/{registry → src/extensions}/nocobase-ai/components/surfaces/chat-side-panel-layout.tsx +0 -0
  240. /package/{registry → src/extensions}/nocobase-ai/components/surfaces/chat-surface-actions.tsx +0 -0
  241. /package/{registry → src/extensions}/nocobase-ai/components/tools/builtin-tool-renderers.tsx +0 -0
  242. /package/{registry → src/extensions}/nocobase-ai/components/tools/business-report-dialog.tsx +0 -0
  243. /package/{registry → src/extensions}/nocobase-ai/components/tools/business-report-renderer.tsx +0 -0
  244. /package/{registry → src/extensions}/nocobase-ai/components/tools/business-report-utils.tsx +0 -0
  245. /package/{registry → src/extensions}/nocobase-ai/components/tools/chart-renderer.tsx +0 -0
  246. /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-preview.tsx +0 -0
  247. /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime-advanced.ts +0 -0
  248. /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime-common.ts +0 -0
  249. /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime-components.ts +0 -0
  250. /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime-hierarchy.ts +0 -0
  251. /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime.ts +0 -0
  252. /package/{registry → src/extensions}/nocobase-ai/components/tools/sub-agent-renderer.tsx +0 -0
  253. /package/{registry → src/extensions}/nocobase-ai/components/tools/suggestions-renderer.tsx +0 -0
  254. /package/{registry → src/extensions}/nocobase-ai/components/tools/tool-renderer-provider.tsx +0 -0
  255. /package/{registry → src/extensions}/nocobase-ai/components/tools/tool-renderer-utils.ts +0 -0
  256. /package/{registry → src/extensions}/nocobase-ai/components/tools/workflow-renderer.tsx +0 -0
  257. /package/{registry → src/extensions}/nocobase-ai/components/triggers/ai-employee-shortcut.tsx +0 -0
  258. /package/{registry → src/extensions}/nocobase-ai/demo/interaction-showcase.tsx +0 -0
  259. /package/{registry → src/extensions}/nocobase-ai/demo/page-context-prompt-generator.tsx +0 -0
  260. /package/{registry → src/extensions}/nocobase-ai/demo/page-context.tsx +0 -0
  261. /package/{registry → src/extensions}/nocobase-ai/demo/page-element-showcase.tsx +0 -0
  262. /package/{registry → src/extensions}/nocobase-ai/demo/prompt-card.tsx +0 -0
  263. /package/{registry → src/extensions}/nocobase-ai/demo/shortcut.tsx +0 -0
  264. /package/{registry → src/extensions}/nocobase-ai/index.ts +0 -0
  265. /package/{registry → src/extensions}/nocobase-ai/providers/avatars.ts +0 -0
  266. /package/{registry → src/extensions}/nocobase-ai/providers/chat-controller.ts +0 -0
  267. /package/{registry → src/extensions}/nocobase-ai/providers/chat-message-utils.ts +0 -0
  268. /package/{registry → src/extensions}/nocobase-ai/providers/chat-reducer.ts +0 -0
  269. /package/{registry → src/extensions}/nocobase-ai/providers/chat-task-utils.ts +0 -0
  270. /package/{registry → src/extensions}/nocobase-ai/providers/chat-transport.ts +0 -0
  271. /package/{registry → src/extensions}/nocobase-ai/providers/form-registry.tsx +0 -0
  272. /package/{registry → src/extensions}/nocobase-ai/providers/frontend-tool-registry.tsx +0 -0
  273. /package/{registry → src/extensions}/nocobase-ai/providers/index.ts +0 -0
  274. /package/{registry → src/extensions}/nocobase-ai/providers/model.ts +0 -0
  275. /package/{registry → src/extensions}/nocobase-ai/providers/page-context.tsx +0 -0
  276. /package/{registry → src/extensions}/nocobase-ai/providers/stream-coalescer.ts +0 -0
  277. /package/{registry → src/extensions}/nocobase-ai/providers/stream-event-utils.ts +0 -0
  278. /package/{registry → src/extensions}/nocobase-ai/providers/stream-parser.ts +0 -0
  279. /package/{registry → src/extensions}/nocobase-ai/providers/sub-agent-stream.ts +0 -0
  280. /package/{registry → src/extensions}/nocobase-ai/providers/types.ts +0 -0
  281. /package/{registry → src/extensions}/nocobase-ai/providers/ui-message-stream.ts +0 -0
  282. /package/{registry → src/extensions}/nocobase-ai/providers/use-automatic-tool-approval.ts +0 -0
  283. /package/{registry → src/extensions}/nocobase-ai/providers/use-chat-message-actions.ts +0 -0
  284. /package/{registry → src/extensions}/nocobase-ai/providers/use-chat-runtime.ts +0 -0
  285. /package/{registry → src/extensions}/nocobase-ai/providers/use-conversation-catalog.ts +0 -0
  286. /package/{registry → src/extensions}/nocobase-ai/providers/use-conversation-history.ts +0 -0
  287. /package/{registry → src/extensions}/nocobase-ai/services/index.ts +0 -0
  288. /package/{registry → src/extensions}/nocobase-ai/services/nocobase-ai-service.ts +0 -0
  289. /package/{registry → src/extensions}/nocobase-ai/services/types.ts +0 -0
  290. /package/{registry → src/extensions}/nocobase-route-surfaces/demo/lazy-route.tsx +0 -0
  291. /package/{registry → src/extensions}/nocobase-route-surfaces/demo/prompt-generator.tsx +0 -0
  292. /package/{registry → src/extensions}/nocobase-route-surfaces/index.ts +0 -0
  293. /package/{registry → src/extensions}/nocobase-route-surfaces/route-dialog.tsx +0 -0
  294. /package/{registry → src/extensions}/nocobase-route-surfaces/route-drawer.tsx +0 -0
  295. /package/{registry → src/extensions}/nocobase-route-surfaces/route-page.tsx +0 -0
  296. /package/{registry → src/extensions}/nocobase-route-surfaces/route-surface-context.ts +0 -0
  297. /package/{registry → src/extensions}/nocobase-route-surfaces/use-refine-unsaved-changes.tsx +0 -0
  298. /package/{registry → src/extensions}/nocobase-route-surfaces/use-route-surface-close.ts +0 -0
  299. /package/{registry → src/extensions}/nocobase-route-surfaces/use-route-surface-state.ts +0 -0
  300. /package/src/{pages/users → extensions/nocobase-users-example}/form-fields.tsx +0 -0
  301. /package/src/{pages/users → extensions/nocobase-users-example}/index.ts +0 -0
  302. /package/src/{pages/users → extensions/nocobase-users-example}/role-badges.tsx +0 -0
  303. /package/src/{pages/users → extensions/nocobase-users-example}/role-utils.ts +0 -0
  304. /package/src/{pages/users → extensions/nocobase-users-example}/types.ts +0 -0
@@ -1,62 +0,0 @@
1
- import { useCallback, useMemo, useState } from "react";
2
- import { useSearchParams } from "react-router";
3
-
4
- import type { Authenticator } from "@/components/auth/types";
5
- import { nocobaseClient } from "@/lib/nocobase/client";
6
-
7
- type WecomAuthUrlResponse = {
8
- url?: string;
9
- };
10
-
11
- export function isWecomBrowser() {
12
- return (
13
- typeof navigator !== "undefined" &&
14
- navigator.userAgent.toLowerCase().includes("wxwork")
15
- );
16
- }
17
-
18
- export function useWecomSignIn(authenticator: Authenticator) {
19
- const [searchParams] = useSearchParams();
20
- const [isPending, setIsPending] = useState(false);
21
- const [error, setError] = useState<Error>();
22
- const callbackError = useMemo(() => {
23
- if (searchParams.get("authenticator") !== authenticator.name) {
24
- return undefined;
25
- }
26
- const message = searchParams.get("errorMsg");
27
- return message ? new Error(message) : undefined;
28
- }, [authenticator.name, searchParams]);
29
-
30
- const signIn = useCallback(async () => {
31
- setError(undefined);
32
- setIsPending(true);
33
- try {
34
- const redirect =
35
- searchParams.get("to") || searchParams.get("redirect") || "/";
36
- const result = await nocobaseClient.action<WecomAuthUrlResponse>(
37
- "wecom",
38
- "getAuthUrl",
39
- {
40
- method: "POST",
41
- authenticator: authenticator.name,
42
- includeRole: false,
43
- withAclMeta: false,
44
- body: { redirect, isWeComBrowser: isWecomBrowser() },
45
- }
46
- );
47
- if (!result?.url) {
48
- throw new Error("NocoBase did not return a WeCom authorization URL.");
49
- }
50
- window.location.replace(nocobaseClient.resolveUrl(result.url));
51
- } catch (cause) {
52
- setError(
53
- cause instanceof Error
54
- ? cause
55
- : new Error("Unable to start WeCom sign-in.")
56
- );
57
- setIsPending(false);
58
- }
59
- }, [authenticator.name, searchParams]);
60
-
61
- return { signIn, isPending, error: error ?? callbackError };
62
- }
@@ -1,70 +0,0 @@
1
- import { Building2 } from "lucide-react";
2
-
3
- import type { AuthenticatorComponentProps } from "@/components/auth/types";
4
- import {
5
- Alert,
6
- AlertDescription,
7
- AlertTitle,
8
- } from "@/components/ui/alert";
9
- import { Button } from "@/components/ui/button";
10
- import {
11
- Tooltip,
12
- TooltipContent,
13
- TooltipTrigger,
14
- } from "@/components/ui/tooltip";
15
- import { resolveTranslatableText } from "@/lib/i18n";
16
-
17
- import { useWecomSignIn } from "./use-wecom-sign-in";
18
-
19
- function plainText(value: unknown) {
20
- return typeof value === "string"
21
- ? value.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim()
22
- : "";
23
- }
24
-
25
- export default function WecomSignInButton({
26
- authenticator,
27
- onSignIn,
28
- }: AuthenticatorComponentProps & { onSignIn?: () => void }) {
29
- const { signIn, isPending, error } = useWecomSignIn(authenticator);
30
- const tooltip = plainText(authenticator.options?.btnTooltip);
31
- const button = (
32
- <Button
33
- type="button"
34
- variant="outline"
35
- className="w-full"
36
- disabled={!onSignIn && isPending}
37
- onClick={onSignIn ?? signIn}
38
- >
39
- <Building2 />
40
- {!onSignIn && isPending
41
- ? "Redirecting…"
42
- : resolveTranslatableText(
43
- authenticator.title ||
44
- authenticator.authTypeTitle ||
45
- "Sign in via WeCom"
46
- )}
47
- </Button>
48
- );
49
-
50
- return (
51
- <div className="space-y-3">
52
- {error && (
53
- <Alert variant="destructive">
54
- <AlertTitle>WeCom sign-in failed</AlertTitle>
55
- <AlertDescription>{error.message}</AlertDescription>
56
- </Alert>
57
- )}
58
- {tooltip ? (
59
- <Tooltip>
60
- <TooltipTrigger render={button} />
61
- <TooltipContent side="right" className="max-w-xs">
62
- {tooltip}
63
- </TooltipContent>
64
- </Tooltip>
65
- ) : (
66
- button
67
- )}
68
- </div>
69
- );
70
- }
@@ -1,44 +0,0 @@
1
- # NocoBase i18n
2
-
3
- Optional NocoBase server-language integration and language controls for the
4
- NocoBase Admin Starter.
5
-
6
- The Starter owns the Refine i18n provider, local i18next runtime, application
7
- resources, locale selection, and the shared `systemSettings:get` bootstrap.
8
- This Registry reuses those foundations and adds only the NocoBase-specific
9
- remote capabilities:
10
-
11
- - load registered dynamic namespaces from `app:getLang`;
12
- - persist a signed-in user's selected language through `users:updateLang`;
13
- - expose reusable page and user-menu language switchers;
14
- - provide an integrated Demo and Prompt generator.
15
-
16
- When this Registry is not installed, the Starter still uses the system default
17
- language and all local translations normally. It does not request
18
- `app:getLang`. When installed, the Registry reads the already-cached system
19
- settings and requests only registered server namespaces. `lm-collections` is
20
- registered by default for collection and field metadata.
21
-
22
- Application-owned React translations belong in `src/locales`, outside the
23
- installed Registry directory:
24
-
25
- ```ts
26
- import { registerLocaleResources } from "@/providers/i18n";
27
-
28
- registerLocaleResources("my-feature", {
29
- "en-US": { title: "Orders" },
30
- "zh-CN": { title: "订单" },
31
- });
32
- ```
33
-
34
- Other installed components can opt into another server-generated namespace:
35
-
36
- ```ts
37
- import { registerServerResourceNamespace } from "@/extensions/nocobase-i18n";
38
-
39
- registerServerResourceNamespace("my-dynamic-namespace");
40
- ```
41
-
42
- Namespaces registered after startup are loaded incrementally. Existing exact
43
- NocoBase expressions such as `{{t("Orders")}}` remain supported by the
44
- Starter's translation compatibility helper.
@@ -1 +0,0 @@
1
- export * from "./language-switcher";
@@ -1,138 +0,0 @@
1
- import { useGetLocale, useSetLocale, useTranslate } from "@refinedev/core";
2
- import { Languages, Loader2 } from "lucide-react";
3
- import { useState, type ReactNode } from "react";
4
-
5
- import {
6
- DropdownMenuRadioGroup,
7
- DropdownMenuRadioItem,
8
- DropdownMenuSeparator,
9
- DropdownMenuSub,
10
- DropdownMenuSubContent,
11
- DropdownMenuSubTrigger,
12
- } from "@/components/ui/dropdown-menu";
13
- import {
14
- Select,
15
- SelectContent,
16
- SelectItem,
17
- SelectTrigger,
18
- SelectValue,
19
- } from "@/components/ui/select";
20
- import { cn } from "@/lib/utils";
21
- import { useEnabledLocales } from "@/providers/i18n";
22
-
23
- export type LanguageSwitcherProps = {
24
- className?: string;
25
- label?: ReactNode | false;
26
- triggerClassName?: string;
27
- };
28
-
29
- export function LanguageSwitcher({
30
- className,
31
- label,
32
- triggerClassName,
33
- }: LanguageSwitcherProps) {
34
- const translate = useTranslate();
35
- const getLocale = useGetLocale();
36
- const setLocale = useSetLocale();
37
- const locales = useEnabledLocales();
38
- const currentLocale = getLocale();
39
- const [switching, setSwitching] = useState(false);
40
- const [error, setError] = useState<string>();
41
- const resolvedLabel =
42
- typeof label === "undefined"
43
- ? translate("language.label", { ns: "nocobase-i18n" }, "Language")
44
- : label;
45
-
46
- if (locales.length < 2) return null;
47
-
48
- const currentDefinition =
49
- locales.find(({ locale }) => locale === currentLocale) ?? locales[0];
50
-
51
- return (
52
- <div className={cn("space-y-2", className)}>
53
- {resolvedLabel === false ? null : (
54
- <p className="text-xs font-medium text-muted-foreground">
55
- {resolvedLabel}
56
- </p>
57
- )}
58
- <Select
59
- value={currentLocale}
60
- disabled={switching}
61
- onValueChange={(value) => {
62
- if (!value || value === currentLocale) return;
63
- setSwitching(true);
64
- setError(undefined);
65
- Promise.resolve(setLocale(value)).catch((reason) => {
66
- setError(
67
- reason instanceof Error
68
- ? reason.message
69
- : translate(
70
- "language.switchError",
71
- { ns: "nocobase-i18n" },
72
- "Unable to switch language."
73
- )
74
- );
75
- setSwitching(false);
76
- });
77
- }}
78
- >
79
- <SelectTrigger
80
- className={cn("w-full min-w-52", triggerClassName)}
81
- aria-label={String(resolvedLabel || "Language")}
82
- >
83
- {switching ? <Loader2 className="animate-spin" /> : <Languages />}
84
- <SelectValue>{currentDefinition?.label ?? currentLocale}</SelectValue>
85
- </SelectTrigger>
86
- <SelectContent>
87
- {locales.map((definition) => (
88
- <SelectItem key={definition.locale} value={definition.locale}>
89
- {definition.label}
90
- </SelectItem>
91
- ))}
92
- </SelectContent>
93
- </Select>
94
- {error ? <p className="text-xs text-destructive">{error}</p> : null}
95
- </div>
96
- );
97
- }
98
-
99
- export function LanguageUserMenuItems() {
100
- const translate = useTranslate();
101
- const getLocale = useGetLocale();
102
- const setLocale = useSetLocale();
103
- const locales = useEnabledLocales();
104
- const currentLocale = getLocale();
105
-
106
- if (locales.length < 2) return null;
107
-
108
- return (
109
- <>
110
- <DropdownMenuSeparator />
111
- <DropdownMenuSub>
112
- <DropdownMenuSubTrigger className="min-h-9 gap-2 px-2 text-muted-foreground focus:text-foreground">
113
- <Languages />
114
- <span>
115
- {translate("language.label", { ns: "nocobase-i18n" }, "Language")}
116
- </span>
117
- </DropdownMenuSubTrigger>
118
- <DropdownMenuSubContent className="min-w-44">
119
- <DropdownMenuRadioGroup
120
- value={currentLocale}
121
- onValueChange={(value) => {
122
- if (value && value !== currentLocale) void setLocale(value);
123
- }}
124
- >
125
- {locales.map((definition) => (
126
- <DropdownMenuRadioItem
127
- key={definition.locale}
128
- value={definition.locale}
129
- >
130
- {definition.label}
131
- </DropdownMenuRadioItem>
132
- ))}
133
- </DropdownMenuRadioGroup>
134
- </DropdownMenuSubContent>
135
- </DropdownMenuSub>
136
- </>
137
- );
138
- }
@@ -1,209 +0,0 @@
1
- import { useGetLocale, useTranslate } from "@refinedev/core";
2
- import { Database, Languages, PanelsTopLeft } from "lucide-react";
3
-
4
- import { Badge } from "@/components/ui/badge";
5
- import {
6
- Card,
7
- CardContent,
8
- CardDescription,
9
- CardHeader,
10
- CardTitle,
11
- } from "@/components/ui/card";
12
- import { nocobaseClient } from "@/lib/nocobase/client";
13
- import {
14
- LanguageSwitcher,
15
- useEnabledLocales,
16
- } from "@/extensions/nocobase-i18n";
17
- import { I18nPromptGenerator } from "./prompt-generator";
18
-
19
- export function I18nDemoPage() {
20
- const t = useTranslate();
21
- const getLocale = useGetLocale();
22
- const locale = getLocale();
23
- const locales = useEnabledLocales();
24
- const canSwitchLanguage = locales.length > 1;
25
-
26
- return (
27
- <div className="space-y-10 pb-12">
28
- <header className="space-y-2">
29
- <div className="flex items-center gap-2">
30
- <Badge variant="secondary">i18n</Badge>
31
- <Badge variant="outline">{locale}</Badge>
32
- </div>
33
- <h1 className="text-2xl font-semibold tracking-[-0.025em] sm:text-3xl">
34
- {t("demo.title", { ns: "nocobase-i18n" }, "Internationalization")}
35
- </h1>
36
- <p className="max-w-3xl text-sm leading-6 text-muted-foreground">
37
- {t(
38
- "demo.description",
39
- { ns: "nocobase-i18n" },
40
- "Optional NocoBase server translations and language controls built on the Starter's internationalization runtime."
41
- )}
42
- </p>
43
- </header>
44
-
45
- <section className="grid gap-5 xl:grid-cols-3">
46
- <Card>
47
- <CardHeader>
48
- <CardTitle className="flex items-center gap-2">
49
- <Languages className="size-4" />
50
- {t(
51
- "demo.switcher.title",
52
- { ns: "nocobase-i18n" },
53
- "Language switcher"
54
- )}
55
- </CardTitle>
56
- <CardDescription>
57
- {t(
58
- "demo.switcher.description",
59
- { ns: "nocobase-i18n" },
60
- "The same reusable component is also integrated into the signed-in user menu."
61
- )}
62
- </CardDescription>
63
- </CardHeader>
64
- <CardContent>
65
- {canSwitchLanguage ? (
66
- <LanguageSwitcher className="max-w-sm" />
67
- ) : (
68
- <div className="flex items-start gap-3 rounded-lg border bg-muted/30 p-4">
69
- <Languages className="mt-0.5 size-5 shrink-0 text-muted-foreground" />
70
- <div>
71
- <p className="text-sm font-medium">
72
- {t(
73
- "demo.switcher.unavailable.title",
74
- { ns: "nocobase-i18n" },
75
- "Only one language is enabled"
76
- )}
77
- </p>
78
- <p className="mt-1 text-xs leading-5 text-muted-foreground">
79
- {t(
80
- "demo.switcher.unavailable.description",
81
- { ns: "nocobase-i18n" },
82
- "Enable another language in NocoBase system settings to display the switcher."
83
- )}
84
- </p>
85
- </div>
86
- </div>
87
- )}
88
- </CardContent>
89
- </Card>
90
-
91
- <CapabilityCard
92
- icon={<PanelsTopLeft className="size-4" />}
93
- title={t(
94
- "demo.frontend.title",
95
- { ns: "nocobase-i18n" },
96
- "Application UI translations"
97
- )}
98
- description={t(
99
- "demo.frontend.description",
100
- { ns: "nocobase-i18n" },
101
- "The Starter provides the runtime while application and Registry components keep their messages in local resource files."
102
- )}
103
- >
104
- <div className="divide-y rounded-lg border">
105
- <DemoRow
106
- label={t(
107
- "language.current",
108
- { ns: "nocobase-i18n" },
109
- "Current language"
110
- )}
111
- value={locale}
112
- />
113
- <DemoRow
114
- label={t(
115
- "demo.frontend.actions",
116
- { ns: "nocobase-i18n" },
117
- "Common actions"
118
- )}
119
- value={`${t("buttons.apply", "Apply")} · ${t(
120
- "buttons.clear",
121
- "Clear"
122
- )}`}
123
- />
124
- </div>
125
- </CapabilityCard>
126
-
127
- <CapabilityCard
128
- icon={<Database className="size-4" />}
129
- title={t(
130
- "demo.server.title",
131
- { ns: "nocobase-i18n" },
132
- "NocoBase metadata translations"
133
- )}
134
- description={t(
135
- "demo.server.description",
136
- { ns: "nocobase-i18n" },
137
- "Collection and field labels are loaded from dynamic server namespaces such as lm-collections."
138
- )}
139
- >
140
- <div className="divide-y rounded-lg border">
141
- <DemoRow
142
- label="Users"
143
- value={t("Users", { ns: "lm-collections" }, "Users")}
144
- />
145
- <DemoRow
146
- label="Nickname"
147
- value={t("Nickname", { ns: "lm-collections" }, "Nickname")}
148
- />
149
- <DemoRow
150
- label="X-Locale"
151
- value={nocobaseClient.getLocale() ?? locale}
152
- code
153
- />
154
- </div>
155
- </CapabilityCard>
156
- </section>
157
-
158
- <section className="border-t pt-8">
159
- <I18nPromptGenerator />
160
- </section>
161
- </div>
162
- );
163
- }
164
-
165
- function DemoRow({
166
- code,
167
- label,
168
- value,
169
- }: {
170
- code?: boolean;
171
- label: string;
172
- value: string;
173
- }) {
174
- return (
175
- <div className="flex items-center justify-between gap-4 px-3 py-2.5">
176
- <span className="text-xs text-muted-foreground">{label}</span>
177
- {code ? (
178
- <code className="rounded bg-muted px-2 py-1 text-xs">{value}</code>
179
- ) : (
180
- <span className="text-sm font-medium">{value}</span>
181
- )}
182
- </div>
183
- );
184
- }
185
-
186
- function CapabilityCard({
187
- children,
188
- description,
189
- icon,
190
- title,
191
- }: {
192
- children: React.ReactNode;
193
- description: string;
194
- icon: React.ReactNode;
195
- title: string;
196
- }) {
197
- return (
198
- <Card>
199
- <CardHeader>
200
- <CardTitle className="flex items-center gap-2">
201
- {icon}
202
- {title}
203
- </CardTitle>
204
- <CardDescription>{description}</CardDescription>
205
- </CardHeader>
206
- <CardContent className="text-sm">{children}</CardContent>
207
- </Card>
208
- );
209
- }
@@ -1,132 +0,0 @@
1
- import { useTranslate } from "@refinedev/core";
2
- import { ChevronDown, Sparkles } from "lucide-react";
3
- import { useMemo, useState } from "react";
4
-
5
- import { PromptOutput } from "@/components/demo/prompt-output";
6
- import {
7
- Card,
8
- CardContent,
9
- CardDescription,
10
- CardHeader,
11
- CardTitle,
12
- } from "@/components/ui/card";
13
- import { Input } from "@/components/ui/input";
14
- import { Label } from "@/components/ui/label";
15
- import { Textarea } from "@/components/ui/textarea";
16
-
17
- export function I18nPromptGenerator() {
18
- const t = useTranslate();
19
- const [scene, setScene] = useState("A customer support workspace");
20
- const [languages, setLanguages] = useState("English and Simplified Chinese");
21
-
22
- const prompt = useMemo(
23
- () => `Build a complete multilingual scene in the NocoBase Admin Starter.
24
-
25
- Application scene
26
- - Product or page: ${scene}
27
- - Supported languages: ${languages}
28
- - Translate the complete visible user flow, including empty, loading, validation, and error states.
29
-
30
- Implementation contract
31
- - Use the Starter's @/providers/i18n runtime and the application's translation and locale hooks.
32
- - Put application-owned React messages in src/locales and register the app namespace through registerTranslationResources from @/lib/i18n.
33
- - Keep each Registry component's messages in its own namespace and register them with registerLocaleResources().
34
- - Do not place application messages inside src/extensions/nocobase-i18n/locales because installed Registry files may be refreshed independently.
35
- - Use the reusable LanguageSwitcher when the page needs an explicit language control; the signed-in user menu already includes one.
36
- - Reuse the Starter's shared system settings instead of requesting systemSettings:get again.
37
- - Keep Starter and Registry UI resources local. Use app:getLang only for registered dynamic server namespaces such as lm-collections when the NocoBase i18n Registry is installed.
38
- - Let the shared NocoBase client send the selected locale through X-Locale.
39
- - Preserve compatibility when server metadata contains exact {{t("...")}} expressions.
40
- - Provide complete React components, locale resource files, route/resource integration, and realistic visible content.`,
41
- [languages, scene]
42
- );
43
-
44
- return (
45
- <details open className="group rounded-xl border bg-muted/15">
46
- <summary className="flex cursor-pointer list-none items-center gap-2 px-4 py-3 text-sm font-medium marker:hidden">
47
- <Sparkles className="size-4 text-primary" />
48
- {t("demo.prompt.title", { ns: "nocobase-i18n" }, "Prompt generator")}
49
- <ChevronDown className="ml-auto size-4 text-muted-foreground transition-transform group-open:rotate-180" />
50
- </summary>
51
- <div className="grid items-start gap-5 border-t p-4 xl:grid-cols-[360px_minmax(0,1fr)]">
52
- <Card className="gap-0 py-0">
53
- <CardHeader className="border-b py-4">
54
- <CardTitle className="text-base">
55
- {t(
56
- "demo.prompt.settings",
57
- { ns: "nocobase-i18n" },
58
- "Scene settings"
59
- )}
60
- </CardTitle>
61
- <CardDescription>
62
- {t(
63
- "demo.prompt.description",
64
- { ns: "nocobase-i18n" },
65
- "Describe a complete multilingual application scene and generate an implementation prompt."
66
- )}
67
- </CardDescription>
68
- </CardHeader>
69
- <CardContent className="space-y-5 py-5">
70
- <div className="space-y-2">
71
- <Label htmlFor="i18n-prompt-scene">
72
- {t(
73
- "demo.prompt.scene",
74
- { ns: "nocobase-i18n" },
75
- "Application scene"
76
- )}
77
- </Label>
78
- <Input
79
- id="i18n-prompt-scene"
80
- value={scene}
81
- onChange={(event) => setScene(event.target.value)}
82
- />
83
- </div>
84
- <div className="space-y-2">
85
- <Label htmlFor="i18n-prompt-languages">
86
- {t(
87
- "demo.prompt.languages",
88
- { ns: "nocobase-i18n" },
89
- "Languages"
90
- )}
91
- </Label>
92
- <Textarea
93
- id="i18n-prompt-languages"
94
- value={languages}
95
- onChange={(event) => setLanguages(event.target.value)}
96
- className="min-h-24"
97
- />
98
- </div>
99
- </CardContent>
100
- </Card>
101
- <PromptOutput
102
- title={t(
103
- "demo.prompt.output",
104
- { ns: "nocobase-i18n" },
105
- "Generated prompt"
106
- )}
107
- description={t(
108
- "demo.prompt.outputDescription",
109
- { ns: "nocobase-i18n" },
110
- "Updates as you change the scene and language requirements."
111
- )}
112
- prompt={prompt}
113
- copyLabel={t(
114
- "demo.prompt.copy",
115
- { ns: "nocobase-i18n" },
116
- "Copy prompt"
117
- )}
118
- copiedLabel={t(
119
- "demo.prompt.copied",
120
- { ns: "nocobase-i18n" },
121
- "Copied"
122
- )}
123
- copyErrorLabel={t(
124
- "demo.prompt.copyError",
125
- { ns: "nocobase-i18n" },
126
- "Clipboard access failed. Select the prompt and copy it manually."
127
- )}
128
- />
129
- </div>
130
- </details>
131
- );
132
- }