refactor(web): remove legacy action button references (#40651)

This commit is contained in:
yyh
2026-08-13 07:04:16 +00:00
committed by GitHub
parent 204a906de8
commit a0ca3d2e81
8 changed files with 5 additions and 33 deletions
+1
View File
@@ -9,6 +9,7 @@
- User-facing strings must use `web/i18n/en-US/` keys. When adding or renaming a key, update every supported locale with the correct localized value.
- For new backend calls and migrated surfaces, use generated `consoleQuery` / `consoleClient` APIs from `@/service/client`. Do not add handwritten REST helpers or DTO mirrors, mock-backed app state, or direct edits to generated contracts.
- Prefer `@langgenius/dify-ui/*` primitives, data attributes, and design tokens. Preserve a visible focus indicator on the final focusable element.
- Use `Button` for actions with visible text and `IconButton` for icon-only actions. Every `IconButton` needs an `aria-label` or `aria-labelledby`; compose Menu, Popover, Toggle, and Collapsible through `render` so those primitives keep ownership of their state.
- Follow `docs/overlay.md` for overlay selection and migration. Migrate a legacy overlay only when the current behavior change actually involves that overlay boundary.
- For custom SVG icons, follow `../packages/iconify-collections/README.md`; do not add generated React icons under `app/components/base/icons/src/`.
- `docs/test.md` is the single source of truth for frontend automated-test policy. Skills may route and execute that policy but must not redefine it.
-7
View File
@@ -132,12 +132,6 @@ vp test run
If a test fails only in CI, inspect the failing job and reproduce it locally when possible. A rerun can help identify a flaky test, but it does not replace diagnosing or reporting the failure.
### Example Code
If you are not familiar with writing tests, refer to:
- [index.spec.tsx] - Component test example
## Documentation
Visit <https://docs.dify.ai> to view the full documentation.
@@ -155,7 +149,6 @@ The Dify community can be found on [Discord community], where you can ask questi
[Storybook]: https://storybook.js.org
[Vite+]: https://viteplus.dev
[Vitest]: https://vitest.dev
[index.spec.tsx]: ./app/components/base/action-button/__tests__/index.spec.tsx
[pnpm]: https://pnpm.io
[vinext]: https://github.com/cloudflare/vinext
[web/docs/test.md]: ./docs/test.md
@@ -36,11 +36,6 @@ describe('Operation', () => {
expect(screen.getByText('explore.sidebar.action.pin')).toBeInTheDocument()
})
it('should apply active state to ActionButton', () => {
render(<Operation {...defaultProps} isActive={true} />)
expect(getTrigger()).toBeInTheDocument()
})
it('should call togglePin when pin/unpin is clicked', async () => {
const user = userEvent.setup()
render(<Operation {...defaultProps} />)
@@ -885,21 +885,6 @@ describe('Operation', () => {
screen.getByTestId('operation-bar').querySelectorAll('.i-ri-thumb-up-line').length,
).toBe(0)
})
it('should render action buttons with Default state when feedback rating is undefined', () => {
// Setting a malformed feedback object with no rating but triggers the wrapper to see undefined fallbacks
const item = {
...baseItem,
feedback: {} as unknown as Record<string, unknown>,
adminFeedback: {} as unknown as Record<string, unknown>,
} as ChatItem
renderOperation({ ...baseProps, item })
// Since it renders the 'else' block for hasAdminFeedback (which is false due to !)
// the like/dislike regular ActionButtons should hit the Default state
// Since it renders the 'else' block for hasAdminFeedback (which is false due to !)
// the like/dislike regular ActionButtons should hit the Default state
expect(screen.getByTestId('operation-bar'))!.toBeInTheDocument()
})
})
describe('Positioning and layout', () => {
@@ -8,8 +8,7 @@ const meta = {
parameters: {
docs: {
description: {
component:
'Copy-to-clipboard button that shows instant feedback and a tooltip. Includes the original ActionButton wrapper and the newer ghost-button variant.',
component: 'Copy-to-clipboard icon buttons that show instant feedback and a tooltip.',
},
},
},
@@ -196,7 +196,7 @@ describe('FileUploaderInAttachmentWrapper', () => {
/>,
)
// ReplayLine is inside ActionButton (a <button>) with data-icon attribute
// ReplayLine is inside an icon button with a data-icon attribute.
const replayIcon = container.querySelector('svg[data-icon="ReplayLine"]')
const replayBtn = replayIcon!.closest('button')
fireEvent.click(replayBtn!)
@@ -14,7 +14,7 @@ const StoryWrapper = (props: ComponentProps<typeof AudioBtn>) => {
return (
<div className="flex items-center justify-center space-x-3">
<AudioBtn {...props} />
<span className="text-xs text-gray-500">Audio toggle using ActionButton styling</span>
<span className="text-xs text-gray-500">Audio toggle using IconButton styling</span>
</div>
)
}
@@ -28,7 +28,7 @@ const meta = {
docs: {
description: {
component:
'Updated audio playback trigger styled with `ActionButton`. Behaves like the legacy audio button but adopts the new button design system.',
'Audio playback trigger using the shared IconButton shape and a feature-owned active state.',
},
},
nextjs: {
@@ -17,7 +17,6 @@ Owns the Agent V2 configure runtime used by the Agent App configure page and wor
## External Modules
- app/components/base/chat
- app/components/base/action-button
- app/components/base/app-icon
- app/components/base/features
- app/components/base/file-uploader