@nocobase/portal-template-default 1.0.15 → 1.0.17

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 (153) hide show
  1. package/AGENTS.md +8 -0
  2. package/README.MD +4 -0
  3. package/dist/assets/{LineDraw-iG-ADes-.js → LineDraw-BBB5hwuJ.js} +1 -1
  4. package/dist/assets/{SymbolDraw-DXoSw1tM.js → SymbolDraw-CKS3uUb_.js} +1 -1
  5. package/dist/assets/{VisualMapping-C_ee4Eht.js → VisualMapping-BCwaW3TD.js} +1 -1
  6. package/dist/assets/auth-method-demo-BdCCvEEz.js +1 -0
  7. package/dist/assets/{auto-login-provider-5Uxza9Ms.js → auto-login-provider-DO5Il6Dp.js} +2 -2
  8. package/dist/assets/auto-login-provider-TQ08B6-i.js +1 -0
  9. package/dist/assets/auto-redirect-provider-ButXp0A3.js +1 -0
  10. package/dist/assets/auto-redirect-provider-DnGGP2Vn.js +1 -0
  11. package/dist/assets/auto-redirect-provider-ja-vFPaF.js +1 -0
  12. package/dist/assets/calendar-C7xnRgOT.js +1 -0
  13. package/dist/assets/{cas-sign-in-button-CyqG1QME.js → cas-sign-in-button-BZCa4lR6.js} +1 -1
  14. package/dist/assets/{components-D-ptYjX_.js → components-_g-GjQeV.js} +3 -3
  15. package/dist/assets/{configuration-gate-C08mkkiX.js → configuration-gate-B4XVz7tS.js} +1 -1
  16. package/dist/assets/{createClipPathFromCoordSys-wj34-b1B.js → createClipPathFromCoordSys-z9Kmh-tu.js} +1 -1
  17. package/dist/assets/createSeriesDataSimply-CPqysF0K.js +1 -0
  18. package/dist/assets/{customGraphicKeyframeAnimation-DWrhrHL_.js → customGraphicKeyframeAnimation-DMU5crAu.js} +1 -1
  19. package/dist/assets/demo-BPlae2bp.js +1 -0
  20. package/dist/assets/demo-Bj_Y0RrW.js +1 -0
  21. package/dist/assets/demo-CKPAQOib.js +1 -0
  22. package/dist/assets/demo-CXRTPvIx.js +1 -0
  23. package/dist/assets/demo-DJuVDu1n.js +1 -0
  24. package/dist/assets/demo-DUmWU7ik.js +1 -0
  25. package/dist/assets/demo-NhIzFRE1.js +1 -0
  26. package/dist/assets/{dingtalk-sign-in-button-DSWsSruv.js → dingtalk-sign-in-button-DMPgE5kT.js} +1 -1
  27. package/dist/assets/{echarts-preview-DxHNfq1C.js → echarts-preview-R96Pbqmz.js} +1 -1
  28. package/dist/assets/{echarts-runtime-D8kXn6ME.js → echarts-runtime-Ce_z2eX_.js} +3 -3
  29. package/dist/assets/{echarts-runtime-advanced-QY8v95qK.js → echarts-runtime-advanced-Dr80KHJR.js} +1 -1
  30. package/dist/assets/{echarts-runtime-common-D-yqAK-r.js → echarts-runtime-common-DB95Yfc1.js} +1 -1
  31. package/dist/assets/{echarts-runtime-components-P4-i8jPU.js → echarts-runtime-components-DCJEaTJk.js} +1 -1
  32. package/dist/assets/{echarts-runtime-hierarchy-ByQZ-DbP.js → echarts-runtime-hierarchy-CezgZs9O.js} +1 -1
  33. package/dist/assets/{floating-BFVEyPEp.js → floating-O9WmiDXk.js} +2 -2
  34. package/dist/assets/index-BBKV6O5d.css +1 -0
  35. package/dist/assets/{index-Btk35Nx-.js → index-CPzehPGe.js} +3 -3
  36. package/dist/assets/index-Cc6awvdg.js +1064 -0
  37. package/dist/assets/index-ChA0z9ke.js +38 -0
  38. package/dist/assets/{index-um5hdKdZ.js → index-DgB7uTMs.js} +2 -2
  39. package/dist/assets/{index-CwNxd66J.js → index-DroUAK80.js} +1 -1
  40. package/dist/assets/index-WKvygTBp.js +59 -0
  41. package/dist/assets/{labelHelper-DQqRy3a_.js → labelHelper-Dk5jkiD-.js} +1 -1
  42. package/dist/assets/ldap-sign-in-form-CKN4l7qM.js +1 -0
  43. package/dist/assets/{oidc-sign-in-button-CQdRcR_p.js → oidc-sign-in-button-BIRonrpC.js} +1 -1
  44. package/dist/assets/{page-context-CnQ4GYM7.js → page-context-DAiW_dId.js} +3 -3
  45. package/dist/assets/prompt-card-rGZqpqkF.js +1 -0
  46. package/dist/assets/prompt-output-B4h3uLWf.js +1 -0
  47. package/dist/assets/saml-sign-in-button-B4ugaLIb.js +1 -0
  48. package/dist/assets/{sectorHelper-DN_Vv6OL.js → sectorHelper-BuxrrJrA.js} +1 -1
  49. package/dist/assets/shortcut-BhKXxJLs.js +47 -0
  50. package/dist/assets/{sms-sign-in-form-DTX9GV2I.js → sms-sign-in-form-DKpxRDdZ.js} +1 -1
  51. package/dist/assets/{static.browser-jI1psK0d.js → static.browser-kzzpH0Xt.js} +8 -8
  52. package/dist/assets/switch-BdVxPIVU.js +1 -0
  53. package/dist/assets/{tool-cards-DFttLAfo.js → tool-cards-CpczIke-.js} +3 -3
  54. package/dist/assets/{use-authenticator-sign-in-CRGjzXju.js → use-authenticator-sign-in-CIj210ry.js} +1 -1
  55. package/dist/assets/use-dingtalk-sign-in-BW4kkXD3.js +1 -0
  56. package/dist/assets/{use-wecom-sign-in-C9j8wfCD.js → use-wecom-sign-in-dIqMtcN9.js} +1 -1
  57. package/dist/assets/wecom-sign-in-button-Dn_2zDab.js +1 -0
  58. package/dist/index.html +2 -2
  59. package/dist/index.raw.html +2 -2
  60. package/package.json +9 -1
  61. package/src/App.tsx +5 -2
  62. package/src/app/extension.ts +2 -0
  63. package/src/app/extensions.tsx +18 -6
  64. package/src/app/route-access-guard.tsx +22 -0
  65. package/src/app/route-runtime.ts +173 -0
  66. package/src/app/routes.tsx +2 -2
  67. package/src/components/app-shell/header.tsx +56 -1
  68. package/src/components/app-shell/sidebar.tsx +14 -2
  69. package/src/components/auth/sign-up-form.tsx +287 -59
  70. package/src/components/auth/types.ts +23 -1
  71. package/src/extensions/nocobase-acl/README.md +28 -14
  72. package/src/extensions/nocobase-acl/demo/index.tsx +87 -15
  73. package/src/extensions/nocobase-acl/demo/prompt-generator.tsx +1 -0
  74. package/src/extensions/nocobase-mail/README.md +74 -0
  75. package/src/extensions/nocobase-mail/components/index.ts +79 -0
  76. package/src/extensions/nocobase-mail/components/mail-api.ts +423 -0
  77. package/src/extensions/nocobase-mail/components/mail-attachment-list.tsx +67 -0
  78. package/src/extensions/nocobase-mail/components/mail-compose-attachments.tsx +166 -0
  79. package/src/extensions/nocobase-mail/components/mail-compose.tsx +1071 -0
  80. package/src/extensions/nocobase-mail/components/mail-detail.tsx +653 -0
  81. package/src/extensions/nocobase-mail/components/mail-draft-autosave.ts +26 -0
  82. package/src/extensions/nocobase-mail/components/mail-empty.tsx +48 -0
  83. package/src/extensions/nocobase-mail/components/mail-filters.tsx +277 -0
  84. package/src/extensions/nocobase-mail/components/mail-inbox.tsx +544 -0
  85. package/src/extensions/nocobase-mail/components/mail-inline-images.ts +69 -0
  86. package/src/extensions/nocobase-mail/components/mail-label-badge.tsx +25 -0
  87. package/src/extensions/nocobase-mail/components/mail-label-manager.tsx +271 -0
  88. package/src/extensions/nocobase-mail/components/mail-labels-editor.tsx +267 -0
  89. package/src/extensions/nocobase-mail/components/mail-mass-tracking.tsx +271 -0
  90. package/src/extensions/nocobase-mail/components/mail-note-editor.tsx +99 -0
  91. package/src/extensions/nocobase-mail/components/mail-recipient-input.tsx +260 -0
  92. package/src/extensions/nocobase-mail/components/mail-reply-quote.ts +28 -0
  93. package/src/extensions/nocobase-mail/components/mail-rich-editor.tsx +287 -0
  94. package/src/extensions/nocobase-mail/components/mail-send-actions.tsx +238 -0
  95. package/src/extensions/nocobase-mail/components/mail-senders.ts +61 -0
  96. package/src/extensions/nocobase-mail/components/mail-settings-drawer.tsx +708 -0
  97. package/src/extensions/nocobase-mail/components/mail-showcase-layout.tsx +64 -0
  98. package/src/extensions/nocobase-mail/components/mail-signature-manager.tsx +258 -0
  99. package/src/extensions/nocobase-mail/components/mail-signatures.ts +25 -0
  100. package/src/extensions/nocobase-mail/components/mail-table.tsx +476 -0
  101. package/src/extensions/nocobase-mail/components/mail-template-manager.tsx +204 -0
  102. package/src/extensions/nocobase-mail/components/mail-toolbar.tsx +155 -0
  103. package/src/extensions/nocobase-mail/components/mail-unread.tsx +111 -0
  104. package/src/extensions/nocobase-mail/components/types.ts +297 -0
  105. package/src/extensions/nocobase-mail/components/use-mail-compose.tsx +262 -0
  106. package/src/extensions/nocobase-mail/components/use-mail-mass-messages.ts +54 -0
  107. package/src/extensions/nocobase-mail/components/use-mail-messages.ts +113 -0
  108. package/src/extensions/nocobase-mail/components/use-mail-signatures.ts +122 -0
  109. package/src/extensions/nocobase-mail/components/use-mail-templates.ts +54 -0
  110. package/src/extensions/nocobase-mail/extension.tsx +105 -0
  111. package/src/extensions/nocobase-mail/index.ts +1 -0
  112. package/src/extensions/nocobase-mail/mail-demo-pages.tsx +503 -0
  113. package/src/extensions/nocobase-mail/mail-pages.tsx +201 -0
  114. package/src/extensions/nocobase-mail/tests/mail-quote-html-regression.mjs +51 -0
  115. package/src/extensions/nocobase-mail/tests/mail-regression.mjs +649 -0
  116. package/src/extensions/nocobase-users-example/app-routes.tsx +121 -0
  117. package/src/extensions/nocobase-users-example/extension.tsx +2 -100
  118. package/src/extensions/nocobase-users-example/index.ts +1 -0
  119. package/src/lib/nocobase/acl/menu.ts +17 -3
  120. package/src/lib/nocobase/acl/types.ts +4 -0
  121. package/src/locales/en-US.ts +2 -1
  122. package/src/locales/zh-CN.ts +2 -1
  123. package/src/providers/runtime-config.ts +18 -0
  124. package/src/routes.tsx +10 -0
  125. package/src/vite-env.d.ts +3 -0
  126. package/vite.config.ts +8 -0
  127. package/dist/assets/auth-method-demo-DaOCuvsq.js +0 -1
  128. package/dist/assets/auto-login-provider-DyaPGK2D.js +0 -1
  129. package/dist/assets/auto-redirect-provider-CfwRvYOI.js +0 -1
  130. package/dist/assets/auto-redirect-provider-Cr3jmYts.js +0 -1
  131. package/dist/assets/auto-redirect-provider-QkJQRBbG.js +0 -1
  132. package/dist/assets/calendar-DjDRfD5t.js +0 -1
  133. package/dist/assets/card-DuQBOS6A.js +0 -1
  134. package/dist/assets/createSeriesDataSimply-D0A6SAVQ.js +0 -1
  135. package/dist/assets/demo-BYWHeKUe.js +0 -1
  136. package/dist/assets/demo-CPWoNtx8.js +0 -1
  137. package/dist/assets/demo-CyvJk5zV.js +0 -1
  138. package/dist/assets/demo-D4OiKplc.js +0 -1
  139. package/dist/assets/demo-DBueJg0m.js +0 -1
  140. package/dist/assets/demo-DkIhyiRK.js +0 -1
  141. package/dist/assets/demo-tpTjO0sC.js +0 -1
  142. package/dist/assets/index-BgCbGDMc.js +0 -43
  143. package/dist/assets/index-MB-jfQld.js +0 -686
  144. package/dist/assets/index-NH3aqqQz.css +0 -1
  145. package/dist/assets/index-gFtCXH3o.js +0 -58
  146. package/dist/assets/ldap-sign-in-form--6Gt3yGq.js +0 -1
  147. package/dist/assets/prompt-card-B2RS4nt2.js +0 -1
  148. package/dist/assets/prompt-output-DZHRM2ft.js +0 -1
  149. package/dist/assets/saml-sign-in-button-BHL5a0JV.js +0 -1
  150. package/dist/assets/shortcut-C5x5LQWU.js +0 -47
  151. package/dist/assets/switch-CRL8PmRI.js +0 -1
  152. package/dist/assets/use-dingtalk-sign-in-8WYzJ2jf.js +0 -1
  153. package/dist/assets/wecom-sign-in-button-mIS1zGSU.js +0 -1
@@ -1 +0,0 @@
1
- import{j as t}from"./index-MB-jfQld.js";import{A as e}from"./auth-method-demo-DaOCuvsq.js";import n from"./oidc-sign-in-button-CQdRcR_p.js";import"./card-DuQBOS6A.js";const o={name:"company-oidc",authType:"OIDC",title:"Company OIDC"};function m(){return t.jsx(e,{authType:"OIDC",methodName:"OpenID Connect",description:"Redirect users to an OpenID Connect provider while the Starter handles callback tokens and the active authenticator.",children:t.jsx(n,{authenticator:o,onSignIn:()=>{}})})}export{m as OidcAuthDemoPage};
@@ -1 +0,0 @@
1
- import{j as t}from"./index-MB-jfQld.js";import{A as e}from"./auth-method-demo-DaOCuvsq.js";import o from"./cas-sign-in-button-CyqG1QME.js";import"./card-DuQBOS6A.js";const n={name:"company-cas",authType:"CAS",title:"Company CAS"};function s(){return t.jsx(e,{authType:"CAS",methodName:"Central Authentication Service",description:"Redirect users to a CAS server and capture the returned NocoBase token without coupling the page UI to CAS.",children:t.jsx(o,{authenticator:n,onSignIn:()=>{}})})}export{s as CasAuthDemoPage};
@@ -1 +0,0 @@
1
- import{j as e}from"./index-MB-jfQld.js";import{A as o}from"./auth-method-demo-DaOCuvsq.js";import i from"./sms-sign-in-form-DTX9GV2I.js";import"./card-DuQBOS6A.js";import"./use-authenticator-sign-in-CRGjzXju.js";const n={name:"company-sms",authType:"SMS",title:"SMS verification code",options:{autoSignup:!0,verifier:"login-sms"}};function p(){return e.jsx(o,{authType:"SMS",methodName:"SMS verification code",description:"Collect a phone number and one-time code while keeping delivery and sign-in bound to the configured verifier.",children:e.jsx(i,{authenticator:n,onSendCode:()=>{},onSignIn:()=>{}})})}export{p as SmsAuthDemoPage};
@@ -1,43 +0,0 @@
1
- import{t as K,j as e,H as Y,M as ee,J as se,D as g,K as S,N as j,O as _,B as P,Q as ae,R as te,V as ne,W as oe,X as ie,Y as R,Z as H,_ as D,$ as F,a0 as G,b as l,a1 as V,I as re,d as O,e as z,f as U,g as B,i as v,a2 as le,l as ce,m as de,n as $,o as k,p as he,q as I,a3 as pe}from"./index-MB-jfQld.js";import{C as x,a as T,b as M,d as E}from"./card-DuQBOS6A.js";import{A as me}from"./configuration-gate-C08mkkiX.js";import{P as ue}from"./prompt-output-DZHRM2ft.js";import{S as xe}from"./switch-CRL8PmRI.js";/**
2
- * @license lucide-react v0.487.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const ge=[["rect",{x:"2",y:"4",width:"20",height:"16",rx:"2",key:"izxlao"}],["path",{d:"M10 4v4",key:"pp8u80"}],["path",{d:"M2 8h20",key:"d11cs7"}],["path",{d:"M6 4v4",key:"1svtjw"}]],be=K("app-window",ge);/**
7
- * @license lucide-react v0.487.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const fe=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M9 3v18",key:"fh3hqa"}],["path",{d:"M15 3v18",key:"14nvp0"}]],ve=K("columns-3",fe),L=[{value:"embedded",title:"Embedded block",description:"Place chat inside a dashboard, record page, or workspace region.",action:"Preview block",icon:ve},{value:"page",title:"Dedicated page",description:"Give the conversation a full route and the largest working area.",action:"Preview page",icon:be},{value:"side-panel",title:"Push side panel",description:"Keep the page operable while the content narrows for chat.",action:"Open panel",icon:Y},{value:"dialog",title:"Dialog",description:"Open a focused conversation from an action without changing route.",action:"Open dialog",icon:ee},{value:"mobile",title:"Mobile container",description:"Use the same component in a narrow, touch-friendly viewport.",action:"Preview mobile",icon:se}];function we({value:s,onValueChange:n,windowProps:o}){var c;return e.jsxs("div",{className:"space-y-5",children:[e.jsx("div",{className:"grid gap-3 sm:grid-cols-2 xl:grid-cols-5",children:L.map(i=>{const m=i.icon,u=i.value===s;return e.jsxs(x,{"data-active":u,className:"gap-0 py-0 transition-colors data-active:border-foreground/35 data-active:bg-muted/20",children:[e.jsxs(T,{className:"p-4",children:[e.jsx("div",{className:"mb-3 flex size-9 items-center justify-center rounded-lg border bg-background",children:e.jsx(m,{className:"size-4 text-muted-foreground"})}),e.jsx(M,{className:"text-sm",children:i.title}),e.jsx("p",{className:"min-h-15 text-xs leading-5 text-muted-foreground",children:i.description})]}),e.jsx(E,{className:"border-t p-3",children:e.jsx(g,{variant:u?"secondary":"ghost",size:"sm",className:"w-full",onClick:()=>n(i.value),children:i.action})})]},i.value)})}),e.jsxs(x,{className:"gap-0 py-0",children:[e.jsxs("div",{className:"flex min-h-12 items-center justify-between border-b px-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium",children:"Container preview"}),e.jsx("div",{className:"text-xs text-muted-foreground",children:(c=L.find(i=>i.value===s))==null?void 0:c.title})]}),e.jsx("code",{className:"rounded-md bg-muted px-2 py-1 text-xs text-muted-foreground",children:Ne(s)})]}),e.jsxs("div",{className:"flex min-h-[650px] justify-center bg-muted/15 p-3 sm:p-5",children:[s==="embedded"?e.jsx(S,{className:"h-[610px] w-full max-w-3xl shadow-sm",children:e.jsx(j,{...o})}):null,s==="page"?e.jsx(_,{className:"h-[610px] min-h-0 w-full",children:e.jsx(j,{...o})}):null,s==="mobile"?e.jsx("div",{className:"w-full max-w-[390px] rounded-[2rem] border-4 border-foreground/10 bg-background p-1 shadow-xl",children:e.jsx(S,{className:"h-[610px] rounded-[1.55rem] border-0",children:e.jsx(j,{...o})})}):null,s==="side-panel"||s==="dialog"?e.jsx(je,{mode:s,onOpen:()=>n(s)}):null]})]})]})}function je({mode:s,onOpen:n}){return e.jsxs("div",{className:"grid w-full max-w-4xl grid-cols-[200px_minmax(0,1fr)] overflow-hidden rounded-xl border bg-background shadow-sm",children:[e.jsxs("div",{className:"border-r bg-muted/30 p-4",children:[e.jsx("div",{className:"h-5 w-24 rounded bg-muted"}),e.jsxs("div",{className:"mt-6 space-y-3",children:[e.jsx("div",{className:"h-8 rounded bg-muted"}),e.jsx("div",{className:"h-8 rounded bg-muted/70"}),e.jsx("div",{className:"h-8 rounded bg-muted/70"})]})]}),e.jsx("div",{className:"flex items-center justify-center p-8",children:e.jsxs("div",{className:"max-w-sm text-center",children:[e.jsx("div",{className:"mx-auto mb-4 h-24 rounded-xl border bg-muted/20"}),e.jsx("h3",{className:"text-sm font-medium",children:s==="side-panel"?"Chat opens beside the current page":"Chat opens above the current page"}),e.jsx("p",{className:"mt-2 text-xs leading-5 text-muted-foreground",children:s==="side-panel"?"The live preview pushes this page narrower instead of blocking interaction.":"The live preview uses a focused dialog while preserving the page underneath."}),e.jsx(g,{className:"mt-4",size:"sm",onClick:n,children:s==="side-panel"?"Open side panel":"Open dialog"})]})})]})}const Ne=s=>{switch(s){case"page":return"<ChatPage />";case"side-panel":return'<ChatSurface variant="side-panel" />';case"dialog":return'<ChatSurface variant="dialog" />';case"mobile":return"<ChatInline /> · 390px";default:return"<ChatInline />"}},ye=[{id:"message-presentation-user",role:"user",parts:[{type:"text",text:"Review the support workspace and propose the most useful dashboard."}]},{id:"message-presentation-assistant",role:"assistant",parts:[{type:"reasoning",text:"I should inspect the existing collections first, then keep the recommendation focused on operational decisions.",state:"done"},{type:"dynamic-tool",toolName:"inspectDataModel",toolCallId:"message-presentation-tool",state:"output-available",input:{collections:["tickets","categories","users"]},output:{collectionsFound:3}},{type:"text",text:"Start with open workload, ownership gaps, SLA risk, and the created-versus-resolved trend. That gives the team one clear operational view without duplicating the underlying NocoBase rules."}]}],Ce=[{key:"web-search",label:"Web search",icon:e.jsx(D,{})}];function Ae(){return e.jsxs("div",{className:"grid items-start gap-4 xl:grid-cols-2",children:[e.jsxs(x,{className:"gap-0 py-0",children:[e.jsxs(T,{className:"border-b py-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(P,{variant:"outline",children:"Inline messages"}),e.jsx(M,{className:"text-base",children:"Standard conversation transcript"})]}),e.jsx("p",{className:"text-xs leading-5 text-muted-foreground",children:"This fixed example shows where reasoning, a normal tool call, and the final assistant response appear in one message sequence."})]}),e.jsx(E,{className:"bg-muted/15 p-4",children:e.jsx(S,{className:"h-[520px] bg-background shadow-sm",children:e.jsxs("div",{className:"flex h-full min-h-0 flex-col",children:[e.jsxs("div",{className:"relative flex h-12 shrink-0 items-center justify-between border-b px-2.5",children:[e.jsx(g,{variant:"ghost",size:"icon-sm","aria-label":"Conversations",children:e.jsx(ae,{})}),e.jsx("div",{className:"pointer-events-none absolute left-1/2 max-w-[55%] -translate-x-1/2 truncate text-sm font-medium",children:"Support workspace review"}),e.jsx(g,{variant:"ghost",size:"icon-sm","aria-label":"New conversation",children:e.jsx(te,{})})]}),e.jsx(ne,{className:"h-full",messages:ye,showMessageActions:!1}),e.jsx("div",{className:"shrink-0 bg-card px-4 pt-2 pb-3",children:e.jsxs("div",{className:"rounded-xl border bg-background px-3 py-2.5 shadow-sm",children:[e.jsx("div",{className:"min-h-10 text-sm text-muted-foreground",children:"Message your AI employee…"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(g,{variant:"ghost",size:"icon-sm","aria-label":"Attach file",children:e.jsx(oe,{})}),e.jsx(g,{size:"icon-sm","aria-label":"Send message",children:e.jsx(ie,{})})]})]})})]})})})]}),e.jsxs(x,{className:"gap-0 py-0",children:[e.jsxs(T,{className:"border-b py-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(P,{variant:"outline",children:"Compact composer"}),e.jsx(M,{className:"text-base",children:"Open the transcript only when needed"})]}),e.jsx("p",{className:"text-xs leading-5 text-muted-foreground",children:"The compact variant keeps only the chat header and composer. Its history button opens a dialog with conversation switching and the selected transcript."})]}),e.jsx(E,{className:"bg-muted/15 p-4",children:e.jsx(R,{id:"message-presentation-compact-demo",children:e.jsx(H,{className:"bg-background",composerActions:Ce,showModelSelector:!1,disclaimer:!1})})})]})]})}const Z=[{value:"embedded",label:"Inside the page",description:"Embed chat in the selected content region."},{value:"page",label:"Dedicated page",description:"Create a full route for the AI conversation."},{value:"side-panel",label:"Right side panel",description:"Push the page narrower while chat is open."},{value:"dialog",label:"Dialog",description:"Open chat from a button or page action."},{value:"mobile",label:"Mobile region",description:"Optimize the embedded container for a narrow viewport."}],ke={conversationList:!0,employeeSelector:!0,modelSelector:!0,userPrompt:!0,pageElement:!0,upload:!0,webSearch:!0,panelExpansion:!0};function Ie(){return e.jsx(R,{id:"prompt-generator-preview",children:e.jsx(Se,{})})}function Se(){const{id:s,addWorkContext:n,focusComposer:o}=F(),{registeredCount:c,startPicking:i}=G(),[m,u]=l.useState("the current page's main content area"),[r,N]=l.useState("embedded"),[h,y]=l.useState("450"),[p,C]=l.useState("transcript"),[a,W]=l.useState(ke),A=l.useMemo(()=>{const t=[];return a.pageElement&&t.push({key:"pick-page-element",label:"Pick page element",icon:e.jsx(V,{}),disabled:c===0,onClick:()=>i({chatId:s,onSelect:f=>{n(f),o()}})}),a.webSearch&&t.push({key:"web-search",label:"Web search",icon:e.jsx(D,{})}),t},[n,a.pageElement,a.webSearch,s,o,c,i]),d=(t,f)=>{W(X=>({...X,[t]:f}))},J=l.useMemo(()=>{const t={embedded:"Render ChatInline inside the target content region and keep its width fluid within the parent container.",page:"Create a dedicated route and render ChatPage with AIChatWindow filling the available page content.","side-panel":`Use ChatSurface with variant="side-panel" on the right and a ${h}px width. Opening chat must push the page narrower instead of covering it on desktop; mobile may use an overlay.`,dialog:'Open ChatSurface with variant="dialog" from a page action. Keep conversation state in AIProvider/AIChatProvider so closing the dialog does not discard it.',mobile:"Render ChatInline in the target region with a mobile-first width around 390px and preserve the same responsive AIChatWindow API."}[r];return`Add the standard NocoBase AI conversation to ${m||"the target page"}.
12
-
13
- Placement:
14
- - ${t}
15
- - Keep AIChatWindow position-independent. The surface wrapper owns placement and dimensions.
16
-
17
- Message presentation:
18
- - ${p==="transcript"?"Render the full AIChatMessageList inline as part of AIChatWindow.":"Use AIChatCompact for the working surface and open AIChatHistoryDialog when the user requests the full transcript."}
19
-
20
- Conversation capabilities:
21
- - Conversation list: ${a.conversationList}
22
- - AI employee selector: ${a.employeeSelector}
23
- - Model selector: ${a.modelSelector}
24
- - Personalized prompt editor: ${a.userPrompt}
25
- - Pick page element: ${a.pageElement}
26
- - Upload action: ${a.upload}
27
- - Web search action: ${a.webSearch}
28
- - Side panel can expand to a 95% dialog and collapse back: ${a.panelExpansion}
29
- - Tool approval follows NocoBase permissions. Always show Allow / Deny when the backend marks a tool as ASK.
30
-
31
- Implementation requirements:
32
- - Use AIProvider at application level and AIChatProvider with a stable id for this chat instance.
33
- - Wrap the application content with AIPageElementProvider when page-element picking is enabled.
34
- - Register selectable React components with useAIPageElement and return serializable business context from getContext.
35
- - Reuse AIChatWindow and the existing providers; do not duplicate message, streaming, reasoning, or tool-call state.
36
- - When the right panel is expandable, render one AIChatWindow inside ChatSurface and change only its variant between "side-panel" and "dialog". Put ChatSurfaceActions in the window header.
37
- - Keep the generic Tool Call shell responsible for status, ASK approval, errors, and disclosure. Register business-specific bodies through AIToolRendererProvider.
38
- - Include the built-in specialized Tool Card renderers. This is part of the standard AI chat capability, not an optional page setting.
39
- - Register browser-side tool implementations through AIProvider.toolInvokers. After all interrupted calls are approved, the provider executes these handlers and sends their results when resuming the NocoBase conversation.
40
- - Pass application actions through composerActions.
41
- - AIChatProvider handles NocoBase ASK decisions and resumes tool execution. Use onToolCallDecision only for application-specific side effects or telemetry.
42
- - Use shadcn/Base UI components only; do not introduce Ant Design, Radix, or Zustand.
43
- - Match the existing NocoBase ChatBox behavior and black/white/gray visual system.`},[a,p,h,r,m]),b=p==="transcript"?e.jsx(j,{composerActions:A,showConversationToggle:a.conversationList,showEmployeeSelector:a.employeeSelector,showModelSelector:a.modelSelector,showUserPrompt:a.userPrompt,enableAttachments:a.upload,attachmentActionIndex:a.pageElement?1:0,disclaimer:!1,onToolCallDecision:async()=>{}}):e.jsx(H,{className:"h-full rounded-none border-0",composerActions:A,showEmployeeSelector:a.employeeSelector,showModelSelector:a.modelSelector,showUserPrompt:a.userPrompt,enableAttachments:a.upload,disclaimer:!1,onToolCallDecision:async()=>{}}),Q=r==="page"?e.jsx(_,{className:"h-[430px] min-h-0 w-full max-w-none",children:b}):r==="side-panel"?e.jsxs("div",{className:"flex h-[430px] w-full overflow-hidden rounded-xl border bg-card shadow-sm",children:[e.jsxs("div",{className:"hidden min-w-0 flex-1 space-y-4 bg-muted/20 p-5 sm:block",children:[e.jsx("div",{className:"h-7 w-40 rounded-md bg-muted"}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx("div",{className:"h-24 rounded-lg border bg-background"}),e.jsx("div",{className:"h-24 rounded-lg border bg-background"})]}),e.jsx("div",{className:"h-48 rounded-lg border bg-background"})]}),e.jsx("aside",{className:"h-full max-w-full shrink-0 border-l bg-card",style:{width:`${h}px`},children:b})]}):r==="dialog"?e.jsxs("div",{className:"relative h-[430px] w-full overflow-hidden rounded-xl border bg-muted/30 p-5",children:[e.jsxs("div",{className:"space-y-3 opacity-45",children:[e.jsx("div",{className:"h-7 w-44 rounded bg-muted-foreground/20"}),e.jsx("div",{className:"h-24 rounded-lg bg-background"}),e.jsx("div",{className:"h-48 rounded-lg bg-background"})]}),e.jsx("div",{className:"absolute inset-4 overflow-hidden rounded-xl border bg-card shadow-2xl sm:inset-8",children:b})]}):r==="mobile"?e.jsx("div",{className:"h-[430px] w-full max-w-[390px] overflow-hidden rounded-[2rem] border-4 border-foreground/15 bg-card shadow-lg",children:b}):e.jsx(S,{className:"h-[430px] w-full max-w-2xl",children:b});return e.jsxs("div",{className:"grid items-start gap-5 xl:grid-cols-[360px_minmax(0,1fr)]",children:[e.jsxs(x,{className:"gap-0 py-0",children:[e.jsxs(T,{className:"border-b py-4",children:[e.jsx(M,{className:"text-base",children:"Describe the integration"}),e.jsx("p",{className:"text-xs leading-5 text-muted-foreground",children:"Choose where chat belongs and which capabilities the target page needs."})]}),e.jsxs(E,{className:"space-y-5 p-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-xs font-medium",htmlFor:"ai-chat-target",children:"Target page or region"}),e.jsx(re,{id:"ai-chat-target",value:m,onChange:t=>u(t.target.value),placeholder:"e.g. the ticket detail page"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-xs font-medium",children:"Placement"}),e.jsx("div",{className:"grid gap-2 sm:grid-cols-2 xl:grid-cols-1",children:Z.map(t=>e.jsxs("button",{type:"button","data-active":r===t.value,className:"rounded-lg border px-3 py-2.5 text-left transition-colors hover:bg-muted/40 data-active:border-foreground/35 data-active:bg-muted/60",onClick:()=>N(t.value),children:[e.jsx("span",{className:"block text-sm font-medium",children:t.label}),e.jsx("span",{className:"mt-0.5 block text-xs leading-5 text-muted-foreground",children:t.description})]},t.value))})]}),r==="side-panel"?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-xs font-medium",children:"Side panel width"}),e.jsxs(O,{value:h,onValueChange:t=>t&&y(t),children:[e.jsx(z,{className:"w-full",children:e.jsxs(U,{children:[h,"px"]})}),e.jsxs(B,{children:[e.jsx(v,{value:"400",children:"400px"}),e.jsx(v,{value:"450",children:"450px · NocoBase default"}),e.jsx(v,{value:"520",children:"520px"})]})]})]}):null,e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-xs font-medium",children:"Message presentation"}),e.jsxs(O,{value:p,onValueChange:t=>t&&C(t),children:[e.jsx(z,{className:"w-full",children:e.jsx(U,{children:p==="transcript"?"Full transcript":"Compact + history dialog"})}),e.jsxs(B,{children:[e.jsx(v,{value:"transcript",children:"Full transcript"}),e.jsx(v,{value:"compact-history-dialog",children:"Compact + history dialog"})]})]})]}),e.jsxs("div",{className:"space-y-1 border-t pt-4",children:[e.jsx("div",{className:"mb-2 text-xs font-medium",children:"Capabilities"}),Object.keys(a).map(t=>e.jsxs("label",{className:"flex items-center justify-between gap-4 py-1.5 text-sm",children:[e.jsx("span",{className:"min-w-0",children:e.jsx("span",{className:"block",children:Pe(t)})}),e.jsx(xe,{size:"sm",checked:a[t],onCheckedChange:f=>d(t,f)})]},t))]})]})]}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs(x,{className:"gap-0 overflow-hidden py-0",children:[e.jsxs("div",{className:"flex items-center justify-between border-b px-4 py-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium",children:"Capabilities preview"}),e.jsx("div",{className:"text-xs text-muted-foreground",children:"The selected controls are rendered on the real AIChatWindow."})]}),e.jsx("code",{className:"rounded-md bg-muted px-2 py-1 text-xs text-muted-foreground",children:Te(r)})]}),e.jsx("div",{className:"flex justify-center bg-muted/20 p-3 sm:p-4",children:Q})]}),e.jsx(ue,{title:"Generated implementation prompt",description:"Updates from the selected page, placement, and capabilities.",prompt:J,promptClassName:"max-h-[760px] min-h-[520px]"})]})]})}const Pe=s=>({conversationList:"Conversation list",employeeSelector:"AI employee selector",modelSelector:"Model selector",userPrompt:"Personalized prompt editor",pageElement:"Pick page element",upload:"Upload files",webSearch:"Web search",panelExpansion:"Panel expand / collapse"})[s],Te=s=>{var n;return((n=Z.find(o=>o.value===s))==null?void 0:n.label)??s},Me=[["className","string","undefined","Adds layout or sizing classes to the root conversation window."],["headerActions","ReactNode","undefined","Adds surface actions such as expand, collapse, or close to the header."],["composerActions","AIChatComposerAction[]","[]","Application-specific buttons rendered in the composer toolbar."],["showConversationToggle","boolean","true","Shows the conversation-list control."],["showNewConversation","boolean","true","Shows the new-conversation action."],["showEmployeeSelector","boolean","true","Shows the AI employee selector in the composer."],["showModelSelector","boolean","true","Shows the model selector in the composer."],["showUserPrompt","boolean","true","Shows the personalized AI employee prompt editor."],["enableAttachments","boolean","false","Enables file picker, drag-and-drop, and pasted-image uploads."],["attachmentActionIndex","number","0","Places the attachment action at a specific position in the composer toolbar."],["onToolCallDecision","(decision: AIToolCallDecision) => void | Promise<void>","undefined","Observes approve, reject, or edit decisions after AIChatProvider has processed them; use it for application side effects or telemetry."],["placeholder","string","Message your AI employee…","Composer placeholder text."],["disclaimer","ReactNode | false","Default disclaimer","Customizes or hides the footer disclaimer."]],Ee=[["variant",'"side-panel" | "dialog"',"required","Changes only the outer presentation while keeping the same chat window mounted."],["open","boolean","required","Controls whether the surface is open."],["onOpenChange","(open: boolean) => void","required","Receives close requests from Escape, the dialog backdrop, or surface actions."],["side",'"left" | "right"','"right"',"Chooses the side used by the side-panel variant."],["width","number | string","450","Sets the width used by the side-panel variant."],["closeOnEscape","boolean","true","Allows Escape to close the active surface."],["showCloseHandle","boolean","false","Shows an outside close handle for the side-panel variant."]];function Be(){return e.jsx(me,{children:e.jsx(R,{id:"ai-chat-demo",children:e.jsx(We,{})})})}function We(){const[s,n]=l.useState("embedded"),[o,c]=l.useState(!1),[i,m]=l.useState(!1),{id:u,addWorkContext:r,focusComposer:N}=F(),{registeredCount:h,startPicking:y}=G(),p=l.useMemo(()=>[{key:"pick-page-element",label:"Pick page element",icon:e.jsx(V,{}),disabled:h===0,onClick:()=>{o&&s==="dialog"&&n("side-panel"),y({chatId:u,onSelect:d=>{r(d),N()}})}},{key:"web-search",label:"Web search",icon:e.jsx(D,{}),active:i,onClick:()=>{m(d=>!d)}}],[r,u,s,N,h,y,o,i]),C=l.useMemo(()=>({composerActions:p,enableAttachments:!0,attachmentActionIndex:1,onToolCallDecision:async()=>{}}),[p]),a=()=>{c(!1)},W={...C,headerActions:e.jsx(pe,{expanded:s==="dialog",onExpandedChange:d=>{n(d?"dialog":"side-panel")},onClose:a})},A=d=>{n(d),c(d==="side-panel"||d==="dialog")};return e.jsxs("div",{"data-open":o&&s==="side-panel","data-side":"right",className:"chat-side-panel-layout @container min-w-0",style:{"--chat-side-panel-width":"450px"},children:[e.jsxs("div",{className:"space-y-14 pb-12",children:[e.jsx("section",{className:"flex flex-wrap items-start justify-between gap-5 border-b pb-8",children:e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(P,{variant:"secondary",children:"AI Components"}),e.jsx(P,{variant:"outline",children:"Preview"})]}),e.jsx("h1",{className:"mt-4 text-3xl font-semibold tracking-[-0.035em]",children:"AI Chat Window"}),e.jsx("p",{className:"mt-3 max-w-3xl text-sm leading-6 text-muted-foreground",children:"A position-independent NocoBase AI employee conversation component. Explore message interactions independently, place the same chat in different containers, then generate an implementation prompt for a target page."})]})}),e.jsxs("section",{className:"space-y-5",children:[e.jsx(w,{eyebrow:"Container patterns",title:"Use the same conversation window wherever the product needs it",description:"The provider owns conversation state. Page, embedded block, push side panel, dialog, and mobile containers only decide placement and dimensions."}),e.jsx(we,{value:s,onValueChange:A,windowProps:C})]}),e.jsxs("section",{className:"space-y-5",children:[e.jsx(w,{eyebrow:"Message presentation",title:"Choose how much conversation history the page should expose",description:"Use the complete transcript for conversational work, or a compact worker surface that opens message history only when the user asks for it."}),e.jsx(Ae,{})]}),e.jsxs("section",{className:"space-y-5",children:[e.jsx(w,{eyebrow:"Prompt generator",title:"Describe where chat belongs, then copy an implementation prompt",description:"This replaces a generic prop configuration panel with a task-oriented generator: choose the target area, placement mode, and required capabilities."}),e.jsx(Ie,{})]}),e.jsxs("section",{className:"space-y-5",children:[e.jsx(w,{eyebrow:"Component API",title:"ChatSurface props",description:"Use variant as the single presentation switch. The child AIChatWindow remains the same React instance while the surface changes shape."}),e.jsx(q,{rows:Ee})]}),e.jsxs("section",{className:"space-y-5",children:[e.jsx(w,{eyebrow:"Component API",title:"AIChatWindow props",description:"The core window stays reusable while business pages provide placement, composer actions, and tool-approval behavior."}),e.jsx(q,{rows:Me})]})]}),e.jsx(le,{open:o,variant:s==="dialog"?"dialog":"side-panel",onOpenChange:c,width:450,children:e.jsx(j,{...W})})]})}function q({rows:s}){return e.jsx(x,{className:"gap-0 overflow-hidden py-0",children:e.jsxs(ce,{children:[e.jsx(de,{children:e.jsxs($,{children:[e.jsx(k,{children:"Prop"}),e.jsx(k,{children:"Type"}),e.jsx(k,{children:"Default"}),e.jsx(k,{children:"Description"})]})}),e.jsx(he,{children:s.map(([n,o,c,i])=>e.jsxs($,{children:[e.jsx(I,{className:"font-mono text-xs font-medium",children:n}),e.jsx(I,{className:"font-mono text-xs text-muted-foreground",children:o}),e.jsx(I,{className:"font-mono text-xs text-muted-foreground",children:c}),e.jsx(I,{className:"min-w-80 whitespace-normal text-muted-foreground",children:i})]},n))})]})})}function w({eyebrow:s,title:n,description:o}){return e.jsxs("div",{children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground",children:s}),e.jsx("h2",{className:"mt-2 text-xl font-semibold tracking-tight",children:n}),e.jsx("p",{className:"mt-1.5 max-w-3xl text-sm leading-6 text-muted-foreground",children:o})]})}export{Be as AIChatPage};