mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
fix: enforce read-only agent resources in build mode (#41220)
This commit is contained in:
6 files changed
+30
-54
No files matched your search
+3
-3
@@ -730,11 +730,11 @@ describe('AgentFiles', () => {
|
||||
).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should keep add action available for build drafts', () => {
|
||||
it('should hide the add action while a build draft is read-only', () => {
|
||||
renderAgentFiles({ readOnly: true })
|
||||
|
||||
expect(
|
||||
screen.getByRole('button', { name: /agentV2\.agentDetail\.configure\.files\.add/i }),
|
||||
).toBeInTheDocument()
|
||||
screen.queryByRole('button', { name: /agentV2\.agentDetail\.configure\.files\.add/i }),
|
||||
).not.toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
@@ -375,6 +375,7 @@ export function AgentFiles() {
|
||||
const { t } = useTranslation('agentV2')
|
||||
const filesTip = t(($) => $['agentDetail.configure.files.tip'])
|
||||
const filesTreeId = 'agent-configure-files-tree'
|
||||
const readOnly = useAgentOrchestrateReadOnly()
|
||||
const [isUploadOpen, setIsUploadOpen] = useState(false)
|
||||
const promptAddCallbackRef = useRef<AgentOrchestrateAddActionOptions['onAdded']>(undefined)
|
||||
const apiContext = useAgentConfigApiContext()
|
||||
@@ -477,10 +478,12 @@ export function AgentFiles() {
|
||||
rootClassName="border-b border-divider-subtle pt-4"
|
||||
panelContentClassName="pb-4"
|
||||
actions={
|
||||
<ConfigureSectionAddButton
|
||||
ariaLabel={t(($) => $['agentDetail.configure.files.add'])}
|
||||
onClick={() => handleOpenUpload()}
|
||||
/>
|
||||
!readOnly ? (
|
||||
<ConfigureSectionAddButton
|
||||
ariaLabel={t(($) => $['agentDetail.configure.files.add'])}
|
||||
onClick={() => handleOpenUpload()}
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
>
|
||||
{visibleFiles.length === 0 ? (
|
||||
|
||||
+7
-31
@@ -1516,7 +1516,7 @@ describe('AgentSkills', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('should keep delete available for an embedded skill while a build draft is read-only', async () => {
|
||||
it('should expose only download for an embedded skill while a build draft is read-only', async () => {
|
||||
const user = userEvent.setup()
|
||||
renderAgentSkills({
|
||||
apiContext: { agentId: 'agent-1', draftType: 'debug_build' },
|
||||
@@ -1530,20 +1530,8 @@ describe('AgentSkills', () => {
|
||||
)
|
||||
|
||||
expect(screen.getByText('common.operation.download')).toBeInTheDocument()
|
||||
await user.click(screen.getByText('common.operation.delete'))
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mocks.deleteSkillMutationFn.mock.calls[0]?.[0]).toEqual({
|
||||
params: {
|
||||
agent_id: 'agent-1',
|
||||
name: 'Tender Analyzer',
|
||||
},
|
||||
query: {
|
||||
draft_type: 'debug_build',
|
||||
version_id: undefined,
|
||||
},
|
||||
})
|
||||
})
|
||||
expect(screen.queryByText('common.operation.delete')).not.toBeInTheDocument()
|
||||
expect(mocks.deleteSkillMutationFn).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should expose only download from an embedded skill row when viewing a version', async () => {
|
||||
@@ -1853,8 +1841,7 @@ describe('AgentSkills', () => {
|
||||
expect(mocks.replaceAgentSkillBindingsMutationFn).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should keep the add menu available for build draft skills', async () => {
|
||||
const user = userEvent.setup()
|
||||
it('should hide the add action while a build draft is read-only', () => {
|
||||
renderAgentSkills({
|
||||
apiContext: {
|
||||
agentId: 'agent-1',
|
||||
@@ -1867,21 +1854,10 @@ describe('AgentSkills', () => {
|
||||
readOnly: true,
|
||||
})
|
||||
|
||||
await user.click(
|
||||
await screen.findByRole('button', {
|
||||
expect(
|
||||
screen.queryByRole('button', {
|
||||
name: /agentV2\.agentDetail\.configure\.skills\.add/i,
|
||||
}),
|
||||
)
|
||||
|
||||
expect(
|
||||
await screen.findByRole('button', {
|
||||
name: /agentV2\.agentDetail\.configure\.skills\.addMenu\.workspace\.label/i,
|
||||
}),
|
||||
).toBeInTheDocument()
|
||||
expect(
|
||||
screen.getByRole('button', {
|
||||
name: /agentV2\.agentDetail\.configure\.skills\.addMenu\.upload\.label/i,
|
||||
}),
|
||||
).toBeInTheDocument()
|
||||
).not.toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
+7
-10
@@ -49,10 +49,7 @@ import { ConfigureSectionEmpty } from '../common/empty'
|
||||
import { ConfigureSection } from '../common/section'
|
||||
import { AgentConfigureTipContent } from '../common/tip-content'
|
||||
import { useAgentConfigApiContext } from '../config-context'
|
||||
import {
|
||||
useAgentOrchestrateReadOnly,
|
||||
useAgentOrchestrateViewingVersion,
|
||||
} from '../read-only-context'
|
||||
import { useAgentOrchestrateReadOnly } from '../read-only-context'
|
||||
import { AgentSkillItem } from './item'
|
||||
import { AgentSkillUploadDialog } from './upload-dialog'
|
||||
|
||||
@@ -463,7 +460,7 @@ export function AgentSkills() {
|
||||
const skillsTip = t(($) => $['agentDetail.configure.skills.tip'])
|
||||
const skillsListId = 'agent-configure-skills-list'
|
||||
const queryClient = useQueryClient()
|
||||
const isViewingVersion = useAgentOrchestrateViewingVersion()
|
||||
const readOnly = useAgentOrchestrateReadOnly()
|
||||
const [addMenuOpen, setAddMenuOpen] = useState(false)
|
||||
const [addMenuView, setAddMenuView] = useState<'menu' | 'workspace-selector'>('menu')
|
||||
const [isUploadOpen, setIsUploadOpen] = useState(false)
|
||||
@@ -511,7 +508,7 @@ export function AgentSkills() {
|
||||
|
||||
const replaceWorkspaceSkillBindings = useCallback(
|
||||
(skillIds: string[], onSuccess?: () => void) => {
|
||||
if (isViewingVersion || !hasLoadedAgentSkillBindings) return
|
||||
if (readOnly || !hasLoadedAgentSkillBindings) return
|
||||
|
||||
replaceAgentSkillBindings(
|
||||
{
|
||||
@@ -563,8 +560,8 @@ export function AgentSkills() {
|
||||
apiContext.agentId,
|
||||
hasLoadedAgentSkillBindings,
|
||||
invalidateAgentSkillBindings,
|
||||
isViewingVersion,
|
||||
queryClient,
|
||||
readOnly,
|
||||
replaceAgentSkillBindings,
|
||||
t,
|
||||
tSkill,
|
||||
@@ -709,7 +706,7 @@ export function AgentSkills() {
|
||||
rootClassName="border-b border-divider-subtle pt-4"
|
||||
panelContentClassName="flex flex-col gap-1 pb-4"
|
||||
actions={
|
||||
!isViewingVersion && (
|
||||
!readOnly && (
|
||||
<Popover open={addMenuOpen} onOpenChange={handleAddMenuOpenChange}>
|
||||
<PopoverTrigger
|
||||
render={
|
||||
@@ -775,7 +772,7 @@ export function AgentSkills() {
|
||||
{workspaceSkills.map((skill) => (
|
||||
<WorkspaceAgentSkillItem
|
||||
key={skill.id}
|
||||
canRemove={!isViewingVersion}
|
||||
canRemove={!readOnly}
|
||||
skill={skill}
|
||||
onRemove={handleRemoveWorkspaceSkill}
|
||||
/>
|
||||
@@ -784,7 +781,7 @@ export function AgentSkills() {
|
||||
<AgentSkillItem
|
||||
key={skill.id}
|
||||
apiContext={apiContext}
|
||||
canRemove={!isViewingVersion}
|
||||
canRemove={!readOnly}
|
||||
skill={skill}
|
||||
onRemove={handleRemoveSkill}
|
||||
/>
|
||||
|
||||
+3
-3
@@ -587,14 +587,14 @@ describe('AgentTools', () => {
|
||||
).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should keep add action available for build drafts', () => {
|
||||
it('should hide the add action while a build draft is read-only', () => {
|
||||
renderReadonlyAgentTools()
|
||||
|
||||
expect(
|
||||
screen.getByRole('button', {
|
||||
screen.queryByRole('button', {
|
||||
name: 'agentV2.agentDetail.configure.tools.add',
|
||||
}),
|
||||
).toBeInTheDocument()
|
||||
).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should hide CLI tool rows while CLI tools are disabled', () => {
|
||||
|
||||
@@ -41,7 +41,7 @@ import { ConfigureSectionAddButton } from '../common/add-button'
|
||||
import { ConfigureSectionEmpty } from '../common/empty'
|
||||
import { ConfigureSection } from '../common/section'
|
||||
import { AgentConfigureTipContent } from '../common/tip-content'
|
||||
import { useAgentOrchestrateViewingVersion } from '../read-only-context'
|
||||
import { useAgentOrchestrateReadOnly } from '../read-only-context'
|
||||
import { CliToolDialog } from './cli-tool/dialog'
|
||||
import { AgentCliToolItem } from './cli-tool/item'
|
||||
import {
|
||||
@@ -380,7 +380,7 @@ function AddToolMenu({
|
||||
|
||||
export function AgentTools() {
|
||||
const { t } = useTranslation('agentV2')
|
||||
const isViewingVersion = useAgentOrchestrateViewingVersion()
|
||||
const readOnly = useAgentOrchestrateReadOnly()
|
||||
const setProviderToolCredential = useSetAtom(setProviderToolCredentialAtom)
|
||||
const invalidateAllBuiltInTools = useInvalidateAllBuiltInTools()
|
||||
const invalidateInstalledPluginList = useInvalidateInstalledPluginList()
|
||||
@@ -530,7 +530,7 @@ export function AgentTools() {
|
||||
rootClassName="border-b border-divider-subtle pt-4"
|
||||
panelContentClassName="flex flex-col gap-1 pb-4"
|
||||
actions={
|
||||
!isViewingVersion ? (
|
||||
!readOnly ? (
|
||||
<AddToolMenu
|
||||
onAddCliTool={openCliToolDialog}
|
||||
onAddTools={addTools}
|
||||
|
||||
Reference in new issue
Block a user