diff --git a/eslint-suppressions.json b/eslint-suppressions.json
index 6ff584e4e9..79ae57e414 100644
--- a/eslint-suppressions.json
+++ b/eslint-suppressions.json
@@ -438,11 +438,6 @@
"count": 1
}
},
- "web/app/components/app/configuration/dataset-config/select-dataset/index.tsx": {
- "no-restricted-imports": {
- "count": 1
- }
- },
"web/app/components/app/configuration/dataset-config/settings-modal/index.tsx": {
"react/set-state-in-effect": {
"count": 2
@@ -3567,11 +3562,6 @@
"count": 1
}
},
- "web/app/components/workflow/dsl-export-confirm-modal.tsx": {
- "no-restricted-imports": {
- "count": 1
- }
- },
"web/app/components/workflow/header/run-mode.tsx": {
"no-console": {
"count": 1
diff --git a/web/app/components/app-sidebar/app-info/__tests__/app-info-modals.spec.tsx b/web/app/components/app-sidebar/app-info/__tests__/app-info-modals.spec.tsx
index 2fdd35cc43..218d4b94e6 100644
--- a/web/app/components/app-sidebar/app-info/__tests__/app-info-modals.spec.tsx
+++ b/web/app/components/app-sidebar/app-info/__tests__/app-info-modals.spec.tsx
@@ -46,6 +46,12 @@ vi.mock('@/app/components/workflow/update-dsl-modal', () => ({
}))
vi.mock('@/app/components/workflow/dsl-export-confirm-modal', () => ({
+ DSLExportConfirmContent: ({ onConfirm, onClose }: { onConfirm: (include?: boolean) => void, onClose: () => void }) => (
+
+
+
+
+ ),
default: ({ onConfirm, onClose }: { onConfirm: (include?: boolean) => void, onClose: () => void }) => (
diff --git a/web/app/components/app-sidebar/app-info/__tests__/app-operations.spec.tsx b/web/app/components/app-sidebar/app-info/__tests__/app-operations.spec.tsx
index ff6aed2c71..5daf0c7100 100644
--- a/web/app/components/app-sidebar/app-info/__tests__/app-operations.spec.tsx
+++ b/web/app/components/app-sidebar/app-info/__tests__/app-operations.spec.tsx
@@ -228,6 +228,21 @@ describe('AppOperations', () => {
})
describe('Visible operations click', () => {
+ it('should keep focus ring inside visible operation buttons', () => {
+ const cleanup = setupDomMeasurements(500, 60, [80])
+ const editOp = createOperation('edit', 'Edit')
+
+ render(
)
+
+ const visibleButton = screen.getAllByText('Edit')
+ .map(label => label.closest('button'))
+ .find(button => button?.tabIndex !== -1)
+
+ expect(visibleButton).toHaveClass('focus-visible:ring-inset')
+
+ cleanup()
+ })
+
it('should call onClick when a visible operation is clicked', async () => {
const cleanup = setupDomMeasurements(500, 60, [80, 80])
const user = userEvent.setup()
diff --git a/web/app/components/app-sidebar/app-info/app-info-modals.tsx b/web/app/components/app-sidebar/app-info/app-info-modals.tsx
index 9535725cd3..e1ed1d62ef 100644
--- a/web/app/components/app-sidebar/app-info/app-info-modals.tsx
+++ b/web/app/components/app-sidebar/app-info/app-info-modals.tsx
@@ -16,13 +16,13 @@ import * as React from 'react'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Input from '@/app/components/base/input'
+import { DSLExportConfirmContent } from '@/app/components/workflow/dsl-export-confirm-modal'
import dynamic from '@/next/dynamic'
const SwitchAppModal = dynamic(() => import('@/app/components/app/switch-app-modal'), { ssr: false })
const CreateAppModal = dynamic(() => import('@/app/components/explore/create-app-modal'), { ssr: false })
const DuplicateAppModal = dynamic(() => import('@/app/components/app/duplicate-modal'), { ssr: false })
const UpdateDSLModal = dynamic(() => import('@/app/components/workflow/update-dsl-modal'), { ssr: false })
-const DSLExportConfirmModal = dynamic(() => import('@/app/components/workflow/dsl-export-confirm-modal'), { ssr: false })
type AppInfoModalsProps = {
appDetail: App & Partial
@@ -54,7 +54,14 @@ const AppInfoModals = ({
const { t } = useTranslation()
const [confirmDeleteInput, setConfirmDeleteInput] = useState('')
const [isConfirmingExport, setIsConfirmingExport] = useState(false)
+ const [isSecretExporting, setIsSecretExporting] = useState(false)
const isDeleteConfirmDisabled = confirmDeleteInput !== appDetail.name
+ const exportDialogMode = secretEnvList.length > 0
+ ? 'secret'
+ : activeModal === 'exportWarning'
+ ? 'warning'
+ : null
+ const isExportDialogOpen = exportDialogMode !== null
const handleDeleteDialogClose = () => {
setConfirmDeleteInput('')
@@ -74,6 +81,22 @@ const AppInfoModals = ({
}
}, [handleConfirmExport, isConfirmingExport])
+ const handleExportDialogClose = useCallback(() => {
+ if (exportDialogMode === 'secret') {
+ setSecretEnvList([])
+ return
+ }
+
+ closeModal()
+ }, [closeModal, exportDialogMode, setSecretEnvList])
+
+ const handleExportDialogOpenChange = useCallback((open: boolean) => {
+ if (open || isConfirmingExport || isSecretExporting)
+ return
+
+ handleExportDialogClose()
+ }, [handleExportDialogClose, isConfirmingExport, isSecretExporting])
+
return (
<>
{activeModal === 'switch' && (
@@ -163,38 +186,42 @@ const AppInfoModals = ({
onBackup={exportCheck}
/>
)}
- !open && closeModal()}>
-
-
-
- {t('sidebar.exportWarning', { ns: 'workflow' })}
-
-
- {t('sidebar.exportWarningDesc', { ns: 'workflow' })}
-
-
-
- {t('operation.cancel', { ns: 'common' })}
-
- {isConfirmingExport
- ? t('operation.exporting', { ns: 'common' })
- : t('operation.confirm', { ns: 'common' })}
-
-
-
+
+ {exportDialogMode === 'secret'
+ ? (
+ setSecretEnvList([])}
+ onExportingChange={setIsSecretExporting}
+ />
+ )
+ : exportDialogMode === 'warning' && (
+
+
+
+ {t('sidebar.exportWarning', { ns: 'workflow' })}
+
+
+ {t('sidebar.exportWarningDesc', { ns: 'workflow' })}
+
+
+
+ {t('operation.cancel', { ns: 'common' })}
+
+ {isConfirmingExport
+ ? t('operation.exporting', { ns: 'common' })
+ : t('operation.confirm', { ns: 'common' })}
+
+
+
+ )}
- {secretEnvList.length > 0 && (
- setSecretEnvList([])}
- />
- )}
>
)
}
diff --git a/web/app/components/app-sidebar/app-info/app-operations.tsx b/web/app/components/app-sidebar/app-info/app-operations.tsx
index cc6afd739c..2e3270a222 100644
--- a/web/app/components/app-sidebar/app-info/app-operations.tsx
+++ b/web/app/components/app-sidebar/app-info/app-operations.tsx
@@ -133,7 +133,7 @@ const AppOperations = ({
data-targetid={operation.id}
size="small"
variant="secondary"
- className="gap-px"
+ className="gap-px focus-visible:ring-inset"
tabIndex={-1}
>
{cloneElement(operation.icon, { className: 'h-3.5 w-3.5 text-components-button-secondary-text' })}
@@ -146,7 +146,7 @@ const AppOperations = ({
id="more-measure"
size="small"
variant="secondary"
- className="gap-px"
+ className="gap-px focus-visible:ring-inset"
tabIndex={-1}
>
@@ -162,7 +162,7 @@ const AppOperations = ({
data-targetid={operation.id}
size="small"
variant="secondary"
- className="gap-px"
+ className="gap-px focus-visible:ring-inset"
onClick={operation.onClick}
>
{cloneElement(operation.icon, { className: 'h-3.5 w-3.5 text-components-button-secondary-text' })}
@@ -178,7 +178,7 @@ const AppOperations = ({
)}
>
diff --git a/web/app/components/app/app-access-control/specific-groups-or-members.tsx b/web/app/components/app/app-access-control/specific-groups-or-members.tsx
index 1caabb3ff9..35e6b1cc19 100644
--- a/web/app/components/app/app-access-control/specific-groups-or-members.tsx
+++ b/web/app/components/app/app-access-control/specific-groups-or-members.tsx
@@ -121,7 +121,7 @@ type BaseItemProps = {
}
function BaseItem({ icon, onRemove, children }: BaseItemProps) {
return (
-
+
{icon}
diff --git a/web/app/components/app/configuration/config/agent/agent-setting/index.tsx b/web/app/components/app/configuration/config/agent/agent-setting/index.tsx
index beae6b2a49..ea24d129ef 100644
--- a/web/app/components/app/configuration/config/agent/agent-setting/index.tsx
+++ b/web/app/components/app/configuration/config/agent/agent-setting/index.tsx
@@ -74,7 +74,7 @@ const AgentSetting: FC
= ({
{/* Body */}
= ({
- {isShowSelectDataSet && (
-
- )}
+
{isShowHistoryModal && (
= ({
onSelect(selected)
}
+ const handleClose = useCallback(() => {
+ setSelectedIdsInModal(selectedIds)
+ onClose()
+ }, [onClose, selectedIds])
+
+ const handleOpenChange = useCallback((open: boolean) => {
+ if (!open)
+ handleClose()
+ }, [handleClose])
+
return (
-
- {(isLoading && datasets.length === 0) && (
-
-
-
- )}
+