diff --git a/oxlint-suppressions.json b/oxlint-suppressions.json index 80f50724af9..c71ba7bc5ef 100644 --- a/oxlint-suppressions.json +++ b/oxlint-suppressions.json @@ -3017,11 +3017,6 @@ "count": 2 } }, - "web/app/components/integrations/index.tsx": { - "better-tailwindcss/enforce-logical-properties": { - "count": 4 - } - }, "web/app/components/integrations/sidebar-nav-item.tsx": { "better-tailwindcss/enforce-logical-properties": { "count": 2 @@ -3463,11 +3458,6 @@ "count": 2 } }, - "web/app/components/plugins/plugin-page/plugins-panel-results.tsx": { - "better-tailwindcss/enforce-logical-properties": { - "count": 1 - } - }, "web/app/components/plugins/plugin-tags-filter/compact-trigger.tsx": { "better-tailwindcss/enforce-logical-properties": { "count": 4 @@ -6451,11 +6441,6 @@ "count": 2 } }, - "web/features/agent-v2/roster/components/agent-roster-list.tsx": { - "better-tailwindcss/enforce-logical-properties": { - "count": 5 - } - }, "web/features/agent-v2/roster/components/agent-workflow-references-menu.tsx": { "better-tailwindcss/enforce-logical-properties": { "count": 1 @@ -6776,11 +6761,6 @@ "count": 13 } }, - "web/features/skills/page.tsx": { - "better-tailwindcss/enforce-logical-properties": { - "count": 4 - } - }, "web/features/tag-management/components/tag-filter.tsx": { "better-tailwindcss/enforce-logical-properties": { "count": 3 diff --git a/web/app/components/apps/list.tsx b/web/app/components/apps/list.tsx index 32b052748b4..f98f3ecd5fb 100644 --- a/web/app/components/apps/list.tsx +++ b/web/app/components/apps/list.tsx @@ -4,13 +4,6 @@ import type { GetAppsData } from '@dify/contracts/api/console/apps/types.gen' import type { RecommendedAppResponse } from '@dify/contracts/api/console/explore/types.gen' import type { AppListCreationDialog } from './app-list-creation-modals' import type { AppListUrlQuery } from './query-params' -import { - ScrollArea, - ScrollAreaContent, - ScrollAreaScrollbar, - ScrollAreaThumb, - ScrollAreaViewport, -} from '@langgenius/dify-ui/scroll-area' import { useDebounce } from 'ahooks' import { useAtomValue } from 'jotai' import { throttle, useQueryStates } from 'nuqs' @@ -132,57 +125,44 @@ export function List({ onCreateLearnDify, onTryLearnDify }: Props) {
)} - - -
- - - - - - - - - - +
+ +
diff --git a/web/app/components/integrations/index.tsx b/web/app/components/integrations/index.tsx index 18efdc41af2..8483e1894ad 100644 --- a/web/app/components/integrations/index.tsx +++ b/web/app/components/integrations/index.tsx @@ -19,13 +19,6 @@ import { DrawerViewport, } from '@langgenius/dify-ui/drawer' import { IconButton } from '@langgenius/dify-ui/icon-button' -import { - ScrollArea, - ScrollAreaContent, - ScrollAreaScrollbar, - ScrollAreaThumb, - ScrollAreaViewport, -} from '@langgenius/dify-ui/scroll-area' import { Suspense, useId, useRef, useState, useSyncExternalStore } from 'react' import { useTranslation } from 'react-i18next' import { UpdateSettingDialog } from '@/app/components/header/account-setting/update-setting-dialog' @@ -278,7 +271,7 @@ export default function IntegrationsPage({ 'flex shrink-0 flex-col bg-components-panel-bg px-2 py-2 transition-[width]', isCompact ? 'h-full w-full items-stretch overflow-y-auto' - : 'w-50 items-end border-r border-divider-burn', + : 'w-50 items-end border-e border-divider-burn', )} data-step-by-step-tour-target={STEP_BY_STEP_TOUR_TARGETS.integration} > @@ -287,7 +280,7 @@ export default function IntegrationsPage({ >
@@ -328,7 +321,7 @@ export default function IntegrationsPage({ > {toolsNavItemContent} - + {toolItems.map((item) => (
) : ( - - - - - - - - - - - - +
+ + + +
)}
diff --git a/web/app/components/integrations/section-layout.tsx b/web/app/components/integrations/section-layout.tsx index 602aac5ac31..2c6ae07c960 100644 --- a/web/app/components/integrations/section-layout.tsx +++ b/web/app/components/integrations/section-layout.tsx @@ -1,13 +1,6 @@ 'use client' import type { ReactNode } from 'react' -import { - ScrollArea, - ScrollAreaContent, - ScrollAreaScrollbar, - ScrollAreaThumb, - ScrollAreaViewport, -} from '@langgenius/dify-ui/scroll-area' type IntegrationSectionLayoutProps = { bodyClassName?: string @@ -21,19 +14,12 @@ export function IntegrationSectionLayout({ label, }: IntegrationSectionLayoutProps) { return ( - - - -
{children}
-
-
- - - -
+
+
{children}
+
) } diff --git a/web/app/components/integrations/tool-provider-list.tsx b/web/app/components/integrations/tool-provider-list.tsx index d3ad4fd87f9..30ab5710582 100644 --- a/web/app/components/integrations/tool-provider-list.tsx +++ b/web/app/components/integrations/tool-provider-list.tsx @@ -4,13 +4,6 @@ import type { ToolCategory } from '@/app/components/integrations/routes' import type { ToolsContentInset } from '@/app/components/tools/content-inset' import type { Collection } from '@/app/components/tools/types' import { cn } from '@langgenius/dify-ui/cn' -import { - ScrollArea, - ScrollAreaContent, - ScrollAreaScrollbar, - ScrollAreaThumb, - ScrollAreaViewport, -} from '@langgenius/dify-ui/scroll-area' import { useQuery } from '@tanstack/react-query' import { useCallback, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -198,69 +191,62 @@ const ProviderList = ({ category, contentInset = 'default', layout }: ProviderLi const body = ( <>
- - $['menus.tools'], { ns: 'navigation' })} - className="overscroll-contain" - role="region" - > - - {activeTab !== 'mcp' && ( - 0} - isLoading={isCollectionListLoading} - useIntegrationsCard={contentInset === 'compact'} - isSearchResultEmpty={isCollectionSearchEmpty} - showCreateCard={shouldShowCustomToolCreateCard} - onRefreshData={refetch} - onSelectProvider={setCurrentProviderId} - /> - )} - {!isCollectionListLoading && - !activeTabCollectionList.length && - activeTab === 'builtin' && ( - $.noTools, { ns: 'tools' })} - className={cn('h-56 shrink-0', toolListFrameClassName)} - /> - )} - {isCollectionSearchEmpty && activeTab === 'builtin' && ( -
- )} - {marketplace && activeTab === 'builtin' && ( - - )} - {activeTab === 'mcp' && ( - - )} - - - - - - +
$['menus.tools'], { ns: 'navigation' })} + className="flex min-h-0 grow flex-col overflow-y-auto overscroll-contain bg-components-panel-bg" + role="region" + > + {activeTab !== 'mcp' && ( + 0} + isLoading={isCollectionListLoading} + useIntegrationsCard={contentInset === 'compact'} + isSearchResultEmpty={isCollectionSearchEmpty} + showCreateCard={shouldShowCustomToolCreateCard} + onRefreshData={refetch} + onSelectProvider={setCurrentProviderId} + /> + )} + {!isCollectionListLoading && + !activeTabCollectionList.length && + activeTab === 'builtin' && ( + $.noTools, { ns: 'tools' })} + className={cn('h-56 shrink-0', toolListFrameClassName)} + /> + )} + {isCollectionSearchEmpty && activeTab === 'builtin' && ( +
+ )} + {marketplace && activeTab === 'builtin' && ( + + )} + {activeTab === 'mcp' && ( + + )} +
{currentProvider && !currentProvider.plugin_id && ( + <>
{isFetching ? t(($) => $.loading, { ns: 'common' }) @@ -134,85 +122,82 @@ const PluginsPanelResults = ({ (hasVisibleBuiltinTools ? filteredBuiltinTools.length : 0), })}
- - - {showCategoryEmptyState && categoryEmptyState && ( - - )} - {(hasVisiblePlugins || hasVisibleBuiltinTools) && ( - - {filteredBuiltinTools.map((collection, index) => ( - - ))} - - )} - {!isLastPage && ( -
- {isFetching ? ( - - ) : autoLoadNextPage ? null : ( - - )} - {autoLoadNextPage && ( -
- )} -
- )} - {marketplace && hasToolMarketplacePanel && ( - - )} - {marketplace && categoryMarketplace && ( - - )} - - - - - - + {showCategoryEmptyState && categoryEmptyState && ( + + )} + {(hasVisiblePlugins || hasVisibleBuiltinTools) && ( + + {filteredBuiltinTools.map((collection, index) => ( + + ))} + + )} + {!isLastPage && ( +
+ {isFetching ? ( + + ) : autoLoadNextPage ? null : ( + + )} + {autoLoadNextPage && ( +
+ )} +
+ )} + {marketplace && hasToolMarketplacePanel && ( + + )} + {marketplace && categoryMarketplace && ( + + )} +
+ ) } diff --git a/web/features/agent-v2/__tests__/delete-agent.browser.spec.tsx b/web/features/agent-v2/__tests__/delete-agent.browser.spec.tsx index 6dc5b463912..96406bb5fcd 100644 --- a/web/features/agent-v2/__tests__/delete-agent.browser.spec.tsx +++ b/web/features/agent-v2/__tests__/delete-agent.browser.spec.tsx @@ -180,7 +180,9 @@ it('focuses the next card without moving the roster scroll position', async () = const targetName = 'Agent 15' const { screen, queryClient, openDelete } = await setup(agents) try { - const viewport = screen.getByRole('region', { name: 'Agents', exact: true }).element() + const viewport = screen + .getByRole('region', { name: 'Agents', exact: true }) + .element().parentElement! await expect.poll(() => viewport.scrollHeight).toBeGreaterThan(viewport.clientHeight) viewport.scrollTo({ top: 600 }) await expect.poll(() => viewport.scrollTop).toBeGreaterThan(0) diff --git a/web/features/agent-v2/roster/components/agent-roster-list.tsx b/web/features/agent-v2/roster/components/agent-roster-list.tsx index 93c5d8e90be..0759c16abeb 100644 --- a/web/features/agent-v2/roster/components/agent-roster-list.tsx +++ b/web/features/agent-v2/roster/components/agent-roster-list.tsx @@ -1,8 +1,7 @@ 'use client' import type { AgentAppPartial } from '@dify/contracts/api/console/agent/types.gen' -import type { ScrollAreaViewportProps } from '@langgenius/dify-ui/scroll-area' -import type { RefObject } from 'react' +import type { ComponentProps, RefObject } from 'react' import { AlertDialog, AlertDialogContent, @@ -19,13 +18,6 @@ import { } from '@langgenius/dify-ui/context-menu' import { IconButton } from '@langgenius/dify-ui/icon-button' import { Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger } from '@langgenius/dify-ui/menu' -import { - ScrollArea, - ScrollAreaContent, - ScrollAreaScrollbar, - ScrollAreaThumb, - ScrollAreaViewport, -} from '@langgenius/dify-ui/scroll-area' import { useMutation } from '@tanstack/react-query' import { useId, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -63,7 +55,7 @@ export type AgentRosterListState = type AgentRosterListProps = { state: AgentRosterListState -} & Pick +} & Pick, 'aria-labelledby'> type DeleteAgentDialogPayload = Pick & { fallbackFocus: RefObject @@ -106,9 +98,9 @@ function AgentRosterSkeleton() {
-
+
- +
))} @@ -412,7 +404,7 @@ function AgentRosterItem({
)} -
+
{hasPublishedReferences ? ( createAlertDialogHandle()) - const scrollViewportRef = useRef(null) + const regionRef = useRef(null) const deletion = useMutation( consoleQuery.agent.byAgentId.delete.mutationOptions({ context: { silent: true } }), ) return ( <> - - - + {state.status === 'pending' && ( +
+ +
+ )} + {state.status === 'error' && ( + $['roster.loadingError'], { ns: 'agentRoster' })} + /> + )} + {state.status === 'ready' && state.agents.length === 0 && ( + $['roster.emptySearch'], { ns: 'agentRoster' }) + : t(($) => $['roster.empty'], { ns: 'agentRoster' }) + } + /> + )} + {state.status === 'ready' && state.agents.length > 0 && ( +
    $['roster.listLabel'])} + className={AGENT_ROSTER_GRID_CLASS_NAME} > - {state.status === 'pending' && ( -
    - -
    - )} - {state.status === 'error' && ( - $['roster.loadingError'], { ns: 'agentRoster' })} + {state.agents.map((agent) => ( + { + deleteDialog.openWithPayload({ + id: agent.id, + name: agent.name, + adjacentFocusTargets: getAdjacentFocusTargets(item, (sibling) => + sibling.querySelector(':scope > a[href], :scope > button'), + ), + fallbackFocus: { current: null }, + }) + }} /> - )} - {state.status === 'ready' && state.agents.length === 0 && ( - $['roster.emptySearch'], { ns: 'agentRoster' }) - : t(($) => $['roster.empty'], { ns: 'agentRoster' }) - } - /> - )} - {state.status === 'ready' && state.agents.length > 0 && ( -
      $['roster.listLabel'])} - className={AGENT_ROSTER_GRID_CLASS_NAME} - > - {state.agents.map((agent) => ( - { - deleteDialog.openWithPayload({ - id: agent.id, - name: agent.name, - adjacentFocusTargets: getAdjacentFocusTargets(item, (sibling) => - sibling.querySelector(':scope > a[href], :scope > button'), - ), - fallbackFocus: { current: null }, - }) - }} - /> - ))} -
    - )} - {state.status === 'ready' && state.footer.status === 'error' && ( -
    - {t(($) => $['roster.loadingError'], { ns: 'agentRoster' })} - -
    - )} - {state.status === 'ready' && state.footer.status === 'load-more' && ( -
    - -
    - )} - - - - - - + ))} +
+ )} + {state.status === 'ready' && state.footer.status === 'error' && ( +
+ {t(($) => $['roster.loadingError'], { ns: 'agentRoster' })} + +
+ )} + {state.status === 'ready' && state.footer.status === 'load-more' && ( +
+ +
+ )} +
{ @@ -593,7 +575,7 @@ export function AgentRosterList({ { params: { agent_id: payload.id } }, { onSuccess: () => { - payload.fallbackFocus.current = scrollViewportRef.current + payload.fallbackFocus.current = regionRef.current deleteDialog.close() }, }, diff --git a/web/features/agent-v2/roster/page.tsx b/web/features/agent-v2/roster/page.tsx index 3e8382f25cf..cd46aa67edf 100644 --- a/web/features/agent-v2/roster/page.tsx +++ b/web/features/agent-v2/roster/page.tsx @@ -99,8 +99,8 @@ export default function RosterPage() { useDocumentTitle(pageTitle) return ( -
-
+
+

-
- -
+
) } diff --git a/web/features/skills/page.tsx b/web/features/skills/page.tsx index c2cf4ae4d83..403a6d7d8e4 100644 --- a/web/features/skills/page.tsx +++ b/web/features/skills/page.tsx @@ -31,13 +31,6 @@ import { Field, FieldLabel } from '@langgenius/dify-ui/field' import { IconButton } from '@langgenius/dify-ui/icon-button' import { InputGroup, InputGroupAddon, InputGroupInput } from '@langgenius/dify-ui/input-group' import { Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger } from '@langgenius/dify-ui/menu' -import { - ScrollArea, - ScrollAreaContent, - ScrollAreaScrollbar, - ScrollAreaThumb, - ScrollAreaViewport, -} from '@langgenius/dify-ui/scroll-area' import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { useDebounce } from 'ahooks' import { useQueryState } from 'nuqs' @@ -201,7 +194,7 @@ function SkillPlaceholderState({
-
+
-
+
+

-
- - - - - - - - - - +
+