From 2c9e30426d9049305dbc661e148bf54fb8f49066 Mon Sep 17 00:00:00 2001 From: yyh <92089059+lyzno1@users.noreply.github.com> Date: Sat, 9 May 2026 14:49:26 +0800 Subject: [PATCH] refactor(web): migrate headless-ui components to dify-ui (#35962) --- web/__tests__/header/nav-flow.test.tsx | 27 +- web/app/account/(commonLayout)/avatar.tsx | 119 ++++---- .../header-opts/__tests__/index.spec.tsx | 152 +++++++---- .../app/annotation/header-opts/index.tsx | 131 ++++----- .../__tests__/access-control-dialog.spec.tsx | 3 +- .../__tests__/access-control.spec.tsx | 6 +- .../access-control-dialog.tsx | 49 +--- .../app/app-access-control/index.tsx | 2 +- .../__tests__/param-config-content.spec.tsx | 48 +--- .../text-to-speech/param-config-content.tsx | 182 ++++--------- .../credential-selector/index.tsx | 142 ++++------ .../operation/transfer-ownership.tsx | 64 ++--- .../__tests__/priority-selector.spec.tsx | 29 -- .../provider-added-card/priority-selector.tsx | 77 ------ .../app-selector/__tests__/index.spec.tsx | 172 ------------ .../components/header/app-selector/index.tsx | 117 -------- .../header/nav/__tests__/index.spec.tsx | 52 ++-- .../nav/nav-selector/__tests__/index.spec.tsx | 17 +- .../header/nav/nav-selector/index.tsx | 256 +++++++++--------- .../form-input-item.branches.spec.tsx | 8 +- .../form-input-item.sections.spec.tsx | 12 +- .../components/form-input-item.sections.tsx | 81 +++--- 22 files changed, 583 insertions(+), 1163 deletions(-) delete mode 100644 web/app/components/header/account-setting/model-provider-page/provider-added-card/__tests__/priority-selector.spec.tsx delete mode 100644 web/app/components/header/account-setting/model-provider-page/provider-added-card/priority-selector.tsx delete mode 100644 web/app/components/header/app-selector/__tests__/index.spec.tsx delete mode 100644 web/app/components/header/app-selector/index.tsx diff --git a/web/__tests__/header/nav-flow.test.tsx b/web/__tests__/header/nav-flow.test.tsx index 667f1e36b7..58c95f0a01 100644 --- a/web/__tests__/header/nav-flow.test.tsx +++ b/web/__tests__/header/nav-flow.test.tsx @@ -1,4 +1,5 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react' +import userEvent from '@testing-library/user-event' import * as React from 'react' import { beforeEach, describe, expect, it, vi } from 'vitest' import Nav from '@/app/components/header/nav' @@ -192,27 +193,23 @@ describe('Header Nav Flow', () => { }) it('opens the nested create menu and emits all app creation branches', async () => { - renderNav() - - fireEvent.click(screen.getByRole('button', { name: /Alpha/i })) - - const openCreateMenu = async () => { - fireEvent.click(await screen.findByText('menus.newApp')) - return screen.findByText('newApp.startFromBlank') + const user = userEvent.setup() + const clickCreateBranch = async (optionName: string) => { + const { unmount } = renderNav() + await user.click(screen.getByRole('button', { name: /Alpha/i })) + await user.hover(await screen.findByRole('menuitem', { name: /menus\.newApp/i })) + fireEvent.click(await screen.findByRole('menuitem', { name: optionName })) + unmount() } - await openCreateMenu() - fireEvent.click(await screen.findByText('newApp.startFromBlank')) - - await openCreateMenu() - fireEvent.click(await screen.findByText('newApp.startFromTemplate')) - - await openCreateMenu() - fireEvent.click(await screen.findByText('importDSL')) + await clickCreateBranch('newApp.startFromBlank') + await clickCreateBranch('newApp.startFromTemplate') + await clickCreateBranch('importDSL') expect(mockOnCreate).toHaveBeenNthCalledWith(1, 'blank') expect(mockOnCreate).toHaveBeenNthCalledWith(2, 'template') expect(mockOnCreate).toHaveBeenNthCalledWith(3, 'dsl') + expect(mockOnCreate).toHaveBeenCalledTimes(3) }) it('keeps the current nav label in sync with prop updates', async () => { diff --git a/web/app/account/(commonLayout)/avatar.tsx b/web/app/account/(commonLayout)/avatar.tsx index ccae182c9a..3fefb8a319 100644 --- a/web/app/account/(commonLayout)/avatar.tsx +++ b/web/app/account/(commonLayout)/avatar.tsx @@ -1,11 +1,13 @@ 'use client' -import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react' import { Avatar } from '@langgenius/dify-ui/avatar' +import { cn } from '@langgenius/dify-ui/cn' import { - RiGraduationCapFill, -} from '@remixicon/react' + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from '@langgenius/dify-ui/dropdown-menu' import { useSuspenseQuery } from '@tanstack/react-query' -import { Fragment } from 'react' import { useTranslation } from 'react-i18next' import { resetUser } from '@/app/components/base/amplitude/utils' import { LogOut01 } from '@/app/components/base/icons/src/vender/line/general' @@ -38,73 +40,48 @@ export default function AppSelector() { } return ( -