From 8581a68174642685374fdea6a1f321e0bdb244d2 Mon Sep 17 00:00:00 2001 From: Coding On Star <447357187@qq.com> Date: Sat, 9 May 2026 18:33:25 +0800 Subject: [PATCH] refactor(web): drop headless-ui, migrate overlay to dify-ui (#35963) Co-authored-by: CodingOnStar Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: yyh Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com> --- eslint-suppressions.json | 364 +++--------------- packages/dify-ui/src/dialog/index.tsx | 2 +- pnpm-lock.yaml | 131 ------- pnpm-workspace.yaml | 1 - .../apps/app-card-operations-flow.test.tsx | 22 -- .../develop/api-key-management-flow.test.tsx | 4 +- .../header/account-dropdown-flow.test.tsx | 1 + web/__tests__/header/nav-flow.test.tsx | 77 ---- .../(appDetailLayout)/[appId]/layout-main.tsx | 5 + .../delete-account/components/feed-back.tsx | 50 ++- .../(commonLayout)/delete-account/index.tsx | 42 +- .../app-sidebar/__tests__/index.spec.tsx | 3 + .../__tests__/app-info-detail-panel.spec.tsx | 25 +- .../__tests__/use-app-info-actions.spec.ts | 21 + .../app-info/app-info-detail-drawer.tsx | 34 ++ .../app-info/app-info-detail-panel.tsx | 15 +- .../components/app-sidebar/app-info/index.tsx | 84 +++- .../app-info/use-app-info-actions.ts | 80 +++- .../app-sidebar/app-sidebar-dropdown.tsx | 17 +- web/app/components/app-sidebar/index.tsx | 20 +- .../batch-add-annotation-modal/index.tsx | 62 +-- .../header-opts/__tests__/index.spec.tsx | 118 ------ .../__tests__/access-control-dialog.spec.tsx | 1 + .../__tests__/access-control.spec.tsx | 29 -- .../access-control-dialog.tsx | 10 +- .../__tests__/version-info-modal.spec.tsx | 16 + .../app/app-publisher/version-info-modal.tsx | 83 ++-- .../__tests__/edit-modal.spec.tsx | 7 +- .../conversation-history/edit-modal.tsx | 66 ++-- .../config-var/config-modal/index.tsx | 64 +-- .../config/automatic/get-automatic-res.tsx | 269 ++++++------- .../code-generator/get-code-generator-res.tsx | 179 ++++----- .../params-config/__tests__/index.spec.tsx | 31 -- .../dataset-config/params-config/index.tsx | 52 +-- .../app/create-app-dialog-shell.tsx | 51 +++ .../__tests__/index.spec.tsx | 127 +----- .../app/create-app-dialog/index.tsx | 20 +- .../components/app/create-app-modal/index.tsx | 31 +- .../__tests__/index.spec.tsx | 81 +++- .../dsl-confirm-modal.tsx | 63 +-- .../app/create-from-dsl-modal/index.tsx | 226 +++++------ .../components/app/duplicate-modal/index.tsx | 69 ++-- .../components/app/switch-app-modal/index.tsx | 122 +++--- .../app/workflow-log/__tests__/list.spec.tsx | 3 +- .../components/base/app-icon-picker/index.tsx | 97 +++-- .../sidebar/__tests__/index.spec.tsx | 21 +- .../sidebar/__tests__/rename-modal.spec.tsx | 26 +- .../content-dialog/__tests__/index.spec.tsx | 59 --- .../base/content-dialog/index.stories.tsx | 119 ------ .../components/base/content-dialog/index.tsx | 40 -- .../date-picker/index.tsx | 2 - .../date-and-time-picker/index.stories.tsx | 2 - .../base/date-and-time-picker/types.ts | 1 - .../base/dialog/__tests__/index.spec.tsx | 138 ------- .../components/base/dialog/index.stories.tsx | 152 -------- web/app/components/base/dialog/index.tsx | 70 ---- .../base/drawer-plus/__tests__/index.spec.tsx | 3 +- .../base/drawer/__tests__/index.spec.tsx | 92 +++-- .../components/base/drawer/index.stories.tsx | 2 +- web/app/components/base/drawer/index.tsx | 142 +++---- .../components/base/emoji-picker/index.tsx | 72 ++-- ...spec.tsx => feature-panel-drawer.spec.tsx} | 59 ++- .../annotation-reply/config-param-modal.tsx | 91 +++-- .../new-feature-panel/dialog-wrapper.tsx | 57 --- .../feature-panel-drawer.tsx | 60 +++ .../base/features/new-feature-panel/index.tsx | 13 +- .../moderation/moderation-setting-modal.tsx | 292 +++++++------- .../__tests__/audio-preview.spec.tsx | 15 +- .../__tests__/pdf-preview.spec.tsx | 12 +- .../__tests__/video-preview.spec.tsx | 17 +- .../base/file-uploader/audio-preview.tsx | 60 +-- .../__tests__/file-item.spec.tsx | 2 +- .../__tests__/file-image-item.spec.tsx | 5 +- .../base/file-uploader/pdf-preview.tsx | 175 +++++---- .../base/file-uploader/video-preview.tsx | 59 +-- .../__tests__/index.spec.tsx | 3 +- .../fullscreen-modal/__tests__/index.spec.tsx | 214 ---------- .../base/fullscreen-modal/index.stories.tsx | 59 --- .../base/fullscreen-modal/index.tsx | 65 ---- .../image-gallery/__tests__/index.spec.tsx | 2 +- .../__tests__/audio-preview.spec.tsx | 2 +- .../__tests__/image-preview.spec.tsx | 14 +- .../__tests__/video-preview.spec.tsx | 2 +- .../base/image-uploader/audio-preview.tsx | 56 ++- .../base/image-uploader/image-preview.tsx | 275 +++++++------ .../base/image-uploader/video-preview.tsx | 54 ++- .../modal-like-wrap/__tests__/index.spec.tsx | 84 ---- .../base/modal-like-wrap/index.stories.tsx | 131 ------- .../components/base/modal-like-wrap/index.tsx | 62 --- .../base/modal/__tests__/index.spec.tsx | 172 --------- .../components/base/modal/index.stories.tsx | 128 ------ web/app/components/base/modal/index.tsx | 93 ----- .../plugins/hitl-input-block/component-ui.tsx | 32 +- .../plugins/hitl-input-block/input-field.tsx | 4 +- .../__tests__/index.spec.tsx | 8 +- .../plugins/shortcuts-popup-plugin/index.tsx | 12 +- .../annotation-full/__tests__/modal.spec.tsx | 26 +- .../billing/annotation-full/modal.tsx | 45 ++- .../image-list/__tests__/index.spec.tsx | 2 +- .../image-previewer/__tests__/index.spec.tsx | 11 +- .../datasets/common/image-previewer/index.tsx | 138 +++---- .../dsl-confirm-modal.tsx | 63 +-- .../hooks/__tests__/use-dsl-import.spec.tsx | 94 ++++- .../hooks/use-dsl-import.ts | 158 +++++--- .../create-from-dsl-modal/index.tsx | 92 +++-- .../template-card/__tests__/index.spec.tsx | 30 ++ .../list/template-card/index.tsx | 52 ++- .../empty-dataset-creation-modal/index.tsx | 41 +- .../__tests__/index.spec.tsx | 3 +- .../create/stop-embedding-modal/index.tsx | 41 +- .../documents/components/rename-modal.tsx | 40 +- .../completed/common/regeneration-modal.tsx | 24 +- .../__tests__/chunk-detail-modal.spec.tsx | 28 +- .../components/chunk-detail-modal.tsx | 165 ++++---- .../components/result-item-external.tsx | 33 +- .../datasets/metadata/base/date-picker.tsx | 1 - .../metadata/edit-metadata-batch/modal.tsx | 95 +++-- .../__tests__/create-content.spec.tsx | 198 ++++------ .../dataset-metadata-drawer.spec.tsx | 46 +-- .../metadata-dataset/create-content.tsx | 115 ++++-- .../create-metadata-modal.tsx | 1 - .../dataset-metadata-drawer.tsx | 207 ++++++---- .../select-metadata-modal.tsx | 17 +- .../metadata/metadata-document/info-group.tsx | 4 +- .../datasets/rename-modal/index.tsx | 60 +-- .../__tests__/secret-key-modal.spec.tsx | 32 +- .../secret-key/secret-key-generate.tsx | 43 ++- .../develop/secret-key/secret-key-modal.tsx | 162 ++++---- .../explore/try-app/__tests__/index.spec.tsx | 56 +++ web/app/components/explore/try-app/index.tsx | 97 ++--- .../account-about/__tests__/index.spec.tsx | 2 +- .../components/header/account-about/index.tsx | 155 ++++---- .../api-based-extension-page/modal.tsx | 76 ++-- .../model-load-balancing-modal.spec.tsx | 8 - .../model-load-balancing-modal.tsx | 210 +++++----- .../header/nav/__tests__/index.spec.tsx | 54 --- .../nav/nav-selector/__tests__/index.spec.tsx | 54 --- .../install-plugin/install-bundle/index.tsx | 43 ++- .../install-from-github/index.tsx | 138 +++---- .../install-from-local-package/index.tsx | 95 ++--- .../steps/__tests__/uploading.spec.tsx | 87 ++++- .../steps/uploading.tsx | 91 +++-- .../install-from-marketplace/index.tsx | 110 +++--- .../__tests__/schema-modal.spec.tsx | 13 +- .../plugins/plugin-mutation-model/index.tsx | 79 ++-- .../__tests__/plugin-info.spec.tsx | 10 +- .../plugins/plugin-page/plugin-info.tsx | 33 +- .../__tests__/index.spec.tsx | 35 +- .../auto-update-setting/index.tsx | 1 - .../plugins/reference-setting-modal/index.tsx | 107 ++--- .../components/__tests__/index.spec.tsx | 6 +- ...blish-as-knowledge-pipeline-modal.spec.tsx | 9 +- .../__tests__/update-dsl-modal.spec.tsx | 20 +- .../__tests__/version-mismatch-modal.spec.tsx | 4 +- .../publish-as-knowledge-pipeline-modal.tsx | 132 ++++--- .../components/update-dsl-modal.tsx | 117 +++--- .../components/version-mismatch-modal.tsx | 63 +-- .../__tests__/use-update-dsl-modal.spec.ts | 56 ++- .../hooks/use-update-dsl-modal.ts | 43 ++- .../share/text-generation/info-modal.tsx | 65 ++-- .../mcp/__tests__/mcp-server-modal.spec.tsx | 67 +++- .../components/tools/mcp/mcp-server-modal.tsx | 147 ++++--- web/app/components/tools/mcp/modal.tsx | 26 +- .../__tests__/update-dsl-modal.spec.tsx | 35 ++ .../workflow/header/online-users.tsx | 1 - .../http/components/authorization/index.tsx | 126 +++--- .../nodes/http/components/curl-panel.tsx | 51 +-- .../json-schema-config-modal/index.tsx | 27 +- .../__tests__/integration.spec.tsx | 15 +- .../components/extract-parameter/update.tsx | 119 +++--- .../__tests__/input-var-list.spec.tsx | 27 +- .../components/workflow/operator/index.tsx | 2 +- .../conversation-variable-modal.tsx | 144 ++++--- .../action-menu/index.tsx | 3 +- .../delete-confirm-modal.tsx | 57 ++- .../panel/version-history-panel/empty.tsx | 2 +- .../version-history-panel/filter/index.tsx | 1 + .../restore-confirm-modal.tsx | 57 ++- .../components/workflow/update-dsl-modal.tsx | 164 ++++---- .../education-apply/expire-notice-modal.tsx | 117 +++--- .../education-apply/verify-state-modal.tsx | 62 +-- web/eslint.constants.mjs | 10 + web/models/pipeline.ts | 1 + web/package.json | 1 - web/service/__tests__/use-pipeline.spec.tsx | 81 ++++ web/service/use-pipeline.ts | 4 +- web/vitest.setup.ts | 40 +- 187 files changed, 5333 insertions(+), 6395 deletions(-) create mode 100644 web/app/components/app-sidebar/app-info/app-info-detail-drawer.tsx create mode 100644 web/app/components/app/create-app-dialog-shell.tsx delete mode 100644 web/app/components/base/content-dialog/__tests__/index.spec.tsx delete mode 100644 web/app/components/base/content-dialog/index.stories.tsx delete mode 100644 web/app/components/base/content-dialog/index.tsx delete mode 100644 web/app/components/base/dialog/__tests__/index.spec.tsx delete mode 100644 web/app/components/base/dialog/index.stories.tsx delete mode 100644 web/app/components/base/dialog/index.tsx rename web/app/components/base/features/new-feature-panel/__tests__/{dialog-wrapper.spec.tsx => feature-panel-drawer.spec.tsx} (51%) delete mode 100644 web/app/components/base/features/new-feature-panel/dialog-wrapper.tsx create mode 100644 web/app/components/base/features/new-feature-panel/feature-panel-drawer.tsx delete mode 100644 web/app/components/base/fullscreen-modal/__tests__/index.spec.tsx delete mode 100644 web/app/components/base/fullscreen-modal/index.stories.tsx delete mode 100644 web/app/components/base/fullscreen-modal/index.tsx delete mode 100644 web/app/components/base/modal-like-wrap/__tests__/index.spec.tsx delete mode 100644 web/app/components/base/modal-like-wrap/index.stories.tsx delete mode 100644 web/app/components/base/modal-like-wrap/index.tsx delete mode 100644 web/app/components/base/modal/__tests__/index.spec.tsx delete mode 100644 web/app/components/base/modal/index.stories.tsx delete mode 100644 web/app/components/base/modal/index.tsx create mode 100644 web/service/__tests__/use-pipeline.spec.tsx diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 683e6b09fe..f7ff4f8d6d 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -159,21 +159,11 @@ "count": 5 } }, - "web/app/account/(commonLayout)/delete-account/components/feed-back.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/account/(commonLayout)/delete-account/components/verify-email.tsx": { "react/set-state-in-effect": { "count": 1 } }, - "web/app/account/(commonLayout)/delete-account/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/account/oauth/authorize/layout.tsx": { "ts/no-explicit-any": { "count": 1 @@ -211,9 +201,6 @@ "erasable-syntax-only/enums": { "count": 1 }, - "no-restricted-imports": { - "count": 1 - }, "react-refresh/only-export-components": { "count": 1 }, @@ -272,16 +259,16 @@ "count": 1 } }, + "web/app/components/app/app-access-control/add-member-or-group-pop.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, "web/app/components/app/app-publisher/features-wrapper.tsx": { "ts/no-explicit-any": { "count": 4 } }, - "web/app/components/app/app-publisher/version-info-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/app/configuration/base/var-highlight/index.tsx": { "react-refresh/only-export-components": { "count": 1 @@ -293,9 +280,6 @@ } }, "web/app/components/app/configuration/config-prompt/conversation-history/edit-modal.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -311,9 +295,6 @@ } }, "web/app/components/app/configuration/config-var/config-modal/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 4 } @@ -356,9 +337,6 @@ } }, "web/app/components/app/configuration/config/automatic/get-automatic-res.tsx": { - "no-restricted-imports": { - "count": 1 - }, "react/set-state-in-effect": { "count": 4 }, @@ -387,9 +365,6 @@ } }, "web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx": { - "no-restricted-imports": { - "count": 1 - }, "react/set-state-in-effect": { "count": 4 }, @@ -418,9 +393,6 @@ } }, "web/app/components/app/configuration/dataset-config/params-config/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, "react/set-state-in-effect": { "count": 1 } @@ -494,26 +466,10 @@ "count": 1 } }, - "web/app/components/app/create-app-modal/index.tsx": { - "react/set-state-in-effect": { - "count": 1 - }, - "ts/no-explicit-any": { - "count": 1 - } - }, - "web/app/components/app/create-from-dsl-modal/dsl-confirm-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/app/create-from-dsl-modal/index.tsx": { "erasable-syntax-only/enums": { "count": 1 }, - "no-restricted-imports": { - "count": 1 - }, "react-refresh/only-export-components": { "count": 1 }, @@ -521,11 +477,6 @@ "count": 2 } }, - "web/app/components/app/duplicate-modal/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/app/log/filter.tsx": { "react-refresh/only-export-components": { "count": 1 @@ -561,9 +512,6 @@ } }, "web/app/components/app/switch-app-modal/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, "react/set-state-in-effect": { "count": 1 } @@ -881,11 +829,6 @@ "count": 3 } }, - "web/app/components/base/content-dialog/index.stories.tsx": { - "react/set-state-in-effect": { - "count": 1 - } - }, "web/app/components/base/date-and-time-picker/hooks.ts": { "react/no-unnecessary-use-prefix": { "count": 2 @@ -901,11 +844,6 @@ "count": 1 } }, - "web/app/components/base/dialog/index.stories.tsx": { - "react/set-state-in-effect": { - "count": 1 - } - }, "web/app/components/base/drawer-plus/index.stories.tsx": { "react/component-hook-factories": { "count": 1 @@ -916,11 +854,6 @@ "count": 1 } }, - "web/app/components/base/emoji-picker/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/base/error-boundary/index.tsx": { "react-refresh/only-export-components": { "count": 3 @@ -942,11 +875,6 @@ "count": 1 } }, - "web/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/base/features/new-feature-panel/annotation-reply/index.tsx": { "ts/no-explicit-any": { "count": 3 @@ -973,9 +901,6 @@ } }, "web/app/components/base/features/new-feature-panel/moderation/moderation-setting-modal.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 2 } @@ -1544,16 +1469,6 @@ "count": 1 } }, - "web/app/components/base/modal-like-wrap/index.stories.tsx": { - "no-console": { - "count": 3 - } - }, - "web/app/components/base/modal/index.stories.tsx": { - "react/set-state-in-effect": { - "count": 1 - } - }, "web/app/components/base/new-audio-button/index.tsx": { "ts/no-explicit-any": { "count": 1 @@ -1600,6 +1515,11 @@ "count": 4 } }, + "web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, "web/app/components/base/prompt-editor/plugins/component-picker-block/menu.tsx": { "erasable-syntax-only/parameter-properties": { "count": 1 @@ -1685,8 +1605,8 @@ } }, "web/app/components/base/prompt-editor/plugins/shortcuts-popup-plugin/index.tsx": { - "ts/no-explicit-any": { - "count": 2 + "no-restricted-imports": { + "count": 1 } }, "web/app/components/base/prompt-editor/plugins/update-block.tsx": { @@ -1840,11 +1760,6 @@ "count": 4 } }, - "web/app/components/billing/annotation-full/modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/billing/billing-page/__tests__/index.spec.tsx": { "ts/no-explicit-any": { "count": 4 @@ -1908,11 +1823,6 @@ "count": 1 } }, - "web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/dsl-confirm-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/hooks/use-dsl-import.ts": { "erasable-syntax-only/enums": { "count": 1 @@ -1921,9 +1831,6 @@ "web/app/components/datasets/create-from-pipeline/create-options/create-from-dsl-modal/index.tsx": { "no-barrel-files/no-barrel-files": { "count": 1 - }, - "no-restricted-imports": { - "count": 1 } }, "web/app/components/datasets/create-from-pipeline/list/template-card/details/types.ts": { @@ -1931,16 +1838,6 @@ "count": 1 } }, - "web/app/components/datasets/create-from-pipeline/list/template-card/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/datasets/create/empty-dataset-creation-modal/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/create/file-preview/index.tsx": { "react/set-state-in-effect": { "count": 1 @@ -1995,11 +1892,6 @@ "count": 1 } }, - "web/app/components/datasets/create/stop-embedding-modal/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/create/website/firecrawl/index.tsx": { "no-console": { "count": 1 @@ -2058,11 +1950,6 @@ "count": 4 } }, - "web/app/components/datasets/documents/components/rename-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/documents/create-from-pipeline/data-source/base/credential-selector/__tests__/index.spec.tsx": { "erasable-syntax-only/enums": { "count": 1 @@ -2133,11 +2020,6 @@ "count": 1 } }, - "web/app/components/datasets/documents/detail/completed/common/regeneration-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/documents/detail/completed/components/segment-list-content.tsx": { "ts/no-non-null-asserted-optional-chain": { "count": 1 @@ -2212,21 +2094,21 @@ "count": 1 } }, + "web/app/components/datasets/formatted-text/flavours/edit-slice.tsx": { + "no-restricted-imports": { + "count": 2 + } + }, + "web/app/components/datasets/formatted-text/flavours/preview-slice.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, "web/app/components/datasets/formatted-text/flavours/type.ts": { "ts/no-empty-object-type": { "count": 1 } }, - "web/app/components/datasets/hit-testing/components/chunk-detail-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/datasets/hit-testing/components/result-item-external.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/hit-testing/components/score.tsx": { "unicorn/prefer-number-properties": { "count": 1 @@ -2245,11 +2127,6 @@ "count": 2 } }, - "web/app/components/datasets/metadata/edit-metadata-batch/modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/metadata/hooks/use-edit-dataset-metadata.ts": { "react/set-state-in-effect": { "count": 1 @@ -2263,36 +2140,11 @@ "count": 2 } }, - "web/app/components/datasets/metadata/metadata-dataset/create-content.tsx": { - "ts/no-explicit-any": { - "count": 1 - } - }, - "web/app/components/datasets/metadata/metadata-dataset/create-metadata-modal.tsx": { - "ts/no-explicit-any": { - "count": 1 - } - }, - "web/app/components/datasets/metadata/metadata-dataset/dataset-metadata-drawer.tsx": { - "no-restricted-imports": { - "count": 2 - } - }, - "web/app/components/datasets/metadata/metadata-dataset/select-metadata-modal.tsx": { - "erasable-syntax-only/enums": { - "count": 1 - } - }, "web/app/components/datasets/metadata/types.ts": { "erasable-syntax-only/enums": { "count": 2 } }, - "web/app/components/datasets/rename-modal/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/settings/chunk-structure/types.ts": { "erasable-syntax-only/enums": { "count": 1 @@ -2311,16 +2163,6 @@ "count": 2 } }, - "web/app/components/develop/secret-key/secret-key-generate.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/develop/secret-key/secret-key-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/explore/banner/banner-item.tsx": { "react-hooks-extra/no-direct-set-state-in-use-effect": { "count": 1 @@ -2342,11 +2184,6 @@ "count": 1 } }, - "web/app/components/explore/try-app/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/explore/try-app/tab.tsx": { "erasable-syntax-only/enums": { "count": 1 @@ -2426,16 +2263,6 @@ "count": 1 } }, - "web/app/components/header/account-about/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/header/account-setting/api-based-extension-page/modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/header/account-setting/data-source-page-new/card.tsx": { "ts/no-explicit-any": { "count": 2 @@ -2505,6 +2332,11 @@ "count": 4 } }, + "web/app/components/header/account-setting/model-provider-page/model-auth/authorized/index.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, "web/app/components/header/account-setting/model-provider-page/model-auth/hooks/index.ts": { "no-barrel-files/no-barrel-files": { "count": 6 @@ -2576,9 +2408,6 @@ } }, "web/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal.tsx": { - "no-restricted-imports": { - "count": 1 - }, "react/set-state-in-effect": { "count": 1 }, @@ -2620,9 +2449,6 @@ "erasable-syntax-only/enums": { "count": 1 }, - "no-restricted-imports": { - "count": 1 - }, "react-refresh/only-export-components": { "count": 1 } @@ -2638,9 +2464,6 @@ } }, "web/app/components/plugins/install-plugin/install-from-github/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 3 } @@ -2650,21 +2473,6 @@ "count": 1 } }, - "web/app/components/plugins/install-plugin/install-from-local-package/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx": { - "ts/no-explicit-any": { - "count": 2 - } - }, - "web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/plugins/marketplace/hooks.ts": { "@tanstack/query/exhaustive-deps": { "count": 1 @@ -2675,6 +2483,11 @@ "count": 1 } }, + "web/app/components/plugins/plugin-auth/authorized/index.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, "web/app/components/plugins/plugin-auth/authorized/item.tsx": { "ts/no-explicit-any": { "count": 1 @@ -2828,11 +2641,21 @@ "count": 7 } }, + "web/app/components/plugins/plugin-detail-panel/tool-selector/components/tool-base-form.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, "web/app/components/plugins/plugin-detail-panel/tool-selector/hooks/index.ts": { "no-barrel-files/no-barrel-files": { "count": 2 } }, + "web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, "web/app/components/plugins/plugin-detail-panel/trigger/event-detail-drawer.tsx": { "no-restricted-imports": { "count": 1 @@ -2846,11 +2669,6 @@ "count": 1 } }, - "web/app/components/plugins/plugin-mutation-model/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/plugins/plugin-page/context.ts": { "ts/no-explicit-any": { "count": 1 @@ -2866,21 +2684,11 @@ "count": 2 } }, - "web/app/components/plugins/plugin-page/plugin-info.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/plugins/reference-setting-modal/auto-update-setting/types.ts": { "erasable-syntax-only/enums": { "count": 2 } }, - "web/app/components/plugins/reference-setting-modal/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/plugins/types.ts": { "erasable-syntax-only/enums": { "count": 7 @@ -2963,11 +2771,6 @@ "count": 4 } }, - "web/app/components/rag-pipeline/components/publish-as-knowledge-pipeline-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/rag-pipeline/components/rag-pipeline-children.tsx": { "ts/no-explicit-any": { "count": 1 @@ -2983,16 +2786,6 @@ "count": 2 } }, - "web/app/components/rag-pipeline/components/update-dsl-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/rag-pipeline/components/version-mismatch-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/rag-pipeline/hooks/index.ts": { "no-barrel-files/no-barrel-files": { "count": 9 @@ -3048,11 +2841,6 @@ "count": 1 } }, - "web/app/components/share/text-generation/info-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/share/text-generation/menu-dropdown.tsx": { "react/set-state-in-effect": { "count": 1 @@ -3130,24 +2918,11 @@ "count": 1 } }, - "web/app/components/tools/mcp/mcp-server-modal.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "ts/no-explicit-any": { - "count": 5 - } - }, "web/app/components/tools/mcp/mcp-server-param-item.tsx": { "ts/no-explicit-any": { "count": 1 } }, - "web/app/components/tools/mcp/modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/tools/mcp/provider-card.tsx": { "ts/no-explicit-any": { "count": 3 @@ -3265,6 +3040,11 @@ "count": 1 } }, + "web/app/components/workflow/block-selector/main.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, "web/app/components/workflow/block-selector/market-place-plugin/action.tsx": { "react/set-state-in-effect": { "count": 1 @@ -3280,6 +3060,11 @@ "count": 1 } }, + "web/app/components/workflow/block-selector/tool-picker.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, "web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx": { "ts/no-explicit-any": { "count": 1 @@ -3843,16 +3628,6 @@ "count": 1 } }, - "web/app/components/workflow/nodes/http/components/authorization/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/workflow/nodes/http/components/curl-panel.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/http/components/key-value/key-value-edit/index.tsx": { "ts/no-explicit-any": { "count": 2 @@ -4034,11 +3809,6 @@ "count": 1 } }, - "web/app/components/workflow/nodes/llm/components/json-schema-config-modal/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-importer.tsx": { "ts/no-explicit-any": { "count": 3 @@ -4159,9 +3929,6 @@ } }, "web/app/components/workflow/nodes/parameter-extractor/components/extract-parameter/update.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -4395,6 +4162,9 @@ } }, "web/app/components/workflow/note-node/note-editor/plugins/link-editor-plugin/component.tsx": { + "no-restricted-imports": { + "count": 1 + }, "react/set-state-in-effect": { "count": 1 } @@ -4405,6 +4175,9 @@ } }, "web/app/components/workflow/operator/add-block.tsx": { + "no-restricted-imports": { + "count": 1 + }, "ts/no-explicit-any": { "count": 1 } @@ -4466,9 +4239,6 @@ } }, "web/app/components/workflow/panel/debug-and-preview/conversation-variable-modal.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 2 } @@ -4496,16 +4266,6 @@ "count": 4 } }, - "web/app/components/workflow/panel/version-history-panel/delete-confirm-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/workflow/panel/version-history-panel/restore-confirm-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow/panel/workflow-preview.tsx": { "ts/no-explicit-any": { "count": 2 @@ -4641,9 +4401,6 @@ } }, "web/app/components/workflow/update-dsl-modal.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } @@ -4757,11 +4514,6 @@ "count": 1 } }, - "web/app/education-apply/expire-notice-modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/education-apply/hooks.ts": { "react/set-state-in-effect": { "count": 5 diff --git a/packages/dify-ui/src/dialog/index.tsx b/packages/dify-ui/src/dialog/index.tsx index 24c5bcc463..dbb2448ff6 100644 --- a/packages/dify-ui/src/dialog/index.tsx +++ b/packages/dify-ui/src/dialog/index.tsx @@ -63,7 +63,7 @@ export function DialogContent({ /> =16.8.0' react-dom: '>=16.8.0' - '@floating-ui/react@0.26.28': - resolution: {integrity: sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==} - peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' - '@floating-ui/react@0.27.19': resolution: {integrity: sha512-31B8h5mm8YxotlE7/AU/PhNAl8eWxAmjL/v2QOxroDNkTFLk3Uu82u63N3b6TXa4EGJeeZLVcd/9AlNlVqzeog==} peerDependencies: @@ -2129,13 +2117,6 @@ packages: '@formatjs/intl-localematcher@0.8.6': resolution: {integrity: sha512-AZRgUxj0q93lyF7Z5lFS85bLINXuBLX4R3tCKicO6fSWo6cvh9GQfoR3B1WlsqQwefZ1QORTivhInx7gM6HUzQ==} - '@headlessui/react@2.2.10': - resolution: {integrity: sha512-5pVLNK9wlpxTUTy9GpgbX/SdcRh+HBnPktjM2wbiLTH4p+2EPHBO1aoSryUCuKUIItdDWO9ITlhUL8UnUN/oIA==} - engines: {node: '>=10'} - peerDependencies: - react: ^18 || ^19 || ^19.0.0-rc - react-dom: ^18 || ^19 || ^19.0.0-rc - '@heroicons/react@2.2.0': resolution: {integrity: sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==} peerDependencies: @@ -3373,43 +3354,6 @@ packages: '@types/react': optional: true - '@react-aria/focus@3.21.5': - resolution: {integrity: sha512-V18fwCyf8zqgJdpLQeDU5ZRNd9TeOfBbhLgmX77Zr5ae9XwaoJ1R3SFJG1wCJX60t34AW+aLZSEEK+saQElf3Q==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - - '@react-aria/interactions@3.27.1': - resolution: {integrity: sha512-M3wLpTTmDflI0QGNK0PJNUaBXXfeBXue8ZxLMngfc1piHNiH4G5lUvWd9W14XVbqrSCVY8i8DfGrNYpyyZu0tw==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - - '@react-aria/ssr@3.9.10': - resolution: {integrity: sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==} - engines: {node: '>= 12'} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - - '@react-aria/utils@3.33.1': - resolution: {integrity: sha512-kIx1Sj6bbAT0pdqCegHuPanR9zrLn5zMRiM7LN12rgRf55S19ptd9g3ncahArifYTRkfEU9VIn+q0HjfMqS9/w==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - - '@react-stately/flags@3.1.2': - resolution: {integrity: sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg==} - - '@react-stately/utils@3.11.0': - resolution: {integrity: sha512-8LZpYowJ9eZmmYLpudbo/eclIRnbhWIJZ994ncmlKlouNzKohtM8qTC6B1w1pwUbiwGdUoyzLuQbeaIor5Dvcw==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - - '@react-types/shared@3.33.1': - resolution: {integrity: sha512-oJHtjvLG43VjwemQDadlR5g/8VepK56B/xKO2XORPHt9zlW6IZs3tZrYlvH29BMvoqC7RtE7E5UjgbnbFtDGag==} - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - '@reactflow/background@11.3.14': resolution: {integrity: sha512-Gewd7blEVT5Lh6jqrvOgd4G6Qk17eGKQfsDXgyRSqM+CTwDqRldG2LsWN4sNeno6sbqVIC2fZ+rAUBFA9ZEUDA==} peerDependencies: @@ -3705,9 +3649,6 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - '@swc/helpers@0.5.20': - resolution: {integrity: sha512-2egEBHUMasdypIzrprsu8g+OEVd7Vp2MM3a2eVlM/cyFYto0nGz5BX5BTgh/ShZZI9ed+ozEq+Ngt+rgmUs8tw==} - '@t3-oss/env-core@0.13.11': resolution: {integrity: sha512-sM7GYY+KL7H/Hl0BE0inWfk3nRHZOLhmVn7sHGxaZt9FAR6KqREXAE+6TqKfiavfXmpRxO/OZ2QgKRd+oiBYRQ==} peerDependencies: @@ -9410,14 +9351,6 @@ snapshots: react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - '@floating-ui/react@0.26.28(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@floating-ui/utils': 0.2.11 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - tabbable: 6.4.0 - '@floating-ui/react@0.27.19(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -9434,16 +9367,6 @@ snapshots: dependencies: '@formatjs/fast-memoize': 3.1.4 - '@headlessui/react@2.2.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@floating-ui/react': 0.26.28(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@react-aria/focus': 3.21.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@react-aria/interactions': 3.27.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@tanstack/react-virtual': 3.13.24(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - use-sync-external-store: 1.6.0(react@19.2.6) - '@heroicons/react@2.2.0(react@19.2.6)': dependencies: react: 19.2.6 @@ -10469,55 +10392,6 @@ snapshots: optionalDependencies: '@types/react': 19.2.14 - '@react-aria/focus@3.21.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@react-aria/interactions': 3.27.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@react-aria/utils': 3.33.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@react-types/shared': 3.33.1(react@19.2.6) - '@swc/helpers': 0.5.20 - clsx: 2.1.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - - '@react-aria/interactions@3.27.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@react-aria/ssr': 3.9.10(react@19.2.6) - '@react-aria/utils': 3.33.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@react-stately/flags': 3.1.2 - '@react-types/shared': 3.33.1(react@19.2.6) - '@swc/helpers': 0.5.20 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - - '@react-aria/ssr@3.9.10(react@19.2.6)': - dependencies: - '@swc/helpers': 0.5.20 - react: 19.2.6 - - '@react-aria/utils@3.33.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@react-aria/ssr': 3.9.10(react@19.2.6) - '@react-stately/flags': 3.1.2 - '@react-stately/utils': 3.11.0(react@19.2.6) - '@react-types/shared': 3.33.1(react@19.2.6) - '@swc/helpers': 0.5.20 - clsx: 2.1.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - - '@react-stately/flags@3.1.2': - dependencies: - '@swc/helpers': 0.5.20 - - '@react-stately/utils@3.11.0(react@19.2.6)': - dependencies: - '@swc/helpers': 0.5.20 - react: 19.2.6 - - '@react-types/shared@3.33.1(react@19.2.6)': - dependencies: - react: 19.2.6 - '@reactflow/background@11.3.14(@types/react@19.2.14)(immer@11.1.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@reactflow/core': 11.11.4(@types/react@19.2.14)(immer@11.1.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -10888,10 +10762,6 @@ snapshots: dependencies: tslib: 2.8.1 - '@swc/helpers@0.5.20': - dependencies: - tslib: 2.8.1 - '@t3-oss/env-core@0.13.11(typescript@6.0.3)(valibot@1.3.1(typescript@6.0.3))(zod@4.4.3)': optionalDependencies: typescript: 6.0.3 @@ -16514,7 +16384,6 @@ time: '@eslint/js@10.0.1': '2026-02-06T22:34:56.290Z' '@floating-ui/react@0.27.19': '2026-03-03T03:02:09.664Z' '@formatjs/intl-localematcher@0.8.6': '2026-05-05T17:39:39.364Z' - '@headlessui/react@2.2.10': '2026-04-07T17:12:43.551Z' '@heroicons/react@2.2.0': '2024-11-18T15:33:27.317Z' '@hey-api/openapi-ts@0.97.1': '2026-05-04T00:37:14.271Z' '@hono/node-server@2.0.1': '2026-04-30T08:51:26.973Z' diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 2a8be97969..1373efd21e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -66,7 +66,6 @@ catalog: '@eslint/js': 10.0.1 '@floating-ui/react': 0.27.19 '@formatjs/intl-localematcher': 0.8.6 - '@headlessui/react': 2.2.10 '@heroicons/react': 2.2.0 '@hey-api/openapi-ts': 0.97.1 '@hono/node-server': 2.0.1 diff --git a/web/__tests__/apps/app-card-operations-flow.test.tsx b/web/__tests__/apps/app-card-operations-flow.test.tsx index ef3bee5167..8162f12dad 100644 --- a/web/__tests__/apps/app-card-operations-flow.test.tsx +++ b/web/__tests__/apps/app-card-operations-flow.test.tsx @@ -63,28 +63,6 @@ vi.mock('@tanstack/react-query', async (importOriginal) => { } }) -// Mock headless UI Popover so it renders content without transition -vi.mock('@headlessui/react', async () => { - const actual = await vi.importActual('@headlessui/react') - return { - ...actual, - Popover: ({ children, className }: { children: ((bag: { open: boolean }) => React.ReactNode) | React.ReactNode, className?: string }) => ( -
- {typeof children === 'function' ? children({ open: true }) : children} -
- ), - PopoverButton: ({ children, className, ref: _ref, ...rest }: Record) => ( - - ), - PopoverPanel: ({ children, className }: { children: ((bag: { close: () => void }) => React.ReactNode) | React.ReactNode, className?: string }) => ( -
- {typeof children === 'function' ? children({ close: vi.fn() }) : children} -
- ), - Transition: ({ children }: { children: React.ReactNode }) => <>{children}, - } -}) - vi.mock('@/next/dynamic', () => ({ default: (loader: () => Promise<{ default: React.ComponentType }>) => { let Component: React.ComponentType> | null = null diff --git a/web/__tests__/develop/api-key-management-flow.test.tsx b/web/__tests__/develop/api-key-management-flow.test.tsx index 188b8e6304..233e152f8f 100644 --- a/web/__tests__/develop/api-key-management-flow.test.tsx +++ b/web/__tests__/develop/api-key-management-flow.test.tsx @@ -13,7 +13,7 @@ import userEvent from '@testing-library/user-event' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import ApiServer from '@/app/components/develop/ApiServer' -// ---------- fake timers (HeadlessUI Dialog transitions) ---------- +// ---------- fake timers (modal transitions) ---------- beforeEach(() => { vi.useFakeTimers({ shouldAdvanceTime: true }) }) @@ -100,7 +100,7 @@ describe('API Key management flow', () => { }) await flushUI() - // SecretKeyModal should render with real HeadlessUI Dialog + // SecretKeyModal should render with real modal content await waitFor(() => { expect(screen.getByText('appApi.apiKeyModal.apiSecretKey')).toBeInTheDocument() expect(screen.getByText('appApi.apiKeyModal.apiSecretKeyTips')).toBeInTheDocument() diff --git a/web/__tests__/header/account-dropdown-flow.test.tsx b/web/__tests__/header/account-dropdown-flow.test.tsx index b4a3befea0..eb128924c0 100644 --- a/web/__tests__/header/account-dropdown-flow.test.tsx +++ b/web/__tests__/header/account-dropdown-flow.test.tsx @@ -131,6 +131,7 @@ describe('Header Account Dropdown Flow', () => { payload: ACCOUNT_SETTING_TAB.MEMBERS, }) + fireEvent.click(screen.getByRole('button', { name: 'common.account.account' })) fireEvent.click(screen.getByText('common.userProfile.about')) await waitFor(() => { diff --git a/web/__tests__/header/nav-flow.test.tsx b/web/__tests__/header/nav-flow.test.tsx index 58c95f0a01..dba7b4bf4a 100644 --- a/web/__tests__/header/nav-flow.test.tsx +++ b/web/__tests__/header/nav-flow.test.tsx @@ -13,83 +13,6 @@ const mockOnLoadMore = vi.fn() let mockSelectedSegment = 'app' let mockIsCurrentWorkspaceEditor = true -vi.mock('@headlessui/react', () => { - type MenuContextValue = { - open: boolean - setOpen: React.Dispatch> - } - const MenuContext = React.createContext(null) - - const Menu = ({ - children, - }: { - children: React.ReactNode | ((props: { open: boolean }) => React.ReactNode) - }) => { - const [open, setOpen] = React.useState(false) - const value = React.useMemo(() => ({ open, setOpen }), [open]) - - return ( - - {typeof children === 'function' ? children({ open }) : children} - - ) - } - - const MenuButton = ({ - children, - onClick, - ...props - }: React.ButtonHTMLAttributes) => { - const context = React.useContext(MenuContext) - - return ( - - ) - } - - const MenuItems = ({ - as: Component = 'div', - children, - ...props - }: { - as?: React.ElementType - children: React.ReactNode - } & Record) => { - const context = React.useContext(MenuContext) - if (!context?.open) - return null - - return {children} - } - - const MenuItem = ({ - as: Component = 'div', - children, - ...props - }: { - as?: React.ElementType - children: React.ReactNode - } & Record) => {children} - - return { - Menu, - MenuButton, - MenuItems, - MenuItem, - Transition: ({ children }: { children: React.ReactNode }) => <>{children}, - } -}) - vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string) => key, diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout-main.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout-main.tsx index 46d7f7833e..1e001a5ca4 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout-main.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout-main.tsx @@ -19,6 +19,8 @@ import { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { useShallow } from 'zustand/react/shallow' import AppSideBar from '@/app/components/app-sidebar' +import { AppInfoDetailLayer } from '@/app/components/app-sidebar/app-info' +import { useAppInfoActions } from '@/app/components/app-sidebar/app-info/use-app-info-actions' import { useStore } from '@/app/components/app/store' import Loading from '@/app/components/base/loading' import { useAppContext } from '@/context/app-context' @@ -45,6 +47,7 @@ const AppDetailLayout: FC = (props) => { const media = useBreakpoints() const isMobile = media === MediaType.mobile const { isCurrentWorkspaceEditor, isLoadingCurrentWorkspace, currentWorkspace } = useAppContext() + const appInfoActions = useAppInfoActions({ resetKey: appId }) const { appDetail, setAppDetail, setAppSidebarExpand } = useStore(useShallow(state => ({ appDetail: state.appDetail, setAppDetail: state.setAppDetail, @@ -162,11 +165,13 @@ const AppDetailLayout: FC = (props) => { {appDetail && ( )}
{children}
+ ) } diff --git a/web/app/account/(commonLayout)/delete-account/components/feed-back.tsx b/web/app/account/(commonLayout)/delete-account/components/feed-back.tsx index ee1e72e6e7..5b68290dd0 100644 --- a/web/app/account/(commonLayout)/delete-account/components/feed-back.tsx +++ b/web/app/account/(commonLayout)/delete-account/components/feed-back.tsx @@ -1,9 +1,9 @@ 'use client' import { Button } from '@langgenius/dify-ui/button' +import { Dialog, DialogContent, DialogTitle } from '@langgenius/dify-ui/dialog' import { toast } from '@langgenius/dify-ui/toast' import { useCallback, useState } from 'react' import { useTranslation } from 'react-i18next' -import CustomDialog from '@/app/components/base/dialog' import Textarea from '@/app/components/base/textarea' import { useAppContext } from '@/context/app-context' import { useRouter } from '@/next/navigation' @@ -47,26 +47,34 @@ export default function FeedBack(props: DeleteAccountProps) { handleSuccess() }, [handleSuccess, props]) return ( - { + if (!open) + props.onCancel() + }} > - - + +
+
- {latestParams.length > 0 && ( -
-
-
{t('mcp.server.modal.parameters', { ns: 'tools' })}
- -
-
{t('mcp.server.modal.parametersTip', { ns: 'tools' })}
-
- {latestParams.map(paramItem => ( - handleParamChange(paramItem.variable, value)} - /> - ))} +
+ {!data ? t('mcp.server.modal.addTitle', { ns: 'tools' }) : t('mcp.server.modal.editTitle', { ns: 'tools' })} +
+
+
+
+
{t('mcp.server.modal.description', { ns: 'tools' })}
+
*
+
- )} -
-
- - -
- + {latestParams.length > 0 && ( +
+
+
{t('mcp.server.modal.parameters', { ns: 'tools' })}
+ +
+
{t('mcp.server.modal.parametersTip', { ns: 'tools' })}
+
+ {latestParams.map((paramItem) => { + if (!paramItem.variable) + return null + + const { variable } = paramItem + + return ( + handleParamChange(variable, value)} + /> + ) + })} +
+
+ )} +
+
+ + +
+ + ) } diff --git a/web/app/components/tools/mcp/modal.tsx b/web/app/components/tools/mcp/modal.tsx index 165535127d..79179ae3dc 100644 --- a/web/app/components/tools/mcp/modal.tsx +++ b/web/app/components/tools/mcp/modal.tsx @@ -4,17 +4,15 @@ import type { AppIconSelection } from '@/app/components/base/app-icon-picker' import type { ToolWithProvider } from '@/app/components/workflow/types' import type { AppIconType } from '@/types/app' import { Button } from '@langgenius/dify-ui/button' -import { cn } from '@langgenius/dify-ui/cn' +import { Dialog, DialogContent } from '@langgenius/dify-ui/dialog' import { toast } from '@langgenius/dify-ui/toast' import { RiCloseLine, RiEditLine } from '@remixicon/react' import { useHover } from 'ahooks' -import { noop } from 'es-toolkit/function' import { useTranslation } from 'react-i18next' import AppIcon from '@/app/components/base/app-icon' import AppIconPicker from '@/app/components/base/app-icon-picker' import { Mcp } from '@/app/components/base/icons/src/vender/other' import Input from '@/app/components/base/input' -import Modal from '@/app/components/base/modal' import TabSlider from '@/app/components/base/tab-slider' import { MCPAuthMethod } from '@/app/components/tools/types' import { shouldUseMcpIconForAppIcon } from '@/utils/mcp' @@ -281,18 +279,16 @@ const MCPModal: FC = ({ const formKey = data?.id ?? 'create' return ( - - - + + + + + ) } diff --git a/web/app/components/workflow/__tests__/update-dsl-modal.spec.tsx b/web/app/components/workflow/__tests__/update-dsl-modal.spec.tsx index 241cd7d762..684c700648 100644 --- a/web/app/components/workflow/__tests__/update-dsl-modal.spec.tsx +++ b/web/app/components/workflow/__tests__/update-dsl-modal.spec.tsx @@ -126,6 +126,15 @@ describe('UpdateDSLModal', () => { expect(defaultProps.onBackup).toHaveBeenCalledTimes(1) }) + it('should call cancel handler when the import dialog requests close', () => { + const onCancel = vi.fn() + renderModal({ ...defaultProps, onCancel }) + + fireEvent.keyDown(document, { key: 'Escape', code: 'Escape' }) + + expect(onCancel).toHaveBeenCalledTimes(1) + }) + it('should import a valid file and emit workflow update payload', async () => { renderModal() @@ -228,6 +237,32 @@ describe('UpdateDSLModal', () => { }) }) + it('should close the pending modal when dialog requests close', async () => { + mockImportDSL.mockResolvedValue({ + id: 'import-8', + status: DSLImportStatus.PENDING, + imported_dsl_version: '1.0.0', + current_dsl_version: '2.0.0', + }) + + renderModal() + + fireEvent.change(screen.getByTestId('dsl-file-input'), { + target: { files: [new File(['workflow'], 'workflow.yml', { type: 'text/yaml' })] }, + }) + fireEvent.click(screen.getByRole('button', { name: 'workflow.common.overwriteAndImport' })) + + await waitFor(() => { + expect(screen.getByRole('button', { name: 'app.newApp.Confirm' })).toBeInTheDocument() + }) + + fireEvent.keyDown(document, { key: 'Escape', code: 'Escape' }) + + await waitFor(() => { + expect(screen.queryByRole('button', { name: 'app.newApp.Confirm' })).not.toBeInTheDocument() + }) + }) + it('should show an error when the selected file content is invalid for the current app mode', async () => { class InvalidDSLFileReader extends MockFileReader { override readAsText(_file: Blob) { diff --git a/web/app/components/workflow/header/online-users.tsx b/web/app/components/workflow/header/online-users.tsx index 17e1de3feb..93e9d1fa85 100644 --- a/web/app/components/workflow/header/online-users.tsx +++ b/web/app/components/workflow/header/online-users.tsx @@ -189,7 +189,6 @@ const OnlineUsers = () => { placement="bottom-start" sideOffset={8} alignOffset={-48} - className="z-[9999]" popupClassName={cn( 'mt-1.5 flex max-h-[200px] w-[240px] flex-col overflow-y-auto', 'rounded-xl border-[0.5px] border-components-panel-border', diff --git a/web/app/components/workflow/nodes/http/components/authorization/index.tsx b/web/app/components/workflow/nodes/http/components/authorization/index.tsx index b72e52911d..684f943d5f 100644 --- a/web/app/components/workflow/nodes/http/components/authorization/index.tsx +++ b/web/app/components/workflow/nodes/http/components/authorization/index.tsx @@ -4,12 +4,12 @@ import type { Authorization as AuthorizationPayloadType } from '../../types' import type { Var } from '@/app/components/workflow/types' import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' +import { Dialog, DialogContent, DialogTitle } from '@langgenius/dify-ui/dialog' import { produce } from 'immer' import * as React from 'react' import { useCallback, useState } from 'react' import { useTranslation } from 'react-i18next' import BaseInput from '@/app/components/base/input' -import Modal from '@/app/components/base/modal' import Input from '@/app/components/workflow/nodes/_base/components/input-support-select-var' import useAvailableVarList from '@/app/components/workflow/nodes/_base/hooks/use-available-var-list' import { VarType } from '@/app/components/workflow/types' @@ -115,70 +115,78 @@ const Authorization: FC = ({ onHide() }, [tempPayload, onChange, onHide]) return ( - { + if (!open) + onHide() + }} > -
-
- - - + + + {t(`${i18nPrefix}.authorization`, { ns: 'workflow' })} + - {tempPayload.type === AuthorizationType.apiKey && ( - <> - - - - {tempPayload.config?.type === APIType.custom && ( - - +
+ + + + + {tempPayload.type === AuthorizationType.apiKey && ( + <> + + - )} + {tempPayload.config?.type === APIType.custom && ( + + + + )} - -
- -
-
- - )} + +
+ +
+
+ + )} +
+
+ + +
-
- - -
-
-
+ + ) } export default React.memo(Authorization) diff --git a/web/app/components/workflow/nodes/http/components/curl-panel.tsx b/web/app/components/workflow/nodes/http/components/curl-panel.tsx index 8ba5fb36a9..87dc2a3427 100644 --- a/web/app/components/workflow/nodes/http/components/curl-panel.tsx +++ b/web/app/components/workflow/nodes/http/components/curl-panel.tsx @@ -2,11 +2,11 @@ import type { FC } from 'react' import type { HttpNodeType } from '../types' import { Button } from '@langgenius/dify-ui/button' +import { Dialog, DialogContent, DialogTitle } from '@langgenius/dify-ui/dialog' import { toast } from '@langgenius/dify-ui/toast' import * as React from 'react' import { useCallback, useState } from 'react' import { useTranslation } from 'react-i18next' -import Modal from '@/app/components/base/modal' import Textarea from '@/app/components/base/textarea' import { useNodesInteractions } from '@/app/components/workflow/hooks' import { parseCurl } from './curl-parser' @@ -42,28 +42,35 @@ const CurlPanel: FC = ({ nodeId, isShow, onHide, handleCurlImport }) => { }, [onHide, nodeId, inputString, handleNodeSelect, handleCurlImport]) return ( - { + if (!open) + onHide() + }} > -
-