@nocobase/plugin-ai 2.2.0-beta.8 → 2.3.0-alpha.1
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.
- package/client-v2.d.ts +1 -0
- package/dist/ai/docs/nocobase/ai-employees/scenarios/company-background-research.md +125 -0
- package/dist/ai/docs/nocobase/api/app/env.md +28 -1
- package/dist/ai/docs/nocobase/api/cli/config/delete.md +8 -6
- package/dist/ai/docs/nocobase/api/cli/config/get.md +8 -6
- package/dist/ai/docs/nocobase/api/cli/config/index.md +37 -26
- package/dist/ai/docs/nocobase/api/cli/config/set.md +14 -8
- package/dist/ai/docs/nocobase/building-tips/operations-dashboard.md +513 -0
- package/dist/ai/docs/nocobase/file-manager/field-attachment.md +6 -0
- package/dist/ai/docs/nocobase/file-manager/file-preview/index.md +3 -12
- package/dist/ai/docs/nocobase/file-manager/stable-url.md +87 -0
- package/dist/ai/docs/nocobase/file-manager/storage/aliyun-oss.md +9 -0
- package/dist/ai/docs/nocobase/file-manager/storage/amazon-s3.md +9 -0
- package/dist/ai/docs/nocobase/file-manager/storage/index.md +23 -0
- package/dist/ai/docs/nocobase/file-manager/storage/local.md +12 -1
- package/dist/ai/docs/nocobase/file-manager/storage/migrate-to-s3-pro.md +269 -0
- package/dist/ai/docs/nocobase/file-manager/storage/tencent-cos.md +9 -0
- package/dist/ai/docs/nocobase/get-started/deployment/production.md +24 -2
- package/dist/ai/docs/nocobase/get-started/installation/docker-caddy.mdx +178 -0
- package/dist/ai/docs/nocobase/get-started/installation/docker-nginx.mdx +179 -0
- package/dist/ai/docs/nocobase/get-started/installation/docker.mdx +118 -1
- package/dist/ai/docs/nocobase/get-started/installation/env.md +47 -4
- package/dist/ai/docs/nocobase/index.md +1 -1
- package/dist/ai/docs/nocobase/interface-builder/blocks/data-blocks/comment.md +107 -0
- package/dist/ai/docs/nocobase/interface-builder/index.md +7 -6
- package/dist/ai/docs/nocobase/interface-builder/ui-layout/desktop.md +97 -0
- package/dist/ai/docs/nocobase/interface-builder/ui-layout/index.md +50 -0
- package/dist/ai/docs/nocobase/interface-builder/ui-layout/mobile.md +133 -0
- package/dist/ai/docs/nocobase/multi-app/multi-app-vs-multi-portal-vs-multi-space.md +159 -0
- package/dist/ai/docs/nocobase/multi-app/multi-portal/index.md +195 -0
- package/dist/ai/docs/nocobase/nocobase-cli/production/index.md +10 -0
- package/dist/ai/docs/nocobase/nocobase-cli/production/reverse-proxy/caddy.md +15 -2
- package/dist/ai/docs/nocobase/nocobase-cli/production/reverse-proxy/index.md +1 -1
- package/dist/ai/docs/nocobase/nocobase-cli/production/reverse-proxy/nginx.md +16 -2
- package/dist/ai/docs/nocobase/ops-management/version-control/index.md +1 -0
- package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-block-comment/index.md +14 -0
- package/dist/ai/docs/nocobase/runjs/context/ai.md +206 -0
- package/dist/ai/docs/nocobase/security/guide.md +23 -0
- package/dist/ai/docs/nocobase/tutorials/index.md +20 -1
- package/dist/ai/docs/nocobase/workflow/development/api.md +259 -77
- package/dist/ai/docs/nocobase/workflow/development/index.md +2 -1
- package/dist/ai/docs/nocobase/workflow/development/migration.md +319 -0
- package/dist/ai/docs/nocobase/workflow/development/node.md +84 -51
- package/dist/ai/docs/nocobase/workflow/development/trigger.md +122 -20
- package/dist/ai/tools/formFiller.js +4 -3
- package/dist/ai/tools/subAgentWebSearch.js +20 -15
- package/dist/client/23.65ea8c37cd4b884b.js +10 -0
- package/dist/client/264.cc98933ef65608b6.js +10 -0
- package/dist/client/336.7a8a8853196ad779.js +11 -0
- package/dist/client/372.40eb52905e3f3049.js +10 -0
- package/dist/client/416.92b74ca47e4099c4.js +10 -0
- package/dist/client/446.d63c38d0309fe250.js +10 -0
- package/dist/client/525.203778500aca5d05.js +10 -0
- package/dist/client/663.680bcf6272a8504d.js +10 -0
- package/dist/client/681.399948c18d753667.js +10 -0
- package/dist/client/705.380279da896021fb.js +10 -0
- package/dist/client/ai-employees/1.x/selector/AIContextCollector.d.ts +1 -4
- package/dist/client/ai-employees/permissions/PermissionsTab.d.ts +21 -5
- package/dist/client/index.d.ts +15 -20
- package/dist/client/index.js +8 -8
- package/dist/client/workflow/nodes/employee/index.d.ts +2 -23
- package/dist/client/workflow/nodes/llm/index.d.ts +2 -52
- package/dist/client/workflow/triggers/ai-employee/index.d.ts +2 -83
- package/dist/client-v2/23.1bcb6986b40723d8.js +10 -0
- package/dist/client-v2/264.be92ff6a4d2612f1.js +10 -0
- package/dist/client-v2/336.e406470429e0670e.js +11 -0
- package/dist/client-v2/372.8cc3fde09c9bec77.js +10 -0
- package/dist/client-v2/406.341be51205c674e0.js +10 -0
- package/dist/client-v2/416.0e1c2d9cde43b83d.js +10 -0
- package/dist/client-v2/446.073d450882db29fd.js +10 -0
- package/dist/client-v2/457.d72febb89e88fc00.js +10 -0
- package/dist/client-v2/663.342341f0b2b412d8.js +10 -0
- package/dist/client-v2/681.082f4f1c7b841983.js +10 -0
- package/dist/client-v2/705.1d10027ff8cfdf79.js +10 -0
- package/dist/{client/ai-employees/admin/AvatarSelect.d.ts → client-v2/ai-employees/AIEmployeeDropdown.d.ts} +8 -9
- package/dist/client-v2/ai-employees/AIEmployeeShortcut.d.ts +9 -2
- package/dist/{client → client-v2}/ai-employees/AddContextButton.d.ts +1 -1
- package/dist/{client → client-v2}/ai-employees/ai-coding/AICodingButton.d.ts +2 -1
- package/dist/{client/ai-employees/chatbox → client-v2/ai-employees/chatbox/components}/Actions.d.ts +2 -4
- package/dist/{client/ai-employees/chatbox → client-v2/ai-employees/chatbox/components}/AddLLMModal.d.ts +2 -4
- package/dist/client-v2/ai-employees/chatbox/components/Attachments.d.ts +27 -0
- package/dist/{client/ai-employees/permissions/Permissions.d.ts → client-v2/ai-employees/chatbox/components/ChatBox.d.ts} +2 -2
- package/dist/{client/ai-employees/chatbox → client-v2/ai-employees/chatbox/components}/ChatBoxLayout.d.ts +1 -1
- package/dist/{client/ai-employees/chatbox → client-v2/ai-employees/chatbox/components}/ContextItem.d.ts +1 -1
- package/dist/{client/ai-employees/admin/Employees.d.ts → client-v2/ai-employees/chatbox/components/DebugPanel.d.ts} +1 -1
- package/dist/{client/ai-employees/chatbox/markdown/Code.d.ts → client-v2/ai-employees/chatbox/components/Markdown.d.ts} +12 -5
- package/dist/{client/ai-employees/admin/ProfileSettings.d.ts → client-v2/ai-employees/chatbox/components/MessageContent.d.ts} +3 -2
- package/dist/client-v2/ai-employees/chatbox/components/MessageRenderers.d.ts +39 -0
- package/dist/{client/ai-employees/chatbox/generative-ui → client-v2/ai-employees/chatbox/components}/ToolCard.d.ts +7 -5
- package/dist/{client/ai-employees/admin/datasource/components/basic → client-v2/ai-employees/chatbox/components}/index.d.ts +5 -2
- package/dist/{client → client-v2}/ai-employees/chatbox/hooks/useChat.d.ts +21 -22
- package/dist/client-v2/ai-employees/chatbox/hooks/useChatBoxActions.d.ts +3 -2
- package/dist/{client → client-v2}/ai-employees/chatbox/hooks/useChatConversationActions.d.ts +2 -2
- package/dist/{client → client-v2}/ai-employees/chatbox/hooks/useChatMessageActions.d.ts +8 -4
- package/dist/{client → client-v2}/ai-employees/chatbox/hooks/useToolCallActions.d.ts +1 -1
- package/dist/client-v2/ai-employees/chatbox/hooks/useUploadFiles.d.ts +46 -0
- package/dist/{client → client-v2}/ai-employees/chatbox/hooks/useWorkflowTasks.d.ts +1 -1
- package/dist/{client → client-v2}/ai-employees/chatbox/model.d.ts +9 -2
- package/dist/client-v2/ai-employees/chatbox/roles.d.ts +162 -0
- package/dist/client-v2/ai-employees/chatbox/stores/chat-box.d.ts +1 -49
- package/dist/client-v2/ai-employees/chatbox/stores/chat-conversations.d.ts +2 -19
- package/dist/client-v2/ai-employees/chatbox/stores/chat-messages.d.ts +1 -46
- package/dist/{client → client-v2}/ai-employees/chatbox/stores/chat-tool-call.d.ts +1 -15
- package/dist/client-v2/ai-employees/chatbox/stores/chat-tools.d.ts +30 -0
- package/dist/client-v2/ai-employees/chatbox/stores/create-selectors.d.ts +31 -3
- package/dist/{client/ai-employees/chatbox/conversations/common.d.ts → client-v2/ai-employees/chatbox/stores/workflow-tasks.d.ts} +21 -4
- package/dist/client-v2/ai-employees/chatbox/utils/normalizeTriggerTaskOptions.d.ts +19 -0
- package/dist/{client → client-v2}/ai-employees/chatbox/utils.d.ts +26 -6
- package/dist/{client/ai-employees/data-visualization/context.d.ts → client-v2/ai-employees/context/chart-config.d.ts} +1 -1
- package/dist/{client → client-v2}/ai-employees/context/code-editor.d.ts +1 -1
- package/dist/{client → client-v2}/ai-employees/context/datasource.d.ts +1 -1
- package/dist/{client → client-v2}/ai-employees/context/flow-models.d.ts +1 -1
- package/dist/{client/ai-employees/admin/datasource/components/DatasourceSettingDetail.d.ts → client-v2/ai-employees/data-modeling/setup.d.ts} +6 -5
- package/dist/{client → client-v2}/ai-employees/datasource/DatasourceSelector.d.ts +6 -2
- package/dist/{client/ai-employees/admin/datasource/flow-models/DatasourceSettingModel.d.ts → client-v2/ai-employees/flow/index.d.ts} +4 -6
- package/dist/{client → client-v2}/ai-employees/form-filler/tools/index.d.ts +1 -1
- package/dist/{client → client-v2}/ai-employees/stores/ai-selection.d.ts +4 -4
- package/dist/{client → client-v2}/ai-employees/stores/dialog-controller.d.ts +4 -4
- package/dist/{client/ai-employees/business-report/ui → client-v2/ai-employees/tools}/BusinessReportCard.d.ts +2 -2
- package/dist/{client/ai-employees/business-report/ui → client-v2/ai-employees/tools}/BusinessReportModal.d.ts +2 -2
- package/dist/{client/ai-employees/1.x/selector/withAISelectable.d.ts → client-v2/ai-employees/tools/ChartGeneratorCard.d.ts} +5 -4
- package/dist/{client/ai-employees/ai-coding/ui → client-v2/ai-employees/tools}/CodeToolCard.d.ts +1 -1
- package/dist/{client/ai-employees/data-modeling/ui → client-v2/ai-employees/tools}/DataModelingCard.d.ts +3 -5
- package/dist/{client/ai-employees/data-modeling/ui → client-v2/ai-employees/tools}/DataModelingModal.d.ts +4 -6
- package/dist/{client/ai-employees/sub-agents/ui → client-v2/ai-employees/tools}/SubAgentDispatchCard.d.ts +4 -9
- package/dist/{client/ai-employees/AISettingsProvider.d.ts → client-v2/ai-employees/tools/SuggestionsOptionsCard.d.ts} +6 -8
- package/dist/{client/ai-employees/workflow-tasks/ui → client-v2/ai-employees/tools}/WorkflowTaskOutputCard.d.ts +7 -2
- package/dist/{client/ai-employees/ai-coding/tools/context-tools.d.ts → client-v2/ai-employees/tools/ai-coding.d.ts} +3 -1
- package/dist/client-v2/ai-employees/tools/business-report-utils.d.ts +45 -0
- package/dist/{client/ai-employees/data-modeling/ui → client-v2/ai-employees/tools/data-modeling}/CollectionNode.d.ts +2 -3
- package/dist/{client/ai-employees/data-modeling/ui → client-v2/ai-employees/tools/data-modeling}/Diagram.d.ts +1 -1
- package/dist/{client/ai-employees/data-modeling/ui → client-v2/ai-employees/tools/data-modeling}/Table.d.ts +2 -2
- package/dist/client-v2/ai-employees/tools/data-modeling/legacy-template.d.ts +13 -0
- package/dist/client-v2/ai-employees/tools/data-modeling/runtime.d.ts +15 -0
- package/dist/{client/ai-employees → client-v2/ai-employees/tools}/data-modeling/types.d.ts +27 -4
- package/dist/client-v2/ai-employees/tools/data-modeling/useFieldInterfaceOptions.d.ts +151 -0
- package/dist/{client/ai-employees/data-visualization/tools/index.d.ts → client-v2/ai-employees/tools/data-visualization.d.ts} +1 -1
- package/dist/client-v2/ai-employees/tools/index.d.ts +32 -0
- package/dist/client-v2/ai-employees/types.d.ts +101 -7
- package/dist/client-v2/components/RemoteSelect.d.ts +43 -0
- package/dist/{client → client-v2}/debug-logger.d.ts +2 -2
- package/dist/client-v2/f0053e745af0ad03.svg +50 -0
- package/dist/client-v2/index.d.ts +9 -9
- package/dist/client-v2/index.js +37 -1
- package/dist/client-v2/llm-providers/forms.d.ts +44 -0
- package/dist/client-v2/llm-providers/index.d.ts +24 -0
- package/dist/{client/ai-employees/ai-coding/tools/index.d.ts → client-v2/llm-services/utils.d.ts} +5 -3
- package/dist/client-v2/locale.d.ts +14 -0
- package/dist/client-v2/manager/ai-manager.d.ts +55 -0
- package/dist/client-v2/models/ai-employees/AIEmployeeActionModel.d.ts +33 -0
- package/dist/client-v2/models/ai-employees/AIEmployeeShortcutModel.d.ts +44 -0
- package/dist/client-v2/pages/AdminSettingsPage.d.ts +24 -0
- package/dist/client-v2/pages/DatasourceSettingsPage.d.ts +62 -0
- package/dist/client-v2/pages/EmployeesPage.d.ts +62 -0
- package/dist/client-v2/pages/LLMServicesPage.d.ts +75 -0
- package/dist/client-v2/pages/MCPSettingsPage.d.ts +73 -0
- package/dist/client-v2/pages/drawerWidth.d.ts +10 -0
- package/dist/client-v2/pages/permissions/Permissions.d.ts +67 -0
- package/dist/client-v2/pages/permissions/PermissionsTab.d.ts +12 -0
- package/dist/client-v2/pages/useUnsavedChangesBeforeClose.d.ts +29 -0
- package/dist/client-v2/plugin.d.ts +33 -0
- package/dist/client-v2/repositories/AIConfigRepository.d.ts +3 -23
- package/dist/client-v2/runjs/registerAIEmployeeRunJSFacade.d.ts +20 -0
- package/dist/client-v2/workflow/components/FormValueRegistry.d.ts +12 -0
- package/dist/{client/components/ListCollapse.d.ts → client-v2/workflow/components/WorkflowListCollapse.d.ts} +4 -4
- package/dist/client-v2/workflow/constants.d.ts +26 -0
- package/dist/client-v2/workflow/nodes/employee/components/AIEmployeeFieldset.d.ts +11 -0
- package/dist/{client/ai-employees/common/CodeHighlight.d.ts → client-v2/workflow/nodes/employee/components/AIEmployeeSelect.d.ts} +5 -6
- package/dist/{client/ai-employees/ContextAwareTooltip.d.ts → client-v2/workflow/nodes/employee/components/Assignees.d.ts} +2 -1
- package/dist/client-v2/workflow/nodes/employee/components/FeedbackSettings.d.ts +17 -0
- package/dist/client-v2/workflow/nodes/employee/components/FileInputs.d.ts +11 -0
- package/dist/{client/ai-employees/AIEmployeesProvider.d.ts → client-v2/workflow/nodes/employee/components/MessageInputs.d.ts} +2 -3
- package/dist/client-v2/workflow/nodes/employee/components/ModelOptions.d.ts +17 -0
- package/dist/{client/ai-employees/admin/datasource/components/basic/CollectionCascader.d.ts → client-v2/workflow/nodes/employee/components/SkillSettings.d.ts} +6 -3
- package/dist/client-v2/workflow/nodes/employee/components/StructuredOutput.d.ts +11 -0
- package/dist/client-v2/workflow/nodes/employee/components/UserInput.d.ts +18 -0
- package/dist/client-v2/workflow/nodes/employee/components/WebSearchOptions.d.ts +16 -0
- package/dist/client-v2/workflow/nodes/employee/index.d.ts +23 -0
- package/dist/{client/ai-employees/AIEmployeeListItem.d.ts → client-v2/workflow/nodes/llm/components/LLMFieldset.d.ts} +3 -5
- package/dist/{client/admin-settings/AdminSettings.d.ts → client-v2/workflow/nodes/llm/components/Messages.d.ts} +2 -1
- package/dist/client-v2/workflow/nodes/llm/components/StructuredOutput.d.ts +11 -0
- package/dist/client-v2/workflow/nodes/llm/index.d.ts +30 -0
- package/dist/{client/ai-employees/1.x/selector/BlockSelector.d.ts → client-v2/workflow/register.d.ts} +2 -6
- package/dist/client-v2/workflow/triggers/ai-employee/AIEmployeeTriggerConfig.d.ts +11 -0
- package/dist/client-v2/workflow/triggers/ai-employee/Parameters.d.ts +11 -0
- package/dist/client-v2/workflow/triggers/ai-employee/index.d.ts +25 -0
- package/dist/client-v2/workflow/types.d.ts +128 -0
- package/dist/externalVersion.js +20 -25
- package/dist/locale/en-US.json +50 -1
- package/dist/locale/zh-CN.json +50 -1
- package/dist/node_modules/@langchain/mistralai/LICENSE +21 -0
- package/dist/node_modules/@langchain/mistralai/dist/_virtual/rolldown_runtime.cjs +25 -0
- package/dist/node_modules/@langchain/mistralai/dist/chat_models.cjs +859 -0
- package/dist/node_modules/@langchain/mistralai/dist/chat_models.d.cts +541 -0
- package/dist/node_modules/@langchain/mistralai/dist/chat_models.d.ts +541 -0
- package/dist/node_modules/@langchain/mistralai/dist/chat_models.js +857 -0
- package/dist/node_modules/@langchain/mistralai/dist/embeddings.cjs +140 -0
- package/dist/node_modules/@langchain/mistralai/dist/embeddings.d.cts +116 -0
- package/dist/node_modules/@langchain/mistralai/dist/embeddings.d.ts +116 -0
- package/dist/node_modules/@langchain/mistralai/dist/embeddings.js +139 -0
- package/dist/node_modules/@langchain/mistralai/dist/index.cjs +21 -0
- package/dist/node_modules/@langchain/mistralai/dist/index.d.cts +4 -0
- package/dist/node_modules/@langchain/mistralai/dist/index.d.ts +4 -0
- package/dist/node_modules/@langchain/mistralai/dist/index.js +5 -0
- package/dist/node_modules/@langchain/mistralai/dist/llms.cjs +275 -0
- package/dist/node_modules/@langchain/mistralai/dist/llms.d.cts +147 -0
- package/dist/node_modules/@langchain/mistralai/dist/llms.d.ts +147 -0
- package/dist/node_modules/@langchain/mistralai/dist/llms.js +274 -0
- package/dist/node_modules/@langchain/mistralai/dist/utils.cjs +61 -0
- package/dist/node_modules/@langchain/mistralai/dist/utils.js +59 -0
- package/dist/node_modules/@langchain/mistralai/package.json +1 -0
- package/dist/node_modules/@langchain/xai/dist/index.cjs +2 -2
- package/dist/node_modules/@langchain/xai/package.json +1 -1
- package/dist/node_modules/fs-extra/package.json +1 -1
- package/dist/node_modules/jsonrepair/package.json +1 -1
- package/dist/node_modules/just-bash/package.json +1 -1
- package/dist/node_modules/nodejs-snowflake/package.json +1 -1
- package/dist/node_modules/openai/package.json +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/dist/server/ai-employees/ai-employee.d.ts +1 -0
- package/dist/server/ai-employees/ai-employee.js +44 -7
- package/dist/server/ai-employees/checkpoints/cleaner.d.ts +2 -0
- package/dist/server/ai-employees/checkpoints/cleaner.js +11 -1
- package/dist/server/ai-employees/middleware/conversation.d.ts +2 -0
- package/dist/server/ai-employees/middleware/conversation.js +2 -1
- package/dist/server/ai-employees/prompts.d.ts +2 -1
- package/dist/server/ai-employees/prompts.js +8 -2
- package/dist/server/ai-employees/tool-call-sanitizer.d.ts +1 -0
- package/dist/server/ai-employees/tool-call-sanitizer.js +2 -1
- package/dist/server/ai-employees/utils.d.ts +3 -1
- package/dist/server/ai-employees/utils.js +13 -5
- package/dist/server/attachments.d.ts +24 -0
- package/dist/server/attachments.js +204 -0
- package/dist/server/collections/ai-usage-events.d.ts +10 -0
- package/dist/server/collections/ai-usage-events.js +183 -0
- package/dist/server/document-loader/cached.d.ts +1 -0
- package/dist/server/document-loader/cached.js +18 -9
- package/dist/server/document-loader/loader.d.ts +0 -1
- package/dist/server/document-loader/loader.js +25 -8
- package/dist/server/document-loader/types.d.ts +7 -0
- package/dist/server/llm-providers/anthropic.d.ts +2 -1
- package/dist/server/llm-providers/anthropic.js +1 -3
- package/dist/server/llm-providers/dashscope.d.ts +2 -1
- package/dist/server/llm-providers/dashscope.js +16 -1
- package/dist/server/llm-providers/deepseek.d.ts +2 -1
- package/dist/server/llm-providers/deepseek.js +33 -2
- package/dist/server/llm-providers/google-genai.d.ts +1 -1
- package/dist/server/llm-providers/google-genai.js +1 -5
- package/dist/server/llm-providers/kimi/provider.d.ts +2 -1
- package/dist/server/llm-providers/kimi/provider.js +22 -2
- package/dist/server/llm-providers/mistral.d.ts +96 -0
- package/dist/server/llm-providers/mistral.js +325 -0
- package/dist/server/llm-providers/openai/completions.d.ts +2 -1
- package/dist/server/llm-providers/openai/completions.js +17 -1
- package/dist/server/llm-providers/openai/responses.d.ts +2 -1
- package/dist/server/llm-providers/openai/responses.js +17 -1
- package/dist/server/llm-providers/orcarouter.d.ts +35 -0
- package/dist/server/llm-providers/orcarouter.js +155 -0
- package/dist/server/llm-providers/provider.d.ts +16 -4
- package/dist/server/llm-providers/provider.js +60 -18
- package/dist/server/manager/ai-chat-conversation.js +2 -0
- package/dist/server/manager/ai-context-datasource-manager.js +34 -7
- package/dist/server/manager/ai-manager.d.ts +2 -1
- package/dist/server/manager/ai-manager.js +4 -1
- package/dist/server/manager/ai-usage-events.d.ts +49 -0
- package/dist/server/manager/ai-usage-events.js +195 -0
- package/dist/server/plugin.js +18 -0
- package/dist/server/resource/aiConversations.js +44 -1
- package/dist/server/utils.d.ts +5 -2
- package/dist/server/utils.js +11 -19
- package/dist/server/workflow/nodes/employee/files.d.ts +3 -1
- package/dist/server/workflow/nodes/employee/files.js +31 -5
- package/dist/server/workflow/nodes/employee/index.js +92 -46
- package/dist/server/workflow/nodes/employee/tools.js +8 -1
- package/package.json +6 -5
- package/dist/client/119.c6bf8c6433167d81.js +0 -10
- package/dist/client/170.d98eacdc00d9d527.js +0 -10
- package/dist/client/228.b4b709f93b86b6b9.js +0 -10
- package/dist/client/280.003b9e9788599244.js +0 -10
- package/dist/client/290.0f7f441d8a94f03c.js +0 -10
- package/dist/client/331.d547c95410476a69.js +0 -10
- package/dist/client/406.15c09d98faa2ccf1.js +0 -10
- package/dist/client/428.e9f38da3b0d8b498.js +0 -10
- package/dist/client/462.d172d0fe91519e35.js +0 -10
- package/dist/client/486.dcac8f3fcec19c33.js +0 -10
- package/dist/client/502.2b4a51e0a8122e52.js +0 -10
- package/dist/client/525.33a9c8ec28be4ec4.js +0 -10
- package/dist/client/559.a0f2f1cc2be3c039.js +0 -10
- package/dist/client/561.7ec804ef39ec7dcd.js +0 -10
- package/dist/client/580.35ba54ff91b7fe6d.js +0 -10
- package/dist/client/597.b0d64948d74cf6cb.js +0 -10
- package/dist/client/604.89c674f35b52b4ef.js +0 -10
- package/dist/client/614.aa766080f6b99aab.js +0 -10
- package/dist/client/646.d4483b4ff23da0a0.js +0 -10
- package/dist/client/687.224e569a99cae4bb.js +0 -10
- package/dist/client/699.57c0a1acb723202a.js +0 -10
- package/dist/client/711.92cd94681fde7e05.js +0 -10
- package/dist/client/758.a9741e81911e53c3.js +0 -10
- package/dist/client/768.5177bff46ae71a5b.js +0 -10
- package/dist/client/792.abb57765453bcbcc.js +0 -10
- package/dist/client/820.f72ef2462b61d812.js +0 -10
- package/dist/client/832.0cf69e3f43c320b2.js +0 -10
- package/dist/client/927.d95c74ebb8fd51c9.js +0 -10
- package/dist/client/ai-employees/1.x/selector/AISelectorProvider.d.ts +0 -33
- package/dist/client/ai-employees/ProfileCard.d.ts +0 -15
- package/dist/client/ai-employees/admin/ChatSettings.d.ts +0 -10
- package/dist/client/ai-employees/admin/DataSourceSettings.d.ts +0 -10
- package/dist/client/ai-employees/admin/EnableSwitch.d.ts +0 -10
- package/dist/client/ai-employees/admin/InputsFormSettings.d.ts +0 -10
- package/dist/client/ai-employees/admin/KnowledgeBaseSettings.d.ts +0 -10
- package/dist/client/ai-employees/admin/ModelSettings.d.ts +0 -10
- package/dist/client/ai-employees/admin/SkillSettings.d.ts +0 -19
- package/dist/client/ai-employees/admin/SystemPrompt.d.ts +0 -10
- package/dist/client/ai-employees/admin/Templates.d.ts +0 -10
- package/dist/client/ai-employees/admin/ToolsSettings.d.ts +0 -17
- package/dist/client/ai-employees/admin/datasource/components/DatasourceSettingForm.d.ts +0 -10
- package/dist/client/ai-employees/admin/datasource/components/DatasourceSettingGrid.d.ts +0 -10
- package/dist/client/ai-employees/admin/datasource/components/basic/FieldsTransfer.d.ts +0 -17
- package/dist/client/ai-employees/admin/datasource/components/form-steps/CollectionSetting.d.ts +0 -17
- package/dist/client/ai-employees/admin/datasource/components/form-steps/FieldsSetting.d.ts +0 -15
- package/dist/client/ai-employees/admin/datasource/components/form-steps/FilterSetting.d.ts +0 -17
- package/dist/client/ai-employees/admin/datasource/components/form-steps/Preview.d.ts +0 -13
- package/dist/client/ai-employees/admin/datasource/components/form-steps/SortSetting.d.ts +0 -15
- package/dist/client/ai-employees/admin/datasource/components/form-steps/index.d.ts +0 -13
- package/dist/client/ai-employees/admin/datasource/components/index.d.ts +0 -9
- package/dist/client/ai-employees/admin/datasource/context.d.ts +0 -17
- package/dist/client/ai-employees/admin/datasource/flow-models/index.d.ts +0 -9
- package/dist/client/ai-employees/admin/datasource/index.d.ts +0 -10
- package/dist/client/ai-employees/admin/hooks.d.ts +0 -39
- package/dist/client/ai-employees/admin/mcp/MCPSettings.d.ts +0 -10
- package/dist/client/ai-employees/admin/mcp/MCPToolsList.d.ts +0 -19
- package/dist/client/ai-employees/admin/mcp/context.d.ts +0 -15
- package/dist/client/ai-employees/admin/mcp/schemas.d.ts +0 -1314
- package/dist/client/ai-employees/ai-coding/CodeHistory.d.ts +0 -10
- package/dist/client/ai-employees/ai-coding/markdown/Code.d.ts +0 -16
- package/dist/client/ai-employees/avatars.d.ts +0 -9
- package/dist/client/ai-employees/built-in/utils.d.ts +0 -15
- package/dist/client/ai-employees/business-report/tools/index.d.ts +0 -10
- package/dist/client/ai-employees/business-report/ui/report-utils.d.ts +0 -38
- package/dist/client/ai-employees/chart-generator/tools/index.d.ts +0 -10
- package/dist/client/ai-employees/chart-generator/ui/ECharts.d.ts +0 -13
- package/dist/client/ai-employees/chatbox/AIThinking.d.ts +0 -12
- package/dist/client/ai-employees/chatbox/Attachment.d.ts +0 -14
- package/dist/client/ai-employees/chatbox/AttachmentsHeader.d.ts +0 -10
- package/dist/client/ai-employees/chatbox/ChatBox.d.ts +0 -12
- package/dist/client/ai-employees/chatbox/ContextItemsHeader.d.ts +0 -10
- package/dist/client/ai-employees/chatbox/DebugPanel.d.ts +0 -16
- package/dist/client/ai-employees/chatbox/EditMessageHeader.d.ts +0 -10
- package/dist/client/ai-employees/chatbox/HintMessageHeader.d.ts +0 -10
- package/dist/client/ai-employees/chatbox/MessageRenderer.d.ts +0 -33
- package/dist/client/ai-employees/chatbox/SenderFooter.d.ts +0 -13
- package/dist/client/ai-employees/chatbox/SenderHeader.d.ts +0 -10
- package/dist/client/ai-employees/chatbox/SenderPrefix.d.ts +0 -10
- package/dist/client/ai-employees/chatbox/Upload.d.ts +0 -12
- package/dist/client/ai-employees/chatbox/VirtualList.d.ts +0 -28
- package/dist/client/ai-employees/chatbox/conversations/ConversationsList.d.ts +0 -13
- package/dist/client/ai-employees/chatbox/conversations/WorkflowTasksList.d.ts +0 -13
- package/dist/client/ai-employees/chatbox/conversations/index.d.ts +0 -9
- package/dist/client/ai-employees/chatbox/generative-ui/DefaultToolCard.d.ts +0 -16
- package/dist/client/ai-employees/chatbox/hooks/useChatBoxActions.d.ts +0 -18
- package/dist/client/ai-employees/chatbox/hooks/useUploadFiles.d.ts +0 -12
- package/dist/client/ai-employees/chatbox/markdown/ECharts.d.ts +0 -10
- package/dist/client/ai-employees/chatbox/markdown/Form.d.ts +0 -10
- package/dist/client/ai-employees/chatbox/markdown/Generating.d.ts +0 -10
- package/dist/client/ai-employees/chatbox/markdown/Markdown.d.ts +0 -13
- package/dist/client/ai-employees/chatbox/roles.d.ts +0 -32
- package/dist/client/ai-employees/chatbox/stores/chat-box.d.ts +0 -9
- package/dist/client/ai-employees/chatbox/stores/chat-conversations.d.ts +0 -9
- package/dist/client/ai-employees/chatbox/stores/chat-messages.d.ts +0 -9
- package/dist/client/ai-employees/chatbox/stores/chat-tools.d.ts +0 -51
- package/dist/client/ai-employees/chatbox/stores/create-selectors.d.ts +0 -18
- package/dist/client/ai-employees/chatbox/stores/workflow-tasks.d.ts +0 -45
- package/dist/client/ai-employees/context/classic-pages.d.ts +0 -10
- package/dist/client/ai-employees/data-modeling/Table.d.ts +0 -12
- package/dist/client/ai-employees/data-modeling/setup.d.ts +0 -10
- package/dist/client/ai-employees/data-modeling/tools/index.d.ts +0 -10
- package/dist/client/ai-employees/data-modeling/ui/useFieldInterfaceOptions.d.ts +0 -14
- package/dist/client/ai-employees/datasource/DatasourceList.d.ts +0 -17
- package/dist/client/ai-employees/datasource/index.d.ts +0 -9
- package/dist/client/ai-employees/flow/events/index.d.ts +0 -9
- package/dist/client/ai-employees/flow/index.d.ts +0 -36
- package/dist/client/ai-employees/flow/models/AIEmployeeActionModel.d.ts +0 -18
- package/dist/client/ai-employees/flow/models/AIEmployeeShortcutModel.d.ts +0 -30
- package/dist/client/ai-employees/shortcuts/ShortcutList.d.ts +0 -10
- package/dist/client/ai-employees/shortcuts/useShortcuts.d.ts +0 -13
- package/dist/client/ai-employees/stores/context-aware.d.ts +0 -19
- package/dist/client/ai-employees/sub-agents/tools/index.d.ts +0 -10
- package/dist/client/ai-employees/suggestions/tools/index.d.ts +0 -10
- package/dist/client/ai-employees/suggestions/ui/SuggestionsOptions.d.ts +0 -13
- package/dist/client/ai-employees/types.d.ts +0 -259
- package/dist/client/ai-employees/workflow-tasks/tools/index.d.ts +0 -10
- package/dist/client/chat-settings/Messages.d.ts +0 -11
- package/dist/client/chat-settings/StructuredOutput.d.ts +0 -11
- package/dist/client/components/skill-settings.d.ts +0 -22
- package/dist/client/features/components.d.ts +0 -9
- package/dist/client/features/feature-manager.d.ts +0 -9
- package/dist/client/features/index.d.ts +0 -9
- package/dist/client/features/vector-database-provider.d.ts +0 -9
- package/dist/client/features/vector-store-provider.d.ts +0 -9
- package/dist/client/llm-providers/anthropic/ModelSettings.d.ts +0 -10
- package/dist/client/llm-providers/anthropic/ProviderSettings.d.ts +0 -10
- package/dist/client/llm-providers/anthropic/index.d.ts +0 -10
- package/dist/client/llm-providers/components/Chat.d.ts +0 -10
- package/dist/client/llm-providers/components/ModelSelect.d.ts +0 -10
- package/dist/client/llm-providers/dashscope/ModelSettings.d.ts +0 -10
- package/dist/client/llm-providers/dashscope/ProviderSettings.d.ts +0 -10
- package/dist/client/llm-providers/dashscope/index.d.ts +0 -10
- package/dist/client/llm-providers/deepseek/ModelSettings.d.ts +0 -10
- package/dist/client/llm-providers/deepseek/index.d.ts +0 -10
- package/dist/client/llm-providers/google-genai/MessageRenderer.d.ts +0 -13
- package/dist/client/llm-providers/google-genai/ModelSettings.d.ts +0 -10
- package/dist/client/llm-providers/google-genai/ProviderSettings.d.ts +0 -10
- package/dist/client/llm-providers/google-genai/index.d.ts +0 -10
- package/dist/client/llm-providers/kimi/ModelSettings.d.ts +0 -10
- package/dist/client/llm-providers/kimi/index.d.ts +0 -10
- package/dist/client/llm-providers/mimo/ModelSettings.d.ts +0 -10
- package/dist/client/llm-providers/mimo/index.d.ts +0 -10
- package/dist/client/llm-providers/ollama/ModelSettings.d.ts +0 -10
- package/dist/client/llm-providers/ollama/ProviderSettings.d.ts +0 -10
- package/dist/client/llm-providers/ollama/index.d.ts +0 -10
- package/dist/client/llm-providers/openai/completions/ModelSettings.d.ts +0 -10
- package/dist/client/llm-providers/openai/completions/index.d.ts +0 -10
- package/dist/client/llm-providers/openai/components/ProviderSettings.d.ts +0 -10
- package/dist/client/llm-providers/openai/responses/ModelSettings.d.ts +0 -10
- package/dist/client/llm-providers/openai/responses/index.d.ts +0 -10
- package/dist/client/llm-providers/tongyi/ModelSettings.d.ts +0 -10
- package/dist/client/llm-providers/tongyi/ProviderSettings.d.ts +0 -10
- package/dist/client/llm-providers/tongyi/index.d.ts +0 -10
- package/dist/client/llm-providers/xai/ModelSettings.d.ts +0 -10
- package/dist/client/llm-providers/xai/index.d.ts +0 -10
- package/dist/client/llm-services/LLMServices.d.ts +0 -13
- package/dist/client/llm-services/component/DefaultModelSelect.d.ts +0 -10
- package/dist/client/llm-services/component/EnabledModelsSelect.d.ts +0 -23
- package/dist/client/llm-services/component/LLMTestFlight.d.ts +0 -10
- package/dist/client/llm-services/component/ModelOptionsSettings.d.ts +0 -10
- package/dist/client/llm-services/component/UnifiedModelSettings.d.ts +0 -10
- package/dist/client/llm-services/hooks/useLLMServiceCatalog.d.ts +0 -18
- package/dist/client/llm-services/llm-providers.d.ts +0 -27
- package/dist/client/llm-services/utils.d.ts +0 -30
- package/dist/client/manager/ai-feature-manager.d.ts +0 -9
- package/dist/client/manager/ai-manager.d.ts +0 -35
- package/dist/client/repositories/AIConfigRepository.d.ts +0 -60
- package/dist/client/repositories/hooks/useAIConfigRepository.d.ts +0 -10
- package/dist/client/schemas/llms.d.ts +0 -347
- package/dist/client/workflow/nodes/employee/components/AIEmployeeSelect.d.ts +0 -10
- package/dist/client/workflow/nodes/employee/components/assigness.d.ts +0 -11
- package/dist/client/workflow/nodes/employee/components/file-inputs.d.ts +0 -10
- package/dist/client/workflow/nodes/employee/components/message-inputs.d.ts +0 -12
- package/dist/client/workflow/nodes/employee/components/model-options.d.ts +0 -10
- package/dist/client/workflow/nodes/employee/components/structured-output.d.ts +0 -10
- package/dist/client/workflow/nodes/employee/components/users-select.d.ts +0 -15
- package/dist/client/workflow/nodes/employee/components/web-search-options.d.ts +0 -10
- package/dist/client/workflow/nodes/employee/configuration.d.ts +0 -12
- package/dist/client/workflow/nodes/employee/flow-models/feedback.d.ts +0 -14
- package/dist/client/workflow/nodes/employee/flow-models/task.d.ts +0 -13
- package/dist/client/workflow/nodes/llm/ModelSettings.d.ts +0 -11
- package/dist/client/workflow/triggers/ai-employee/Parameters.d.ts +0 -13
- package/dist/client-v2/ai-employees/flow/models/AIEmployeeButtonModel.d.ts +0 -32
- /package/dist/{client → client-v2}/ai-employees/AISelection.d.ts +0 -0
- /package/dist/{client → client-v2}/ai-employees/AISelectionControl.d.ts +0 -0
- /package/dist/{client → client-v2}/ai-employees/ai-coding/prompts.d.ts +0 -0
- /package/dist/{client → client-v2}/ai-employees/ai-coding/setup.d.ts +0 -0
- /package/dist/{client/ai-employees/chatbox/AIEmployeeSwitch.d.ts → client-v2/ai-employees/chatbox/components/AIEmployeeSwitcher.d.ts} +0 -0
- /package/dist/{client/ai-employees/chatbox → client-v2/ai-employees/chatbox/components}/ChatButton.d.ts +0 -0
- /package/dist/{client/ai-employees/chatbox/conversations → client-v2/ai-employees/chatbox/components}/Conversations.d.ts +0 -0
- /package/dist/{client/ai-employees/chatbox → client-v2/ai-employees/chatbox/components}/Messages.d.ts +0 -0
- /package/dist/{client/ai-employees/chatbox → client-v2/ai-employees/chatbox/components}/ModelSwitcher.d.ts +0 -0
- /package/dist/{client/ai-employees/chatbox → client-v2/ai-employees/chatbox/components}/SearchSwitch.d.ts +0 -0
- /package/dist/{client/ai-employees/chatbox → client-v2/ai-employees/chatbox/components}/Sender.d.ts +0 -0
- /package/dist/{client/ai-employees/chatbox/generative-ui → client-v2/ai-employees/chatbox/components}/ToolModal.d.ts +0 -0
- /package/dist/{client/ai-employees/chatbox → client-v2/ai-employees/chatbox/components}/UserPrompt.d.ts +0 -0
- /package/dist/{client → client-v2}/ai-employees/chatbox/hooks/useChatBoxEffect.d.ts +0 -0
- /package/dist/{client → client-v2}/ai-employees/chatbox/hooks/useLoadMoreObserver.d.ts +0 -0
- /package/dist/client-v2/ai-employees/{chatbox/stores → stores}/global-store.d.ts +0 -0
- /package/dist/{client/ai-employees/flow/models → client-v2/models/ai-employees}/AIEmployeeShortcutListModel.d.ts +0 -0
- /package/dist/{client/ai-employees/flow/models → client-v2/models/ai-employees}/index.d.ts +0 -0
- /package/dist/{client/ai-employees/flow/events/ai-context-selection.d.ts → client-v2/workflow/components/index.d.ts} +0 -0
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Use NocoBase to build a linkable operational dashboard"
|
|
3
|
+
description: "Taking the work order operation dashboard as an example, the chart block, filter block and JS block are combined to achieve unified filtering, KPI, chart drill-down and custom styles."
|
|
4
|
+
keywords: "NocoBase, operational dashboard, data visualization, chart block, filter block, JS block, chart drill-down"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Use NocoBase to build a linkable operational dashboard
|
|
8
|
+
|
|
9
|
+
This article takes the operation dashboard of the "work order system" as an example to introduce how to use NocoBase's chart block, filter block and JS block in combination to build a data dashboard that supports filter linkage, chart drill-down and custom styles.
|
|
10
|
+
|
|
11
|
+
Although the examples are from work order scenarios, these methods are also applicable to business systems such as CRM, equipment operations, project management, approval flow, customer success, etc.
|
|
12
|
+
|
|
13
|
+
:::tip
|
|
14
|
+
What this article wants to introduce is not "how to use JS blocks to write a large screen", but how to combine NocoBase's native block capabilities and JS blocks: Let the native blocks be responsible for standard capabilities, and let the JS blocks complement the personalized experience.
|
|
15
|
+
:::
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
## scene target
|
|
20
|
+
|
|
21
|
+
We hope to build an Operations dashboard to help the operation or service team quickly determine the current workload:
|
|
22
|
+
|
|
23
|
+
- How many open work orders are there currently?
|
|
24
|
+
- Which work orders are at SLA risk?
|
|
25
|
+
- What is the trend in new work orders?
|
|
26
|
+
- What is the status and priority distribution of work orders?
|
|
27
|
+
- After clicking on a chart, you can view the corresponding details
|
|
28
|
+
|
|
29
|
+
The page can be roughly divided into four layers:
|
|
30
|
+
|
|
31
|
+
1. Top filter area: time, service group, request type, priority, SLA status
|
|
32
|
+
2. KPI statistics area: Open backlog, Unassigned, SLA warning, etc.
|
|
33
|
+
3. Chart analysis area: trend, status, SLA, priority distribution
|
|
34
|
+
4. Drill-down detail area: Click on the chart to display matching records
|
|
35
|
+
|
|
36
|
+
## First, clarify a construction idea
|
|
37
|
+
|
|
38
|
+
When many people make data dashboards, they tend to think of the problem as one of two options:
|
|
39
|
+
|
|
40
|
+
Either use all NocoBase's native blocks, which are simple to configure, but worry that the style and interaction are not flexible enough; or simply write a large JS block and control the query, chart, filtering, and drill-down by yourself, but this will lose the convenience brought by low-code configuration.
|
|
41
|
+
|
|
42
|
+
In fact, the more recommended way is to combine the two.
|
|
43
|
+
|
|
44
|
+
In this Operations dashboard, we did not write the entire page as a large JS screen, but split it according to responsibilities:
|
|
45
|
+
|
|
46
|
+
- Top filtering uses the filtering block that comes with the NocoBase system;
|
|
47
|
+
- Trend charts, status distribution, and SLA distribution use native chart blocks;
|
|
48
|
+
- KPI cards and drill-down details use JS blocks;
|
|
49
|
+
- Filter blocks affect both chart blocks and JS blocks;
|
|
50
|
+
- After the chart is clicked, the drill-down conditions are passed to the JS detail block below.
|
|
51
|
+
|
|
52
|
+
The advantage of this is that standard statistics and filtering still retain the configuration capabilities of NocoBase, while personalized display and complex interactions are completed by JS blocks. The page is neither "configurable only" nor "all code", but configuration and code each perform their own duties.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 1. How to customize the style of the chart block
|
|
57
|
+
|
|
58
|
+

|
|
59
|
+
|
|
60
|
+
The chart block of NocoBase can first use Query builder to define the statistical caliber, and then use the custom ECharts option to adjust the style.
|
|
61
|
+
|
|
62
|
+
Taking "work order status statistics" as an example, Query builder can be configured as:
|
|
63
|
+
|
|
64
|
+
- Datasheet: tickets
|
|
65
|
+
- Metrics: id count, alias ticketCount
|
|
66
|
+
- Dimensions: status
|
|
67
|
+
|
|
68
|
+
The key is that when customizing the style, you do not need to rewrite the query, you only need to process the chart display based on `ctx.data.objects`.
|
|
69
|
+
|
|
70
|
+
```javascript
|
|
71
|
+
const rows = Array.isArray(ctx.data?.objects) ? ctx.data.objects : [];
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This line of code reads the chart query results. Then define status labels and colors:
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
const labels = {
|
|
78
|
+
new: ctx.t('New'),
|
|
79
|
+
open: ctx.t('Open'),
|
|
80
|
+
pending_customer: ctx.t('Pending customer'),
|
|
81
|
+
resolved: ctx.t('Resolved'),
|
|
82
|
+
closed: ctx.t('Closed'),
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const colors = {
|
|
86
|
+
new: '#1677ff',
|
|
87
|
+
open: '#22a06b',
|
|
88
|
+
pending_customer: '#f59f00',
|
|
89
|
+
resolved: '#13c2c2',
|
|
90
|
+
closed: '#8c8c8c',
|
|
91
|
+
};
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
It is recommended that all visible copywriting use `ctx.t()` to facilitate subsequent multi-language support.
|
|
95
|
+
|
|
96
|
+
When generating chart data, you can attach drill-down information to each chart data point:
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
const data = rows.map((row) => ({
|
|
100
|
+
value: Number(row.ticketCount || 0),
|
|
101
|
+
itemStyle: {
|
|
102
|
+
color: colors[row.status] || '#8c8c8c',
|
|
103
|
+
borderRadius: [6, 6, 0, 0],
|
|
104
|
+
},
|
|
105
|
+
ticketingDrilldown: {
|
|
106
|
+
label: ctx.t('Status') + ': ' + (labels[row.status] || row.status),
|
|
107
|
+
filter: { status: { $eq: row.status } },
|
|
108
|
+
},
|
|
109
|
+
}));
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The most critical thing here is `ticketingDrilldown`. It is not a standard field of ECharts, but a business context that we put in ourselves, which will be used when clicking on the chart later.
|
|
113
|
+
|
|
114
|
+
Finally return to ECharts option:
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
return {
|
|
118
|
+
grid: { top: 28, right: 22, bottom: 48, left: 42 },
|
|
119
|
+
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
|
120
|
+
xAxis: {
|
|
121
|
+
type: 'category',
|
|
122
|
+
data: rows.map((row) => labels[row.status] || row.status),
|
|
123
|
+
},
|
|
124
|
+
yAxis: {
|
|
125
|
+
type: 'value',
|
|
126
|
+
minInterval: 1,
|
|
127
|
+
},
|
|
128
|
+
series: [
|
|
129
|
+
{
|
|
130
|
+
name: ctx.t('Tickets'),
|
|
131
|
+
type: 'bar',
|
|
132
|
+
barWidth: 36,
|
|
133
|
+
data,
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
};
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The core idea of this part is:
|
|
140
|
+
|
|
141
|
+
- Query builder is responsible for statistics;
|
|
142
|
+
- Custom option is responsible for visual expression;
|
|
143
|
+
- Custom fields are responsible for carrying drill-down context.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 2. Let the system filter block become the observation scope of the entire page
|
|
148
|
+
|
|
149
|
+

|
|
150
|
+
|
|
151
|
+
The filter area in the operational dashboard should not be just an isolated form. It represents the current observation diameter of the entire page.
|
|
152
|
+
|
|
153
|
+
For example, if the user selects a service group, a request type, and a creation time, then KPIs, trend charts, status distribution, and drill-down details should all be displayed based on the same set of conditions. Otherwise, the numbers in different blocks on the page will fight with each other, and it will be difficult for users to judge which data is the result within the current range.
|
|
154
|
+
|
|
155
|
+
Here we directly use the filtering block that comes with the NocoBase system instead of writing a filtering component ourselves. Native filter blocks can be naturally bound to chart blocks, allowing the chart block to continue to use the Query builder, permissions, refresh and filter mechanisms.
|
|
156
|
+
|
|
157
|
+
Top `Dashboard scope` can configure these filter items:
|
|
158
|
+
|
|
159
|
+
- Created at
|
|
160
|
+
- Service group
|
|
161
|
+
- Request type
|
|
162
|
+
- Priority
|
|
163
|
+
- SLA status
|
|
164
|
+
|
|
165
|
+
For JS blocks, you only need to read the same set of filter conditions in the code and then convert them into query filters. In this way, KPIs and drill-down details can also be consistent with the native chart.
|
|
166
|
+
|
|
167
|
+
The combination of filter conditions can be encapsulated into a small function:
|
|
168
|
+
|
|
169
|
+
```javascript
|
|
170
|
+
function combineFilters(...filters) {
|
|
171
|
+
const parts = filters.filter(Boolean);
|
|
172
|
+
if (!parts.length) return undefined;
|
|
173
|
+
if (parts.length === 1) return parts[0];
|
|
174
|
+
return { $and: parts };
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Count by filter:
|
|
179
|
+
|
|
180
|
+
```javascript
|
|
181
|
+
async function countTickets(filter) {
|
|
182
|
+
const resource = ctx.makeResource('MultiRecordResource');
|
|
183
|
+
resource.setResourceName('tickets');
|
|
184
|
+
resource.setPageSize(1);
|
|
185
|
+
|
|
186
|
+
if (filter) {
|
|
187
|
+
resource.setFilter(filter);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
await resource.refresh();
|
|
191
|
+
|
|
192
|
+
const meta = resource.getMeta?.() || {};
|
|
193
|
+
return Number(meta.count || meta.total || 0);
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The key points here are:
|
|
198
|
+
|
|
199
|
+
```javascript
|
|
200
|
+
resource.setFilter(filter);
|
|
201
|
+
await resource.refresh();
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The JS block queries business data through resources instead of writing SQL directly. This makes it easier to keep consistent with NocoBase's permissions, data sources, and page runtimes.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## 3. Use JS blocks to display KPI cards
|
|
209
|
+
|
|
210
|
+

|
|
211
|
+
|
|
212
|
+
KPIs are better suited to use JS blocks. Because KPI is usually not a single query, but a combination of multiple business calibers: unfinished, unassigned, SLA warning, SLA breached, new, resolved, etc.
|
|
213
|
+
|
|
214
|
+
The JS block can requery data based on the current filtering range and render it into a statistical card.
|
|
215
|
+
|
|
216
|
+
```javascript
|
|
217
|
+
const { Card, Col, Row, Statistic, Tag } = ctx.libs.antd;
|
|
218
|
+
|
|
219
|
+
const scopeFilter = getDashboardScopeFilter();
|
|
220
|
+
|
|
221
|
+
const openBacklog = await countTickets(
|
|
222
|
+
combineFilters(scopeFilter, {
|
|
223
|
+
status: { $notIn: ['resolved', 'closed', 'cancelled'] },
|
|
224
|
+
}),
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
ctx.render(
|
|
228
|
+
<Row gutter={[12, 12]}>
|
|
229
|
+
<Col span={6}>
|
|
230
|
+
<Card size="small">
|
|
231
|
+
<Tag color="blue">{ctx.t('Active')}</Tag>
|
|
232
|
+
<Statistic title={ctx.t('Open backlog')} value={openBacklog} />
|
|
233
|
+
</Card>
|
|
234
|
+
</Col>
|
|
235
|
+
</Row>,
|
|
236
|
+
);
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The key points of JS blocks are:
|
|
240
|
+
|
|
241
|
+
- Use `ctx.makeResource()` to query data;
|
|
242
|
+
- Use `ctx.libs.antd` to render the interface;
|
|
243
|
+
- Use `ctx.render()` to output content;
|
|
244
|
+
- Re-render JS chunks after filtering changes.
|
|
245
|
+
|
|
246
|
+
In a real page, the filter button and reset button can configure the event flow so that they refresh the KPI JS block and drill-down JS block at the same time after completing the native filter action. In this way, the user clicks once to filter, and both charts and custom content will be updated based on the same range.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 4. Chart linkage JS block for drill-down
|
|
251
|
+
|
|
252
|
+

|
|
253
|
+
|
|
254
|
+
Clicking on the chart to drill down is a very practical interaction in the dashboard.
|
|
255
|
+
|
|
256
|
+
In the work order scenario, the user clicks the "Status: Open" column, and all Open work orders are displayed in the detail area below; when the user clicks "SLA breached", all overtime work orders are displayed below.
|
|
257
|
+
|
|
258
|
+
The implementation idea is:
|
|
259
|
+
|
|
260
|
+
1. Chart data points carry `ticketingDrilldown`;
|
|
261
|
+
2. The chart event reads this drill-down information;
|
|
262
|
+
3. Write drill-down information into the target JS block context;
|
|
263
|
+
4. Trigger the target JS block to re-render.
|
|
264
|
+
|
|
265
|
+
The key code in the chart event is as follows. First find the drill-down JS block:
|
|
266
|
+
|
|
267
|
+
```javascript
|
|
268
|
+
const DRILLDOWN_TARGET_UID = 'v7mioopm6rm';
|
|
269
|
+
|
|
270
|
+
function getDrilldownTarget() {
|
|
271
|
+
if (typeof ctx.getModel === 'function') {
|
|
272
|
+
return ctx.getModel(DRILLDOWN_TARGET_UID);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const engine =
|
|
276
|
+
ctx.model?.flowEngine || ctx.model?.context?.flowEngine || ctx.engine;
|
|
277
|
+
return engine?.getModel?.(DRILLDOWN_TARGET_UID);
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Then write the drill-down conditions obtained by clicking on the chart into the target block:
|
|
282
|
+
|
|
283
|
+
```javascript
|
|
284
|
+
function applyDrilldown(drilldown) {
|
|
285
|
+
if (!drilldown?.filter) return;
|
|
286
|
+
|
|
287
|
+
const target = getDrilldownTarget();
|
|
288
|
+
if (!target?.context?.defineProperty) return;
|
|
289
|
+
|
|
290
|
+
target.context.defineProperty('ticketingDashboardDrilldown', {
|
|
291
|
+
value: drilldown,
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
target.rerender?.();
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
The most critical are these two lines:
|
|
299
|
+
|
|
300
|
+
```javascript
|
|
301
|
+
target.context.defineProperty('ticketingDashboardDrilldown', {
|
|
302
|
+
value: drilldown,
|
|
303
|
+
});
|
|
304
|
+
target.rerender?.();
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
The first line passes the drill-down condition to the JS block, and the second line triggers the JS block refresh.
|
|
308
|
+
|
|
309
|
+
Finally bind the chart click event:
|
|
310
|
+
|
|
311
|
+
```javascript
|
|
312
|
+
const clickHandler = (params) => {
|
|
313
|
+
applyDrilldown(params?.data?.ticketingDrilldown);
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
chart.on('click', clickHandler);
|
|
317
|
+
|
|
318
|
+
return () => chart.off('click', clickHandler);
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
It is recommended here that you must return cleanup:
|
|
322
|
+
|
|
323
|
+
```javascript
|
|
324
|
+
return () => chart.off('click', clickHandler);
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
In this way, when the chart is reconfigured or re-rendered, old events can be cleaned up to avoid repeated binding.
|
|
328
|
+
|
|
329
|
+
The above click event-related code is applicable to [v2.2.0-beta.10](https://github.com/nocobase/nocobase/releases/tag/v2.2.0-beta.10) and above versions. Reference to the old version code:
|
|
330
|
+
|
|
331
|
+
```javascript
|
|
332
|
+
chart.off('click');
|
|
333
|
+
chart.on('click', clickHandler);
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## 5. How to display details in drill-down JS blocks
|
|
339
|
+
|
|
340
|
+

|
|
341
|
+
|
|
342
|
+
Drill down into the JS block to read the `ticketingDashboardDrilldown` just written, and then query the data according to the filter in it.
|
|
343
|
+
|
|
344
|
+
```javascript
|
|
345
|
+
const drilldown = ctx.model?.context?.ticketingDashboardDrilldown;
|
|
346
|
+
|
|
347
|
+
if (!drilldown) {
|
|
348
|
+
ctx.render(
|
|
349
|
+
<Alert
|
|
350
|
+
type="info"
|
|
351
|
+
showIcon
|
|
352
|
+
message={ctx.t('Select a chart segment to inspect matching tickets')}
|
|
353
|
+
/>,
|
|
354
|
+
);
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
If the user has not clicked on the chart, display a prompt. After clicking, query the work order based on `drilldown.filter`:
|
|
360
|
+
|
|
361
|
+
```javascript
|
|
362
|
+
const resource = ctx.makeResource('MultiRecordResource');
|
|
363
|
+
resource.setResourceName('tickets');
|
|
364
|
+
resource.setFilter(drilldown.filter);
|
|
365
|
+
resource.setPageSize(10);
|
|
366
|
+
await resource.refresh();
|
|
367
|
+
|
|
368
|
+
const rows = resource.getData?.() || [];
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Then render the table:
|
|
372
|
+
|
|
373
|
+
```javascript
|
|
374
|
+
const { Table, Typography } = ctx.libs.antd;
|
|
375
|
+
|
|
376
|
+
ctx.render(
|
|
377
|
+
<>
|
|
378
|
+
<Typography.Title level={5}>
|
|
379
|
+
{ctx.t('Drilldown')}: {drilldown.label}
|
|
380
|
+
</Typography.Title>
|
|
381
|
+
|
|
382
|
+
<Table
|
|
383
|
+
size="small"
|
|
384
|
+
rowKey="id"
|
|
385
|
+
dataSource={rows}
|
|
386
|
+
pagination={false}
|
|
387
|
+
columns={[
|
|
388
|
+
{ title: ctx.t('Ticket No'), dataIndex: 'ticketNo' },
|
|
389
|
+
{ title: ctx.t('Title'), dataIndex: 'title' },
|
|
390
|
+
{ title: ctx.t('Status'), dataIndex: 'status' },
|
|
391
|
+
{ title: ctx.t('Priority'), dataIndex: 'priority' },
|
|
392
|
+
]}
|
|
393
|
+
/>
|
|
394
|
+
</>,
|
|
395
|
+
);
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
If you need to clear drill-down conditions, you can refer to
|
|
399
|
+
|
|
400
|
+
```javascript
|
|
401
|
+
function clearChartDrilldown() {
|
|
402
|
+
if (ctx.model?.context?.defineProperty) {
|
|
403
|
+
ctx.model.context.defineProperty('ticketingDashboardDrilldown', {
|
|
404
|
+
value: null,
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
if (typeof ctx.model?.rerender === 'function') {
|
|
408
|
+
ctx.model.rerender();
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
The key points in this part are:
|
|
414
|
+
|
|
415
|
+
- The chart is only responsible for passing the filter;
|
|
416
|
+
- The JS block is responsible for querying and displaying details;
|
|
417
|
+
- Click on different charts to share the same drill-down block.
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Practical suggestions
|
|
422
|
+
|
|
423
|
+
### 1. Don’t rush to code the complex page as a whole
|
|
424
|
+
|
|
425
|
+
The most important lesson from this page is: don’t pit native capabilities against JS capabilities.
|
|
426
|
+
|
|
427
|
+
If a capability is already a native capability of NocoBase, such as filtering, chart query, table display, and permission control, the native block will be used first. In this way, when fields, filter conditions, and chart caliber are subsequently adjusted, they can still be configured on the interface.
|
|
428
|
+
|
|
429
|
+
JS blocks are more suitable for processing parts that native blocks are not good at, such as combining multiple indicators into a set of KPIs, special card styles, displaying a set of custom details after clicking on the chart, or passing business context between different blocks.
|
|
430
|
+
|
|
431
|
+
In other words, the native block is responsible for "configurable standard capabilities", and the JS block is responsible for "business-oriented personalized experience". This is also the most reusable construction idea for this dashboard.
|
|
432
|
+
|
|
433
|
+
### 2. For simple statistics, use the chart block Query builder first.
|
|
434
|
+
|
|
435
|
+
This preserves NocoBase's standard query, permissions, filtering and refreshing capabilities. Only when the default chart style cannot express the business focus, use the customized ECharts option for visual optimization.
|
|
436
|
+
|
|
437
|
+
### 3. KPI cards give priority to using JS blocks
|
|
438
|
+
|
|
439
|
+
KPIs often require multiple queries, condition combinations, and custom layouts, and JS blocks are more flexible. Especially when KPIs need to respond to the same set of system filter conditions, it will be clearer to use JS blocks to handle them uniformly.
|
|
440
|
+
|
|
441
|
+
### 4. Chart events should return cleanup
|
|
442
|
+
|
|
443
|
+
Recommended writing method:
|
|
444
|
+
|
|
445
|
+
```javascript
|
|
446
|
+
const handler = (params) => {
|
|
447
|
+
// handle click
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
chart.on('click', handler);
|
|
451
|
+
|
|
452
|
+
return () => chart.off('click', handler);
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
Do not directly use `chart.off('click')` to clear all click events, as this may accidentally delete the chart block or configure the panel's own monitoring.
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
## Let AI help you build it
|
|
460
|
+
|
|
461
|
+
This type of dashboard is very suitable for AI-assisted generation because it involves data models, statistical calibers, chart styles, and page interactions at the same time. You can hand it the content of this article and ask questions using the prompt words below.
|
|
462
|
+
|
|
463
|
+
You can ask questions like this:
|
|
464
|
+
|
|
465
|
+
```markdown
|
|
466
|
+
I am using NocoBase to build an operational dashboard for a work order system.
|
|
467
|
+
Please take the work order scenario as an example and help me design an Operations dashboard.
|
|
468
|
+
|
|
469
|
+
The data table tickets contains:
|
|
470
|
+
ticketNo、title、status、priority、slaStatus、
|
|
471
|
+
requestType、serviceGroup、assignee、createdAt、updatedAt。
|
|
472
|
+
|
|
473
|
+
The page requires:
|
|
474
|
+
|
|
475
|
+
1. Top filter: Created at, Service group, Request type, Priority, SLA status.
|
|
476
|
+
2. KPI cards: Open backlog, Unassigned, SLA warning, SLA breached, New tickets, Resolved tickets.
|
|
477
|
+
3. Chart: Created tickets trend, Ticket status, SLA status, Priority mix.
|
|
478
|
+
4. After clicking on the chart, the JS block below displays the matching Ticket drilldown table.
|
|
479
|
+
5. The chart style should be suitable for the operating market, with clear colors and compact layout.
|
|
480
|
+
6. Use ctx.t() for all JS copy.
|
|
481
|
+
7. Chart events use chart.on and return the cleanup function.
|
|
482
|
+
8. Prioritize using NocoBase’s native filter blocks and chart blocks. Only use JS blocks for KPIs, drill-down details, special styles, and cross-block interactions. Do not write the entire page as one large JS block.
|
|
483
|
+
|
|
484
|
+
Please give the configuration ideas for each block and mark the key JS code.
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
If you already have a page, you can also let AI help you optimize it:
|
|
488
|
+
|
|
489
|
+
```markdown
|
|
490
|
+
This is my current NocoBase dashboard design:
|
|
491
|
+
At the top is the filter area, in the middle are 4 charts, and below is the drill-down JS block.
|
|
492
|
+
Please help me optimize from the perspective of operator experience:
|
|
493
|
+
|
|
494
|
+
1. What indicators should the KPI display?
|
|
495
|
+
2. Whether there is a need for linkage between charts;
|
|
496
|
+
3. Which columns should be displayed in drill-down details;
|
|
497
|
+
4. How should JS block and chart events be organized;
|
|
498
|
+
5. Which code should be placed in the chart custom option and which should be placed in the JS block.
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
In this way, the content generated by AI will be closer to the real business, rather than just giving isolated code.
|
|
502
|
+
|
|
503
|
+
:::warning
|
|
504
|
+
If you choose to let AI help you build it, please use the backup manager to back up the project before starting.
|
|
505
|
+
:::
|
|
506
|
+
|
|
507
|
+
## Reference documentation
|
|
508
|
+
|
|
509
|
+
- [Chart configuration ](/data-visualization/guide/chart-options)
|
|
510
|
+
- [Frontend RunJS](/runjs/)
|
|
511
|
+
- [Filter form ](/interface-builder/blocks/filter-blocks/form)
|
|
512
|
+
- [AI Construction - Interface Construction ](/ai-builder/ui-builder)
|
|
513
|
+
- [ECharts Options](https://echarts.apache.org/en/option.html)
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Attachment
|
|
2
2
|
|
|
3
|
+
:::warning Note
|
|
4
|
+
|
|
5
|
+
The Attachment field will be deprecated in a future version. For new apps or when adjusting existing business flows, migrate to a custom file collection as early as possible and manage related files with association fields.
|
|
6
|
+
|
|
7
|
+
:::
|
|
8
|
+
|
|
3
9
|
## Introduction
|
|
4
10
|
|
|
5
11
|
The system has a built-in "Attachment" field type to support file uploads in custom collections.
|
|
@@ -12,17 +12,8 @@ Currently, NocoBase provides the following file preview plugins:
|
|
|
12
12
|
|
|
13
13
|
## PDF preview with external storage
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
NocoBase previews PDFs through a browser iframe. Some browsers or PDF readers may support scripts, forms, or other interactive content inside PDF files. If the previewed file comes from an untrusted source, pay attention to the security boundary for script execution.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
We recommend isolating the file access domain from the NocoBase site and API domains. For example, serve files from OSS, S3, COS, or a CDN through a dedicated domain, instead of sharing the same origin with the NocoBase frontend or API.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
```http
|
|
22
|
-
Access-Control-Allow-Origin: https://your-nocobase-domain
|
|
23
|
-
Access-Control-Allow-Methods: GET, HEAD
|
|
24
|
-
Access-Control-Allow-Headers: *
|
|
25
|
-
Access-Control-Expose-Headers: Content-Length, Content-Range, Accept-Ranges, Content-Disposition, Content-Type
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
`Access-Control-Allow-Origin` should be set to the actual domain used to access NocoBase. Avoid using `*` for non-public files over the long term, because it expands the range of sites that can read the files.
|
|
19
|
+
If the file domain is different from the API domain, and the API does not enable CORS access for the file domain, scripts running in the PDF preview environment are usually restricted by the browser's same-origin policy. They cannot directly read the NocoBase page, browser storage, or API responses.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
pkg: '@nocobase/plugin-file-manager'
|
|
3
|
+
title: "Stable URL (proxy URL)"
|
|
4
|
+
description: "Explains NocoBase stable file URLs, access permissions, redirects, temporary Office preview URLs, and behavior across file-related features."
|
|
5
|
+
keywords: "stable URL,proxy URL,permanent URL,file access,file permissions,Office preview,NocoBase"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Stable URL
|
|
9
|
+
|
|
10
|
+
Files managed by a NocoBase storage engine are accessed through a **stable URL**. The URL first reaches NocoBase, where the file record and access permissions are checked, and then redirects to the actual URL generated by the storage engine.
|
|
11
|
+
|
|
12
|
+
## URL format
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
/files/<app>/<dataSource>/<collection>/<id><extname>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
For example:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
/files/main/main/attachments/42.pdf
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
When `APP_PUBLIC_PATH=/nocobase` is configured, the URL starts with `/nocobase/files/`. The path identifies the app, data source, file collection, record ID, and extension. The ID and extension cannot be changed after creation, which keeps the URL stable for the lifetime of the record.
|
|
25
|
+
|
|
26
|
+
## URL variants
|
|
27
|
+
|
|
28
|
+
| Purpose | URL | Behavior |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| Open or embed | `/files/.../42.pdf` | Checks permission and redirects to the actual file URL |
|
|
31
|
+
| Preview | `/files/.../42.png?preview=1` | Redirects to the preview or thumbnail URL |
|
|
32
|
+
| Download | `/files/.../42.pdf?download=1` | Redirects with download semantics |
|
|
33
|
+
| Office preview | `/files/.../42.xlsx?temporaryAccessToken=...` | Allows Microsoft Office Online Viewer to fetch one file for a short time |
|
|
34
|
+
|
|
35
|
+
:::tip
|
|
36
|
+
|
|
37
|
+
Use the `url` and `preview` values returned by NocoBase. Application code normally should not construct `/files` URLs or their query parameters.
|
|
38
|
+
|
|
39
|
+
:::
|
|
40
|
+
|
|
41
|
+
## Behavior across NocoBase
|
|
42
|
+
|
|
43
|
+
- Attachment fields and file collections return stable URLs after upload and when records are queried
|
|
44
|
+
- [HTTP API](./http-api.md) responses no longer expose local paths, storage domains, or presigned download URLs
|
|
45
|
+
- Markdown uploads store the stable URL, including files in private S3, OSS, COS, or S3 Pro storage
|
|
46
|
+
- Attachment URL fields store a stable URL for managed uploads, while manually entered external URLs remain unchanged
|
|
47
|
+
- Image, PDF, audio, video, and text previews use the stable URL and the current NocoBase login session
|
|
48
|
+
- Public forms grant limited access to files uploaded in the current public-form browser session; this does not create a generally public link
|
|
49
|
+
|
|
50
|
+
## Office preview
|
|
51
|
+
|
|
52
|
+
Microsoft Office Online Viewer fetches the file from Microsoft servers and cannot use the user's NocoBase cookie. When the user opens an Office preview, NocoBase first checks the user's file permission and then issues a temporary URL for that file.
|
|
53
|
+
|
|
54
|
+
The URL is valid for 10 minutes by default. `TEMPORARY_FILE_ACCESS_EXPIRES_IN` may be set from 5 to 10 minutes. It is requested again when the preview is reopened and must never be saved in an attachment field, Markdown content, or a business record.
|
|
55
|
+
|
|
56
|
+
## Permissions and redirects
|
|
57
|
+
|
|
58
|
+
Logged-in requests use the current app credentials and role. After permission is granted, NocoBase responds with `302` and redirects to the local or object-storage URL.
|
|
59
|
+
|
|
60
|
+
Stable URLs support `GET` and `HEAD`. Other methods return `405`. A command-line client must follow redirects, for example:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
curl -L \
|
|
64
|
+
-H "Authorization: Bearer <JWT>" \
|
|
65
|
+
"https://example.com/files/main/main/attachments/42.pdf"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Important notes
|
|
69
|
+
|
|
70
|
+
- Stable does not mean public; recipients still need permission to view the file
|
|
71
|
+
- Deleting the record or changing its app, data source, or collection context invalidates the old URL
|
|
72
|
+
- Do not persist `temporaryAccessToken` or use it as a sharing link
|
|
73
|
+
- Do not cache the `302 Location` as a permanent URL because storage signatures can expire
|
|
74
|
+
- Do not rewrite the app, data source, collection, ID, or extension in the path
|
|
75
|
+
- Reverse proxies must forward the `/files/` route under `APP_PUBLIC_PATH` to NocoBase. For subpath deployments, keep a compatible root-level `/files/` route as well. Configurations generated by the NocoBase CLI include both routes automatically
|
|
76
|
+
- Deployments where the pages access the API cross-origin (with `API_BASE_URL` pointing to another origin) must add the page origin to `CORS_ORIGIN_WHITELIST`; otherwise the login cookie is never stored and stable URLs return `403` for lack of credentials. See [Environment Variables](../get-started/installation/env.md#api_base_url)
|
|
77
|
+
- Use a different `hostname` for each independent NocoBase service instead of separating services only by port. Browser cookies are not isolated by port; see [Production Environment Deployment](../get-started/deployment/production.md)
|
|
78
|
+
- Sub-apps in the same NocoBase deployment are distinguished by app name and do not need separate hostnames. However, an independent service on another port still needs hostname isolation if it contains a main app or sub-app with the same name
|
|
79
|
+
- Custom `fetch()` code may also need object-storage CORS after following the redirect
|
|
80
|
+
- Use a dedicated sharing or public-access feature when a long-lived public link is required
|
|
81
|
+
|
|
82
|
+
## Related links
|
|
83
|
+
|
|
84
|
+
- [HTTP API](./http-api.md) — Upload and query files through the API
|
|
85
|
+
- [File preview](./file-preview/index.md) — Preview behavior for supported file types
|
|
86
|
+
- [Office file preview](./file-preview/ms-office.md) — Configure Microsoft Office Online Viewer
|
|
87
|
+
- [Storage engines](./storage/index.md) — Configure local and object storage
|
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
A storage engine based on Aliyun OSS. Before use, you need to prepare the relevant account and permissions.
|
|
4
4
|
|
|
5
|
+
|
|
6
|
+
:::warning Note
|
|
7
|
+
|
|
8
|
+
This engine does not support private access. After a file is uploaded, NocoBase generates a directly accessible URL, and anyone who has that URL can access the file.
|
|
9
|
+
|
|
10
|
+
Even if the OSS bucket itself is private, the built-in Aliyun OSS engine does not generate temporary signed URLs for file access. If you need private access, use [S3 Pro](./s3-pro). If historical files already exist, see [Migrate to S3 Pro](./migrate-to-s3-pro.md).
|
|
11
|
+
|
|
12
|
+
:::
|
|
13
|
+
|
|
5
14
|
## Configuration Parameters
|
|
6
15
|
|
|
7
16
|
|
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
A storage engine based on Amazon S3. You need to prepare the relevant account and permissions before use.
|
|
4
4
|
|
|
5
|
+
|
|
6
|
+
:::warning Note
|
|
7
|
+
|
|
8
|
+
This engine does not support private access. After a file is uploaded, NocoBase generates a directly accessible URL, and anyone who has that URL can access the file.
|
|
9
|
+
|
|
10
|
+
Even if the S3 bucket itself is private, the built-in Amazon S3 engine does not generate temporary signed URLs for file access. If you need private access, use [S3 Pro](./s3-pro). If historical files already exist, see [Migrate to S3 Pro](./migrate-to-s3-pro.md).
|
|
11
|
+
|
|
12
|
+
:::
|
|
13
|
+
|
|
5
14
|
## Configuration Parameters
|
|
6
15
|
|
|
7
16
|
|