mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
refactor(web): move app builder button to canvas header
This commit is contained in:
1 parent
cb53f02905
commit
c200902173
5 files changed
+109
-56
No files matched your search
@@ -0,0 +1,36 @@
|
||||
import { screen } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { renderWorkflowComponent } from '../../__tests__/workflow-test-env'
|
||||
import DifyBuilderButton from '../dify-builder-button'
|
||||
|
||||
describe('DifyBuilderButton', () => {
|
||||
it('should expose a visible label and toggle the builder panel', async () => {
|
||||
const user = userEvent.setup()
|
||||
const { store } = renderWorkflowComponent(<DifyBuilderButton disabled={false} />)
|
||||
const button = screen.getByRole('button', {
|
||||
name: 'workflow.difyBuilder.buttonTooltip',
|
||||
})
|
||||
|
||||
expect(button).toHaveTextContent('workflow.difyBuilder.buttonTooltip')
|
||||
expect(button).toHaveAttribute('aria-pressed', 'false')
|
||||
|
||||
await user.click(button)
|
||||
|
||||
expect(store.getState().showDifyBuilderPanel).toBe(true)
|
||||
expect(button).toHaveAttribute('aria-pressed', 'true')
|
||||
})
|
||||
|
||||
it('should remain closed when the button is disabled', async () => {
|
||||
const user = userEvent.setup()
|
||||
const { store } = renderWorkflowComponent(<DifyBuilderButton disabled />)
|
||||
const button = screen.getByRole('button', {
|
||||
name: 'workflow.difyBuilder.buttonTooltip',
|
||||
})
|
||||
|
||||
expect(button).toBeDisabled()
|
||||
|
||||
await user.click(button)
|
||||
|
||||
expect(store.getState().showDifyBuilderPanel).toBe(false)
|
||||
})
|
||||
})
|
||||
@@ -259,6 +259,25 @@ describe('Header layout components', () => {
|
||||
expect(screen.queryByTestId('env-button')).not.toBeInTheDocument()
|
||||
expect(screen.queryByTestId('global-variable-button')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should place App Builder at the end of the canvas actions', () => {
|
||||
renderWorkflowComponent(
|
||||
<HeaderInNormal
|
||||
components={{
|
||||
middle: <button type="button">middle-action</button>,
|
||||
}}
|
||||
controls={{
|
||||
showDifyBuilderButton: true,
|
||||
}}
|
||||
/>,
|
||||
)
|
||||
|
||||
const appBuilderButton = screen.getByRole('button', {
|
||||
name: 'workflow.difyBuilder.buttonTooltip',
|
||||
})
|
||||
|
||||
expect(screen.getAllByRole('button').at(-1)).toBe(appBuilderButton)
|
||||
})
|
||||
})
|
||||
|
||||
describe('HeaderInRestoring', () => {
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { Button } from '@langgenius/dify-ui/button'
|
||||
import { cn } from '@langgenius/dify-ui/cn'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip'
|
||||
import { memo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useStore } from '@/app/components/workflow/store'
|
||||
import useTheme from '@/hooks/use-theme'
|
||||
|
||||
const DifyBuilderButton = ({ disabled }: { disabled: boolean }) => {
|
||||
const { t } = useTranslation()
|
||||
const { theme } = useTheme()
|
||||
const showDifyBuilderPanel = useStore((s) => s.showDifyBuilderPanel)
|
||||
const setShowDifyBuilderPanel = useStore((s) => s.setShowDifyBuilderPanel)
|
||||
const label = t(($) => $['difyBuilder.buttonTooltip'], { ns: 'workflow' })
|
||||
@@ -24,20 +21,16 @@ const DifyBuilderButton = ({ disabled }: { disabled: boolean }) => {
|
||||
<Button
|
||||
aria-label={label}
|
||||
aria-pressed={showDifyBuilderPanel}
|
||||
className={cn(
|
||||
'rounded-lg border border-transparent p-2',
|
||||
theme === 'dark' &&
|
||||
showDifyBuilderPanel &&
|
||||
'border-black/5 bg-white/10 backdrop-blur-xs',
|
||||
)}
|
||||
className="dify-blue-glass-surface relative h-8 shrink-0 rounded-lg p-2 text-text-accent! data-disabled:text-components-button-ghost-text-disabled!"
|
||||
variant="ghost"
|
||||
disabled={disabled}
|
||||
onClick={handleClick}
|
||||
>
|
||||
<span
|
||||
aria-hidden
|
||||
className="i-ri-magic-line size-4 text-components-button-secondary-text"
|
||||
className="i-ri-chat-ai-line size-4 shrink-0 drop-shadow-[0_0_4px_var(--color-components-main-nav-glass-text-glow)]"
|
||||
/>
|
||||
<span className="system-xs-semibold-uppercase">{label}</span>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -9,6 +9,7 @@ import { useNodesInteractions } from '../hooks/use-nodes-interactions'
|
||||
import { useNodesReadOnly } from '../hooks/use-workflow'
|
||||
import { useWorkflowRun } from '../hooks/use-workflow-run'
|
||||
import { useStore, useWorkflowStore } from '../store'
|
||||
import DifyBuilderButton from './dify-builder-button'
|
||||
import EditingTitle from './editing-title'
|
||||
import EnvButton from './env-button'
|
||||
import GlobalVariableButton from './global-variable-button'
|
||||
@@ -16,7 +17,6 @@ import OnlineUsers from './online-users'
|
||||
import RunAndHistory from './run-and-history'
|
||||
import ScrollToSelectedNodeButton from './scroll-to-selected-node-button'
|
||||
import { VersionHistoryButton } from './version-history-button'
|
||||
import DifyBuilderButton from './dify-builder-button'
|
||||
|
||||
export type HeaderInNormalProps = {
|
||||
components?: {
|
||||
@@ -93,7 +93,6 @@ const HeaderInNormal = ({ components, controls, runAndHistoryProps }: HeaderInNo
|
||||
{components?.left}
|
||||
<Divider type="vertical" className="mx-auto h-3.5" />
|
||||
<RunAndHistory {...runAndHistoryProps} />
|
||||
{showDifyBuilderButton && <DifyBuilderButton disabled={nodesReadOnly} />}
|
||||
{showContextButtons && (
|
||||
<div className="shrink-0 cursor-pointer rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg shadow-xs backdrop-blur-[10px]">
|
||||
{components?.chatVariableTrigger}
|
||||
@@ -103,6 +102,12 @@ const HeaderInNormal = ({ components, controls, runAndHistoryProps }: HeaderInNo
|
||||
)}
|
||||
{components?.middle}
|
||||
{canReleaseAndVersion && <VersionHistoryButton onClick={onStartRestoring} />}
|
||||
{showDifyBuilderButton && (
|
||||
<>
|
||||
<Divider type="vertical" className="mx-0 h-4" />
|
||||
<DifyBuilderButton disabled={nodesReadOnly} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -297,50 +297,6 @@
|
||||
"common.workflowProcessRunning": "Workflow Process running",
|
||||
"common.workflowProcessSucceeded": "Workflow Process succeeded",
|
||||
"common.workflowSaveStatus": "Workflow save status",
|
||||
"difyBuilder.actionApproveRepair": "Approve repair",
|
||||
"difyBuilder.actionProvideTestdata": "Provide mock test data",
|
||||
"difyBuilder.actionPublish": "Publish",
|
||||
"difyBuilder.actionReFix": "Re-fix",
|
||||
"difyBuilder.actionRunVerify": "Run verify",
|
||||
"difyBuilder.actionUndo": "Undo",
|
||||
"difyBuilder.actionsTitle": "Actions",
|
||||
"difyBuilder.appLabel": "App",
|
||||
"difyBuilder.buttonTooltip": "Dify Builder",
|
||||
"difyBuilder.checklistFixAction_one": "Fix {{count}} checklist issue",
|
||||
"difyBuilder.checklistFixAction_other": "Fix {{count}} checklist issues",
|
||||
"difyBuilder.checklistFixSummary_one": "{{count}} configuration issue can be auto-fixed",
|
||||
"difyBuilder.checklistFixSummary_other": "{{count}} configuration issues can be auto-fixed",
|
||||
"difyBuilder.checklistFixTitle": "Checklist issues",
|
||||
"difyBuilder.checklistRecheckAction": "Recheck checklist",
|
||||
"difyBuilder.checklistRecheckDescription": "The proposed fix was applied to the draft. Recheck the checklist to confirm it resolved the issue.",
|
||||
"difyBuilder.checklistRecheckTitle": "Checklist recheck",
|
||||
"difyBuilder.checklistUnfixableNote_one": "{{count}} issue can't be auto-fixed yet — resolve it manually before publishing",
|
||||
"difyBuilder.checklistUnfixableNote_other": "{{count}} issues can't be auto-fixed yet — resolve them manually before publishing",
|
||||
"difyBuilder.contextMissing": "Open this panel from an app's workflow editor to use Dify Builder.",
|
||||
"difyBuilder.errorPrefix": "Error",
|
||||
"difyBuilder.messagePlaceholder": "Send a message to the difyBuilder",
|
||||
"difyBuilder.messageSend": "Send",
|
||||
"difyBuilder.panelDescription": "Diagnose and repair a failed workflow run with AI-assisted fixes.",
|
||||
"difyBuilder.panelTitle": "Dify Builder",
|
||||
"difyBuilder.progressEmpty": "Progress will appear here once a fix starts.",
|
||||
"difyBuilder.progressTitle": "Progress",
|
||||
"difyBuilder.runToFixAutoEmpty": "No failed run found yet. Enter a run ID manually.",
|
||||
"difyBuilder.runToFixAutoLabel": "Latest failed run",
|
||||
"difyBuilder.runToFixAutoLoading": "Looking for the latest failed run…",
|
||||
"difyBuilder.runToFixManualLabel": "Or enter a run ID",
|
||||
"difyBuilder.runToFixManualPlaceholder": "Workflow run ID",
|
||||
"difyBuilder.runToFixTitle": "Run to fix",
|
||||
"difyBuilder.sessionCanvasReadOnlyLabel": "Canvas read-only",
|
||||
"difyBuilder.sessionEmpty": "No active fix session yet.",
|
||||
"difyBuilder.sessionIdLabel": "Session",
|
||||
"difyBuilder.sessionInterruptedLabel": "Interrupted",
|
||||
"difyBuilder.sessionRunStatusLabel": "Run status",
|
||||
"difyBuilder.sessionStateLabel": "State",
|
||||
"difyBuilder.sessionVersionLabel": "Version",
|
||||
"difyBuilder.startFix": "Start Fix",
|
||||
"difyBuilder.starting": "Starting…",
|
||||
"difyBuilder.useThisRun": "Fix this run",
|
||||
"difyBuilder.workspaceLabel": "Workspace",
|
||||
"customWebhook": "Custom Webhook",
|
||||
"debug.copyLastRun": "Copy Last Run",
|
||||
"debug.copyLastRunError": "Failed to copy last run inputs",
|
||||
@@ -391,6 +347,50 @@
|
||||
"debug.variableInspect.trigger.running": "Caching running status",
|
||||
"debug.variableInspect.trigger.stop": "Stop run",
|
||||
"debug.variableInspect.view": "View log",
|
||||
"difyBuilder.actionApproveRepair": "Approve repair",
|
||||
"difyBuilder.actionProvideTestdata": "Provide mock test data",
|
||||
"difyBuilder.actionPublish": "Publish",
|
||||
"difyBuilder.actionReFix": "Re-fix",
|
||||
"difyBuilder.actionRunVerify": "Run verify",
|
||||
"difyBuilder.actionUndo": "Undo",
|
||||
"difyBuilder.actionsTitle": "Actions",
|
||||
"difyBuilder.appLabel": "App",
|
||||
"difyBuilder.buttonTooltip": "App Builder",
|
||||
"difyBuilder.checklistFixAction_one": "Fix {{count}} checklist issue",
|
||||
"difyBuilder.checklistFixAction_other": "Fix {{count}} checklist issues",
|
||||
"difyBuilder.checklistFixSummary_one": "{{count}} configuration issue can be auto-fixed",
|
||||
"difyBuilder.checklistFixSummary_other": "{{count}} configuration issues can be auto-fixed",
|
||||
"difyBuilder.checklistFixTitle": "Checklist issues",
|
||||
"difyBuilder.checklistRecheckAction": "Recheck checklist",
|
||||
"difyBuilder.checklistRecheckDescription": "The proposed fix was applied to the draft. Recheck the checklist to confirm it resolved the issue.",
|
||||
"difyBuilder.checklistRecheckTitle": "Checklist recheck",
|
||||
"difyBuilder.checklistUnfixableNote_one": "{{count}} issue can't be auto-fixed yet — resolve it manually before publishing",
|
||||
"difyBuilder.checklistUnfixableNote_other": "{{count}} issues can't be auto-fixed yet — resolve them manually before publishing",
|
||||
"difyBuilder.contextMissing": "Open this panel from an app's workflow editor to use Dify Builder.",
|
||||
"difyBuilder.errorPrefix": "Error",
|
||||
"difyBuilder.messagePlaceholder": "Send a message to the difyBuilder",
|
||||
"difyBuilder.messageSend": "Send",
|
||||
"difyBuilder.panelDescription": "Diagnose and repair a failed workflow run with AI-assisted fixes.",
|
||||
"difyBuilder.panelTitle": "Dify Builder",
|
||||
"difyBuilder.progressEmpty": "Progress will appear here once a fix starts.",
|
||||
"difyBuilder.progressTitle": "Progress",
|
||||
"difyBuilder.runToFixAutoEmpty": "No failed run found yet. Enter a run ID manually.",
|
||||
"difyBuilder.runToFixAutoLabel": "Latest failed run",
|
||||
"difyBuilder.runToFixAutoLoading": "Looking for the latest failed run…",
|
||||
"difyBuilder.runToFixManualLabel": "Or enter a run ID",
|
||||
"difyBuilder.runToFixManualPlaceholder": "Workflow run ID",
|
||||
"difyBuilder.runToFixTitle": "Run to fix",
|
||||
"difyBuilder.sessionCanvasReadOnlyLabel": "Canvas read-only",
|
||||
"difyBuilder.sessionEmpty": "No active fix session yet.",
|
||||
"difyBuilder.sessionIdLabel": "Session",
|
||||
"difyBuilder.sessionInterruptedLabel": "Interrupted",
|
||||
"difyBuilder.sessionRunStatusLabel": "Run status",
|
||||
"difyBuilder.sessionStateLabel": "State",
|
||||
"difyBuilder.sessionVersionLabel": "Version",
|
||||
"difyBuilder.startFix": "Start Fix",
|
||||
"difyBuilder.starting": "Starting…",
|
||||
"difyBuilder.useThisRun": "Fix this run",
|
||||
"difyBuilder.workspaceLabel": "Workspace",
|
||||
"difyTeam": "Dify Team",
|
||||
"entryNodeStatus.disabled": "START • DISABLED",
|
||||
"entryNodeStatus.enabled": "START",
|
||||
|
||||
Reference in new issue
Block a user